solargraph 0.59.0.dev.1 → 0.59.0

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 (175) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linting.yml +3 -1
  3. data/.github/workflows/plugins.yml +12 -3
  4. data/.github/workflows/rspec.yml +9 -54
  5. data/.github/workflows/typecheck.yml +2 -1
  6. data/.gitignore +1 -0
  7. data/.rubocop.yml +38 -6
  8. data/.rubocop_todo.yml +40 -931
  9. data/CHANGELOG.md +22 -1
  10. data/Gemfile +3 -1
  11. data/Rakefile +25 -23
  12. data/bin/solargraph +2 -1
  13. data/lib/solargraph/api_map/constants.rb +0 -1
  14. data/lib/solargraph/api_map/index.rb +11 -11
  15. data/lib/solargraph/api_map/source_to_yard.rb +9 -8
  16. data/lib/solargraph/api_map/store.rb +28 -20
  17. data/lib/solargraph/api_map.rb +70 -41
  18. data/lib/solargraph/bench.rb +44 -45
  19. data/lib/solargraph/complex_type/type_methods.rb +14 -16
  20. data/lib/solargraph/complex_type/unique_type.rb +56 -47
  21. data/lib/solargraph/complex_type.rb +70 -62
  22. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  23. data/lib/solargraph/convention/data_definition/data_definition_node.rb +4 -4
  24. data/lib/solargraph/convention/data_definition.rb +1 -1
  25. data/lib/solargraph/convention/gemfile.rb +15 -15
  26. data/lib/solargraph/convention/gemspec.rb +23 -23
  27. data/lib/solargraph/convention/rakefile.rb +17 -17
  28. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -1
  29. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +3 -3
  30. data/lib/solargraph/convention/struct_definition.rb +3 -3
  31. data/lib/solargraph/convention.rb +78 -78
  32. data/lib/solargraph/converters/dd.rb +19 -17
  33. data/lib/solargraph/converters/dl.rb +17 -15
  34. data/lib/solargraph/converters/dt.rb +17 -15
  35. data/lib/solargraph/converters/misc.rb +3 -1
  36. data/lib/solargraph/diagnostics/rubocop.rb +10 -10
  37. data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -3
  38. data/lib/solargraph/diagnostics/type_check.rb +10 -10
  39. data/lib/solargraph/diagnostics/update_errors.rb +37 -41
  40. data/lib/solargraph/doc_map.rb +370 -132
  41. data/lib/solargraph/equality.rb +3 -3
  42. data/lib/solargraph/gem_pins.rb +19 -18
  43. data/lib/solargraph/language_server/error_codes.rb +20 -20
  44. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  45. data/lib/solargraph/language_server/host/dispatch.rb +2 -3
  46. data/lib/solargraph/language_server/host/message_worker.rb +2 -2
  47. data/lib/solargraph/language_server/host/sources.rb +1 -1
  48. data/lib/solargraph/language_server/host.rb +24 -21
  49. data/lib/solargraph/language_server/message/base.rb +97 -97
  50. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
  51. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
  52. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +10 -11
  53. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  54. data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
  55. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  56. data/lib/solargraph/language_server/message/initialize.rb +197 -191
  57. data/lib/solargraph/language_server/message/text_document/completion.rb +8 -8
  58. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -34
  59. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
  60. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -21
  61. data/lib/solargraph/language_server/message/text_document/formatting.rb +6 -6
  62. data/lib/solargraph/language_server/message/text_document/hover.rb +3 -5
  63. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
  64. data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
  65. data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
  66. data/lib/solargraph/language_server/message/text_document/signature_help.rb +2 -2
  67. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -19
  68. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
  69. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
  70. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
  71. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -19
  72. data/lib/solargraph/language_server/message.rb +94 -94
  73. data/lib/solargraph/language_server/request.rb +29 -27
  74. data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
  75. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  76. data/lib/solargraph/library.rb +68 -95
  77. data/lib/solargraph/location.rb +10 -12
  78. data/lib/solargraph/logging.rb +4 -6
  79. data/lib/solargraph/page.rb +92 -92
  80. data/lib/solargraph/parser/comment_ripper.rb +12 -4
  81. data/lib/solargraph/parser/flow_sensitive_typing.rb +32 -44
  82. data/lib/solargraph/parser/node_processor/base.rb +4 -4
  83. data/lib/solargraph/parser/node_processor.rb +1 -1
  84. data/lib/solargraph/parser/parser_gem/class_methods.rb +4 -6
  85. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  86. data/lib/solargraph/parser/parser_gem/node_chainer.rb +20 -20
  87. data/lib/solargraph/parser/parser_gem/node_methods.rb +66 -65
  88. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +12 -12
  89. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +1 -2
  90. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +3 -3
  91. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
  92. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +3 -3
  93. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +2 -1
  94. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +1 -1
  95. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +3 -5
  96. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +118 -112
  97. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  98. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +1 -1
  99. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +1 -1
  100. data/lib/solargraph/parser/parser_gem.rb +14 -12
  101. data/lib/solargraph/parser/snippet.rb +2 -0
  102. data/lib/solargraph/parser.rb +25 -23
  103. data/lib/solargraph/pin/base.rb +76 -64
  104. data/lib/solargraph/pin/base_variable.rb +28 -71
  105. data/lib/solargraph/pin/block.rb +3 -2
  106. data/lib/solargraph/pin/breakable.rb +2 -0
  107. data/lib/solargraph/pin/callable.rb +23 -26
  108. data/lib/solargraph/pin/closure.rb +5 -4
  109. data/lib/solargraph/pin/common.rb +5 -2
  110. data/lib/solargraph/pin/compound_statement.rb +3 -3
  111. data/lib/solargraph/pin/constant.rb +43 -45
  112. data/lib/solargraph/pin/conversions.rb +9 -4
  113. data/lib/solargraph/pin/delegated_method.rb +4 -4
  114. data/lib/solargraph/pin/documenting.rb +3 -2
  115. data/lib/solargraph/pin/local_variable.rb +4 -4
  116. data/lib/solargraph/pin/method.rb +74 -70
  117. data/lib/solargraph/pin/namespace.rb +13 -12
  118. data/lib/solargraph/pin/parameter.rb +28 -27
  119. data/lib/solargraph/pin/proxy_type.rb +2 -0
  120. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  121. data/lib/solargraph/pin/reference.rb +18 -0
  122. data/lib/solargraph/pin/search.rb +2 -2
  123. data/lib/solargraph/pin/signature.rb +9 -14
  124. data/lib/solargraph/pin/symbol.rb +1 -0
  125. data/lib/solargraph/pin/until.rb +1 -3
  126. data/lib/solargraph/pin/while.rb +1 -3
  127. data/lib/solargraph/pin_cache.rb +71 -488
  128. data/lib/solargraph/position.rb +38 -17
  129. data/lib/solargraph/range.rb +10 -9
  130. data/lib/solargraph/rbs_map/conversions.rb +327 -221
  131. data/lib/solargraph/rbs_map/core_fills.rb +91 -84
  132. data/lib/solargraph/rbs_map/stdlib_map.rb +0 -1
  133. data/lib/solargraph/rbs_map.rb +5 -15
  134. data/lib/solargraph/server_methods.rb +16 -16
  135. data/lib/solargraph/shell.rb +224 -66
  136. data/lib/solargraph/source/chain/array.rb +39 -37
  137. data/lib/solargraph/source/chain/call.rb +49 -44
  138. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  139. data/lib/solargraph/source/chain/constant.rb +3 -1
  140. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  141. data/lib/solargraph/source/chain/hash.rb +8 -6
  142. data/lib/solargraph/source/chain/if.rb +11 -10
  143. data/lib/solargraph/source/chain/instance_variable.rb +3 -1
  144. data/lib/solargraph/source/chain/link.rb +99 -109
  145. data/lib/solargraph/source/chain/literal.rb +4 -6
  146. data/lib/solargraph/source/chain/or.rb +2 -4
  147. data/lib/solargraph/source/chain/q_call.rb +13 -11
  148. data/lib/solargraph/source/chain/variable.rb +15 -13
  149. data/lib/solargraph/source/chain/z_super.rb +28 -30
  150. data/lib/solargraph/source/chain.rb +26 -16
  151. data/lib/solargraph/source/change.rb +3 -3
  152. data/lib/solargraph/source/cursor.rb +18 -18
  153. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  154. data/lib/solargraph/source/source_chainer.rb +46 -32
  155. data/lib/solargraph/source/updater.rb +1 -1
  156. data/lib/solargraph/source.rb +27 -29
  157. data/lib/solargraph/source_map/clip.rb +38 -30
  158. data/lib/solargraph/source_map/mapper.rb +51 -47
  159. data/lib/solargraph/source_map.rb +8 -4
  160. data/lib/solargraph/type_checker/rules.rb +8 -8
  161. data/lib/solargraph/type_checker.rb +95 -102
  162. data/lib/solargraph/version.rb +1 -1
  163. data/lib/solargraph/workspace/config.rb +11 -10
  164. data/lib/solargraph/workspace/gemspecs.rb +3 -3
  165. data/lib/solargraph/workspace.rb +45 -165
  166. data/lib/solargraph/yard_map/helpers.rb +6 -2
  167. data/lib/solargraph/yard_map/mapper/to_method.rb +8 -6
  168. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -1
  169. data/lib/solargraph/yard_map/mapper.rb +12 -12
  170. data/lib/solargraph/yard_map.rb +17 -18
  171. data/lib/solargraph/yard_tags.rb +20 -20
  172. data/lib/solargraph/yardoc.rb +26 -33
  173. data/lib/solargraph.rb +7 -5
  174. data/solargraph.gemspec +36 -35
  175. metadata +33 -38
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'open3'
4
4
  require 'json'
