solargraph 0.58.2 → 0.59.0.dev.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 (203) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +4 -5
  4. data/.github/workflows/plugins.yml +41 -34
  5. data/.github/workflows/rspec.yml +44 -23
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.rubocop.yml +32 -5
  8. data/.rubocop_todo.yml +50 -966
  9. data/Gemfile +3 -1
  10. data/README.md +3 -3
  11. data/Rakefile +26 -23
  12. data/bin/solargraph +2 -1
  13. data/lib/solargraph/api_map/cache.rb +3 -3
  14. data/lib/solargraph/api_map/constants.rb +13 -3
  15. data/lib/solargraph/api_map/index.rb +23 -18
  16. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  17. data/lib/solargraph/api_map/store.rb +33 -28
  18. data/lib/solargraph/api_map.rb +150 -82
  19. data/lib/solargraph/bench.rb +44 -45
  20. data/lib/solargraph/complex_type/conformance.rb +176 -0
  21. data/lib/solargraph/complex_type/type_methods.rb +28 -17
  22. data/lib/solargraph/complex_type/unique_type.rb +218 -57
  23. data/lib/solargraph/complex_type.rb +170 -57
  24. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  25. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  26. data/lib/solargraph/convention/data_definition.rb +5 -2
  27. data/lib/solargraph/convention/gemfile.rb +15 -15
  28. data/lib/solargraph/convention/gemspec.rb +23 -23
  29. data/lib/solargraph/convention/rakefile.rb +17 -17
  30. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  31. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  32. data/lib/solargraph/convention/struct_definition.rb +8 -4
  33. data/lib/solargraph/convention.rb +78 -78
  34. data/lib/solargraph/converters/dd.rb +19 -17
  35. data/lib/solargraph/converters/dl.rb +17 -15
  36. data/lib/solargraph/converters/dt.rb +17 -15
  37. data/lib/solargraph/converters/misc.rb +3 -1
  38. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  39. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  40. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  41. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  42. data/lib/solargraph/diagnostics/update_errors.rb +37 -41
  43. data/lib/solargraph/doc_map.rb +133 -373
  44. data/lib/solargraph/equality.rb +4 -4
  45. data/lib/solargraph/gem_pins.rb +21 -20
  46. data/lib/solargraph/language_server/error_codes.rb +20 -20
  47. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  48. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  49. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  50. data/lib/solargraph/language_server/host/sources.rb +2 -1
  51. data/lib/solargraph/language_server/host.rb +30 -22
  52. data/lib/solargraph/language_server/message/base.rb +97 -97
  53. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
  54. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
  55. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  56. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  57. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  58. data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
  59. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  60. data/lib/solargraph/language_server/message/initialize.rb +197 -191
  61. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  62. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  63. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
  64. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  65. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  66. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  67. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
  68. data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
  69. data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
  70. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  71. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  72. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
  73. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
  74. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
  75. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  76. data/lib/solargraph/language_server/message.rb +94 -94
  77. data/lib/solargraph/language_server/request.rb +29 -27
  78. data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
  79. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  80. data/lib/solargraph/library.rb +85 -44
  81. data/lib/solargraph/location.rb +17 -14
  82. data/lib/solargraph/logging.rb +24 -4
  83. data/lib/solargraph/page.rb +92 -92
  84. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  85. data/lib/solargraph/parser/flow_sensitive_typing.rb +326 -108
  86. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  87. data/lib/solargraph/parser/node_processor.rb +8 -7
  88. data/lib/solargraph/parser/parser_gem/class_methods.rb +32 -14
  89. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  90. data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
  91. data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
  92. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  93. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  94. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  95. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +12 -12
  96. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  97. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
  98. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  99. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  100. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  101. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  102. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  103. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  104. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  105. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  106. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  107. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  108. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  109. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  110. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  111. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  112. data/lib/solargraph/parser/parser_gem.rb +14 -12
  113. data/lib/solargraph/parser/region.rb +9 -3
  114. data/lib/solargraph/parser/snippet.rb +3 -1
  115. data/lib/solargraph/parser.rb +25 -23
  116. data/lib/solargraph/pin/base.rb +126 -80
  117. data/lib/solargraph/pin/base_variable.rb +273 -24
  118. data/lib/solargraph/pin/block.rb +29 -6
  119. data/lib/solargraph/pin/breakable.rb +7 -1
  120. data/lib/solargraph/pin/callable.rb +65 -21
  121. data/lib/solargraph/pin/closure.rb +7 -10
  122. data/lib/solargraph/pin/common.rb +24 -6
  123. data/lib/solargraph/pin/compound_statement.rb +55 -0
  124. data/lib/solargraph/pin/constant.rb +43 -45
  125. data/lib/solargraph/pin/conversions.rb +10 -4
  126. data/lib/solargraph/pin/delegated_method.rb +19 -8
  127. data/lib/solargraph/pin/documenting.rb +4 -2
  128. data/lib/solargraph/pin/instance_variable.rb +5 -1
  129. data/lib/solargraph/pin/keyword.rb +0 -4
  130. data/lib/solargraph/pin/local_variable.rb +15 -59
  131. data/lib/solargraph/pin/method.rb +153 -104
  132. data/lib/solargraph/pin/method_alias.rb +8 -0
  133. data/lib/solargraph/pin/namespace.rb +19 -12
  134. data/lib/solargraph/pin/parameter.rb +100 -36
  135. data/lib/solargraph/pin/proxy_type.rb +4 -1
  136. data/lib/solargraph/pin/reference/override.rb +1 -1
  137. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  138. data/lib/solargraph/pin/reference.rb +19 -0
  139. data/lib/solargraph/pin/search.rb +3 -2
  140. data/lib/solargraph/pin/signature.rb +15 -12
  141. data/lib/solargraph/pin/symbol.rb +2 -1
  142. data/lib/solargraph/pin/until.rb +2 -4
  143. data/lib/solargraph/pin/while.rb +2 -4
  144. data/lib/solargraph/pin.rb +2 -0
  145. data/lib/solargraph/pin_cache.rb +490 -73
  146. data/lib/solargraph/position.rb +14 -10
  147. data/lib/solargraph/range.rb +16 -15
  148. data/lib/solargraph/rbs_map/conversions.rb +343 -214
  149. data/lib/solargraph/rbs_map/core_fills.rb +91 -84
  150. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  151. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  152. data/lib/solargraph/rbs_map.rb +77 -32
  153. data/lib/solargraph/server_methods.rb +16 -16
  154. data/lib/solargraph/shell.rb +128 -73
  155. data/lib/solargraph/source/chain/array.rb +39 -37
  156. data/lib/solargraph/source/chain/call.rb +96 -56
  157. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  158. data/lib/solargraph/source/chain/constant.rb +5 -1
  159. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  160. data/lib/solargraph/source/chain/hash.rb +8 -5
  161. data/lib/solargraph/source/chain/if.rb +12 -10
  162. data/lib/solargraph/source/chain/instance_variable.rb +24 -1
  163. data/lib/solargraph/source/chain/link.rb +99 -109
  164. data/lib/solargraph/source/chain/literal.rb +9 -6
  165. data/lib/solargraph/source/chain/or.rb +10 -4
  166. data/lib/solargraph/source/chain/q_call.rb +13 -11
  167. data/lib/solargraph/source/chain/variable.rb +15 -13
  168. data/lib/solargraph/source/chain/z_super.rb +28 -30
  169. data/lib/solargraph/source/chain.rb +49 -38
  170. data/lib/solargraph/source/change.rb +12 -5
  171. data/lib/solargraph/source/cursor.rb +23 -17
  172. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  173. data/lib/solargraph/source/source_chainer.rb +56 -32
  174. data/lib/solargraph/source/updater.rb +5 -1
  175. data/lib/solargraph/source.rb +59 -35
  176. data/lib/solargraph/source_map/clip.rb +48 -29
  177. data/lib/solargraph/source_map/data.rb +4 -1
  178. data/lib/solargraph/source_map/mapper.rb +71 -42
  179. data/lib/solargraph/source_map.rb +21 -9
  180. data/lib/solargraph/type_checker/problem.rb +3 -1
  181. data/lib/solargraph/type_checker/rules.rb +81 -8
  182. data/lib/solargraph/type_checker.rb +195 -120
  183. data/lib/solargraph/version.rb +1 -1
  184. data/lib/solargraph/workspace/config.rb +13 -10
  185. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  186. data/lib/solargraph/workspace/require_paths.rb +1 -0
  187. data/lib/solargraph/workspace.rb +149 -30
  188. data/lib/solargraph/yard_map/helpers.rb +8 -3
  189. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  190. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  191. data/lib/solargraph/yard_map/mapper.rb +13 -8
  192. data/lib/solargraph/yard_tags.rb +20 -20
  193. data/lib/solargraph/yardoc.rb +33 -23
  194. data/lib/solargraph.rb +29 -8
  195. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  196. data/rbs/fills/tuple/tuple.rbs +28 -0
  197. data/rbs/shims/ast/0/node.rbs +1 -1
  198. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  199. data/solargraph.gemspec +36 -34
  200. metadata +38 -33
  201. data/lib/solargraph/type_checker/checks.rb +0 -124
  202. data/lib/solargraph/type_checker/param_def.rb +0 -37
  203. data/lib/solargraph/yard_map/to_method.rb +0 -89
