solargraph 0.58.3 → 0.59.0.dev.1

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 (201) 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 -38
  5. data/.github/workflows/rspec.yml +45 -13
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.gitignore +0 -1
  8. data/.rubocop_todo.yml +27 -49
  9. data/CHANGELOG.md +1 -10
  10. data/README.md +3 -3
  11. data/Rakefile +1 -0
  12. data/lib/solargraph/api_map/cache.rb +3 -3
  13. data/lib/solargraph/api_map/constants.rb +13 -3
  14. data/lib/solargraph/api_map/index.rb +22 -11
  15. data/lib/solargraph/api_map/source_to_yard.rb +13 -1
  16. data/lib/solargraph/api_map/store.rb +11 -8
  17. data/lib/solargraph/api_map.rb +105 -50
  18. data/lib/solargraph/bench.rb +45 -45
  19. data/lib/solargraph/complex_type/conformance.rb +176 -0
  20. data/lib/solargraph/complex_type/type_methods.rb +16 -2
  21. data/lib/solargraph/complex_type/unique_type.rb +170 -20
  22. data/lib/solargraph/complex_type.rb +119 -14
  23. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  24. data/lib/solargraph/convention/data_definition/data_definition_node.rb +3 -1
  25. data/lib/solargraph/convention/data_definition.rb +4 -1
  26. data/lib/solargraph/convention/gemfile.rb +15 -15
  27. data/lib/solargraph/convention/gemspec.rb +23 -23
  28. data/lib/solargraph/convention/rakefile.rb +17 -17
  29. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -0
  30. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +1 -0
  31. data/lib/solargraph/convention/struct_definition.rb +5 -1
  32. data/lib/solargraph/convention.rb +78 -78
  33. data/lib/solargraph/converters/dd.rb +17 -17
  34. data/lib/solargraph/converters/dl.rb +15 -15
  35. data/lib/solargraph/converters/dt.rb +15 -15
  36. data/lib/solargraph/converters/misc.rb +1 -1
  37. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  38. data/lib/solargraph/diagnostics/rubocop.rb +1 -0
  39. data/lib/solargraph/diagnostics/rubocop_helpers.rb +2 -0
  40. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  41. data/lib/solargraph/diagnostics/update_errors.rb +41 -41
  42. data/lib/solargraph/doc_map.rb +134 -373
  43. data/lib/solargraph/equality.rb +1 -1
  44. data/lib/solargraph/gem_pins.rb +14 -15
  45. data/lib/solargraph/language_server/error_codes.rb +20 -20
  46. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  47. data/lib/solargraph/language_server/host/dispatch.rb +1 -0
  48. data/lib/solargraph/language_server/host/message_worker.rb +2 -1
  49. data/lib/solargraph/language_server/host/sources.rb +1 -0
  50. data/lib/solargraph/language_server/host.rb +6 -1
  51. data/lib/solargraph/language_server/message/base.rb +97 -97
  52. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -15
  53. data/lib/solargraph/language_server/message/completion_item/resolve.rb +60 -60
  54. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -7
  55. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  56. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  57. data/lib/solargraph/language_server/message/extended/download_core.rb +19 -19
  58. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  59. data/lib/solargraph/language_server/message/initialize.rb +191 -191
  60. data/lib/solargraph/language_server/message/text_document/completion.rb +2 -0
  61. data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
  62. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -16
  63. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +2 -0
  64. data/lib/solargraph/language_server/message/text_document/formatting.rb +2 -0
  65. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  66. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -11
  67. data/lib/solargraph/language_server/message/text_document/references.rb +16 -16
  68. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -19
  69. data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -0
  70. data/lib/solargraph/language_server/message/text_document/type_definition.rb +2 -0
  71. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +35 -35
  72. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +40 -40
  73. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +26 -26
  74. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -0
  75. data/lib/solargraph/language_server/message.rb +94 -94
  76. data/lib/solargraph/language_server/request.rb +27 -27
  77. data/lib/solargraph/language_server/transport/data_reader.rb +74 -74
  78. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  79. data/lib/solargraph/library.rb +59 -13
  80. data/lib/solargraph/location.rb +9 -4
  81. data/lib/solargraph/logging.rb +21 -1
  82. data/lib/solargraph/page.rb +92 -92
  83. data/lib/solargraph/parser/comment_ripper.rb +7 -0
  84. data/lib/solargraph/parser/flow_sensitive_typing.rb +330 -102
  85. data/lib/solargraph/parser/node_processor/base.rb +32 -2
  86. data/lib/solargraph/parser/node_processor.rb +7 -6
  87. data/lib/solargraph/parser/parser_gem/class_methods.rb +28 -10
  88. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  89. data/lib/solargraph/parser/parser_gem/node_chainer.rb +31 -6
  90. data/lib/solargraph/parser/parser_gem/node_methods.rb +27 -7
  91. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  92. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +2 -0
  93. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  94. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -11
  95. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +7 -0
  96. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +37 -37
  97. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  98. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +3 -2
  99. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  100. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  101. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +2 -2
  102. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  103. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  104. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  105. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +1 -0
  106. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +12 -7
  107. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  108. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  109. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +5 -1
  110. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  111. data/lib/solargraph/parser/parser_gem.rb +12 -12
  112. data/lib/solargraph/parser/region.rb +9 -3
  113. data/lib/solargraph/parser/snippet.rb +1 -1
  114. data/lib/solargraph/parser.rb +23 -23
  115. data/lib/solargraph/pin/base.rb +53 -21
  116. data/lib/solargraph/pin/base_variable.rb +312 -20
  117. data/lib/solargraph/pin/block.rb +26 -4
  118. data/lib/solargraph/pin/breakable.rb +5 -1
  119. data/lib/solargraph/pin/callable.rb +50 -3
  120. data/lib/solargraph/pin/closure.rb +2 -6
  121. data/lib/solargraph/pin/common.rb +20 -5
  122. data/lib/solargraph/pin/compound_statement.rb +55 -0
  123. data/lib/solargraph/pin/constant.rb +45 -45
  124. data/lib/solargraph/pin/conversions.rb +2 -1
  125. data/lib/solargraph/pin/delegated_method.rb +15 -4
  126. data/lib/solargraph/pin/documenting.rb +1 -0
  127. data/lib/solargraph/pin/instance_variable.rb +5 -1
  128. data/lib/solargraph/pin/keyword.rb +0 -4
  129. data/lib/solargraph/pin/local_variable.rb +13 -57
  130. data/lib/solargraph/pin/method.rb +90 -42
  131. data/lib/solargraph/pin/method_alias.rb +8 -0
  132. data/lib/solargraph/pin/namespace.rb +7 -1
  133. data/lib/solargraph/pin/parameter.rb +76 -13
  134. data/lib/solargraph/pin/proxy_type.rb +2 -1
  135. data/lib/solargraph/pin/reference/override.rb +1 -1
  136. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  137. data/lib/solargraph/pin/reference.rb +2 -0
  138. data/lib/solargraph/pin/search.rb +1 -0
  139. data/lib/solargraph/pin/signature.rb +8 -0
  140. data/lib/solargraph/pin/symbol.rb +1 -1
  141. data/lib/solargraph/pin/until.rb +1 -1
  142. data/lib/solargraph/pin/while.rb +1 -1
  143. data/lib/solargraph/pin.rb +2 -0
  144. data/lib/solargraph/pin_cache.rb +477 -57
  145. data/lib/solargraph/position.rb +12 -26
  146. data/lib/solargraph/range.rb +6 -6
  147. data/lib/solargraph/rbs_map/conversions.rb +33 -10
  148. data/lib/solargraph/rbs_map/core_fills.rb +84 -84
  149. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  150. data/lib/solargraph/rbs_map/stdlib_map.rb +34 -5
  151. data/lib/solargraph/rbs_map.rb +74 -20
  152. data/lib/solargraph/server_methods.rb +16 -16
  153. data/lib/solargraph/shell.rb +73 -39
  154. data/lib/solargraph/source/chain/array.rb +37 -37
  155. data/lib/solargraph/source/chain/call.rb +52 -17
  156. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  157. data/lib/solargraph/source/chain/constant.rb +2 -0
  158. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  159. data/lib/solargraph/source/chain/hash.rb +1 -0
  160. data/lib/solargraph/source/chain/if.rb +1 -0
  161. data/lib/solargraph/source/chain/instance_variable.rb +22 -1
  162. data/lib/solargraph/source/chain/link.rb +109 -109
  163. data/lib/solargraph/source/chain/literal.rb +5 -0
  164. data/lib/solargraph/source/chain/or.rb +9 -1
  165. data/lib/solargraph/source/chain/q_call.rb +11 -11
  166. data/lib/solargraph/source/chain/variable.rb +13 -13
  167. data/lib/solargraph/source/chain/z_super.rb +30 -30
  168. data/lib/solargraph/source/chain.rb +25 -22
  169. data/lib/solargraph/source/change.rb +9 -2
  170. data/lib/solargraph/source/cursor.rb +7 -1
  171. data/lib/solargraph/source/source_chainer.rb +13 -3
  172. data/lib/solargraph/source/updater.rb +4 -0
  173. data/lib/solargraph/source.rb +33 -7
  174. data/lib/solargraph/source_map/clip.rb +13 -2
  175. data/lib/solargraph/source_map/data.rb +4 -1
  176. data/lib/solargraph/source_map/mapper.rb +24 -1
  177. data/lib/solargraph/source_map.rb +14 -6
  178. data/lib/solargraph/type_checker/problem.rb +3 -1
  179. data/lib/solargraph/type_checker/rules.rb +75 -2
  180. data/lib/solargraph/type_checker.rb +111 -30
  181. data/lib/solargraph/version.rb +1 -1
  182. data/lib/solargraph/workspace/config.rb +3 -1
  183. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  184. data/lib/solargraph/workspace/require_paths.rb +1 -0
  185. data/lib/solargraph/workspace.rb +158 -16
  186. data/lib/solargraph/yard_map/helpers.rb +2 -1
  187. data/lib/solargraph/yard_map/mapper/to_method.rb +5 -1
  188. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
  189. data/lib/solargraph/yard_map/mapper.rb +5 -0
  190. data/lib/solargraph/yard_tags.rb +20 -20
  191. data/lib/solargraph/yardoc.rb +33 -23
  192. data/lib/solargraph.rb +24 -3
  193. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  194. data/rbs/fills/tuple/tuple.rbs +28 -0
  195. data/rbs/shims/ast/0/node.rbs +1 -1
  196. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  197. data/solargraph.gemspec +2 -1
  198. metadata +12 -7
  199. data/lib/solargraph/type_checker/checks.rb +0 -124
  200. data/lib/solargraph/type_checker/param_def.rb +0 -37
  201. data/lib/solargraph/yard_map/to_method.rb +0 -89