5
- require 'yaml'
6
5
 
7
6
  module Solargraph
8
7
  # A workspace consists of the files in a project's directory and the
@@ -10,8 +9,6 @@ module Solargraph
10
9
  # in an associated Library or ApiMap.
11
10
  #
12
11
  class Workspace
13
- include Logging
14
-
15
12
  autoload :Config, 'solargraph/workspace/config'
16
13
  autoload :Gemspecs, 'solargraph/workspace/gemspecs'
17
14
  autoload :RequirePaths, 'solargraph/workspace/require_paths'
@@ -23,8 +20,7 @@ module Solargraph
23
20
  attr_reader :gemnames
24
21
  alias source_gems gemnames
25
22
 
26
- # @todo Remove '' and '*' special cases
27
- # @param directory [String]
23
+ # @param directory [String] TODO: Remove '' and '*' special cases
28
24
  # @param config [Config, nil]
29
25
  # @param server [Hash]
30
26
  def initialize directory = '', config = nil, server = {}
@@ -55,79 +51,9 @@ module Solargraph
55
51
  @config ||= Solargraph::Workspace::Config.new(directory)
56
52
  end
57
53
 
58
- # @param stdlib_name [String]
59
- #
60
- # @return [Array<String>]
61
- def stdlib_dependencies stdlib_name
62
- gemspecs.stdlib_dependencies(stdlib_name)
63
- end
64
-
65
- # @param out [IO, nil] output stream for logging
66
- # @param gemspec [Gem::Specification]
67
- # @return [Array<Gem::Specification>]
68
- def fetch_dependencies gemspec, out: $stderr
69
- gemspecs.fetch_dependencies(gemspec, out: out)
70
- end
71
-
72
- # @param require [String] The string sent to 'require' in the code to resolve, e.g. 'rails', 'bundler/require'
73
- # @return [Array<Gem::Specification>, nil]
74
- def resolve_require require
75
- gemspecs.resolve_require(require)
76
- end
77
-
78
- # @return [Solargraph::PinCache]
79
- def pin_cache
80
- @pin_cache ||= fresh_pincache
81
- end
82
-
83
- # @param stdlib_name [String]
84
- #
85
- # @return [Array<String>]
86
- def stdlib_dependencies stdlib_name
87
- deps = RbsMap::StdlibMap.stdlib_dependencies(stdlib_name, nil) || []
88
- deps.map { |dep| dep['name'] }.compact
89
- end
90
-
91
- # @return [Environ]
92
- def global_environ
93
- # empty docmap, since the result needs to work in any possible
94
- # context here
95
- @global_environ ||= Convention.for_global(DocMap.new([], self, out: nil))
96
- end
97
-
98
- # @param gemspec [Gem::Specification]
99
- # @param out [StringIO, IO, nil] output stream for logging
100
- # @param rebuild [Boolean] whether to rebuild the pins even if they are cached
101
- #
102
- # @return [void]
103
- def cache_gem gemspec, out: nil, rebuild: false
104
- pin_cache.cache_gem(gemspec: gemspec, out: out, rebuild: rebuild)
105
- end
106
-
107
- # @param gemspec [Gem::Specification, Bundler::LazySpecification]
108
- # @param out [StringIO, IO, nil] output stream for logging
109
- #
110
- # @return [void]
111
- def uncache_gem gemspec, out: nil
112
- pin_cache.uncache_gem(gemspec, out: out)
113
- end
114
-
115
- # @return [Solargraph::PinCache]
116
- def fresh_pincache
117
- PinCache.new(rbs_collection_path: rbs_collection_path,
118
- rbs_collection_config_path: rbs_collection_config_path,
119
- yard_plugins: yard_plugins,
120
- directory: directory)
121
- end
122
-
123
- # @return [Array<String>]
124
- def yard_plugins
125
- @yard_plugins ||= global_environ.yard_plugins.sort.uniq
126
- end
127
-
128
54
  # @param level [Symbol]