@@ -1,9 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rubygems'
3
4
  require 'pathname'
4
5
  require 'observer'
5
6
  require 'open3'
6
7
 
8
+ # @!parse
9
+ # class ::Gem::Specification
10
+ # # @return [String]
11
+ # def name; end
12
+ # end
13
+
7
14
  module Solargraph
8
15
  # A Library handles coordination between a Workspace and an ApiMap.
9
16
  #
@@ -33,6 +40,7 @@ module Solargraph
33
40
  # @type [Source, nil]
34
41
  @current = nil
35
42
  @sync_count = 0
43
+ @cache_progress = nil
36
44
  end
37
45
 
38
46
  def inspect
@@ -57,8 +65,11 @@ module Solargraph
57
65
  # @param source [Source, nil]
58
66
  # @return [void]
59
67
  def attach source
68
+ # @sg-ignore Need to add nil check here
60
69
  if @current && (!source || @current.filename != source.filename) && source_map_hash.key?(@current.filename) && !workspace.has_file?(@current.filename)
70
+ # @sg-ignore Need to add nil check here
61
71
  source_map_hash.delete @current.filename
72
+ # @sg-ignore Need to add nil check here
62
73
  source_map_external_require_hash.delete @current.filename
63
74
  @external_requires = nil
64
75
  end
