solargraph 0.50.0 → 0.58.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/linting.yml +127 -0
  4. data/.github/workflows/plugins.yml +218 -0
  5. data/.github/workflows/rspec.yml +58 -12
  6. data/.github/workflows/typecheck.yml +39 -0
  7. data/.gitignore +8 -0
  8. data/.overcommit.yml +72 -0
  9. data/.rspec +1 -0
  10. data/.rubocop.yml +66 -0
  11. data/.rubocop_todo.yml +1279 -0
  12. data/.yardopts +3 -2
  13. data/CHANGELOG.md +306 -3
  14. data/README.md +29 -18
  15. data/Rakefile +125 -13
  16. data/SPONSORS.md +2 -9
  17. data/bin/solargraph +3 -0
  18. data/lib/solargraph/api_map/cache.rb +110 -70
  19. data/lib/solargraph/api_map/constants.rb +279 -0
  20. data/lib/solargraph/api_map/index.rb +193 -0
  21. data/lib/solargraph/api_map/source_to_yard.rb +97 -81
  22. data/lib/solargraph/api_map/store.rb +384 -268
  23. data/lib/solargraph/api_map.rb +945 -704
  24. data/lib/solargraph/bench.rb +21 -3
  25. data/lib/solargraph/complex_type/type_methods.rb +228 -134
  26. data/lib/solargraph/complex_type/unique_type.rb +482 -132
  27. data/lib/solargraph/complex_type.rb +444 -254
  28. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  29. data/lib/solargraph/convention/base.rb +20 -3
  30. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
  31. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
  32. data/lib/solargraph/convention/data_definition.rb +105 -0
  33. data/lib/solargraph/convention/gemspec.rb +3 -2
  34. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -0
  35. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -0
  36. data/lib/solargraph/convention/struct_definition.rb +164 -0
  37. data/lib/solargraph/convention.rb +36 -7
  38. data/lib/solargraph/converters/dd.rb +5 -0
  39. data/lib/solargraph/converters/dl.rb +3 -0
  40. data/lib/solargraph/converters/dt.rb +3 -0
  41. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  42. data/lib/solargraph/diagnostics/rubocop.rb +118 -112
  43. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -65
  44. data/lib/solargraph/diagnostics/type_check.rb +55 -54
  45. data/lib/solargraph/diagnostics.rb +2 -2
  46. data/lib/solargraph/doc_map.rb +439 -0
  47. data/lib/solargraph/environ.rb +9 -2
  48. data/lib/solargraph/equality.rb +34 -0
  49. data/lib/solargraph/gem_pins.rb +98 -0
  50. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  51. data/lib/solargraph/language_server/host/dispatch.rb +130 -111
  52. data/lib/solargraph/language_server/host/message_worker.rb +112 -59
  53. data/lib/solargraph/language_server/host/sources.rb +99 -156
  54. data/lib/solargraph/language_server/host.rb +878 -869
  55. data/lib/solargraph/language_server/message/base.rb +20 -12
  56. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  57. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -100
  58. data/lib/solargraph/language_server/message/extended/document.rb +23 -20
  59. data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
  60. data/lib/solargraph/language_server/message/initialize.rb +28 -1
  61. data/lib/solargraph/language_server/message/initialized.rb +1 -0
  62. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -59
  63. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -38
  64. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -23
  65. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -126
  66. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -56
  67. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  68. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -0
  69. data/lib/solargraph/language_server/message/text_document.rb +1 -1
  70. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  71. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  72. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  73. data/lib/solargraph/language_server/message.rb +1 -0
  74. data/lib/solargraph/language_server/progress.rb +143 -0
  75. data/lib/solargraph/language_server/request.rb +4 -1
  76. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  77. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  78. data/lib/solargraph/language_server.rb +1 -0
  79. data/lib/solargraph/library.rb +683 -551
  80. data/lib/solargraph/location.rb +82 -37
  81. data/lib/solargraph/logging.rb +37 -27
  82. data/lib/solargraph/page.rb +9 -0
  83. data/lib/solargraph/parser/comment_ripper.rb +69 -52
  84. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -0
  85. data/lib/solargraph/parser/node_processor/base.rb +92 -77
  86. data/lib/solargraph/parser/node_processor.rb +62 -43
  87. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +149 -135
  88. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +4 -1
  89. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +166 -148
  90. data/lib/solargraph/parser/{legacy → parser_gem}/node_methods.rb +486 -325
  91. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +3 -2
  92. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -0
  93. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -0
  94. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +15 -15
  95. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +46 -42
  96. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +4 -3
  97. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +3 -2
  98. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +53 -63
  99. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +4 -3
  100. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +3 -2
  101. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -0
  102. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +40 -38
  103. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +29 -28
  104. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -0
  105. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +10 -9
  106. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -0
  107. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +17 -16
  108. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +38 -36
  109. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +52 -42
  110. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +291 -257
  111. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +4 -2
  112. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
  113. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
  114. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -0
  115. data/lib/solargraph/parser/parser_gem.rb +12 -0
  116. data/lib/solargraph/parser/region.rb +69 -66
  117. data/lib/solargraph/parser/snippet.rb +17 -13
  118. data/lib/solargraph/parser.rb +9 -12
  119. data/lib/solargraph/pin/base.rb +729 -299
  120. data/lib/solargraph/pin/base_variable.rb +126 -84
  121. data/lib/solargraph/pin/block.rb +104 -73
  122. data/lib/solargraph/pin/breakable.rb +9 -0
  123. data/lib/solargraph/pin/callable.rb +231 -0
  124. data/lib/solargraph/pin/closure.rb +72 -37
  125. data/lib/solargraph/pin/common.rb +79 -70
  126. data/lib/solargraph/pin/constant.rb +2 -0
  127. data/lib/solargraph/pin/conversions.rb +123 -92
  128. data/lib/solargraph/pin/delegated_method.rb +120 -0
  129. data/lib/solargraph/pin/documenting.rb +114 -105
  130. data/lib/solargraph/pin/instance_variable.rb +34 -30
  131. data/lib/solargraph/pin/keyword.rb +20 -15
  132. data/lib/solargraph/pin/local_variable.rb +75 -55
  133. data/lib/solargraph/pin/method.rb +672 -335
  134. data/lib/solargraph/pin/method_alias.rb +34 -31
  135. data/lib/solargraph/pin/namespace.rb +115 -94
  136. data/lib/solargraph/pin/parameter.rb +275 -206
  137. data/lib/solargraph/pin/proxy_type.rb +39 -29
  138. data/lib/solargraph/pin/reference/override.rb +47 -29
  139. data/lib/solargraph/pin/reference/require.rb +2 -2
  140. data/lib/solargraph/pin/reference/superclass.rb +15 -10
  141. data/lib/solargraph/pin/reference.rb +39 -14
  142. data/lib/solargraph/pin/search.rb +61 -56
  143. data/lib/solargraph/pin/signature.rb +61 -23
  144. data/lib/solargraph/pin/singleton.rb +1 -1
  145. data/lib/solargraph/pin/symbol.rb +53 -47
  146. data/lib/solargraph/pin/until.rb +18 -0
  147. data/lib/solargraph/pin/while.rb +18 -0
  148. data/lib/solargraph/pin.rb +44 -38
  149. data/lib/solargraph/pin_cache.rb +245 -0
  150. data/lib/solargraph/position.rb +132 -100
  151. data/lib/solargraph/range.rb +112 -95
  152. data/lib/solargraph/rbs_map/conversions.rb +823 -394
  153. data/lib/solargraph/rbs_map/core_fills.rb +53 -30
  154. data/lib/solargraph/rbs_map/core_map.rb +58 -38
  155. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -36
  156. data/lib/solargraph/rbs_map.rb +163 -73
  157. data/lib/solargraph/shell.rb +352 -244
  158. data/lib/solargraph/source/chain/array.rb +37 -0
  159. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  160. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  161. data/lib/solargraph/source/chain/call.rb +337 -215
  162. data/lib/solargraph/source/chain/constant.rb +26 -75
  163. data/lib/solargraph/source/chain/hash.rb +34 -28
  164. data/lib/solargraph/source/chain/head.rb +1 -1
  165. data/lib/solargraph/source/chain/if.rb +28 -0
  166. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  167. data/lib/solargraph/source/chain/link.rb +44 -6
  168. data/lib/solargraph/source/chain/literal.rb +48 -23
  169. data/lib/solargraph/source/chain/or.rb +23 -23
  170. data/lib/solargraph/source/chain/z_super.rb +4 -4
  171. data/lib/solargraph/source/chain.rb +291 -179
  172. data/lib/solargraph/source/change.rb +82 -79
  173. data/lib/solargraph/source/cursor.rb +166 -164
  174. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  175. data/lib/solargraph/source/source_chainer.rb +194 -191
  176. data/lib/solargraph/source/updater.rb +55 -54
  177. data/lib/solargraph/source.rb +498 -522
  178. data/lib/solargraph/source_map/clip.rb +226 -229
  179. data/lib/solargraph/source_map/data.rb +34 -0
  180. data/lib/solargraph/source_map/mapper.rb +259 -243
  181. data/lib/solargraph/source_map.rb +212 -180
  182. data/lib/solargraph/type_checker/checks.rb +124 -112
  183. data/lib/solargraph/type_checker/param_def.rb +37 -35
  184. data/lib/solargraph/type_checker/problem.rb +32 -32
  185. data/lib/solargraph/type_checker/rules.rb +84 -57
  186. data/lib/solargraph/type_checker.rb +814 -549
  187. data/lib/solargraph/version.rb +5 -5
  188. data/lib/solargraph/views/_method.erb +10 -10
  189. data/lib/solargraph/views/_namespace.erb +3 -3
  190. data/lib/solargraph/views/document.erb +10 -10
  191. data/lib/solargraph/views/environment.erb +3 -5
  192. data/lib/solargraph/workspace/config.rb +255 -231
  193. data/lib/solargraph/workspace/require_paths.rb +97 -0
  194. data/lib/solargraph/workspace.rb +220 -212
  195. data/lib/solargraph/yard_map/cache.rb +6 -0
  196. data/lib/solargraph/yard_map/helpers.rb +44 -16
  197. data/lib/solargraph/yard_map/mapper/to_constant.rb +8 -5
  198. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -81
  199. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -27
  200. data/lib/solargraph/yard_map/mapper.rb +79 -77
  201. data/lib/solargraph/yard_map/to_method.rb +89 -79
  202. data/lib/solargraph/yard_map.rb +1 -284
  203. data/lib/solargraph/yard_tags.rb +20 -0
  204. data/lib/solargraph/yardoc.rb +87 -0
  205. data/lib/solargraph.rb +105 -69
  206. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  207. data/rbs/fills/open3/0/open3.rbs +172 -0
  208. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  209. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  210. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  211. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  212. data/rbs/fills/tuple/tuple.rbs +149 -0
  213. data/rbs/shims/ast/0/node.rbs +5 -0
  214. data/rbs/shims/ast/2.4/.rbs_meta.yaml +9 -0
  215. data/rbs/shims/ast/2.4/ast.rbs +73 -0
  216. data/rbs/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  217. data/rbs/shims/parser/3.2.0.1/manifest.yaml +7 -0
  218. data/rbs/shims/parser/3.2.0.1/parser.rbs +201 -0
  219. data/rbs/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  220. data/rbs/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  221. data/rbs/shims/thor/1.2.0.1/manifest.yaml +7 -0
  222. data/rbs/shims/thor/1.2.0.1/thor.rbs +17 -0
  223. data/rbs_collection.yaml +19 -0
  224. data/solargraph.gemspec +39 -11
  225. metadata +354 -97
  226. data/lib/.rubocop.yml +0 -22
  227. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  228. data/lib/solargraph/cache.rb +0 -53
  229. data/lib/solargraph/convention/rspec.rb +0 -30
  230. data/lib/solargraph/documentor.rb +0 -76
  231. data/lib/solargraph/language_server/host/cataloger.rb +0 -56
  232. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  233. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -35
  234. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  235. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
  236. data/lib/solargraph/parser/legacy/node_processors.rb +0 -54
  237. data/lib/solargraph/parser/legacy.rb +0 -12
  238. data/lib/solargraph/parser/node_methods.rb +0 -43
  239. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -149
  240. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
  241. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -315
  242. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  243. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  244. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
  245. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  246. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
  247. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
  248. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  249. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  250. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  251. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  252. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  253. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  254. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  255. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  256. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -45
  257. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
  258. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  259. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
  260. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -63
  261. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
  262. data/lib/solargraph/parser/rubyvm.rb +0 -40
  263. data/lib/solargraph/rbs_map/core_signs.rb +0 -33
  264. data/lib/yard-solargraph.rb +0 -33
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yard'
4
- require 'yard-solargraph'
5
- require 'rubygems/package'
6
- require 'set'
4
+ require 'solargraph/yard_tags'
7
5
 