129
55
  # @return [TypeChecker::Rules]
130
- def rules(level)
56
+ def rules level
131
57
  @rules ||= TypeChecker::Rules.new(level, config.type_checker_rules)
132
58
  end
133
59
 
@@ -138,7 +64,6 @@ module Solargraph
138
64
  # @param sources [Array<Solargraph::Source>]
139
65
  # @return [Boolean] True if the source was added to the workspace
140
66
  def merge *sources
141
- # @sg-ignore Need to add nil check here
142
67
  unless directory == '*' || sources.all? { |source| source_hash.key?(source.filename) }
143
68
  # Reload the config to determine if a new source should be included
144
69
  @config = Solargraph::Workspace::Config.new(directory)
@@ -146,10 +71,9 @@ module Solargraph
146
71
 
147
72
  includes_any = false
148
73
  sources.each do |source|
149
- # @sg-ignore Need to add nil check here
150
- next unless directory == "*" || config.calculated.include?(source.filename)
74
+ next unless directory == '*' || config.calculated.include?(source.filename)
151
75
 
152
- # @sg-ignore Need to add nil check here
76
+ # @sg-ignore Wrong argument type for Hash#[]=: arg0 expected String, received String, nil
153
77
  source_hash[source.filename] = source
154
78
  includes_any = true
