solargraph 0.52.0 → 0.53.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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/plugins.yml +40 -0
  3. data/.github/workflows/rspec.yml +1 -3
  4. data/.github/workflows/typecheck.yml +34 -0
  5. data/CHANGELOG.md +30 -0
  6. data/README.md +13 -16
  7. data/SPONSORS.md +1 -7
  8. data/lib/solargraph/api_map/cache.rb +59 -21
  9. data/lib/solargraph/api_map/store.rb +45 -9
  10. data/lib/solargraph/api_map.rb +152 -93
  11. data/lib/solargraph/bench.rb +2 -2
  12. data/lib/solargraph/cache.rb +29 -5
  13. data/lib/solargraph/complex_type/type_methods.rb +53 -8
  14. data/lib/solargraph/complex_type/unique_type.rb +149 -59
  15. data/lib/solargraph/complex_type.rb +62 -9
  16. data/lib/solargraph/convention.rb +0 -1
  17. data/lib/solargraph/converters/dd.rb +5 -0
  18. data/lib/solargraph/converters/dl.rb +3 -0
  19. data/lib/solargraph/converters/dt.rb +3 -0
  20. data/lib/solargraph/diagnostics/rubocop.rb +8 -7
  21. data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
  22. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  23. data/lib/solargraph/diagnostics.rb +2 -2
  24. data/lib/solargraph/doc_map.rb +146 -0
  25. data/lib/solargraph/gem_pins.rb +64 -0
  26. data/lib/solargraph/language_server/host/cataloger.rb +1 -0
  27. data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
  28. data/lib/solargraph/language_server/host/dispatch.rb +10 -4
  29. data/lib/solargraph/language_server/host/message_worker.rb +4 -0
  30. data/lib/solargraph/language_server/host/sources.rb +7 -4
  31. data/lib/solargraph/language_server/host.rb +15 -6
  32. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  33. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
  34. data/lib/solargraph/language_server/message/initialize.rb +5 -2
  35. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  36. data/lib/solargraph/language_server/message/text_document.rb +0 -1
  37. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  38. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  39. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  40. data/lib/solargraph/library.rb +58 -11
  41. data/lib/solargraph/location.rb +1 -0
  42. data/lib/solargraph/parser/comment_ripper.rb +3 -0
  43. data/lib/solargraph/parser/node_methods.rb +47 -8
  44. data/lib/solargraph/parser/node_processor/base.rb +9 -0
  45. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +29 -3
  46. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
  47. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +42 -34
  48. data/lib/solargraph/parser/{legacy → parser_gem}/node_methods.rb +201 -29
  49. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
  50. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/args_node.rb +4 -1
  51. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
  52. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
  53. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
  54. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
  55. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +1 -1
  56. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
  57. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
  58. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
  59. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
  60. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
  61. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
  62. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
  63. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
  64. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
  65. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
  66. data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
  67. data/lib/solargraph/parser/parser_gem.rb +12 -0
  68. data/lib/solargraph/parser/snippet.rb +2 -0
  69. data/lib/solargraph/parser.rb +8 -11
  70. data/lib/solargraph/pin/base.rb +63 -8
  71. data/lib/solargraph/pin/base_variable.rb +6 -2
  72. data/lib/solargraph/pin/block.rb +11 -6
  73. data/lib/solargraph/pin/closure.rb +17 -2
  74. data/lib/solargraph/pin/common.rb +7 -3
  75. data/lib/solargraph/pin/conversions.rb +33 -3
  76. data/lib/solargraph/pin/documenting.rb +25 -34
  77. data/lib/solargraph/pin/instance_variable.rb +4 -0
  78. data/lib/solargraph/pin/local_variable.rb +13 -1
  79. data/lib/solargraph/pin/method.rb +109 -15
  80. data/lib/solargraph/pin/namespace.rb +16 -10
  81. data/lib/solargraph/pin/parameter.rb +41 -10
  82. data/lib/solargraph/pin/reference/override.rb +2 -2
  83. data/lib/solargraph/pin/reference.rb +8 -0
  84. data/lib/solargraph/pin/search.rb +3 -3
  85. data/lib/solargraph/pin/signature.rb +114 -2
  86. data/lib/solargraph/pin.rb +0 -1
  87. data/lib/solargraph/range.rb +2 -2
  88. data/lib/solargraph/rbs_map/conversions.rb +212 -25
  89. data/lib/solargraph/rbs_map/core_fills.rb +4 -26
  90. data/lib/solargraph/rbs_map/core_map.rb +1 -0
  91. data/lib/solargraph/rbs_map/core_signs.rb +2 -0
  92. data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
  93. data/lib/solargraph/rbs_map.rb +19 -9
  94. data/lib/solargraph/shell.rb +62 -59
  95. data/lib/solargraph/source/chain/array.rb +4 -1
  96. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  97. data/lib/solargraph/source/chain/call.rb +95 -26
  98. data/lib/solargraph/source/chain/constant.rb +15 -1
  99. data/lib/solargraph/source/chain/if.rb +23 -0
  100. data/lib/solargraph/source/chain/link.rb +7 -1
  101. data/lib/solargraph/source/chain/or.rb +1 -1
  102. data/lib/solargraph/source/chain/z_super.rb +2 -2
  103. data/lib/solargraph/source/chain.rb +20 -4
  104. data/lib/solargraph/source/change.rb +3 -0
  105. data/lib/solargraph/source/cursor.rb +2 -0
  106. data/lib/solargraph/source/source_chainer.rb +6 -5
  107. data/lib/solargraph/source.rb +15 -16
  108. data/lib/solargraph/source_map/clip.rb +11 -7
  109. data/lib/solargraph/source_map/mapper.rb +10 -0
  110. data/lib/solargraph/source_map.rb +13 -3
  111. data/lib/solargraph/type_checker/checks.rb +10 -2
  112. data/lib/solargraph/type_checker.rb +74 -19
  113. data/lib/solargraph/version.rb +1 -1
  114. data/lib/solargraph/workspace/config.rb +8 -6
  115. data/lib/solargraph/workspace.rb +1 -1
  116. data/lib/solargraph/yard_map/cache.rb +6 -0
  117. data/lib/solargraph/yard_map/helpers.rb +1 -1
  118. data/lib/solargraph/yard_map/mapper/to_method.rb +11 -1
  119. data/lib/solargraph/yard_map/to_method.rb +11 -4
  120. data/lib/solargraph/yard_map.rb +0 -292
  121. data/lib/solargraph/yardoc.rb +52 -0
  122. data/lib/solargraph.rb +4 -1
  123. data/solargraph.gemspec +2 -2
  124. metadata +35 -57
  125. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  126. data/lib/solargraph/documentor.rb +0 -76
  127. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  128. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  129. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
  130. data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
  131. data/lib/solargraph/parser/legacy.rb +0 -12
  132. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -151
  133. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -163
  134. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
  135. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  136. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  137. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
  138. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  139. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
  140. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
  141. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  142. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  143. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  144. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  145. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  146. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  147. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  148. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  149. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
  150. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
  151. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  152. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
  153. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
  154. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
  155. data/lib/solargraph/parser/rubyvm.rb +0 -40