@@ -22,8 +22,9 @@ module Solargraph
22
22
  # @param attribute [Boolean]
23
23
  # @param signatures [::Array<Signature>, nil]
24
24
  # @param anon_splat [Boolean]
25
+ # @param context [ComplexType, ComplexType::UniqueType, nil]
25
26
  def initialize visibility: :public, explicit: true, block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false,
26
- **splat
27
+ context: nil, **splat
27
28
  super(**splat)
28
29
  @visibility = visibility
29
30
  @explicit = explicit
@@ -32,26 +33,7 @@ module Solargraph
32
33
  @attribute = attribute
33
34
  @signatures = signatures
34
35
  @anon_splat = anon_splat
35
- end
36
-
37
- # @param signature_pins [Array<Pin::Signature>]
38
- # @return [Array<Pin::Signature>]
39
- def combine_all_signature_pins(*signature_pins)
40
- # @type [Hash{Array => Array<Pin::Signature>}]
41
- by_arity = {}
42
- signature_pins.each do |signature_pin|
43
- by_arity[signature_pin.arity] ||= []
44
- by_arity[signature_pin.arity] << signature_pin
45
- end
46
- by_arity.transform_values! do |same_arity_pins|
47
- # @param memo [Pin::Signature, nil]
48
- # @param signature [Pin::Signature]
49
- same_arity_pins.reduce(nil) do |memo, signature|
50
- next signature if memo.nil?
51
- memo.combine_with(signature)
52
- end
53
- end
54
- by_arity.values.flatten
36
+ @context = context if context
55
37
  end