155
79
  end
@@ -199,42 +123,22 @@ module Solargraph
199
123
  def would_require? path
200
124
  require_paths.each do |rp|
201
125
  full = File.join rp, path
202
- return true if File.file?(full) || File.file?(full << ".rb")
126
+ return true if File.file?(full) || File.file?(full << '.rb')
203
127
  end
204
128
  false
205
129
  end
206
130
 
207
- # True if the workspace contains at least one gemspec file.
208
- #
209
- # @return [Boolean]
210
- def gemspec?
211
- !gemspec_files.empty?
212
- end
213
-
214
- # Get an array of all gemspec files in the workspace.
215
- #
216
- # @return [Array<String>]
217
- def gemspec_files
218
- return [] if directory.empty? || directory == '*'
219
- @gemspec_files ||= Dir[File.join(directory, '**/*.gemspec')].select do |gs|
220
- config.allow? gs
221
- end
222
- end
223
-
224
131
  # @return [String, nil]
225
132
  def rbs_collection_path
226
- @gem_rbs_collection ||= read_rbs_collection_path
133
+ @rbs_collection_path ||= read_rbs_collection_path
227
134
  end
228
135
 
229
136
  # @return [String, nil]
230
137
  def rbs_collection_config_path
231
- @rbs_collection_config_path ||=
232
- begin
233
- unless directory.empty? || directory == '*'
234
- yaml_file = File.join(directory, 'rbs_collection.yaml')
235
- yaml_file if File.file?(yaml_file)
236
- end
237
- end
138
+ @rbs_collection_config_path ||= unless directory.empty? || directory == '*'
139
+ yaml_file = File.join(directory, 'rbs_collection.yaml')
140
+ yaml_file if File.file?(yaml_file)
141
+ end
238
142
  end
239
143
 
240
144
  # @param name [String]
@@ -243,42 +147,7 @@ module Solargraph
243
147
  #
244
148
  # @return [Gem::Specification, nil]
245
149
  def find_gem name, version = nil, out: nil
246
- gemspecs.find_gem(name, version, out: out)
247
- end
248
-
249
- # @return [Array<Gem::Specification>]
250
- def all_gemspecs_from_bundle
251
- gemspecs.all_gemspecs_from_bundle
252
- end
253
-
254
- # @todo make this actually work against bundle instead of pulling
255
- # all installed gemspecs -
256
- # https://github.com/apiology/solargraph/pull/10
257
- # @return [Array<Gem::Specification>]
258
- def all_gemspecs_from_bundle
259
- Gem::Specification.to_a
260
- end
261
-
262
- # @param out [StringIO, IO, nil] output stream for logging
263
- # @param rebuild [Boolean] whether to rebuild the pins even if they are cached
264
- # @return [void]
265
- def cache_all_for_workspace! out, rebuild: false
266
- PinCache.cache_core(out: out) unless PinCache.core? && !rebuild
267
-
268
- gem_specs = all_gemspecs_from_bundle
269
- # try any possible standard libraries, but be quiet about it
270
- stdlib_specs = pin_cache.possible_stdlibs.map { |stdlib| find_gem(stdlib, out: nil) }.compact
271
- specs = (gem_specs + stdlib_specs)
272
- specs.each do |spec|
273
- pin_cache.cache_gem(gemspec: spec, rebuild: rebuild, out: out) unless pin_cache.cached?(spec)
274
- end
275
- out&.puts "Documentation cached for all #{specs.length} gems."
276
-
277
- # do this after so that we prefer stdlib requires from gems,
278
- # which are likely to be newer and have more pins
279
- pin_cache.cache_all_stdlibs(out: out, rebuild: rebuild)
280
-
281
- out&.puts "Documentation cached for core, standard library and gems."
150
+ Gem::Specification.find_by_name(name, version)
282
151
  end