@@ -7,7 +7,7 @@ module Solargraph
7
7
  class Method < Closure
8
8
  include Solargraph::Parser::NodeMethods
9
9
 
10
- # @return [Array<Pin::Parameter>]
10
+ # @return [::Array<Pin::Parameter>]
11
11
  attr_reader :parameters
12
12
 
13
13
  # @return [::Symbol] :public, :private, or :protected
@@ -18,21 +18,66 @@ module Solargraph
18
18
 
19
19
  # @param visibility [::Symbol] :public, :protected, or :private
20
20
  # @param explicit [Boolean]
21
- # @param parameters [Array<Pin::Parameter>]
21
+ # @param parameters [::Array<Pin::Parameter>]
22
+ # @param block [Pin::Signature, nil, ::Symbol]
22
23
  # @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node, nil]
23
24
  # @param attribute [Boolean]
24
- def initialize visibility: :public, explicit: true, parameters: [], node: nil, attribute: false, signatures: nil, anon_splat: false, **splat
25
+ # @param signatures [::Array<Signature>, nil]
26
+ # @param anon_splat [Boolean]
27
+ # @param return_type [ComplexType, nil]
28
+ def initialize visibility: :public, explicit: true, parameters: [], block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false, return_type: nil, **splat
25
29
  super(**splat)