56
38
 
57
39
  # @param other [Pin::Method]
@@ -66,20 +48,6 @@ module Solargraph
66
48
  end
67
49
  end
68
50
 
69
- # @param other [Pin::Method]
70
- # @return [Array<Pin::Signature>]
71
- def combine_signatures(other)
72
- all_undefined = signatures.all? { |sig| sig.return_type.undefined? }
73
- other_all_undefined = other.signatures.all? { |sig| sig.return_type.undefined? }
74
- if all_undefined && !other_all_undefined
75
- other.signatures
76
- elsif other_all_undefined && !all_undefined
77
- signatures
78
- else
79
- combine_all_signature_pins(*signatures, *other.signatures)
80
- end
81
- end
82
-
83
51
  def combine_with(other, attrs = {})
84
52
  priority_choice = choose_priority(other)
85
53
  return priority_choice unless priority_choice.nil?
@@ -92,7 +60,6 @@ module Solargraph
92
60
  end
93
61
  new_attrs = {
94
62
  visibility: combine_visibility(other),
95
- # @sg-ignore https://github.com/castwide/solargraph/pull/1050
96
63
  explicit: explicit? || other.explicit?,
97
64
  block: combine_blocks(other),
98
65
  node: choose_node(other, :node),
@@ -160,6 +127,8 @@ module Solargraph
160
127
  !block.nil?
161
128
  end
162
129
 
130
+ # @sg-ignore flow sensitive typing needs to remove literal with
131
+ # this unless block
163
132
  # @return [Pin::Signature, nil]
164
133
  def block
165
134
  return @block unless @block == :undefined
@@ -179,9 +148,10 @@ module Solargraph
179
148
  end
180
149
 
181
150
  # @param parameters [::Array<Parameter>]
182
- # @param return_type [ComplexType]
151
+ # @param return_type [ComplexType, nil]
183
152
  # @return [Signature]
184
153
  def generate_signature(parameters, return_type)
154
+ # @type [Pin::Signature, nil]
185
155
  block = nil
186
156
  yieldparam_tags = docstring.tags(:yieldparam)
187
157
  yieldreturn_tags = docstring.tags(:yieldreturn)
@@ -202,6 +172,7 @@ module Solargraph
202
172
  comments: p.text,
203
173
  name: name,
204
174
  decl: decl,
175
+ # @sg-ignore flow sensitive typing needs to handle attrs
205
176
  presence: location ? location.range : nil,
206
177
  return_type: ComplexType.try_parse(*p.types),
207
178
  source: source
@@ -247,6 +218,7 @@ module Solargraph
247
218
  else
248
219
  "(#{signatures.first.parameters.map(&:full).join(', ')}) " unless signatures.first.parameters.empty?
249
220
  end.to_s
221
+ # @sg-ignore Need to add nil check here
250
222
  detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
251
223
  detail.strip!
252
224
  return nil if detail.empty?
@@ -276,6 +248,7 @@ module Solargraph
276
248
  return nil if signatures.empty?
277
249
 
278
250
  rbs = "def #{name}: #{signatures.first.to_rbs}"
251
+ # @sg-ignore Need to add nil check here
279
252
  signatures[1..].each do |sig|
280
253
  rbs += "\n"
281
254
  rbs += (' ' * (4 + name.length))
@@ -294,6 +267,7 @@ module Solargraph
294
267
  end
295
268
 
296
269
  def typify api_map
270
+ # @sg-ignore Need to add nil check here
297
271
  logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context.rooted_tags}, return_type=#{return_type.rooted_tags}) - starting" }