283
152
 
284
153
  # Synchronize the workspace from the provided updater.
@@ -289,9 +158,8 @@ module Solargraph
289
158
  source_hash[updater.filename] = source_hash[updater.filename].synchronize(updater)
290
159
  end
291
160
 
292
- # @sg-ignore Need to validate config
161
+ # @sg-ignore return type could not be inferred
293
162
  # @return [String]
294
- # @sg-ignore Need to validate config
295
163
  def command_path
296
164
  server['commandPath'] || 'solargraph'
297
165
  end
@@ -302,9 +170,29 @@ module Solargraph
302
170
  directory
303
171
  end
304
172
 
305
- # @return [Solargraph::Workspace::Gemspecs]
306
- def gemspecs
307
- @gemspecs ||= Solargraph::Workspace::Gemspecs.new(directory_or_nil)
173
+ # True if the workspace has a root Gemfile.
174
+ #
175
+ # @todo Handle projects with custom Bundler/Gemfile setups (see DocMap#gemspecs_required_from_bundler)
176
+ #
177
+ def gemfile?
178
+ directory && File.file?(File.join(directory, 'Gemfile'))
179
+ end
180
+
181
+ # True if the workspace contains at least one gemspec file.
182
+ #
183
+ # @return [Boolean]
184
+ def gemspec?
185
+ !gemspec_files.empty?
186
+ end
187
+
188
+ # Get an array of all gemspec files in the workspace.
189
+ #
190
+ # @return [Array<String>]
191
+ def gemspec_files
192
+ return [] if directory.empty? || directory == '*'
193
+ @gemspec_files ||= Dir[File.join(directory, '**/*.gemspec')].select do |gs|
194
+ config.allow? gs
195
+ end
308
196
  end
309
197
 
310
198
  private
@@ -323,30 +211,22 @@ module Solargraph
323
211
  # @return [void]
324
212
  def load_sources
325
213
  source_hash.clear
326
- unless directory.empty? || directory == '*'
327
- size = config.calculated.length
328
- if config.max_files > 0 and size > config.max_files
329
- raise WorkspaceTooLargeError,
330
- "The workspace is too large to index (#{size} files, #{config.max_files} max)"
331
- end
332
- config.calculated.each do |filename|
333
- begin
334
- source_hash[filename] = Solargraph::Source.load(filename)
335
- rescue Errno::ENOENT => e
336
- Solargraph.logger.warn("Error loading #{filename}: [#{e.class}] #{e.message}")
337
- end
338
- end
214
+ return if directory.empty? || directory == '*'
215
+ size = config.calculated.length
216
+ raise WorkspaceTooLargeError, "The workspace is too large to index (#{size} files, #{config.max_files} max)" if config.max_files.positive? && size > config.max_files
217
+ config.calculated.each do |filename|
218
+ source_hash[filename] = Solargraph::Source.load(filename)
219
+ rescue Errno::ENOENT => e
220
+ Solargraph.logger.warn("Error loading #{filename}: [#{e.class}] #{e.message}")
339
221
  end
340
222
  end
341
223
 
342
224
  # @return [void]
343
225
  def require_plugins
344
226
  config.plugins.each do |plugin|
345
- begin
346
- require plugin
347
- rescue LoadError
348
- Solargraph.logger.warn "Failed to load plugin '#{plugin}'"
349
- end
227
+ require plugin
228
+ rescue LoadError
229
+ Solargraph.logger.warn "Failed to load plugin '#{plugin}'"
350
230
  end
351
231
  end
352
232
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Solargraph
2
4
  class YardMap
3
5
  module Helpers
@@ -22,10 +24,12 @@ module Solargraph
22
24
  # @param code_object [YARD::CodeObjects::Base]
23
25
  # @param spec [Gem::Specification, nil]
24
26
  # @return [Solargraph::Pin::Namespace]
25
- def create_closure_namespace_for(code_object, spec)
27
+ def create_closure_namespace_for code_object, spec
26
28
  code_object_for_location = code_object
27
29
  # code_object.namespace is sometimes a YARD proxy object pointing to a method path ("Object#new")
28
- code_object_for_location = code_object.namespace if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
30
+ if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
31
+ code_object_for_location = code_object.namespace
32
+ end
29
33
  namespace_location = object_location(code_object_for_location, spec)
30
34
  ns_name = code_object.namespace.to_s
31
35
  if ns_name.empty?
@@ -9,8 +9,8 @@ module Solargraph
9
9
  # @type [Hash{Array<String, Symbol, String> => Symbol}]