@@ -116,8 +127,8 @@ module Solargraph
116
127
  # @return [Boolean] True if at least one file was added to the workspace.
117
128
  def create_from_disk *filenames
118
129
  sources = filenames
119
- .reject { |filename| File.directory?(filename) || !File.exist?(filename) }
120
- .map { |filename| Solargraph::Source.load_string(File.read(filename), filename) }
130
+ .reject { |filename| File.directory?(filename) || !File.exist?(filename) }
131
+ .map { |filename| Solargraph::Source.load_string(File.read(filename), filename) }
121
132
  result = workspace.merge(*sources)
122
133
  sources.each { |source| maybe_map source }
123
134
  result
@@ -182,9 +193,14 @@ module Solargraph
182
193
  if cursor.comment?
183
194
  source = read(filename)
184
195
  offset = Solargraph::Position.to_offset(source.code, Solargraph::Position.new(line, column))
185
- lft = source.code[0..offset-1].match(/\[[a-z0-9_:<, ]*?([a-z0-9_:]*)\z/i)
186
- rgt = source.code[offset..-1].match(/^([a-z0-9_]*)(:[a-z0-9_:]*)?[\]>, ]/i)
196
+ # @sg-ignore Need to add nil check here
197
+ # @type [MatchData, nil]
198
+ lft = source.code[0..(offset - 1)].match(/\[[a-z0-9_:<, ]*?([a-z0-9_:]*)\z/i)
199
+ # @sg-ignore Need to add nil check here
200
+ # @type [MatchData, nil]
201
+ rgt = source.code[offset..].match(/^([a-z0-9_]*)(:[a-z0-9_:]*)?[\]>, ]/i)
187
202
  if lft && rgt
203
+ # @sg-ignore Need to add nil check here
188
204
  tag = (lft[1] + rgt[1]).sub(/:+$/, '')
189
205
  clip = mutex.synchronize { api_map.clip(cursor) }
190
206
  clip.translate tag
@@ -248,22 +264,26 @@ module Solargraph
248
264
  return [] unless pin
249
265
  result = []
250
266
  files = if only
251
- [api_map.source_map(filename)]
252
- else
253
- (workspace.sources + (@current ? [@current] : []))
254
- end
267
+ [api_map.source_map(filename)]
268
+ else
269
+ (workspace.sources + (@current ? [@current] : []))
270
+ end
255
271
  files.uniq(&:filename).each do |source|
256
272
  found = source.references(pin.name)
257
273
  found.select! do |loc|
274
+ # @sg-ignore Need to add nil check here
275
+ # @type [Solargraph::Pin::Base, nil]
258
276
  referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character).first
259
277
  referenced&.path == pin.path
260
278
  end
261
279
  if pin.path == 'Class#new'
280
+ # @todo flow sensitive typing should allow shadowing of Kernel#caller
262
281
  caller = cursor.chain.base.infer(api_map, clip.send(:closure), clip.locals).first