26
30
  @visibility = visibility
27
31
  @explicit = explicit
28
32
  @parameters = parameters
33
+ @block = block
29
34
  @node = node
30
35
  @attribute = attribute
31
36
  @signatures = signatures
32
37
  @anon_splat = anon_splat
38
+ @return_type = return_type
33
39
  end
34
40
 
35
- # @return [Array<String>]
41
+ def transform_types(&transform)
42
+ # @todo 'super' alone should work here I think, but doesn't typecheck at level typed
43
+ m = super(&transform)
44
+ m.signatures = m.signatures.map do |sig|
45
+ sig.transform_types(&transform)
46
+ end
47
+ m.parameters = m.parameters.map do |param|
48
+ param.transform_types(&transform)
49
+ end
50
+ m.block = block&.transform_types(&transform)
51
+ m.signature_help = nil
52
+ m.documentation = nil
53
+ m
54
+ end
55
+
56
+ # @param signature [Pin::Signature]
57
+ # @return [Pin::Method]
58
+ def with_single_signature(signature)
59
+ m = proxy signature.return_type
60
+ m.signature_help = nil
61
+ m.documentation = nil
62
+ # @todo populating the single parameters/return_type/block
63
+ # arguments here seems to be needed for some specs to pass,
64
+ # even though we have a signature with the same information.
65
+ # Is this a problem for RBS-populated methods, which don't
66
+ # populate these three?
67
+ m.parameters = signature.parameters
68
+ m.return_type = signature.return_type
69
+ m.block = signature.block
70
+ m.signatures = [signature]
71
+ m
72
+ end
73
+
74
+ # @return [Pin::Signature, nil]
75
+ def block
76
+ return @block unless @block == :undefined
77
+ @block = signatures.first.block
78
+ end
79
+
80
+ # @return [::Array<String>]
36
81
  def parameter_names
37
82
  @parameter_names ||= parameters.map(&:name)
38
83
  end
@@ -49,11 +94,14 @@ module Solargraph
49
94
  @return_type ||= ComplexType.new(signatures.map(&:return_type).flat_map(&:items))
50
95
  end
51
96
 
97
+ # @param parameters [::Array<Parameter>]
98
+ # @param return_type [ComplexType]
52
99
  # @return [Signature]
53
100
  def generate_signature(parameters, return_type)
54
101
  block = nil
55
102
  yieldparam_tags = docstring.tags(:yieldparam)
56
103
  yieldreturn_tags = docstring.tags(:yieldreturn)
104
+ generics = docstring.tags(:generic).map(&:name)
57
105
  needs_block_param_signature =
58
106
  parameters.last&.block? || !yieldreturn_tags.empty? || !yieldparam_tags.empty?
59
107
  if needs_block_param_signature
@@ -75,12 +123,12 @@ module Solargraph
75
123
  )
76
124
  end
77
125
  yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
78
- block = Signature.new(yield_parameters, yield_return_type)
126
+ block = Signature.new(generics, yield_parameters, yield_return_type)
79
127
  end
80
- Signature.new(parameters, return_type, block)
128
+ Signature.new(generics, parameters, return_type, block)
81
129
  end
82
130
 
83
- # @return [Array<Signature>]
131
+ # @return [::Array<Signature>]
84
132
  def signatures
85
133
  @signatures ||= begin
86
134
  top_type = generate_complex_type
@@ -92,7 +140,7 @@ module Solargraph
92
140
  end
93
141
  end
94
142
 
95
- # @return [String]
143
+ # @return [String, nil]
96
144
  def detail
97
145
  # This property is not cached in an instance variable because it can
98
146
  # change when pins get proxied.
@@ -108,7 +156,7 @@ module Solargraph
108
156
  detail
109
157
  end
110
158
 