8
6
  module Solargraph
9
7
  # The YardMap provides access to YARD documentation for the Ruby core, the
@@ -14,288 +12,7 @@ module Solargraph
14
12
 
15
13
  autoload :Cache, 'solargraph/yard_map/cache'
16
14
  autoload :Mapper, 'solargraph/yard_map/mapper'
17
- autoload :RdocToYard, 'solargraph/yard_map/rdoc_to_yard'
18
15
  autoload :Helpers, 'solargraph/yard_map/helpers'
19
16
  autoload :ToMethod, 'solargraph/yard_map/to_method'
20
-
21
- include ApiMap::BundlerMethods
22
-
23
- # @return [Boolean]
24
- attr_writer :with_dependencies
25
-
26
- # @param required [Array<String>, Set<String>]
27
- # @param directory [String]
28
- # @param source_gems [Array<String>, Set<String>]
29
- # @param with_dependencies [Boolean]
30
- def initialize(required: [], directory: '', source_gems: [], with_dependencies: true)
31
- @with_dependencies = with_dependencies
32
- change required.to_set, directory, source_gems.to_set
33
- end
34
-
35
- # @return [Array<Solargraph::Pin::Base>]
36
- def pins
37
- @pins ||= []
38
- end
39
-
40
- def with_dependencies?
41
- @with_dependencies ||= true unless @with_dependencies == false
42
- @with_dependencies
43
- end
44
-
45
- # @param new_requires [Set<String>] Required paths to use for loading gems
46
- # @param new_directory [String] The workspace directory
47
- # @param new_source_gems [Set<String>] Gems under local development (i.e., part of the workspace)
48
- # @return [Boolean]
49
- def change new_requires, new_directory, new_source_gems
50
- return false if new_requires == base_required && new_directory == @directory && new_source_gems == @source_gems
51
- @gem_paths = {}
52
- base_required.replace new_requires
53
- required.replace new_requires
54
- # HACK: Hardcoded YAML handling
55
- required.add 'psych' if new_requires.include?('yaml')
56
- @source_gems = new_source_gems
57
- @directory = new_directory
58
- process_requires
59
- @rebindable_method_names = nil
60
- @pin_class_hash = nil
61
- @pin_select_cache = {}
62
- pins.each { |p| p.source = :yard }
63
- true
64
- end
65
-
66
- # @return [Set<String>]
67
- def rebindable_method_names
68
- @rebindable_method_names ||= pins_by_class(Pin::Method)
69
- .select { |pin| pin.comments && pin.comments.include?('@yieldself') }
70
- .map(&:name)
71
- .concat(['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec', 'define_method'])
72
- .to_set
73
- end
74
-
75
- # @return [Array<String>]
76
- def yardocs
77
- @yardocs ||= []
78
- end
79
-
80
- # @return [Set<String>]
81
- def required
82
- @required ||= Set.new
83
- end
84
-
85
- # @return [Array<String>]
86
- def unresolved_requires
87
- @unresolved_requires ||= []
88
- end
89
-
90
- # @return [Array<String>]
91
- def missing_docs
92
- @missing_docs ||= []
93
- end
94
-
95
- # @param y [String]
96
- # @return [YARD::Registry]
97
- def load_yardoc y
98
- if y.is_a?(Array)
99
- YARD::Registry.load y, true
100
- else
101
- YARD::Registry.load! y
102
- end
103
- rescue StandardError => e
104
- Solargraph::Logging.logger.warn "Error loading yardoc '#{y}' #{e.class} #{e.message}"
105
- yardocs.delete y
106
- nil
107
- end
108
-
109
- # @param path [String]
110
- # @return [Pin::Base]
111
- def path_pin path
112
- pins.select { |p| p.path == path }.first
113
- end
114
-
115
- # Get the location of a file referenced by a require path.
116
- #
117
- # @param path [String]
118
- # @return [Location]
119
- def require_reference path
120
- # @type [Gem::Specification]
121
- spec = spec_for_require(path)
122
- spec.full_require_paths.each do |rp|
123
- file = File.join(rp, "#{path}.rb")
124
- next unless File.file?(file)
125
- return Solargraph::Location.new(file, Solargraph::Range.from_to(0, 0, 0, 0))
126
- end
127
- nil
128
- rescue Gem::LoadError
129
- nil
130
- end
131
-
132
- def base_required
133
- @base_required ||= Set.new
134
- end
135
-
136
- def directory
137
- @directory ||= ''
138
- end
139
-
140
- private
141
-
142
- # @return [YardMap::Cache]
143
- def cache
144
- @cache ||= YardMap::Cache.new
145
- end
146
-
147
- # @return [Hash]
148
- def pin_class_hash
149
- @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
150
- end
151
-
152
- # @return [Array<Pin::Base>]
153
- def pins_by_class klass
154
- @pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
155
- end
156
-
157
- # @param ns [YARD::CodeObjects::NamespaceObject]
158
- # @return [Array<YARD::CodeObjects::Base>]
159
- def recurse_namespace_object ns
160
- result = []
161
- ns.children.each do |c|
162
- result.push c
163
- result.concat recurse_namespace_object(c) if c.respond_to?(:children)
164
- end
165
- result
166
- end
167
-
168
- # @return [void]
169
- def process_requires
170
- @gemset = process_gemsets
171
- required.merge @gemset.keys if required.include?('bundler/require')
172
- pins.clear
173
- unresolved_requires.clear
174
- missing_docs.clear
175
- environ = Convention.for_global(self)
176
- done = []
177
- already_errored = []
178
- (required + environ.requires).each do |r|
179
- next if r.nil? || r.empty? || done.include?(r)
180
- done.push r
181
- cached = cache.get_path_pins(r)
182
- unless cached.nil?
183
- pins.concat cached
184
- next
185
- end
186
- result = pins_for_require r, already_errored
187
- result.delete_if(&:nil?)
188
- unless result.empty?
189
- cache.set_path_pins r, result
190
- pins.concat result
191
- end
192
- end
193
- if required.include?('yaml') && required.include?('psych')
194
- # HACK: Hardcoded YAML handling
195
- # @todo Why can't this be handled with an override or a virtual pin?
196
- pin = path_pin('YAML')
197
- pin.instance_variable_set(:@return_type, ComplexType.parse('Module<Psych>')) unless pin.nil?
198
- end
199
- pins.concat environ.pins
200
- end
201
-
202
- def process_error(req, result, already_errored, yd = 1)
203
- base = req.split('/').first
204
- return if already_errored.include?(base)
205
- already_errored.push base
206
- if yd.nil?
207
- missing_docs.push req
208
- else
209
- unresolved_requires.push req
210
- end
211
- end
212
-
213
- def process_gemsets
214
- return {} if directory.empty? || !File.file?(File.join(directory, 'Gemfile'))
215
- require_from_bundle(directory)
216
- end
217
-
218
- # @param r [String]
219
- def pins_for_require r, already_errored
220
- result = []
221
- begin
222
- name = r.split('/').first.to_s
223
- return [] if name.empty? || @source_gems.include?(name) || @gem_paths.key?(name)
224
- spec = spec_for_require(name)
225
- @gem_paths[name] = spec.full_gem_path
226
-
227
- yd = yardoc_file_for_spec(spec)
228
- # YARD detects gems for certain libraries that do not have a yardoc
229
- # but exist in the stdlib. `fileutils` is an example. Treat those
230
- # cases as errors and check the stdlib yardoc.
231
- if yd.nil?
232
- process_error(r, result, already_errored, nil)
233
- return []
234
- end
235
- unless yardocs.include?(yd)
236
- yardocs.unshift yd
237
- result.concat process_yardoc yd, spec
238
- if with_dependencies?
239
- (spec.dependencies - spec.development_dependencies).each do |dep|
240
- result.concat pins_for_require dep.name, already_errored
241
- end
242
- end
243
- end
244
- rescue Gem::LoadError, NoYardocError
245
- process_error(r, result, already_errored)
246
- end
247
- return result
248
- end
249
-
250
- # @param y [String, nil]
251
- # @param spec [Gem::Specification, nil]
252
- # @return [Array<Pin::Base>]
253
- def process_yardoc y, spec = nil
254
- return [] if y.nil?
255
- if spec
256
- cache = Solargraph::Cache.load('gems', "#{spec.name}-#{spec.version}.ser")
257
- return cache if cache
258
- end
259
- size = Dir.glob(File.join(y, '**', '*'))
260
- .map{ |f| File.size(f) }
261
- .inject(:+)
262
- if !size.nil? && size > 20_000_000
263
- Solargraph::Logging.logger.warn "Yardoc at #{y} is too large to process (#{size} bytes)"
264
- return []
265
- end
266
- Solargraph.logger.info "Loading #{spec.name} #{spec.version} from #{y}"
267
- load_yardoc y
268
- result = Mapper.new(YARD::Registry.all, spec).map
269
- raise NoYardocError, "Yardoc at #{y} is empty" if result.empty?
270
- if spec
271
- Solargraph::Cache.save 'gems', "#{spec.name}-#{spec.version}.ser", result
272
- end
273
- result
274
- end
275
-
276
- # @param spec [Gem::Specification]
277
- # @return [String]
278
- def yardoc_file_for_spec spec
279
- YARD::Registry.yardoc_file_for_gem(spec.name, "= #{spec.version}")
280
- end
281
-
282
- # @param path [String]
283
- # @return [Gem::Specification]
284
- def spec_for_require path
285
- name = path.split('/').first.to_s
286
- spec = Gem::Specification.find_by_name(name, @gemset[name])
287
-
288
- # Avoid loading the spec again if it's going to be skipped anyway
289
- return spec if @source_gems.include?(spec.name)
290
- # Avoid loading the spec again if it's already the correct version
291
- if @gemset[spec.name] && @gemset[spec.name] != spec.version
292
- begin
293
- return Gem::Specification.find_by_name(spec.name, "= #{@gemset[spec.name]}")
294
- rescue Gem::LoadError
295
- Solargraph.logger.warn "Unable to load #{spec.name} #{@gemset[spec.name]} specified by workspace, using #{spec.version} instead"
296
- end
297
- end
298
- spec
299
- end
300
17
  end