263
282
  if caller.defined?
264
283
  found.select! do |loc|
265
284
  clip = api_map.clip_at(loc.filename, loc.range.start)
266
285
  other = clip.send(:cursor).chain.base.infer(api_map, clip.send(:closure), clip.locals).first
286
+ # @todo flow sensitive typing should allow shadowing of Kernel#caller
267
287
  caller == other
268
288
  end
269
289
  else
@@ -271,14 +291,15 @@ module Solargraph
271
291
  end
272
292
  end
273
293
  # HACK: for language clients that exclude special characters from the start of variable names
274
- if strip && match = cursor.word.match(/^[^a-z0-9_]+/i)
294
+ if strip && (match = cursor.word.match(/^[^a-z0-9_]+/i))
275
295
  found.map! do |loc|
276
- Solargraph::Location.new(loc.filename, Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line, loc.range.ending.column))
296
+ Solargraph::Location.new(loc.filename,
297
+ # @sg-ignore flow sensitive typing needs to handle if foo = bar
298
+ Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line,
299
+ loc.range.ending.column))
277
300
  end
278
301
  end
279
- result.concat(found.sort do |a, b|
280
- a.range.start.line <=> b.range.start.line
281
- end)
302
+ result.concat(found.sort { |a, b| a.range.start.line <=> b.range.start.line })
282
303
  end
283
304
  result.uniq
284
305
  end
@@ -299,18 +320,17 @@ module Solargraph
299
320
  def locate_ref location
300
321
  map = source_map_hash[location.filename]
301
322
  return if map.nil?
323
+ # @sg-ignore Need to add nil check here
302
324
  pin = map.requires.select { |p| p.location.range.contain?(location.range.start) }.first
303
325
  return nil if pin.nil?
304
326
  # @param full [String]
305
327
  return_if_match = proc do |full|
306
- if source_map_hash.key?(full)
307
- return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0))
308
- end
328
+ return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0)) if source_map_hash.key?(full)
309
329
  end
310
330
  workspace.require_paths.each do |path|
311
331
  full = File.join path, pin.name
312
- return_if_match.(full)
313
- return_if_match.(full << ".rb")
332
+ return_if_match.call(full)
333
+ return_if_match.call(full << '.rb')
314
334
  end
315
335
  nil
316
336
  rescue FileNotFoundError
@@ -403,6 +423,7 @@ module Solargraph
403
423
  workspace.config.reporters.each do |line|
404
424
  if line == 'all!'
405
425
  Diagnostics.reporters.each do |reporter_name|
426
+ # @sg-ignore Need to add nil check here
406
427
  repargs[Diagnostics.reporter(reporter_name)] ||= []
407
428
  end
408
429
  else
@@ -410,7 +431,9 @@ module Solargraph
410
431
  name = args.shift
411
432
  reporter = Diagnostics.reporter(name)
412
433
  raise DiagnosticsError, "Diagnostics reporter #{name} does not exist" if reporter.nil?
434
+ # @sg-ignore flow sensitive typing needs to handle 'raise if'
413
435
  repargs[reporter] ||= []
436
+ # @sg-ignore flow sensitive typing needs to handle 'raise if'
414
437
  repargs[reporter].concat args
415
438
  end
416
439
  end
@@ -433,6 +456,7 @@ module Solargraph
433
456
  source_maps: source_map_hash.values,
434
457
  workspace: workspace,
435
458
  external_requires: external_requires,
459
+ # @sg-ignore Need to add nil check here
436
460
  live_map: @current ? source_map_hash[@current.filename] : nil
437
461
  )
438
462
  end
@@ -469,10 +493,13 @@ module Solargraph
469
493
  # @return [SourceMap, Boolean]
470
494
  def next_map
471
495
  return false if mapped?
496
+ # @sg-ignore Need to add nil check here
472
497
  src = workspace.sources.find { |s| !source_map_hash.key?(s.filename) }
473
498
  if src
474
499
  Logging.logger.debug "Mapping #{src.filename}"
500
+ # @sg-ignore Need to add nil check here
475
501
  source_map_hash[src.filename] = Solargraph::SourceMap.map(src)
502
+ # @sg-ignore Need to add nil check here
476
503
  source_map_hash[src.filename]
477
504
  else
478
505
  false
@@ -482,7 +509,9 @@ module Solargraph
482
509
  # @return [self]
483
510
  def map!
484
511
  workspace.sources.each do |src|
512
+ # @sg-ignore Need to add nil check here
485
513
  source_map_hash[src.filename] = Solargraph::SourceMap.map(src)