111
- # @return [Array<Hash>]
159
+ # @return [::Array<Hash>]
112
160
  def signature_help
113
161
  @signature_help ||= signatures.map do |sig|
114
162
  {
@@ -118,6 +166,27 @@ module Solargraph
118
166
  end
119
167
  end
120
168
 
169
+ def desc
170
+ # ensure the signatures line up when logged
171
+ if signatures.length > 1
172
+ "\n#{to_rbs}\n"
173
+ else
174
+ to_rbs
175
+ end
176
+ end
177
+
178
+ def to_rbs
179
+ return nil if signatures.empty?
180
+
181
+ rbs = "def #{name}: #{signatures.first.to_rbs}"
182
+ signatures[1..].each do |sig|
183
+ rbs += "\n"
184
+ rbs += (' ' * (4 + name.length))
185
+ rbs += "| #{name}: #{sig.to_rbs}"
186
+ end
187
+ rbs
188
+ end
189
+
121
190
  def path
122
191
  @path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}"
123
192
  end
@@ -217,10 +286,11 @@ module Solargraph
217
286
  true
218
287
  end
219
288
 
220
- # @return [Array<Pin::Method>]
289
+ # @return [::Array<Pin::Method>]
221
290
  def overloads
222
291
  @overloads ||= docstring.tags(:overload).map do |tag|