298
272
  decl = super
299
273
  unless decl.undefined?
@@ -303,6 +277,7 @@ module Solargraph
303
277
  type = see_reference(api_map) || typify_from_super(api_map)
304
278
  logger.debug { "Method#typify(self=#{self}) - type=#{type&.rooted_tags.inspect}" }
305
279
  unless type.nil?
280
+ # @sg-ignore Need to add nil check here
306
281
  qualified = type.qualify(api_map, *closure.gates)
307
282
  logger.debug { "Method#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
308
283
  return qualified
@@ -396,7 +371,7 @@ module Solargraph
396
371
  attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
397
372
  end
398
373
 
399
- # @return [::Array<Pin::Method>]
374
+ # @return [::Array<Pin::Signature>]
400
375
  def overloads
401
376
  # Ignore overload tags with nil parameters. If it's not an array, the
402
377
  # tag's source is likely malformed.
@@ -414,6 +389,7 @@ module Solargraph
414
389
  comments: tag.docstring.all.to_s,
415
390
  name: name,
416
391
  decl: decl,
392
+ # @sg-ignore flow sensitive typing needs to handle attrs
417
393
  presence: location ? location.range : nil,
418
394
  return_type: param_type_from_name(tag, src.first),
419
395
  source: :overloads
@@ -468,10 +444,12 @@ module Solargraph
468
444
 
469
445
  attr_writer :documentation
470
446
 
447
+ # @sg-ignore Need to add nil check here
471
448
  def dodgy_visibility_source?
472
449
  # as of 2025-03-12, the RBS generator used for
473
450
  # e.g. activesupport did not understand 'private' markings
474
451
  # inside 'class << self' blocks, but YARD did OK at it
452
+ # @sg-ignore Need to add nil check here
475
453
  source == :rbs && scope == :class && type_location&.filename&.include?('generated') && return_type.undefined? ||
476
454
  # YARD's RBS generator seems to miss a lot of should-be protected instance methods
477
455
  source == :rbs && scope == :instance && namespace.start_with?('YARD::') ||
@@ -485,6 +463,71 @@ module Solargraph
485
463
 
486
464
  private
487
465
 
466
+ # @param other [Pin::Method]
467
+ # @return [Array<Pin::Signature>]
468
+ def combine_signatures(other)
469
+ all_undefined = signatures.all? { |sig| !sig.return_type&.defined? }
470
+ other_all_undefined = other.signatures.all? { |sig| !sig.return_type&.defined? }
471
+ if all_undefined && !other_all_undefined
472
+ other.signatures
473
+ elsif other_all_undefined && !all_undefined
474
+ signatures
475
+ else
476
+ combine_signatures_by_type_arity(*signatures, *other.signatures)
477
+ end
478
+ end
479
+
480
+ # @param signature_pins [Array<Pin::Signature>]
481
+ #
482
+ # @return [Array<Pin::Signature>]
483
+ def combine_signatures_by_type_arity(*signature_pins)
484
+ # @type [Hash{Array => Array<Pin::Signature>}]
485
+ by_type_arity = {}
486
+ signature_pins.each do |signature_pin|
487
+ by_type_arity[signature_pin.type_arity] ||= []
488
+ by_type_arity[signature_pin.type_arity] << signature_pin
489
+ end
490
+
491
+ by_type_arity.transform_values! do |same_type_arity_signatures|
492
+ combine_same_type_arity_signatures same_type_arity_signatures
493
+ end
494
+ by_type_arity.values.flatten
495
+ end
496
+
497
+ # @param same_type_arity_signatures [Array<Pin::Signature>]
498
+ #
499
+ # @return [Array<Pin::Signature>]
500
+ def combine_same_type_arity_signatures(same_type_arity_signatures)
501
+ # This is an O(n^2) operation, so bail out if n is not small
502
+ return same_type_arity_signatures if same_type_arity_signatures.length > 10
503
+
504
+ # @param old_signatures [Array<Pin::Signature>]
505
+ # @param new_signature [Pin::Signature]
506
+ same_type_arity_signatures.reduce([]) do |old_signatures, new_signature|
507
+ next [new_signature] if old_signatures.empty?
508
+
509
+ found_merge = false
510
+ old_signatures.flat_map do |old_signature|
511
+ potential_new_signature = old_signature.combine_with(new_signature)
512
+
513
+ if potential_new_signature.type_arity == old_signature.type_arity
514
+ # the number of types in each parameter and return type
515
+ # match, so we found compatible signatures to merge. If
516
+ # we increased the number of types, we'd potentially
517
+ # have taken away the ability to use parameter types to
518
+ # choose the correct return type (while Ruby doesn't
519
+ # dispatch based on type, RBS does distinguish overloads
520
+ # based on types, not just arity, allowing for type
521
+ # information describing how methods behave based on
522
+ # their input types)
523
+ old_signatures - [old_signature] + [potential_new_signature]
524
+ else
525
+ old_signatures + [new_signature]
526
+ end
527
+ end
528
+ end
529
+ end
530
+
488
531
  # @param name [String]
489
532
  # @param asgn [Boolean]
490
533
  #
@@ -532,19 +575,20 @@ module Solargraph
532
575
  end
533
576
 
534
577
  # @param api_map [ApiMap]
535
- # @return [ComplexType, nil]
578
+ # @return [ComplexType, ComplexType::UniqueType, nil]
536
579
  def see_reference api_map
537
580
  # This should actually be an intersection type
538
- # @param ref [YARD::Tags::Tag, Solargraph::Yard::Tags::RefTag]
581
+ # @param ref [YARD::Tags::Tag, YARD::Tags::RefTag]
539
582
  docstring.ref_tags.each do |ref|
540
583
  # @sg-ignore ref should actually be an intersection type
541
584
  next unless ref.tag_name == 'return' && ref.owner
542
- # @sg-ignore ref should actually be an intersection type
585
+ # @sg-ignore should actually be an intersection type
543
586
  result = resolve_reference(ref.owner.to_s, api_map)
544
587
  return result unless result.nil?
545
588
  end
546
589
  match = comments.match(/^[ \t]*\(see (.*)\)/m)
547
590
  return nil if match.nil?
591
+ # @sg-ignore Need to add nil check here
548
592
  resolve_reference match[1], api_map
549
593
  end
550
594
 
@@ -559,6 +603,7 @@ module Solargraph
559
603
  stack = rest_of_stack api_map
560
604
  return nil if stack.empty?
561
605
  stack.each do |pin|
606
+ # @sg-ignore Need to add nil check here
562
607
  return pin.return_type unless pin.return_type.undefined?
563
608
  end
564
609
  nil
@@ -566,7 +611,7 @@ module Solargraph
566
611
 
567
612
  # @param ref [String]
568
613
  # @param api_map [ApiMap]
569
- # @return [ComplexType, nil]
614
+ # @return [ComplexType, ComplexType::UniqueType, nil]
570
615
  def resolve_reference ref, api_map
571
616
  parts = ref.split(/[.#]/)
572
617
  if parts.first.empty? || parts.one?
@@ -574,6 +619,7 @@ module Solargraph
574
619
  else
575
620
  fqns = api_map.qualify(parts.first, *gates)
576
621
  return ComplexType::UNDEFINED if fqns.nil?
622
+ # @sg-ignore Need to add nil check here
577
623
  path = fqns + ref[parts.first.length] + parts.last
578
624
  end
579
625
  pins = api_map.get_path_pins(path)
@@ -609,9 +655,11 @@ module Solargraph
609
655
  rng = Range.from_node(n)
610
656
  next unless rng
611
657
  clip = api_map.clip_at(
658
+ # @sg-ignore Need to add nil check here
612
659
  location.filename,
613
660
  rng.ending
614
661
  )
662
+ # @sg-ignore Need to add nil check here
615
663
  chain = Solargraph::Parser.chain(n, location.filename)
616
664
  type = chain.infer(api_map, self, clip.locals)
617
665
  result.push type unless type.undefined?
@@ -26,6 +26,14 @@ module Solargraph
26
26
  :public
27
27
  end
28
28
 
29
+ def to_rbs
30
+ if scope == :class
31
+ "alias self.#{name} self.#{original}"
32
+ else
33
+ "alias #{name} #{original}"
34
+ end
35
+ end
36
+
29
37
  def path
30
38
  @path ||= namespace + (scope == :instance ? '#' : '.') + name
31
39
  end
@@ -26,7 +26,6 @@ module Solargraph
26
26
  @type = type
27
27
  @visibility = visibility
28
28
  if name.start_with?('::')
29
- # @type [String]
30
29
  name = name[2..-1] || ''
31
30
  @closure = Solargraph::Pin::ROOT_PIN
32
31
  end
@@ -39,6 +38,7 @@ module Solargraph
39
38
  closure_name = if [Solargraph::Pin::ROOT_PIN, nil].include?(closure)
40
39
  ''
41
40
  else
41
+ # @sg-ignore Need to add nil check here
42
42
  closure.full_context.namespace + '::'
43
43
  end
44
44
  closure_name += parts.join('::')
@@ -48,6 +48,12 @@ module Solargraph
48
48
  @name = name
49
49
  end
50
50
 
51
+ def reset_generated!
52
+ @return_type = nil
53
+ @full_context = nil
54
+ @path = nil
55
+ end
56
+
51
57
  def to_rbs
52
58
  "#{@type.to_s} #{return_type.all_params.first.to_rbs}#{rbs_generics}".strip
53
59
  end
@@ -30,12 +30,29 @@ module Solargraph
30
30
  end
31
31
 
32
32
  def combine_with(other, attrs={})
33
- new_attrs = {
34
- decl: assert_same(other, :decl),
35
- presence: choose(other, :presence),
36
- asgn_code: choose(other, :asgn_code),
37
- }.merge(attrs)
38
- super(other, new_attrs)
33
+ # Parameters can be combined with local variables
34
+ new_attrs = if other.is_a?(Parameter)
35
+ {
36
+ decl: assert_same(other, :decl),
37
+ asgn_code: choose(other, :asgn_code)
38
+ }
39
+ else
40
+ {
41
+ decl: decl,
42
+ asgn_code: asgn_code
43
+ }
44
+ end
45
+ super(other, new_attrs.merge(attrs))
46
+ end
47
+
48
+ def combine_return_type(other)
49
+ out = super
50
+ if out&.undefined?
51
+ # allow our return_type method to provide a better type
52
+ # using :param tag
53
+ out = nil
54
+ end
55
+ out
39
56
  end
40
57
 
41
58
  def keyword?
@@ -43,6 +60,7 @@ module Solargraph
43
60
  end
44
61
 
45
62
  def kwrestarg?
63
+ # @sg-ignore flow sensitive typing needs to handle attrs
46
64
  decl == :kwrestarg || (assignment && [:HASH, :hash].include?(assignment.type))
47
65
  end
48
66
 
@@ -72,6 +90,11 @@ module Solargraph
72
90
  end
73
91
  end
74
92
 
93
+ # @return [String]
94
+ def type_arity_decl
95
+ arity_decl + return_type.items.count.to_s
96
+ end
97
+
75
98
  def arg?
76
99
  decl == :arg
77
100
  end
@@ -80,6 +103,14 @@ module Solargraph
80
103
  decl == :restarg
81
104
  end
82
105
 
106
+ def mandatory_positional?
107
+ decl == :arg
108
+ end
109
+
110
+ def positional?
111
+ !keyword?
112
+ end
113
+
83
114
  def rest?
84
115
  decl == :restarg || decl == :kwrestarg
85
116
  end
@@ -123,6 +154,11 @@ module Solargraph
123
154
  end
124
155
  end
125
156
 
157
+ def reset_generated!
158
+ @return_type = nil if param_tag
159
+ super
160
+ end
161
+
126
162
  # @return [String]
127
163
  def full
128
164
  full_name + case decl
@@ -135,12 +171,14 @@ module Solargraph
135
171
  end
136
172
  end
137
173
 
174
+ # @sg-ignore super always sets @return_type to something
138
175
  # @return [ComplexType]
139
176
  def return_type
140
177
  if @return_type.nil?
141
178
  @return_type = ComplexType::UNDEFINED
142
179
  found = param_tag
143
180
  @return_type = ComplexType.try_parse(*found.types) unless found.nil? or found.types.nil?
181
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
144
182
  if @return_type.undefined?
145
183
  if decl == :restarg
146
184
  @return_type = ComplexType.try_parse('::Array')
@@ -152,22 +190,29 @@ module Solargraph
152
190
  end
153
191
  end
154
192
  super
155
- @return_type
156
193
  end
157
194
 
158
195
  # The parameter's zero-based location in the block's signature.
159
196
  #
197
+ # @sg-ignore Need to add nil check here
160
198
  # @return [Integer]
161
199
  def index
162
- # @type [Method, Block]
163
200
  method_pin = closure
201
+ # @sg-ignore Need to add nil check here
164
202
  method_pin.parameter_names.index(name)
165
203
  end
166
204
 
167
205
  # @param api_map [ApiMap]
168
206
  def typify api_map
169
- return return_type.qualify(api_map, *closure.gates) unless return_type.undefined?
170
- closure.is_a?(Pin::Block) ? typify_block_param(api_map) : typify_method_param(api_map)
207
+ new_type = super
208
+ return new_type if new_type.defined?
209
+
210
+ # sniff based on param tags
211
+ new_type = closure.is_a?(Pin::Block) ? typify_block_param(api_map) : typify_method_param(api_map)
212
+
213
+ return adjust_type api_map, new_type.self_to_type(full_context) if new_type.defined?
214
+
215
+ adjust_type api_map, super.self_to_type(full_context)
171
216
  end
172
217
 
173
218
  # @param atype [ComplexType]
@@ -176,9 +221,16 @@ module Solargraph
176
221
  # make sure we get types from up the method
177
222
  # inheritance chain if we don't have them on this pin
178
223
  ptype = typify api_map
179
- ptype.undefined? || ptype.can_assign?(api_map, atype) || ptype.generic?
224
+ return true if ptype.undefined?
225
+
226
+ return true if atype.conforms_to?(api_map,
227
+ ptype,
228
+ :method_call,
229
+ [:allow_empty_params, :allow_undefined])
230
+ ptype.generic?
180
231
  end
181
232
 
233
+ # @sg-ignore flow sensitive typing needs to handle attrs
182
234
  def documentation
183
235
  tag = param_tag
184
236
  return '' if tag.nil? || tag.text.nil?
@@ -187,12 +239,19 @@ module Solargraph
187
239
 
188
240
  private
189
241
 
242
+ def generate_complex_type
243
+ nil
244
+ end
245
+
190
246
  # @return [YARD::Tags::Tag, nil]
191
247
  def param_tag
248
+ # @sg-ignore Need to add nil check here
192
249
  params = closure.docstring.tags(:param)
250
+ # @sg-ignore Need to add nil check here
193
251
  params.each do |p|
194
252
  return p if p.name == name
195
253
  end
254
+ # @sg-ignore Need to add nil check here
196
255
  params[index] if index && params[index] && (params[index].name.nil? || params[index].name.empty?)
197
256
  end
198
257
 
@@ -200,7 +259,7 @@ module Solargraph
200
259
  # @return [ComplexType]
201
260
  def typify_block_param api_map
202
261
  block_pin = closure
203
- if block_pin.is_a?(Pin::Block) && block_pin.receiver
262
+ if block_pin.is_a?(Pin::Block) && block_pin.receiver && index
204
263
  return block_pin.typify_parameters(api_map)[index]
205
264
  end
206
265
  ComplexType::UNDEFINED
@@ -209,6 +268,7 @@ module Solargraph
209
268
  # @param api_map [ApiMap]
210
269
  # @return [ComplexType]
211
270
  def typify_method_param api_map
271
+ # @sg-ignore Need to add nil check here
212
272
  meths = api_map.get_method_stack(closure.full_context.tag, closure.name, scope: closure.scope)
213
273
  # meths.shift # Ignore the first one
214
274
  meths.each do |meth|
@@ -222,6 +282,7 @@ module Solargraph
222
282
  if found.nil? and !index.nil?
223
283
  found = params[index] if params[index] && (params[index].name.nil? || params[index].name.empty?)
224
284
  end
285
+ # @sg-ignore Need to add nil check here
225
286
  return ComplexType.try_parse(*found.types).qualify(api_map, *meth.closure.gates) unless found.nil? || found.types.nil?
226
287
  end
227
288
  ComplexType::UNDEFINED
@@ -230,6 +291,7 @@ module Solargraph
230
291
  # @param heredoc [YARD::Docstring]
231
292
  # @param api_map [ApiMap]
232
293
  # @param skip [::Array]
294
+ #
233
295
  # @return [::Array<YARD::Tags::Tag>]
234
296
  def see_reference heredoc, api_map, skip = []
235
297
  # This should actually be an intersection type
@@ -237,7 +299,7 @@ module Solargraph
237
299
  heredoc.ref_tags.each do |ref|
238
300
  # @sg-ignore ref should actually be an intersection type
239
301
  next unless ref.tag_name == 'param' && ref.owner
240
- # @sg-ignore ref should actually be an intersection type
302
+ # @todo ref should actually be an intersection type
241
303
  result = resolve_reference(ref.owner.to_s, api_map, skip)
242
304
  return result unless result.nil?
243
305
  end
@@ -257,6 +319,7 @@ module Solargraph
257
319
  else
258
320
  fqns = api_map.qualify(parts.first, namespace)
259
321
  return nil if fqns.nil?
322
+ # @sg-ignore Need to add nil check here
260
323
  path = fqns + ref[parts.first.length] + parts.last
261
324
  end
262
325
  pins = api_map.get_path_pins(path)
@@ -3,7 +3,7 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class ProxyType < Base
6
- # @param return_type [ComplexType]
6
+ # @param return_type [ComplexType, ComplexType::UniqueType]
7
7
  # @param gates [Array<String>, nil] Namespaces to try while resolving non-rooted types
8
8
  # @param binder [ComplexType, ComplexType::UniqueType, nil]
9
9
  # @param gates [Array<String>, nil]
@@ -25,6 +25,7 @@ module Solargraph
25
25
  def self.anonymous context, closure: nil, binder: nil, **kwargs
26
26
  unless closure
27
27
  parts = context.namespace.split('::')
28
+ # @sg-ignore Need to add nil check here
28
29
  namespace = parts[0..-2].join('::').to_s
29
30
  closure = Solargraph::Pin::Namespace.new(name: namespace, source: :proxy_type)
30
31
  end
@@ -7,7 +7,7 @@ module Solargraph
7
7
  # @return [::Array<YARD::Tags::Tag>]
8
8
  attr_reader :tags
9
9
 
10
- # @return [::Array<Symbol>]
10
+ # @return [::Array<::Symbol>]
11
11
  attr_reader :delete
12
12
 
13
13
  def closure
@@ -6,7 +6,9 @@ module Solargraph
6
6
  # A Superclass reference pin.
7
7
  #
8
8
  class Superclass < Reference
9
+ # @sg-ignore Need to add nil check here
9
10
  def reference_gates
11
+ # @sg-ignore Need to add nil check here
10
12
  @reference_gates ||= closure.gates - [closure.path]
11
13
  end
12
14
  end
@@ -30,8 +30,10 @@ module Solargraph
30
30
  )
31
31
  end
32
32
 
33
+ # @sg-ignore Need to add nil check here
33
34
  # @return [Array<String>]
34
35
  def reference_gates
36
+ # @sg-ignore Need to add nil check here
35
37
  closure.gates
36
38
  end
37
39
  end
@@ -51,6 +51,7 @@ module Solargraph
51
51
 
52
52
  # @param str1 [String]
53
53
  # @param str2 [String]
54
+ #
54
55
  # @return [Float]
55
56
  def fuzzy_string_match str1, str2
56
57
  return 1.0 + (str2.length.to_f / str1.length.to_f) if str1.downcase.include?(str2.downcase)
@@ -10,6 +10,7 @@ module Solargraph
10
10
  end
11
11
 
12
12
  def generics
13
+ # @type [Array<::String, nil>]
13
14
  @generics ||= [].freeze
14
15
  end
15
16
 
@@ -19,6 +20,7 @@ module Solargraph
19
20
 
20
21
  attr_writer :closure
21
22
 
23
+ # @ sg-ignore need boolish support for ? methods
22
24
  def dodgy_return_type_source?
23
25
  super || closure&.dodgy_return_type_source?
24
26
  end
@@ -32,8 +34,11 @@ module Solargraph
32
34
  end
33
35
 
34
36
  def typify api_map
37
+ # @sg-ignore Need to add nil check here
35
38
  if return_type.defined?
39
+ # @sg-ignore Need to add nil check here
36
40
  qualified = return_type.qualify(api_map, closure.namespace)
41
+ # @sg-ignore Need to add nil check here
37
42
  logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
38
43
  return qualified
39
44
  end
@@ -46,8 +51,11 @@ module Solargraph
46
51
  method_stack.each do |pin|
47
52
  sig = pin.signatures.find { |s| s.arity == self.arity }
48
53
  next unless sig
54
+ # @sg-ignore Need to add nil check here
49
55
  unless sig.return_type.undefined?
56
+ # @sg-ignore Need to add nil check here
50
57
  qualified = sig.return_type.qualify(api_map, closure.namespace)
58
+ # @sg-ignore Need to add nil check here
51
59
  logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
52
60
  return qualified
53
61
  end
@@ -3,7 +3,7 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class Symbol < Base
6
- # @param location [Solargraph::Location]
6
+ # @param location [Solargraph::Location, nil]
7
7
  # @param name [String]
8
8
  def initialize(location, name, **kwargs)
9
9
  # @sg-ignore "Unrecognized keyword argument kwargs to Solargraph::Pin::Base#initialize"
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Pin
5
- class Until < Base
5
+ class Until < CompoundStatement
6
6
  include Breakable
7
7
 
8
8
  # @param receiver [Parser::AST::Node, nil]
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Solargraph
4
4
  module Pin
5
- class While < Base
5
+ class While < CompoundStatement
6
6
  include Breakable
7
7
 
8
8
  # @param receiver [Parser::AST::Node, nil]
@@ -38,6 +38,8 @@ module Solargraph
38
38
  autoload :Until, 'solargraph/pin/until'
39
39
  autoload :While, 'solargraph/pin/while'
40
40
  autoload :Callable, 'solargraph/pin/callable'
41
+ autoload :CompoundStatement,
42
+ 'solargraph/pin/compound_statement'
41
43
 
42
44
  ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil, source: :pin_rb)
43
45
  end