514
+ # @sg-ignore Need to add nil check here
486
515
  find_external_requires source_map_hash[src.filename]
487
516
  end
488
517
  self
@@ -500,6 +529,11 @@ module Solargraph
500
529
 
501
530
  private
502
531
 
532
+ # @return [PinCache]
533
+ def pin_cache
534
+ workspace.pin_cache
535
+ end
536
+
503
537
  # @return [Hash{String => Array<String>}]
504
538
  def source_map_external_require_hash
505
539
  @source_map_external_require_hash ||= {}
@@ -509,14 +543,15 @@ module Solargraph
509
543
  # @return [void]
510
544
  def find_external_requires source_map
511
545
  # @type [Set<String>]
512
- new_set = source_map.requires.map(&:name).to_set
546
+ new_set = source_map.requires.to_set(&:name)
513
547
  # return if new_set == source_map_external_require_hash[source_map.filename]
514
548
  _filenames = nil
515
- filenames = ->{ _filenames ||= workspace.filenames.to_set }
549
+ filenames = -> { _filenames ||= workspace.filenames.to_set }
550
+ # @sg-ignore Need to add nil check here
516
551
  source_map_external_require_hash[source_map.filename] = new_set.reject do |path|
517
552
  workspace.require_paths.any? do |base|
518
553
  full = File.join(base, path)
519
- filenames[].include?(full) or filenames[].include?(full << ".rb")
554
+ filenames[].include?(full) or filenames[].include?(full << '.rb')
520
555
  end
521
556
  end
522
557
  @external_requires = nil
@@ -550,23 +585,24 @@ module Solargraph
550
585
  # @param error [FileNotFoundError]
551
586
  # @return [nil]
552
587
  def handle_file_not_found filename, error
553
- if workspace.source(filename)
554
- Solargraph.logger.debug "#{filename} is not cataloged in the ApiMap"
555
- nil
556
- else
557
- raise error
558
- end
588
+ raise error unless workspace.source(filename)
589
+ Solargraph.logger.debug "#{filename} is not cataloged in the ApiMap"
590
+ nil
559
591
  end
560
592
 
561
593
  # @param source [Source, nil]
562
594
  # @return [void]
563
595
  def maybe_map source
564
596
  return unless source
597
+ # @sg-ignore Need to add nil check here
565
598
  return unless @current == source || workspace.has_file?(source.filename)
599
+ # @sg-ignore Need to add nil check here
566
600
  if source_map_hash.key?(source.filename)
567
601
  new_map = Solargraph::SourceMap.map(source)
602
+ # @sg-ignore Need to add nil check here
568
603
  source_map_hash[source.filename] = new_map
569
604
  else
605
+ # @sg-ignore Need to add nil check here
570
606
  source_map_hash[source.filename] = Solargraph::SourceMap.map(source)
571
607
  end
572
608
  end
@@ -585,7 +621,7 @@ module Solargraph
585
621
 
586
622
  pending = api_map.uncached_gemspecs.length - cache_errors.length - 1
587
623
 
588
- if Yardoc.processing?(spec)
624
+ if pin_cache.yardoc_processing?(spec)
589
625
  logger.info "Enqueuing cache of #{spec.name} #{spec.version} (already being processed)"
590
626
  queued_gemspec_cache.push(spec)
591
627
  return if pending - queued_gemspec_cache.length < 1
@@ -596,7 +632,10 @@ module Solargraph
596
632
  logger.info "Caching #{spec.name} #{spec.version}"
597
633
  Thread.new do
598
634
  report_cache_progress spec.name, pending
599
- _o, e, s = Open3.capture3(workspace.command_path, 'cache', spec.name, spec.version.to_s)
635
+ kwargs = {}
636
+ kwargs[:chdir] = workspace.directory.to_s if workspace.directory && !workspace.directory.empty?
637
+ _o, e, s = Open3.capture3(workspace.command_path, 'cache', spec.name, spec.version.to_s,
638
+ **kwargs)
600
639
  if s.success?
601
640
  logger.info "Cached #{spec.name} #{spec.version}"
602
641
  else
@@ -613,8 +652,7 @@ module Solargraph
613
652
 
614
653
  # @return [Array<Gem::Specification>]
615
654
  def cacheable_specs
616
- cacheable = api_map.uncached_yard_gemspecs +
617
- api_map.uncached_rbs_collection_gemspecs -
655
+ cacheable = api_map.uncached_gemspecs +
618
656
  queued_gemspec_cache -
619
657
  cache_errors.to_a
620
658
  return cacheable unless cacheable.empty?