223
292
  Pin::Signature.new(
293
+ generics,
224
294
  tag.parameters.map do |src|
225
295
  name, decl = parse_overload_param(src.first)
226
296
  Pin::Parameter.new(
@@ -243,8 +313,24 @@ module Solargraph
243
313
  @anon_splat
244
314
  end
245
315
 
316
+ protected
317
+
318
+ attr_writer :block
319
+
320
+ attr_writer :parameters
321
+
322
+ attr_writer :signatures
323
+
324
+ attr_writer :signature_help
325
+
326
+ attr_writer :documentation
327
+
246
328
  private
247
329
 
330
+ # @param name [String]
331
+ # @param asgn [Boolean]
332
+ #
333
+ # @return [::Symbol]
248
334
  def select_decl name, asgn
249
335
  if name.start_with?('**')
250
336
  :kwrestarg
@@ -263,11 +349,16 @@ module Solargraph
263
349
  end
264
350
  end
265
351
 
352
+ # @param name [String]
353
+ # @return [String]
266
354
  def clean_param name
267
355
  name.gsub(/[*&:]/, '')
268
356
  end
269
357
 
270
358
  # @param tag [YARD::Tags::OverloadTag]
359
+ # @param name [String]
360
+ #
361
+ # @return [ComplexType]
271
362
  def param_type_from_name(tag, name)
272
363
  param = tag.tags(:param).select { |t| t.name == name }.first
273
364
  return ComplexType::UNDEFINED unless param
@@ -276,7 +367,7 @@ module Solargraph
276
367
 
277
368
  # @return [ComplexType]
278
369
  def generate_complex_type
279
- tags = docstring.tags(:return).map(&:types).flatten.reject(&:nil?)
370
+ tags = docstring.tags(:return).map(&:types).flatten.compact
280
371
  return ComplexType::UNDEFINED if tags.empty?
281
372
  ComplexType.try_parse *tags
282
373
  end
@@ -307,7 +398,7 @@ module Solargraph
307
398
 
308
399
  # @param ref [String]
309
400
  # @param api_map [ApiMap]
310
- # @return [ComplexType]
401
+ # @return [ComplexType, nil]
311
402
  def resolve_reference ref, api_map
312
403
  parts = ref.split(/[\.#]/)
313
404
  if parts.first.empty? || parts.one?
@@ -342,7 +433,7 @@ module Solargraph
342
433
  result = []
343
434
  has_nil = false
344
435
  return ComplexType::NIL if method_body_node.nil?
345
- returns_from(method_body_node).each do |n|
436
+ returns_from_method_body(method_body_node).each do |n|
346
437
  if n.nil? || [:NIL, :nil].include?(n.type)
347
438
  has_nil = true
348
439
  next
@@ -362,6 +453,8 @@ module Solargraph
362
453
  ComplexType.try_parse(*result.map(&:tag).uniq)
363
454
  end
364
455
 
456
+ # @param [ApiMap] api_map
457
+ # @return [ComplexType]
365
458
  def infer_from_iv api_map
366
459
  types = []
367
460
  varname = "@#{name.gsub(/=$/, '')}"
@@ -377,8 +470,8 @@ module Solargraph
377
470
 
378
471
  # When YARD parses an overload tag, it includes rest modifiers in the parameters names.
379
472
  #
380
- # @param arg [String]
381
- # @return [Array(String, Symbol)]
473
+ # @param name [String]
474
+ # @return [::Array(String, ::Symbol)]
382
475
  def parse_overload_param(name)
383
476
  if name.start_with?('**')
384
477
  [name[2..-1], :kwrestarg]
@@ -389,6 +482,7 @@ module Solargraph
389
482
  end
390
483
  end
391
484
 
485
+ # @return [void]
392
486
  def concat_example_tags
393
487
  example_tags = docstring.tags(:example)
394
488
  return if example_tags.empty?
@@ -11,12 +11,10 @@ module Solargraph
11
11
  # @return [::Symbol] :class or :module
12
12
  attr_reader :type
13
13
 
14
- attr_reader :generics
15
-
16
14
  # @param type [::Symbol] :class or :module
17
15
  # @param visibility [::Symbol] :public or :private
18
- # @param gates [Array<String>]
19
- def initialize type: :class, visibility: :public, gates: [''], generics: nil, **splat
16
+ # @param gates [::Array<String>]
17
+ def initialize type: :class, visibility: :public, gates: [''], **splat
20
18
  # super(location, namespace, name, comments)
21
19
  super(**splat)
22
20
  @type = type
@@ -40,7 +38,18 @@ module Solargraph
40
38
  @closure = Pin::Namespace.new(name: closure_name, gates: [parts.join('::')])
41
39
  @context = nil
42
40
  end
43
- @generics = generics
41
+ end
42
+
43
+ def to_rbs
44
+ "#{@type.to_s} #{generics_as_rbs}#{return_type.to_rbs}"
45
+ end
46
+
47
+ def desc
48
+ if name.nil?
49
+ '(top-level)'
50
+ else
51
+ to_rbs
52
+ end
44
53
  end
45
54
 
46
55
  def namespace
@@ -68,6 +77,7 @@ module Solargraph
68
77
  (type == :class ? LanguageServer::SymbolKinds::CLASS : LanguageServer::SymbolKinds::MODULE)
69
78
  end
70
79
 
80
+ # @return [String]
71
81
  def path
72
82
  @path ||= (namespace.empty? ? '' : "#{namespace}::") + name
73
83
  end
@@ -76,6 +86,7 @@ module Solargraph
76
86
  @return_type ||= ComplexType.try_parse( (type == :class ? 'Class' : 'Module') + "<#{path}>" )
77
87
  end
78
88
 
89
+ # @return [Array<String>]
79
90
  def domains
80
91
  @domains ||= []
81
92
  end
@@ -91,11 +102,6 @@ module Solargraph
91
102
  [path] + @open_gates
92
103
  end
93
104
  end
94
-
95
- # @return [Array<String>]
96
- def generics
97
- @generics ||= docstring.tags(:generic).map(&:name)
98
- end
99
105
  end
100
106
  end
101
107
  end
@@ -9,6 +9,9 @@ module Solargraph
9
9
  # @return [String]
10
10
  attr_reader :asgn_code
11
11
 
12
+ # @param decl [::Symbol] :arg, :optarg, :kwarg, :kwoptarg, :restarg, :kwrestarg, :block, :blockarg
13
+ # @param asgn_code [String, nil]
14
+ # @param return_type [ComplexType, nil]
12
15
  def initialize decl: :arg, asgn_code: nil, return_type: nil, **splat
13
16
  super(**splat)
14
17
  @asgn_code = asgn_code
@@ -36,6 +39,24 @@ module Solargraph
36
39
  [:block, :blockarg].include?(decl)
37
40
  end
38
41
 
42
+ def to_rbs
43
+ case decl
44
+ when :optarg
45
+ "?#{super}"
46
+ when :kwarg
47
+ "#{name}: #{return_type.to_rbs}"
48
+ when :kwoptarg
49
+ "?#{name}: #{return_type.to_rbs}"
50
+ when :restarg
51
+ "*#{super}"
52
+ when :kwrestarg
53
+ "**#{super}"
54
+ else
55
+ super
56
+ end
57
+ end
58
+
59
+ # @return [String]
39
60
  def full
40
61
  case decl
41
62
  when :optarg
@@ -100,7 +121,7 @@ module Solargraph
100
121
 
101
122
  private
102
123
 
103
- # @return [YARD::Tags::Tag]
124
+ # @return [YARD::Tags::Tag, nil]
104
125
  def param_tag
105
126
  found = nil
106
127
  params = closure.docstring.tags(:param)
@@ -119,15 +140,25 @@ module Solargraph
119
140
  # @return [ComplexType]
120
141
  def typify_block_param api_map
121
142
  if closure.is_a?(Pin::Block) && closure.receiver
122
- chain = Parser.chain(closure.receiver, filename)
143
+ chain = Parser.chain(closure.receiver, filename, closure.node)
123
144
  clip = api_map.clip_at(location.filename, location.range.start)
124
145
  locals = clip.locals - [self]
125
146
  meths = chain.define(api_map, closure, locals)
126
147
  receiver_type = chain.base.infer(api_map, closure, locals)
127
148
  meths.each do |meth|
128
- yps = meth.docstring.tags(:yieldparam)
129
- unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
130
- yield_type = ComplexType.try_parse(yps[index].types.first)
149
+ block_signature = meth.block
150
+ if block_signature
151
+ yield_type = block_signature.parameters[index]&.return_type
152
+ else
153
+ # @todo move the yieldparam tag parsing logic into the
154
+ # creation of Method pins so we don't need this else
155
+ # statement
156
+ yps = meth.docstring.tags(:yieldparam)
157
+ unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
158
+ yield_type = ComplexType.try_parse(yps[index].types.first)
159
+ end
160
+ end
161
+ unless yield_type.nil?
131
162
  if yield_type.generic? && receiver_type.defined?
132
163
  namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
133
164
  return yield_type.resolve_generics(namespace_pin, receiver_type)
@@ -143,7 +174,7 @@ module Solargraph
143
174
  # @param api_map [ApiMap]
144
175
  # @return [ComplexType]
145
176
  def typify_method_param api_map
146
- meths = api_map.get_method_stack(closure.full_context.namespace, closure.name, scope: closure.scope)
177
+ meths = api_map.get_method_stack(closure.full_context.tag, closure.name, scope: closure.scope)
147
178
  # meths.shift # Ignore the first one
148
179
  meths.each do |meth|
149
180
  found = nil
@@ -163,8 +194,8 @@ module Solargraph
163
194
 
164
195
  # @param heredoc [YARD::Docstring]
165
196
  # @param api_map [ApiMap]
166
- # @param skip [Array]
167
- # @return [Array<YARD::Tags::Tag>]
197
+ # @param skip [::Array]
198
+ # @return [::Array<YARD::Tags::Tag>]
168
199
  def see_reference heredoc, api_map, skip = []
169
200
  heredoc.ref_tags.each do |ref|
170
201
  next unless ref.tag_name == 'param' && ref.owner
@@ -176,8 +207,8 @@ module Solargraph
176
207
 
177
208
  # @param ref [String]
178
209
  # @param api_map [ApiMap]
179
- # @param skip [Array]
180
- # @return [Array<YARD::Tags::Tag>, nil]
210
+ # @param skip [::Array]
211
+ # @return [::Array<YARD::Tags::Tag>, nil]
181
212
  def resolve_reference ref, api_map, skip
182
213
  return nil if skip.include?(ref)
183
214
  skip.push ref
@@ -4,10 +4,10 @@ module Solargraph
4
4
  module Pin
5
5
  class Reference
6
6
  class Override < Reference
7
- # @return [Array<YARD::Tags::Tag>]
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 initialize location, name, tags, delete = []
@@ -9,6 +9,14 @@ module Solargraph
9
9
  autoload :Prepend, 'solargraph/pin/reference/prepend'
10
10
  autoload :Extend, 'solargraph/pin/reference/extend'
11
11
  autoload :Override, 'solargraph/pin/reference/override'
12
+
13
+ attr_reader :generic_values
14
+
15
+ # @param generic_values [Array<String>]
16
+ def initialize generic_values: [], **splat
17
+ super(**splat)
18
+ @generic_values = generic_values
19
+ end
12
20
  end
13
21
  end
14
22
  end
@@ -18,21 +18,21 @@ module Solargraph
18
18
  end
19
19
  end
20
20
 
21
- # @param pins [Array<Pin::Base>]
21
+ # @param pins [::Array<Pin::Base>]
22
22
  # @param query [String]
23
23
  def initialize pins, query
24
24
  @pins = pins
25
25
  @query = query
26
26
  end
27
27
 
28
- # @return [Array<Pin::Base>]
28
+ # @return [::Array<Pin::Base>]
29
29
  def results
30
30
  @results ||= do_query
31
31
  end
32
32
 
33
33
  private
34
34
 
35
- # @return [Array<Pin::Base>]
35
+ # @return [::Array<Pin::Base>]
36
36
  def do_query
37
37
  return @pins if @query.nil? || @query.empty?
38
38
  @pins.map do |pin|
@@ -1,7 +1,7 @@
1
1
  module Solargraph
2
2
  module Pin
3
3
  class Signature < Base
4
- # @return [Array<Parameter>]
4
+ # @return [::Array<Parameter>]
5
5
  attr_reader :parameters
6
6
 
7
7
  # @return [ComplexType]
@@ -10,15 +10,121 @@ module Solargraph
10
10
  # @return [self]
11
11
  attr_reader :block
12
12
 
13
+ # @param generics [Array<String>]
13
14
  # @param parameters [Array<Parameter>]
14
15
  # @param return_type [ComplexType]
15
16
  # @param block [Signature, nil]
16
- def initialize parameters, return_type, block = nil
17
+ def initialize generics, parameters, return_type, block = nil
18
+ @generics = generics
17
19
  @parameters = parameters
18
20
  @return_type = return_type
19
21
  @block = block
20
22
  end
21
23
 
24
+ def generics
25
+ @generics ||= [].freeze
26
+ end
27
+
28
+ # @return [String]
29
+ def to_rbs
30
+ rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs
31
+ end
32
+
33
+ # @return [String]
34
+ def rbs_generics
35
+ if generics.empty?
36
+ return ''
37
+ else
38
+ return '[' + generics.map { |gen| gen.to_s }.join(', ') + '] '
39
+ end
40
+ end
41
+
42
+ # @return [Array<String>]
43
+ # @yieldparam [ComplexType]
44
+ # @yieldreturn [ComplexType]
45
+ # @return [self]
46
+ def transform_types(&transform)
47
+ # @todo 'super' alone should work here I think, but doesn't typecheck at level typed
48
+ signature = super(&transform)
49
+ signature.parameters = signature.parameters.map do |param|
50
+ param.transform_types(&transform)
51
+ end
52
+ signature.block = block.transform_types(&transform) if signature.block?
53
+ signature
54
+ end
55
+
56
+ # @param generics_to_resolve [Enumerable<String>]
57
+ # @param arg_types [Array<ComplexType>, nil]
58
+ # @param return_type_context [ComplexType, nil]
59
+ # @param yield_arg_types [Array<ComplexType>, nil]
60
+ # @param yield_return_type_context [ComplexType, nil]
61
+ # @param context [ComplexType, nil]
62
+ # @param resolved_generic_values [Hash{String => ComplexType}]
63
+ # @return [self]
64
+ def resolve_generics_from_context(generics_to_resolve,
65
+ arg_types = nil,
66
+ return_type_context = nil,
67
+ yield_arg_types = nil,
68
+ yield_return_type_context = nil,
69
+ resolved_generic_values: {})
70
+ signature = super(generics_to_resolve, return_type_context, resolved_generic_values: resolved_generic_values)
71
+ signature.parameters = signature.parameters.each_with_index.map do |param, i|
72
+ if arg_types.nil?
73
+ param.dup
74
+ else
75
+ param.resolve_generics_from_context(generics_to_resolve,
76
+ arg_types[i],
77
+ resolved_generic_values: resolved_generic_values)
78
+ end
79
+ end
80
+ signature.block = block.resolve_generics_from_context(generics_to_resolve,
81
+ yield_arg_types,
82
+ yield_return_type_context,
83
+ resolved_generic_values: resolved_generic_values) if signature.block?
84
+ signature
85
+ end
86
+
87
+ # @param generics_to_resolve [Enumerable<String>]
88
+ # @param arg_types [Array<ComplexType>, nil]
89
+ # @param return_type_context [ComplexType, nil]
90
+ # @param yield_arg_types [Array<ComplexType>, nil]
91
+ # @param yield_return_type_context [ComplexType, nil]
92
+ # @param context [ComplexType, nil]
93
+ # @param resolved_generic_values [Hash{String => ComplexType}]
94
+ # @return [self]
95
+ def resolve_generics_from_context_until_complete(generics_to_resolve,
96
+ arg_types = nil,
97
+ return_type_context = nil,
98
+ yield_arg_types = nil,
99
+ yield_return_type_context = nil,
100
+ resolved_generic_values: {})
101
+ # See
102
+ # https://github.com/soutaro/steep/tree/master/lib/steep/type_inference
103
+ # and
104
+ # https://github.com/sorbet/sorbet/blob/master/infer/inference.cc
105
+ # for other implementations
106
+
107
+ return self if generics_to_resolve.empty?
108
+
109
+ last_resolved_generic_values = resolved_generic_values.dup
110
+ new_pin = resolve_generics_from_context(generics_to_resolve,
111
+ arg_types,
112
+ return_type_context,
113
+ yield_arg_types,
114
+ yield_return_type_context,
115
+ resolved_generic_values: resolved_generic_values)
116
+ if last_resolved_generic_values == resolved_generic_values
117
+ # erase anything unresolved
118
+ return new_pin.erase_generics(self.generics)
119
+ end
120
+ new_pin.resolve_generics_from_context_until_complete(generics_to_resolve,
121
+ arg_types,
122
+ return_type_context,
123
+ yield_arg_types,
124
+ yield_return_type_context,
125
+ resolved_generic_values: resolved_generic_values)
126
+ end
127
+
22
128
  def identity
23
129
  @identity ||= "signature#{object_id}"
24
130
  end
@@ -26,6 +132,12 @@ module Solargraph
26
132
  def block?
27
133
  !!@block
28
134
  end
135
+
136
+ protected
137
+
138
+ attr_writer :block
139
+
140
+ attr_writer :parameters
29
141
  end
30
142
  end
31
143
  end
@@ -27,7 +27,6 @@ module Solargraph
27
27
  autoload :Reference, 'solargraph/pin/reference'
28
28
  autoload :Documenting, 'solargraph/pin/documenting'
29
29
  autoload :Block, 'solargraph/pin/block'
30
- autoload :Localized, 'solargraph/pin/localized'
31
30
  autoload :ProxyType, 'solargraph/pin/proxy_type'
32
31
  autoload :DuckMethod, 'solargraph/pin/duck_method'
33
32
  autoload :Singleton, 'solargraph/pin/singleton'
@@ -62,8 +62,8 @@ module Solargraph
62
62
 
63
63
  # Get a range from a node.
64
64
  #
65
- # @param node [RubyVM::AbstractSyntaxTree::Node, Parser::AST::Node]
66
- # @return [Range]
65
+ # @param node [Parser::AST::Node]
66
+ # @return [Range, nil]
67
67
  def self.from_node node
68
68
  if Parser.rubyvm? && node.is_a?(RubyVM::AbstractSyntaxTree::Node)
69
69
  Solargraph::Range.from_to(node.first_lineno - 1, node.first_column, node.last_lineno - 1, node.last_column)