10
10
  VISIBILITY_OVERRIDE = {
11
11
  # YARD pays attention to 'private' statements prior to class methods but shouldn't
12
- ["Rails::Engine", :class, "find_root_with_flag"] => :public
13
- }
12
+ ['Rails::Engine', :class, 'find_root_with_flag'] => :public
13
+ }.freeze
14
14
 
15
15
  # @param code_object [YARD::CodeObjects::MethodObject]
16
16
  # @param name [String, nil]
@@ -32,7 +32,9 @@ module Solargraph
32
32
  # @sg-ignore Need to add nil check here
33
33
  final_visibility ||= VISIBILITY_OVERRIDE[[closure.path, final_scope]]
34
34
  # @sg-ignore Need to add nil check here
35
- final_visibility ||= :private if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(name.to_sym)
35
+ if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(name.to_sym)
36
+ final_visibility ||= :private
37
+ end
36
38
  final_visibility ||= visibility
37
39
  final_visibility ||= :private if code_object.module_function? && final_scope == :instance
38
40
  final_visibility ||= :public if code_object.module_function? && final_scope == :class
@@ -50,7 +52,7 @@ module Solargraph
50
52
  explicit: code_object.is_explicit?,
51
53
  return_type: return_type,
52
54
  parameters: [],
53
- source: :yardoc,
55
+ source: :yardoc
54
56
  )
55
57
  else
56
58
  # @sg-ignore Need to add nil check here
@@ -66,7 +68,7 @@ module Solargraph
66
68
  return_type: return_type,
67
69
  attribute: code_object.is_attribute?,
68
70
  parameters: [],
69
- source: :yardoc,
71
+ source: :yardoc
70
72
  )
71
73
  pin.parameters.concat get_parameters(code_object, location, comments, pin)
72
74
  pin.parameters.freeze
@@ -99,7 +101,7 @@ module Solargraph
99
101
  presence: nil,
100
102
  decl: arg_type(a),
101
103
  asgn_code: a[1],
102
- source: :yardoc,
104
+ source: :yardoc
103
105
  )
104
106
  end
105
107
  end
@@ -23,7 +23,7 @@ module Solargraph
23
23
  closure: closure,
24
24
  # @sg-ignore need to add a nil check here
25
25
  gates: closure.gates,
26
- source: :yardoc,
26
+ source: :yardoc
27
27
  )
28
28
  end
29
29
  end
@@ -35,28 +35,27 @@ module Solargraph
35
35
  # @return [Array<Pin::Base>]
36
36
  def generate_pins code_object
37
37
  result = []
38
- if code_object.is_a?(YARD::CodeObjects::NamespaceObject)
38
+ case code_object
39
+ when YARD::CodeObjects::NamespaceObject
39
40
  nspin = ToNamespace.make(code_object, @spec, @namespace_pins[code_object.namespace.to_s])
40
41
  @namespace_pins[code_object.path] = nspin
41
42
  result.push nspin
42
- # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
43
- if code_object.is_a?(YARD::CodeObjects::ClassObject) and !code_object.superclass.nil?
43
+ if code_object.is_a?(YARD::CodeObjects::ClassObject) && !code_object.superclass.nil?
44
44
  # This method of superclass detection is a bit of a hack. If
45
45
  # the superclass is a Proxy, it is assumed to be undefined in its
46
46
  # yardoc and converted to a fully qualified namespace.
47
- # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
48
47
  superclass = if code_object.superclass.is_a?(YARD::CodeObjects::Proxy)
49
- # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
50
- "::#{code_object.superclass}"
51
- else
52
- # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
53
- code_object.superclass.to_s
54
- end
48
+ "::#{code_object.superclass}"
49
+ else
50
+ code_object.superclass.to_s
51
+ end
55
52
  result.push Solargraph::Pin::Reference::Superclass.new(name: superclass, closure: nspin, source: :yard_map)
56
53
  end
54
+ # @sg-ignore flow sensitive typing ought to be able to handle 'when ClassName'
57
55
  code_object.class_mixins.each do |m|
58
56
  result.push Solargraph::Pin::Reference::Extend.new(closure: nspin, name: m.path, source: :yard_map)
59
57
  end
58
+ # @sg-ignore flow sensitive typing ought to be able to handle 'when ClassName'
60
59
  code_object.instance_mixins.each do |m|
61
60
  result.push Solargraph::Pin::Reference::Include.new(
62
61
  closure: nspin, # @todo Fix this
@@ -64,8 +63,9 @@ module Solargraph
64
63
  source: :yard_map
65
64
  )
66
65
  end