@@ -632,26 +670,30 @@ module Solargraph
632
670
  # @return [void]
633
671
  def report_cache_progress gem_name, pending
634
672
  @total ||= pending
673
+ # @sg-ignore flow sensitive typing needs better handling of ||= on lvars
635
674
  @total = pending if pending > @total
675
+ # @sg-ignore flow sensitive typing needs better handling of ||= on lvars
636
676
  finished = @total - pending
677
+ # @sg-ignore flow sensitive typing needs better handling of ||= on lvars
637
678
  pct = if @total.zero?
638
- 0
639
- else
640
- ((finished.to_f / @total.to_f) * 100).to_i
641
- end
642
- message = "#{gem_name}#{pending > 0 ? " (+#{pending})" : ''}"
679
+ 0
680
+ else
681
+ # @sg-ignore flow sensitive typing needs better handling of ||= on lvars
682
+ ((finished.to_f / @total) * 100).to_i
683
+ end
684
+ message = "#{gem_name}#{" (+#{pending})" if pending.positive?}"
643
685
  # "
644
- if @cache_progress
645
- @cache_progress.report(message, pct)
646
- else
686
+ unless @cache_progress
647
687
  @cache_progress = LanguageServer::Progress.new('Caching gem')
648
688
  # If we don't send both a begin and a report, the progress notification
649
689
  # might get stuck in the status bar forever
690
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
650
691
  @cache_progress.begin(message, pct)
651
692
  changed
652
693
  notify_observers @cache_progress
653
- @cache_progress.report(message, pct)
654
694
  end
695
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
696
+ @cache_progress.report(message, pct)
655
697
  changed
656
698
  notify_observers @cache_progress
657
699
  end
@@ -666,15 +708,14 @@ module Solargraph
666
708
 
667
709
  # @return [void]
668
710
  def sync_catalog
669
- return if @sync_count == 0
711
+ return if @sync_count.zero?
670
712
 
671
713
  mutex.synchronize do
672
714
  logger.info "Cataloging #{workspace.directory.empty? ? 'generic workspace' : workspace.directory}"
673
- source_map_hash.values.each { |map| find_external_requires(map) }
715
+ source_map_hash.each_value { |map| find_external_requires(map) }
674
716
  api_map.catalog bench
675
717
  logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)"
676
- logger.info "#{api_map.uncached_yard_gemspecs.length} uncached YARD gemspecs"
677
- logger.info "#{api_map.uncached_rbs_collection_gemspecs.length} uncached RBS collection gemspecs"
718
+ logger.info "#{api_map.uncached_gemspecs.length} uncached gemspecs"
678
719
  cache_next_gemspec
679
720
  @sync_count = 0
680
721
  end
@@ -6,6 +6,7 @@ module Solargraph
6
6
  #
7
7
  class Location
8
8
  include Equality
9
+ include Comparable
9
10
 
10
11
  # @return [String]
11
12
  attr_reader :filename
@@ -13,20 +14,17 @@ module Solargraph
13
14
  # @return [Solargraph::Range]
14
15
  attr_reader :range
15
16
 
16
- # @param filename [String]
17
+ # @param filename [String, nil]
17
18
  # @param range [Solargraph::Range]
18
19
  def initialize filename, range
20
+ raise 'Use nil to represent no-file' if filename&.empty?
21
+
19
22
  @filename = filename
20
23
  @range = range
21
24
  end
22
25
 
23
- # @sg-ignore Fix "Not enough arguments to Module#protected"
24
- protected def equality_fields
25
- [filename, range]
26
- end
27
-
28
26
  # @param other [self]
29
- def <=>(other)
27
+ def <=> other
30
28
  return nil unless other.is_a?(Location)
31
29
  if filename == other.filename
32
30
  range <=> other.range
@@ -44,10 +42,6 @@ module Solargraph
44
42
  range.contain?(location.range.start) && range.contain?(location.range.ending) && filename == location.filename
45
43
  end
46
44
 
47
- def inspect
48
- "<#{self.class.name}: filename=#{filename}, range=#{range.inspect}>"
49
- end
50
-
51
45
  def to_s
52
46
  inspect
53
47
  end
@@ -62,21 +56,30 @@ module Solargraph
62
56
 
63
57
  # @param node [Parser::AST::Node, nil]
64
58
  # @return [Location, nil]
65
- def self.from_node(node)
59
+ def self.from_node node
66
60
  return nil if node.nil? || node.loc.nil?
61
+ filename = node.loc.expression.source_buffer.name
62
+ # @sg-ignore flow sensitive typing needs to create separate ranges for postfix if
63
+ filename = nil if filename.empty?
67
64
  range = Range.from_node(node)
68
- self.new(node.loc.expression.source_buffer.name, range)
65
+ # @sg-ignore Need to add nil check here
66
+ new(filename, range)
69
67
  end
70
68
 
71
69
  # @param other [BasicObject]
72
70
  def == other
73
71
  return false unless other.is_a?(Location)
74
- # @sg-ignore https://github.com/castwide/solargraph/pull/1114
75
72
  filename == other.filename and range == other.range
76
73
  end
77
74
 
78
75
  def inspect
79
76
  "#<#{self.class} #{filename}, #{range.inspect}>"
80
77
  end
78
+
79
+ protected
80
+
81
+ def equality_fields
82
+ [filename, range]
83
+ end
81
84
  end
82
85
  end
@@ -10,7 +10,7 @@ module Solargraph
10
10
  'warn' => Logger::WARN,
11
11
  'info' => Logger::INFO,
12
12
  'debug' => Logger::DEBUG
13
- }
13
+ }.freeze
14
14
  configured_level = ENV.fetch('SOLARGRAPH_LOG', nil)