301
18
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yard'
4
+
5
+ # Change YARD log IO to avoid sending unexpected messages to STDOUT
6
+ YARD::Logger.instance.io = File.new(File::NULL, 'w')
7
+
8
+ module Solargraph
9
+ # A placeholder for the @!domain directive. It doesn't need to do anything
10
+ # for yardocs. It's only used for Solargraph API maps.
11
+ class DomainDirective < YARD::Tags::Directive
12
+ def call; end
13
+ end
14
+ end
15
+
16
+ # Define a @type tag for documenting variables
17
+ YARD::Tags::Library.define_tag("Type", :type, :with_types_and_name)
18
+
19
+ # Define an @!override directive for overriding method tags
20
+ YARD::Tags::Library.define_directive("override", :with_name, Solargraph::DomainDirective)
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ module Solargraph
6
+ # Methods for caching and loading YARD documentation for gems.
7
+ #
8
+ module Yardoc
9
+ module_function
10
+
11
+ # Build and cache a gem's yardoc and return the path. If the cache already
12
+ # exists, do nothing and return the path.
13
+ #
14
+ # @param yard_plugins [Array<String>] The names of YARD plugins to use.
15
+ # @param gemspec [Gem::Specification]
16
+ # @return [String] The path to the cached yardoc.
17
+ def cache(yard_plugins, gemspec)
18
+ path = PinCache.yardoc_path gemspec
19
+ return path if cached?(gemspec)
20
+
21
+ unless Dir.exist? gemspec.gem_dir
22
+ # Can happen in at least some (old?) RubyGems versions when we
23
+ # have a gemspec describing a standard library like bundler.
24
+ #
25
+ # https://github.com/apiology/solargraph/actions/runs/17650140201/job/50158676842?pr=10
26
+ Solargraph.logger.info { "Bad info from gemspec - #{gemspec.gem_dir} does not exist" }
27
+ return path
28
+ end
29
+
30
+ Solargraph.logger.info "Caching yardoc for #{gemspec.name} #{gemspec.version}"
31
+ cmd = "yardoc --db #{path} --no-output --plugin solargraph"
32
+ yard_plugins.each { |plugin| cmd << " --plugin #{plugin}" }
33
+ Solargraph.logger.debug { "Running: #{cmd}" }
34
+ # @todo set these up to run in parallel
35
+ stdout_and_stderr_str, status = Open3.capture2e(current_bundle_env_tweaks, cmd, chdir: gemspec.gem_dir)
36
+ unless status.success?
37
+ Solargraph.logger.warn { "YARD failed running #{cmd.inspect} in #{gemspec.gem_dir}" }
38
+ Solargraph.logger.info stdout_and_stderr_str
39
+ end
40
+ path
41
+ end
42
+
43
+ # True if the gem yardoc is cached.
44
+ #
45
+ # @param gemspec [Gem::Specification]
46
+ def cached?(gemspec)
47
+ yardoc = File.join(PinCache.yardoc_path(gemspec), 'complete')
48
+ File.exist?(yardoc)
49
+ end
50
+
51
+ # True if another process is currently building the yardoc cache.
52
+ #
53
+ # @param gemspec [Gem::Specification]
54
+ def processing?(gemspec)
55
+ yardoc = File.join(PinCache.yardoc_path(gemspec), 'processing')
56
+ File.exist?(yardoc)
57
+ end
58
+
59
+ # Load a gem's yardoc and return its code objects.
60
+ #
61
+ # @note This method modifies the global YARD registry.
62
+ #
63
+ # @param gemspec [Gem::Specification]
64
+ # @return [Array<YARD::CodeObjects::Base>]
65
+ def load!(gemspec)
66
+ YARD::Registry.load! PinCache.yardoc_path gemspec
67
+ YARD::Registry.all
68
+ end
69
+
70
+ # If the BUNDLE_GEMFILE environment variable is set, we need to
71
+ # make sure it's an absolute path, as we'll be changing
72
+ # directories.
73
+ #
74
+ # 'bundle exec' sets an absolute path here, but at least the
75
+ # overcommit gem does not, breaking on-the-fly documention with a
76
+ # spawned yardoc command from our current bundle
77
+ #
78
+ # @return [Hash{String => String}] a hash of environment variables to override
79
+ def current_bundle_env_tweaks
80
+ tweaks = {}
81
+ if ENV['BUNDLE_GEMFILE'] && !ENV['BUNDLE_GEMFILE'].empty?
82
+ tweaks['BUNDLE_GEMFILE'] = File.expand_path(ENV['BUNDLE_GEMFILE'])
83
+ end
84
+ tweaks
85
+ end
86
+ end
87
+ end
data/lib/solargraph.rb CHANGED
@@ -1,69 +1,105 @@
1
- # frozen_string_literal: true
2
-
3
- Encoding.default_external = 'UTF-8'
4
-
5
- require 'solargraph/version'
6
-
7
- # The top-level namespace for the Solargraph code mapping, documentation,
8
- # static analysis, and language server libraries.
9
- #
10
- module Solargraph
11
- class InvalidOffsetError < RangeError; end
12
- class DiagnosticsError < RuntimeError; end
13
- class FileNotFoundError < RuntimeError; end
14
- class SourceNotAvailableError < StandardError; end
15
- class ComplexTypeError < StandardError; end
16
- class WorkspaceTooLargeError < RuntimeError; end
17
- class BundleNotFoundError < StandardError; end
18
- class InvalidRubocopVersionError < RuntimeError; end
19
-
20
- autoload :Position, 'solargraph/position'
21
- autoload :Range, 'solargraph/range'
22
- autoload :Location, 'solargraph/location'
23
- autoload :Shell, 'solargraph/shell'
24
- autoload :Source, 'solargraph/source'
25
- autoload :SourceMap, 'solargraph/source_map'
26
- autoload :ApiMap, 'solargraph/api_map'
27
- autoload :YardMap, 'solargraph/yard_map'
28
- autoload :Pin, 'solargraph/pin'
29
- autoload :ServerMethods, 'solargraph/server_methods'
30
- autoload :LanguageServer, 'solargraph/language_server'
31
- autoload :Workspace, 'solargraph/workspace'
32
- autoload :Page, 'solargraph/page'
33
- autoload :Library, 'solargraph/library'
34
- autoload :Diagnostics, 'solargraph/diagnostics'
35
- autoload :ComplexType, 'solargraph/complex_type'
36
- autoload :Bench, 'solargraph/bench'
37
- autoload :Logging, 'solargraph/logging'
38
- autoload :TypeChecker, 'solargraph/type_checker'
39
- autoload :Environ, 'solargraph/environ'
40
- autoload :Convention, 'solargraph/convention'
41
- autoload :Documentor, 'solargraph/documentor'
42
- autoload :Parser, 'solargraph/parser'
43
- autoload :RbsMap, 'solargraph/rbs_map'
44
- autoload :Cache, 'solargraph/cache'
45
-
46
- dir = File.dirname(__FILE__)
47
- YARD_EXTENSION_FILE = File.join(dir, 'yard-solargraph.rb')
48
- VIEWS_PATH = File.join(dir, 'solargraph', 'views')
49
-
50
- # A convenience method for Solargraph::Logging.logger.
51
- #
52
- # @return [Logger]
53
- def self.logger
54
- Solargraph::Logging.logger
55
- end
56
-
57
- # A helper method that runs Bundler.with_unbundled_env or falls back to
58
- # Bundler.with_clean_env for earlier versions of Bundler.
59
- #
60
- # @return [void]
61
- def self.with_clean_env &block
62
- meth = if Bundler.respond_to?(:with_original_env)
63
- :with_original_env
64
- else
65
- :with_clean_env
66
- end
67
- Bundler.send meth, &block
68
- end
69
- end
1
+ # frozen_string_literal: true
2
+
3
+ Encoding.default_external = 'UTF-8'
4
+
5
+ require 'bundler'
6
+ require 'set'
7
+ require 'yard-solargraph'
8
+ require 'solargraph/yard_tags'
9
+ require 'solargraph/version'
10
+
11
+ # The top-level namespace for the Solargraph code mapping, documentation,
12
+ # static analysis, and language server libraries.
13
+ #
14
+ module Solargraph
15
+ class InvalidOffsetError < RangeError; end
16
+ class DiagnosticsError < RuntimeError; end
17
+ class FileNotFoundError < RuntimeError; end
18
+ class SourceNotAvailableError < StandardError; end
19
+ class ComplexTypeError < StandardError; end
20
+ class WorkspaceTooLargeError < RuntimeError; end
21
+ class BundleNotFoundError < StandardError; end
22
+ class InvalidRubocopVersionError < RuntimeError; end
23
+
24
+ autoload :Position, 'solargraph/position'
25
+ autoload :Range, 'solargraph/range'
26
+ autoload :Location, 'solargraph/location'
27
+ autoload :Shell, 'solargraph/shell'
28
+ autoload :Source, 'solargraph/source'
29
+ autoload :SourceMap, 'solargraph/source_map'
30
+ autoload :ApiMap, 'solargraph/api_map'
31
+ autoload :Yardoc, 'solargraph/yardoc'
32
+ autoload :YardMap, 'solargraph/yard_map'
33
+ autoload :Pin, 'solargraph/pin'
34
+ autoload :DocMap, 'solargraph/doc_map'
35
+ autoload :ServerMethods, 'solargraph/server_methods'
36
+ autoload :LanguageServer, 'solargraph/language_server'
37
+ autoload :Workspace, 'solargraph/workspace'
38
+ autoload :Page, 'solargraph/page'
39
+ autoload :Library, 'solargraph/library'
40
+ autoload :Diagnostics, 'solargraph/diagnostics'
41
+ autoload :ComplexType, 'solargraph/complex_type'
42
+ autoload :Bench, 'solargraph/bench'
43
+ autoload :Logging, 'solargraph/logging'
44
+ autoload :TypeChecker, 'solargraph/type_checker'
45
+ autoload :Environ, 'solargraph/environ'
46
+ autoload :Equality, 'solargraph/equality'
47
+ autoload :Convention, 'solargraph/convention'
48
+ autoload :Parser, 'solargraph/parser'
49
+ autoload :RbsMap, 'solargraph/rbs_map'
50
+ autoload :GemPins, 'solargraph/gem_pins'
51
+ autoload :PinCache, 'solargraph/pin_cache'
52
+
53
+ dir = File.dirname(__FILE__)
54
+ VIEWS_PATH = File.join(dir, 'solargraph', 'views')
55
+
56
+ CHDIR_MUTEX = Mutex.new
57
+
58
+ # @param type [Symbol] Type of assert.
59
+ def self.asserts_on?(type)
60
+ if ENV['SOLARGRAPH_ASSERTS'].nil? || ENV['SOLARGRAPH_ASSERTS'].empty?
61
+ false
62
+ elsif ENV['SOLARGRAPH_ASSERTS'] == 'on'
63
+ true
64
+ else
65
+ logger.warn "Unrecognized SOLARGRAPH_ASSERTS value: #{ENV['SOLARGRAPH_ASSERTS']}"
66
+ false
67
+ end
68
+ end
69
+
70
+ # @param type [Symbol] The type of assertion to perform.
71
+ # @param msg [String, nil] An optional message to log
72
+ # @param block [Proc] A block that returns a message to log
73
+ # @return [void]
74
+ def self.assert_or_log(type, msg = nil, &block)
75
+ raise (msg || block.call) if asserts_on?(type) && ![:combine_with_visibility].include?(type)
76
+ logger.info msg, &block
77
+ end
78
+
79
+ # A convenience method for Solargraph::Logging.logger.
80
+ #
81
+ # @return [Logger]
82
+ def self.logger
83
+ Solargraph::Logging.logger
84
+ end
85
+
86
+ # A helper method that runs Bundler.with_unbundled_env or falls back to
87
+ # Bundler.with_clean_env for earlier versions of Bundler.
88
+ #
89
+ # @generic T
90
+ # @yieldreturn [generic<T>]
91
+ # @sg-ignore dynamic call, but both functions behave the same
92
+ # @return [generic<T>]
93
+ def self.with_clean_env &block
94
+ meth = if Bundler.respond_to?(:with_original_env)
95
+ :with_original_env
96
+ else
97
+ :with_clean_env
98
+ end
99
+ Bundler.send meth, &block
100
+ end
101
+ end
102
+
103
+ # Ensure that ParserGem node processors are properly loaded to avoid conflicts
104
+ # with Convention node processors
105
+ require 'solargraph/parser/parser_gem/node_processors'