67
- elsif code_object.is_a?(YARD::CodeObjects::MethodObject)
66
+ when YARD::CodeObjects::MethodObject
68
67
  closure = @namespace_pins[code_object.namespace.to_s]
68
+ # @sg-ignore flow sensitive typing ought to be able to handle 'when ClassName'
69
69
  if code_object.name == :initialize && code_object.scope == :instance
70
70
  # @todo Check the visibility of <Class>.new
71
71
  result.push ToMethod.make(code_object, 'new', :class, :public, closure, @spec)
@@ -73,7 +73,7 @@ module Solargraph
73
73
  else
74
74
  result.push ToMethod.make(code_object, nil, nil, nil, closure, @spec)
75
75
  end
76
- elsif code_object.is_a?(YARD::CodeObjects::ConstantObject)
76
+ when YARD::CodeObjects::ConstantObject
77
77
  closure = @namespace_pins[code_object.namespace]
78
78
  result.push ToConstant.make(code_object, closure, @spec)
79
79
  end
@@ -1,18 +1,17 @@
1
- # frozen_string_literal: true
2
-
3
- require 'yard'
4
- require 'solargraph/yard_tags'
5
-
6
- module Solargraph
7
- # The YardMap provides access to YARD documentation for the Ruby core, the
8
- # stdlib, and gems.
9
- #
10
- class YardMap
11
- class NoYardocError < StandardError; end
12
-
13
- autoload :Cache, 'solargraph/yard_map/cache'
14
- autoload :Mapper, 'solargraph/yard_map/mapper'
15
- autoload :Helpers, 'solargraph/yard_map/helpers'
16
- autoload :ToMethod, 'solargraph/yard_map/to_method'
17
- end
18
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'yard'
4
+ require 'solargraph/yard_tags'
5
+
6
+ module Solargraph
7
+ # The YardMap provides access to YARD documentation for the Ruby core, the
8
+ # stdlib, and gems.
9
+ #
10
+ class YardMap
11
+ class NoYardocError < StandardError; end
12
+
13
+ autoload :Cache, 'solargraph/yard_map/cache'
14
+ autoload :Mapper, 'solargraph/yard_map/mapper'
15
+ autoload :Helpers, 'solargraph/yard_map/helpers'
16
+ end
17
+ end
@@ -1,20 +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)
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)
@@ -8,15 +8,15 @@ module Solargraph
8
8
  module Yardoc
9
9
  module_function
10
10
 
11
- # Build and save a gem's yardoc into a given path.
11
+ # Build and cache a gem's yardoc and return the path. If the cache already
12
+ # exists, do nothing and return the path.
12
13
  #
13
- # @param gem_yardoc_path [String] the path to the yardoc cache of a particular gem
14
- # @param yard_plugins [Array<String>]
14
+ # @param yard_plugins [Array<String>] The names of YARD plugins to use.
15
15
  # @param gemspec [Gem::Specification]
16
- #
17
- # @return [void]
18
- def build_docs gem_yardoc_path, yard_plugins, gemspec
19
- return if docs_built?(gem_yardoc_path)
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
20
 
21
21
  unless Dir.exist? gemspec.gem_dir
22
22
  # Can happen in at least some (old?) RubyGems versions when we
@@ -24,44 +24,37 @@ module Solargraph
24
24
  #
25
25
  # https://github.com/apiology/solargraph/actions/runs/17650140201/job/50158676842?pr=10
26
26
  Solargraph.logger.info { "Bad info from gemspec - #{gemspec.gem_dir} does not exist" }
27
- return
27
+ return path
28
28
  end
29
29
 
30
30
  Solargraph.logger.info "Caching yardoc for #{gemspec.name} #{gemspec.version}"
31
- cmd = "yardoc --db #{gem_yardoc_path} --no-output --plugin solargraph"
31
+ cmd = "yardoc --db #{path} --no-output --plugin solargraph"
32
32
  yard_plugins.each { |plugin| cmd << " --plugin #{plugin}" }
33
33
  Solargraph.logger.debug { "Running: #{cmd}" }
34
34
  # @todo set these up to run in parallel
35
- # @sg-ignore Our fill won't work properly due to an issue in
36
- # Callable#arity_matches? - see comment there
35
+ # @todo Is the chdir argument being used here?
36
+ # @sg-ignore Unrecognized keyword argument chdir to Open3.capture2e
37
37
  stdout_and_stderr_str, status = Open3.capture2e(current_bundle_env_tweaks, cmd, chdir: gemspec.gem_dir)