15
15
  level = if LOG_LEVELS.keys.include?(configured_level)
16
16
  LOG_LEVELS.fetch(configured_level)
@@ -21,17 +21,37 @@ module Solargraph
21
21
  end
22
22
  DEFAULT_LOG_LEVEL
23
23
  end
24
- @@logger = Logger.new(STDERR, level: level)
24
+ @@logger = Logger.new($stderr, level: level)
25
25
  # @sg-ignore Fix cvar issue
26
- @@logger.formatter = proc do |severity, datetime, progname, msg|
26
+ @@logger.formatter = proc do |severity, _datetime, _progname, msg|
27
27
  "[#{severity}] #{msg}\n"
28
28
  end
29
29
 
30
30
  module_function
31
31
 
32
+ # override this in your class to temporarily set a custom
33
+ # filtering log level for the class (e.g., suppress any debug
34
+ # message by setting it to :info even if it is set elsewhere, or
35
+ # show existing debug messages by setting to :debug).
36
+ #
37
+ # @return [Symbol]
38
+ def log_level
39
+ :warn
40
+ end
41
+
32
42
  # @return [Logger]
33
43
  def logger
34
- @@logger
44
+ if LOG_LEVELS[log_level.to_s] == DEFAULT_LOG_LEVEL
45
+ @@logger
46
+ else
47
+ new_log_level = LOG_LEVELS[log_level.to_s]
48
+ logger = Logger.new($stderr, level: new_log_level)
49
+
50
+ # @sg-ignore Wrong argument type for Logger#formatter=: arg_0
51
+ # expected nil, received Logger::_Formatter, nil
52
+ logger.formatter = @@logger.formatter
53
+ logger
54
+ end
35
55
  end
36
56
  end
37
57
  end