38
- return if status.success?
39
- Solargraph.logger.warn { "YARD failed running #{cmd.inspect} in #{gemspec.gem_dir}" }
40
- Solargraph.logger.info stdout_and_stderr_str
41
- end
42
-
43
- # @param gem_yardoc_path [String] the path to the yardoc cache of a particular gem
44
- # @param gemspec [Gem::Specification, Bundler::LazySpecification]
45
- # @param out [StringIO, IO, nil] where to log messages
46
- # @return [Array<Pin::Base>]
47
- def build_pins gem_yardoc_path, gemspec, out: $stderr
48
- yardoc = load!(gem_yardoc_path)
49
- YardMap::Mapper.new(yardoc, gemspec).map
38
+ unless status.success?
39
+ Solargraph.logger.warn { "YARD failed running #{cmd.inspect} in #{gemspec.gem_dir}" }
40
+ Solargraph.logger.info stdout_and_stderr_str
41
+ end
42
+ path
50
43
  end
51
44
 
52
45
  # True if the gem yardoc is cached.
53
46
  #
54
- # @param gem_yardoc_path [String]
55
- def docs_built? gem_yardoc_path
56
- yardoc = File.join(gem_yardoc_path, 'complete')
47
+ # @param gemspec [Gem::Specification]
48
+ def cached? gemspec
49
+ yardoc = File.join(PinCache.yardoc_path(gemspec), 'complete')
57
50
  File.exist?(yardoc)
58
51
  end
59
52
 
60
53
  # True if another process is currently building the yardoc cache.
61
54
  #
62
- # @param gem_yardoc_path [String] the path to the yardoc cache of a particular gem
63
- def processing? gem_yardoc_path
64
- yardoc = File.join(gem_yardoc_path, 'processing')
55
+ # @param gemspec [Gem::Specification]
56
+ def processing? gemspec
57
+ yardoc = File.join(PinCache.yardoc_path(gemspec), 'processing')
65
58
  File.exist?(yardoc)
66
59
  end
67
60
 
@@ -69,10 +62,10 @@ module Solargraph
69
62
  #
70
63
  # @note This method modifies the global YARD registry.
71
64
  #
72
- # @param gem_yardoc_path [String] the path to the yardoc cache of a particular gem
65
+ # @param gemspec [Gem::Specification]
73
66
  # @return [Array<YARD::CodeObjects::Base>]
74
- def load! gem_yardoc_path
75
- YARD::Registry.load! gem_yardoc_path
67
+ def load! gemspec
68
+ YARD::Registry.load! PinCache.yardoc_path gemspec
76
69
  YARD::Registry.all
77
70
  end
78
71
 
@@ -87,7 +80,7 @@ module Solargraph
87
80
  # @return [Hash{String => String}] a hash of environment variables to override
88
81
  def current_bundle_env_tweaks
89
82
  tweaks = {}
90
- # @sg-ignore Translate to something flow sensitive typing understands
83
+ # @sg-ignore Unresolved call to empty? on String, nil
91
84
  if ENV['BUNDLE_GEMFILE'] && !ENV['BUNDLE_GEMFILE'].empty?
92
85
  tweaks['BUNDLE_GEMFILE'] = File.expand_path(ENV['BUNDLE_GEMFILE'])
93
86
  end
data/lib/solargraph.rb CHANGED
@@ -71,7 +71,7 @@ module Solargraph
71
71
  # @param msg [String, nil] An optional message to log
72
72
  # @param block [Proc] A block that returns a message to log
73
73
  # @return [void]
74
- def self.assert_or_log(type, msg = nil, &block)
74
+ def self.assert_or_log type, msg = nil, &block
75
75
  if asserts_on?
76
76
  # @type [String, nil]
77
77
  msg ||= block.call
@@ -83,6 +83,8 @@ module Solargraph
83
83
  return if type == :alias_target_missing && msg.include?('highline/compatibility.rb')
84
84
  # @sg-ignore flow sensitive typing needs to handle 'raise if'
85
85
  return if type == :alias_target_missing && msg.include?('lib/json/add/date.rb')
86
+ # @sg-ignore flow sensitive typing needs to handle 'raise if'
87
+ return if type == :alias_target_missing && msg.include?('rubocop-ast.rbs')
86
88
  # @todo :combine_with_visibility is not ready for prime time -
87
89
  # lots of disagreements found in practice that heuristics need
88
90
  # to be created for and/or debugging needs to resolve in pin
@@ -113,10 +115,10 @@ module Solargraph
113
115
  # @return [generic<T>]
114
116
  def self.with_clean_env &block
115
117
  meth = if Bundler.respond_to?(:with_original_env)
116
- :with_original_env
117
- else
118
- :with_clean_env
119
- end
118
+ :with_original_env
119
+ else
120
+ :with_clean_env
121
+ end
120
122
  Bundler.send meth, &block
121
123
  end
122
124
  end