@@ -1,92 +1,92 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ostruct'
4
- require 'tilt'
5
- require 'yard'
6
- require 'cgi'
7
-
8
- module Solargraph
9
- class Page
10
- # @todo This method directive is necessary because OpenStruct.new confuses
11
- # the typechecker.
12
- # @!method self.new(locals, render_method)
13
- # @param locals[Hash]
14
- # @param render_method [Proc]
15
- # @return [Binder]
16
- class Binder < OpenStruct
17
- # @param locals [Hash]
18
- # @param render_method [Proc]
19
- def initialize locals, render_method
20
- super(locals)
21
- define_singleton_method :render do |template, layout: false, locals: {}|
22
- render_method.call(template, layout: layout, locals: locals)
23
- end
24
- define_singleton_method :erb do |template, layout: false, locals: {}|
25
- render_method.call(template, layout: layout, locals: locals)
26
- end
27
- end
28
-
29
- # @param text [String]
30
- # @return [String]
31
- def htmlify text
32
- # @type [String]
33
- YARD::Templates::Helpers::Markup::RDocMarkup.new(text).to_html
34
- end
35
-
36
- # @param text [String]
37
- # @return [String]
38
- def escape text
39
- CGI.escapeHTML(text)
40
- end
41
-
42
- # @param code [String]
43
- # @return [String]
44
- def ruby_to_html code
45
- code
46
- end
47
- end
48
- private_constant :Binder
49
-
50
- # @param directory [String]
51
- def initialize directory = VIEWS_PATH
52
- directory = VIEWS_PATH if directory.nil? or !File.directory?(directory)
53
- directories = [directory]
54
- directories.push VIEWS_PATH if directory != VIEWS_PATH
55
- # @type [Proc]
56
- # @param template [String]
57
- # @param layout [Boolean]
58
- # @param locals [Hash]
59
- @render_method = proc { |template, layout: false, locals: {}|
60
- binder = Binder.new(locals, @render_method)
61
- if layout
62
- Tilt::ERBTemplate.new(Page.select_template(directories, 'layout')).render(binder) do
63
- Tilt::ERBTemplate.new(Page.select_template(directories, template)).render(binder)
64
- end
65
- else
66
- Tilt::ERBTemplate.new(Page.select_template(directories, template)).render(binder)
67
- end
68
- }
69
- end
70
-
71
- # @param template [String]
72
- # @param layout [Boolean]
73
- # @param locals [Hash]
74
- # @sg-ignore
75
- # @return [String]
76
- def render template, layout: true, locals: {}
77
- # @type [String]
78
- @render_method.call(template, layout: layout, locals: locals)
79
- end
80
-
81
- # @param directories [Array<String>]
82
- # @param name [String]
83
- # @return [String]
84
- def self.select_template directories, name
85
- directories.each do |dir|
86
- path = File.join(dir, "#{name}.erb")
87
- return path if File.file?(path)
88
- end
89
- raise FileNotFoundError, "Template not found: #{name}"
90
- end
91
- end
92
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'ostruct'
4
+ require 'tilt'
5
+ require 'yard'
6
+ require 'cgi'
7
+
8
+ module Solargraph
9
+ class Page
10
+ # @todo This method directive is necessary because OpenStruct.new confuses
11
+ # the typechecker.
12
+ # @!method self.new(locals, render_method)
13
+ # @param locals[Hash]
14
+ # @param render_method [Proc]
15
+ # @return [Binder]
16
+ class Binder < OpenStruct
17
+ # @param locals [Hash]
18
+ # @param render_method [Proc]
19
+ def initialize locals, render_method
20
+ super(locals)
21
+ define_singleton_method :render do |template, layout: false, locals: {}|
22
+ render_method.call(template, layout: layout, locals: locals)
23
+ end
24
+ define_singleton_method :erb do |template, layout: false, locals: {}|
25
+ render_method.call(template, layout: layout, locals: locals)
26
+ end
27
+ end
28
+
29
+ # @param text [String]
30
+ # @return [String]
31
+ def htmlify text
32
+ # @type [String]
33
+ YARD::Templates::Helpers::Markup::RDocMarkup.new(text).to_html
34
+ end
35
+
36
+ # @param text [String]
37
+ # @return [String]
38
+ def escape text
39
+ CGI.escapeHTML(text)
40
+ end
41
+
42
+ # @param code [String]
43
+ # @return [String]
44
+ def ruby_to_html code
45
+ code
46
+ end
47
+ end
48
+ private_constant :Binder
49
+
50
+ # @param directory [String]
51
+ def initialize directory = VIEWS_PATH
52
+ directory = VIEWS_PATH if directory.nil? || !File.directory?(directory)
53
+ directories = [directory]
54
+ directories.push VIEWS_PATH if directory != VIEWS_PATH
55
+ # @type [Proc]
56
+ # @param template [String]
57
+ # @param layout [Boolean]
58
+ # @param locals [Hash]
59
+ @render_method = proc { |template, layout: false, locals: {}|
60
+ binder = Binder.new(locals, @render_method)
61
+ if layout
62
+ Tilt::ERBTemplate.new(Page.select_template(directories, 'layout')).render(binder) do
63
+ Tilt::ERBTemplate.new(Page.select_template(directories, template)).render(binder)
64
+ end
65
+ else
66
+ Tilt::ERBTemplate.new(Page.select_template(directories, template)).render(binder)
67
+ end
68
+ }
69
+ end
70
+
71
+ # @param template [String]
72
+ # @param layout [Boolean]
73
+ # @param locals [Hash]
74
+ # @sg-ignore
75
+ # @return [String]
76
+ def render template, layout: true, locals: {}
77
+ # @type [String]
78
+ @render_method.call(template, layout: layout, locals: locals)
79
+ end
80
+
81
+ # @param directories [Array<String>]
82
+ # @param name [String]
83
+ # @return [String]
84
+ def self.select_template directories, name
85
+ directories.each do |dir|
86
+ path = File.join(dir, "#{name}.erb")
87
+ return path if File.file?(path)
88
+ end
89
+ raise FileNotFoundError, "Template not found: #{name}"
90
+ end
91
+ end
92
+ end