solargraph 0.51.2 → 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 (162) 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/.yardopts +2 -2
  6. data/CHANGELOG.md +55 -5
  7. data/README.md +13 -16
  8. data/SPONSORS.md +1 -7
  9. data/lib/solargraph/api_map/cache.rb +60 -20
  10. data/lib/solargraph/api_map/store.rb +47 -11
  11. data/lib/solargraph/api_map.rb +161 -95
  12. data/lib/solargraph/bench.rb +2 -2
  13. data/lib/solargraph/cache.rb +29 -5
  14. data/lib/solargraph/complex_type/type_methods.rb +54 -9
  15. data/lib/solargraph/complex_type/unique_type.rb +155 -58
  16. data/lib/solargraph/complex_type.rb +73 -16
  17. data/lib/solargraph/convention.rb +0 -1
  18. data/lib/solargraph/converters/dd.rb +5 -0
  19. data/lib/solargraph/converters/dl.rb +3 -0
  20. data/lib/solargraph/converters/dt.rb +3 -0
  21. data/lib/solargraph/diagnostics/rubocop.rb +8 -7
  22. data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
  23. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  24. data/lib/solargraph/diagnostics.rb +2 -2
  25. data/lib/solargraph/doc_map.rb +146 -0
  26. data/lib/solargraph/gem_pins.rb +64 -0
  27. data/lib/solargraph/language_server/host/cataloger.rb +1 -0
  28. data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
  29. data/lib/solargraph/language_server/host/dispatch.rb +10 -4
  30. data/lib/solargraph/language_server/host/message_worker.rb +4 -0
  31. data/lib/solargraph/language_server/host/sources.rb +7 -4
  32. data/lib/solargraph/language_server/host.rb +15 -6
  33. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  34. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
  35. data/lib/solargraph/language_server/message/initialize.rb +5 -2
  36. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  37. data/lib/solargraph/language_server/message/text_document.rb +0 -1
  38. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  39. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  40. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  41. data/lib/solargraph/library.rb +70 -16
  42. data/lib/solargraph/location.rb +1 -0
  43. data/lib/solargraph/parser/comment_ripper.rb +4 -0
  44. data/lib/solargraph/parser/node_methods.rb +47 -7
  45. data/lib/solargraph/parser/node_processor/base.rb +9 -0
  46. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -5
  47. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
  48. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +49 -36
  49. data/lib/solargraph/parser/parser_gem/node_methods.rb +499 -0
  50. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
  51. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/args_node.rb +4 -1
  52. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
  53. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
  54. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
  55. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
  56. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +1 -1
  57. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
  58. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
  59. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
  60. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
  61. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
  62. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
  63. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
  64. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
  65. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
  66. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
  67. data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
  68. data/lib/solargraph/parser/parser_gem.rb +12 -0
  69. data/lib/solargraph/parser/region.rb +1 -1
  70. data/lib/solargraph/parser/snippet.rb +2 -0
  71. data/lib/solargraph/parser.rb +8 -9
  72. data/lib/solargraph/pin/base.rb +64 -9
  73. data/lib/solargraph/pin/base_variable.rb +6 -2
  74. data/lib/solargraph/pin/block.rb +13 -8
  75. data/lib/solargraph/pin/closure.rb +17 -2
  76. data/lib/solargraph/pin/common.rb +7 -3
  77. data/lib/solargraph/pin/conversions.rb +33 -3
  78. data/lib/solargraph/pin/delegated_method.rb +1 -1
  79. data/lib/solargraph/pin/documenting.rb +25 -34
  80. data/lib/solargraph/pin/instance_variable.rb +4 -0
  81. data/lib/solargraph/pin/local_variable.rb +13 -1
  82. data/lib/solargraph/pin/method.rb +169 -18
  83. data/lib/solargraph/pin/namespace.rb +18 -5
  84. data/lib/solargraph/pin/parameter.rb +44 -14
  85. data/lib/solargraph/pin/reference/override.rb +2 -2
  86. data/lib/solargraph/pin/reference.rb +8 -0
  87. data/lib/solargraph/pin/search.rb +3 -3
  88. data/lib/solargraph/pin/signature.rb +123 -3
  89. data/lib/solargraph/pin.rb +0 -1
  90. data/lib/solargraph/range.rb +2 -2
  91. data/lib/solargraph/rbs_map/conversions.rb +287 -45
  92. data/lib/solargraph/rbs_map/core_fills.rb +6 -29
  93. data/lib/solargraph/rbs_map/core_map.rb +2 -1
  94. data/lib/solargraph/rbs_map/core_signs.rb +2 -0
  95. data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
  96. data/lib/solargraph/rbs_map.rb +20 -11
  97. data/lib/solargraph/shell.rb +62 -59
  98. data/lib/solargraph/source/chain/array.rb +32 -0
  99. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  100. data/lib/solargraph/source/chain/call.rb +99 -46
  101. data/lib/solargraph/source/chain/constant.rb +15 -1
  102. data/lib/solargraph/source/chain/if.rb +23 -0
  103. data/lib/solargraph/source/chain/link.rb +8 -2
  104. data/lib/solargraph/source/chain/or.rb +1 -1
  105. data/lib/solargraph/source/chain/z_super.rb +3 -3
  106. data/lib/solargraph/source/chain.rb +29 -14
  107. data/lib/solargraph/source/change.rb +3 -0
  108. data/lib/solargraph/source/cursor.rb +2 -0
  109. data/lib/solargraph/source/source_chainer.rb +8 -5
  110. data/lib/solargraph/source.rb +18 -19
  111. data/lib/solargraph/source_map/clip.rb +11 -23
  112. data/lib/solargraph/source_map/mapper.rb +12 -1
  113. data/lib/solargraph/source_map.rb +15 -5
  114. data/lib/solargraph/type_checker/checks.rb +10 -2
  115. data/lib/solargraph/type_checker.rb +92 -26
  116. data/lib/solargraph/version.rb +1 -1
  117. data/lib/solargraph/workspace/config.rb +8 -6
  118. data/lib/solargraph/workspace.rb +3 -2
  119. data/lib/solargraph/yard_map/cache.rb +6 -0
  120. data/lib/solargraph/yard_map/helpers.rb +1 -1
  121. data/lib/solargraph/yard_map/mapper/to_method.rb +11 -1
  122. data/lib/solargraph/yard_map/mapper.rb +1 -1
  123. data/lib/solargraph/yard_map/to_method.rb +11 -4
  124. data/lib/solargraph/yard_map.rb +1 -292
  125. data/lib/solargraph/yard_tags.rb +20 -0
  126. data/lib/solargraph/yardoc.rb +52 -0
  127. data/lib/solargraph.rb +6 -4
  128. data/solargraph.gemspec +3 -2
  129. metadata +51 -58
  130. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  131. data/lib/solargraph/documentor.rb +0 -76
  132. data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
  133. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  134. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  135. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
  136. data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
  137. data/lib/solargraph/parser/legacy.rb +0 -12
  138. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -153
  139. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
  140. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
  141. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  142. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  143. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
  144. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  145. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
  146. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
  147. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  148. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  149. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  150. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  151. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  152. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  153. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  154. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  155. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
  156. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
  157. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  158. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
  159. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
  160. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
  161. data/lib/solargraph/parser/rubyvm.rb +0 -40
  162. data/lib/yard-solargraph.rb +0 -33
@@ -6,12 +6,16 @@ module Solargraph
6
6
  # @return [Range]
7
7
  attr_reader :presence
8
8
 
9
+ # @param assignment [AST::Node, nil]
10
+ # @param presence [Range, nil]
11
+ # @param splat [Hash]
9
12
  def initialize assignment: nil, presence: nil, **splat
10
13
  super(**splat)
11
14
  @assignment = assignment
12
15
  @presence = presence
13
16
  end
14
17
 
18
+ # @param pin [self]
15
19
  def try_merge! pin
16
20
  return false unless super
17
21
  @presence = pin.presence
@@ -21,11 +25,16 @@ module Solargraph
21
25
  # @param other_closure [Pin::Closure]
22
26
  # @param other_loc [Location]
23
27
  def visible_at?(other_closure, other_loc)
24
- return true if location.filename == other_loc.filename &&
28
+ location.filename == other_loc.filename &&
25
29
  presence.include?(other_loc.range.start) &&
26
30
  match_named_closure(other_closure, closure)
27
31
  end
28
32
 
33
+ # @return [String]
34
+ def to_rbs
35
+ (name || '(anon)') + ' ' + (return_type&.to_rbs || 'untyped')
36
+ end
37
+
29
38
  private
30
39
 
31
40
  # @param tag1 [String]
@@ -40,6 +49,9 @@ module Solargraph
40
49
  (['', 'Class<>'].include?(tag1) && ['', 'Class<>'].include?(tag2))
41
50
  end
42
51
 
52
+ # @param needle [Pin::Base]
53
+ # @param haystack [Pin::Base]
54
+ # @return [Boolean]
43
55
  def match_named_closure needle, haystack
44
56
  return true if needle == haystack || haystack.is_a?(Pin::Block)
45
57
  cursor = haystack
@@ -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>]
22
- # @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node]
21
+ # @param parameters [::Array<Pin::Parameter>]
22
+ # @param block [Pin::Signature, nil, ::Symbol]
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
@@ -46,22 +91,56 @@ module Solargraph
46
91
  end
47
92
 
48
93
  def return_type
49
- @return_type ||= ComplexType.try_parse(*signatures.map(&:return_type).map(&:to_s))
94
+ @return_type ||= ComplexType.new(signatures.map(&:return_type).flat_map(&:items))
50
95
  end
51
96
 
52
- # @return [Array<Signature>]
97
+ # @param parameters [::Array<Parameter>]
98
+ # @param return_type [ComplexType]
99
+ # @return [Signature]
100
+ def generate_signature(parameters, return_type)
101
+ block = nil
102
+ yieldparam_tags = docstring.tags(:yieldparam)
103
+ yieldreturn_tags = docstring.tags(:yieldreturn)
104
+ generics = docstring.tags(:generic).map(&:name)
105
+ needs_block_param_signature =
106
+ parameters.last&.block? || !yieldreturn_tags.empty? || !yieldparam_tags.empty?
107
+ if needs_block_param_signature
108
+ yield_parameters = yieldparam_tags.map do |p|
109
+ name = p.name
110
+ decl = :arg
111
+ if name
112
+ decl = select_decl(name, false)
113
+ name = clean_param(name)
114
+ end
115
+ Pin::Parameter.new(
116
+ location: location,
117
+ closure: self,
118
+ comments: p.text,
119
+ name: name,
120
+ decl: decl,
121
+ presence: location ? location.range : nil,
122
+ return_type: ComplexType.try_parse(*p.types)
123
+ )
124
+ end
125
+ yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
126
+ block = Signature.new(generics, yield_parameters, yield_return_type)
127
+ end
128
+ Signature.new(generics, parameters, return_type, block)
129
+ end
130
+
131
+ # @return [::Array<Signature>]
53
132
  def signatures
54
133
  @signatures ||= begin
55
134
  top_type = generate_complex_type
56
135
  result = []
57
- result.push Signature.new(parameters, top_type) if top_type.defined?
58
- result.concat(overloads.map { |meth| Signature.new(meth.parameters, meth.return_type) })
59
- result.push Signature.new(parameters, top_type) if result.empty?
136
+ result.push generate_signature(parameters, top_type) if top_type.defined?
137
+ result.concat(overloads.map { |meth| generate_signature(meth.parameters, meth.return_type) }) unless overloads.empty?
138
+ result.push generate_signature(parameters, top_type) if result.empty?
60
139
  result
61
140
  end
62
141
  end
63
142
 
64
- # @return [String]
143
+ # @return [String, nil]
65
144
  def detail
66
145
  # This property is not cached in an instance variable because it can
67
146
  # change when pins get proxied.
@@ -77,7 +156,7 @@ module Solargraph
77
156
  detail
78
157
  end
79
158
 
80
- # @return [Array<Hash>]
159
+ # @return [::Array<Hash>]
81
160
  def signature_help
82
161
  @signature_help ||= signatures.map do |sig|
83
162
  {
@@ -87,6 +166,27 @@ module Solargraph
87
166
  end
88
167
  end
89
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
+
90
190
  def path
91
191
  @path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}"
92
192
  end
@@ -115,6 +215,32 @@ module Solargraph
115
215
  end
116
216
  @documentation += lines.join("\n")
117
217
  end
218
+ yieldparam_tags = docstring.tags(:yieldparam)
219
+ unless yieldparam_tags.nil? or yieldparam_tags.empty?
220
+ @documentation += "\n\n" unless @documentation.empty?
221
+ @documentation += "Block Params:\n"
222
+ lines = []
223
+ yieldparam_tags.each do |p|
224
+ l = "* #{p.name}"
225
+ l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? or p.types.empty?
226
+ l += " #{p.text}"
227
+ lines.push l
228
+ end
229
+ @documentation += lines.join("\n")
230
+ end
231
+ yieldreturn_tags = docstring.tags(:yieldreturn)
232
+ unless yieldreturn_tags.empty?
233
+ @documentation += "\n\n" unless @documentation.empty?
234
+ @documentation += "Block Returns:\n"
235
+ lines = []
236
+ yieldreturn_tags.each do |r|
237
+ l = "*"
238
+ l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty?
239
+ l += " #{r.text}"
240
+ lines.push l
241
+ end
242
+ @documentation += lines.join("\n")
243
+ end
118
244
  return_tags = docstring.tags(:return)
119
245
  unless return_tags.empty?
120
246
  @documentation += "\n\n" unless @documentation.empty?
@@ -160,10 +286,11 @@ module Solargraph
160
286
  true
161
287
  end
162
288
 
163
- # @return [Array<Pin::Method>]
289
+ # @return [::Array<Pin::Method>]
164
290
  def overloads
165
291
  @overloads ||= docstring.tags(:overload).map do |tag|
166
292
  Pin::Signature.new(
293
+ generics,
167
294
  tag.parameters.map do |src|
168
295
  name, decl = parse_overload_param(src.first)
169
296
  Pin::Parameter.new(
@@ -186,8 +313,24 @@ module Solargraph
186
313
  @anon_splat
187
314
  end
188
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
+
189
328
  private
190
329
 
330
+ # @param name [String]
331
+ # @param asgn [Boolean]
332
+ #
333
+ # @return [::Symbol]
191
334
  def select_decl name, asgn
192
335
  if name.start_with?('**')
193
336
  :kwrestarg
@@ -206,11 +349,16 @@ module Solargraph
206
349
  end
207
350
  end
208
351
 
352
+ # @param name [String]
353
+ # @return [String]
209
354
  def clean_param name
210
355
  name.gsub(/[*&:]/, '')
211
356
  end
212
357
 
213
358
  # @param tag [YARD::Tags::OverloadTag]
359
+ # @param name [String]
360
+ #
361
+ # @return [ComplexType]
214
362
  def param_type_from_name(tag, name)
215
363
  param = tag.tags(:param).select { |t| t.name == name }.first
216
364
  return ComplexType::UNDEFINED unless param
@@ -219,7 +367,7 @@ module Solargraph
219
367
 
220
368
  # @return [ComplexType]
221
369
  def generate_complex_type
222
- tags = docstring.tags(:return).map(&:types).flatten.reject(&:nil?)
370
+ tags = docstring.tags(:return).map(&:types).flatten.compact
223
371
  return ComplexType::UNDEFINED if tags.empty?
224
372
  ComplexType.try_parse *tags
225
373
  end
@@ -250,7 +398,7 @@ module Solargraph
250
398
 
251
399
  # @param ref [String]
252
400
  # @param api_map [ApiMap]
253
- # @return [ComplexType]
401
+ # @return [ComplexType, nil]
254
402
  def resolve_reference ref, api_map
255
403
  parts = ref.split(/[\.#]/)
256
404
  if parts.first.empty? || parts.one?
@@ -285,7 +433,7 @@ module Solargraph
285
433
  result = []
286
434
  has_nil = false
287
435
  return ComplexType::NIL if method_body_node.nil?
288
- returns_from(method_body_node).each do |n|
436
+ returns_from_method_body(method_body_node).each do |n|
289
437
  if n.nil? || [:NIL, :nil].include?(n.type)
290
438
  has_nil = true
291
439
  next
@@ -305,6 +453,8 @@ module Solargraph
305
453
  ComplexType.try_parse(*result.map(&:tag).uniq)
306
454
  end
307
455
 
456
+ # @param [ApiMap] api_map
457
+ # @return [ComplexType]
308
458
  def infer_from_iv api_map
309
459
  types = []
310
460
  varname = "@#{name.gsub(/=$/, '')}"
@@ -320,8 +470,8 @@ module Solargraph
320
470
 
321
471
  # When YARD parses an overload tag, it includes rest modifiers in the parameters names.
322
472
  #
323
- # @param arg [String]
324
- # @return [Array(String, Symbol)]
473
+ # @param name [String]
474
+ # @return [::Array(String, ::Symbol)]
325
475
  def parse_overload_param(name)
326
476
  if name.start_with?('**')
327
477
  [name[2..-1], :kwrestarg]
@@ -332,6 +482,7 @@ module Solargraph
332
482
  end
333
483
  end
334
484
 
485
+ # @return [void]
335
486
  def concat_example_tags
336
487
  example_tags = docstring.tags(:example)
337
488
  return if example_tags.empty?
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'solargraph/yard_tags'
4
+
3
5
  module Solargraph
4
6
  module Pin
5
7
  class Namespace < Closure
@@ -9,12 +11,10 @@ module Solargraph
9
11
  # @return [::Symbol] :class or :module
10
12
  attr_reader :type
11
13
 
12
- attr_reader :parameters
13
-
14
14
  # @param type [::Symbol] :class or :module
15
15
  # @param visibility [::Symbol] :public or :private
16
- # @param gates [Array<String>]
17
- def initialize type: :class, visibility: :public, gates: [''], parameters: [], **splat
16
+ # @param gates [::Array<String>]
17
+ def initialize type: :class, visibility: :public, gates: [''], **splat
18
18
  # super(location, namespace, name, comments)
19
19
  super(**splat)
20
20
  @type = type
@@ -38,7 +38,18 @@ module Solargraph
38
38
  @closure = Pin::Namespace.new(name: closure_name, gates: [parts.join('::')])
39
39
  @context = nil
40
40
  end
41
- @parameters = parameters
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
42
53
  end
43
54
 
44
55
  def namespace
@@ -66,6 +77,7 @@ module Solargraph
66
77
  (type == :class ? LanguageServer::SymbolKinds::CLASS : LanguageServer::SymbolKinds::MODULE)
67
78
  end
68
79
 
80
+ # @return [String]
69
81
  def path
70
82
  @path ||= (namespace.empty? ? '' : "#{namespace}::") + name
71
83
  end
@@ -74,6 +86,7 @@ module Solargraph
74
86
  @return_type ||= ComplexType.try_parse( (type == :class ? 'Class' : 'Module') + "<#{path}>" )
75
87
  end
76
88
 
89
+ # @return [Array<String>]
77
90
  def domains
78
91
  @domains ||= []
79
92
  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,21 +140,30 @@ 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)
147
+ receiver_type = chain.base.infer(api_map, closure, locals)
126
148
  meths.each do |meth|
127
- if meth.docstring.has_tag?(:yieldparam_single_parameter)
128
- type = chain.base.infer(api_map, closure, locals)
129
- if type.defined? && !type.subtypes.empty?
130
- bmeth = chain.base.define(api_map, closure, locals).first
131
- return type.subtypes.first.qualify(api_map, bmeth.context.namespace)
132
- end
149
+ block_signature = meth.block
150
+ if block_signature
151
+ yield_type = block_signature.parameters[index]&.return_type
133
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
134
156
  yps = meth.docstring.tags(:yieldparam)
135
157
  unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
136
- return ComplexType.try_parse(yps[index].types.first).self_to(chain.base.infer(api_map, closure, locals).namespace).qualify(api_map, meth.context.namespace)
158
+ yield_type = ComplexType.try_parse(yps[index].types.first)
159
+ end
160
+ end
161
+ unless yield_type.nil?
162
+ if yield_type.generic? && receiver_type.defined?
163
+ namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
164
+ return yield_type.resolve_generics(namespace_pin, receiver_type)
165
+ else
166
+ return yield_type.self_to(chain.base.infer(api_map, closure, locals).namespace).qualify(api_map, meth.context.namespace)
137
167
  end
138
168
  end
139
169
  end
@@ -144,7 +174,7 @@ module Solargraph
144
174
  # @param api_map [ApiMap]
145
175
  # @return [ComplexType]
146
176
  def typify_method_param api_map
147
- 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)
148
178
  # meths.shift # Ignore the first one
149
179
  meths.each do |meth|
150
180
  found = nil
@@ -164,8 +194,8 @@ module Solargraph
164
194
 
165
195
  # @param heredoc [YARD::Docstring]
166
196
  # @param api_map [ApiMap]
167
- # @param skip [Array]
168
- # @return [Array<YARD::Tags::Tag>]
197
+ # @param skip [::Array]
198
+ # @return [::Array<YARD::Tags::Tag>]
169
199
  def see_reference heredoc, api_map, skip = []
170
200
  heredoc.ref_tags.each do |ref|
171
201
  next unless ref.tag_name == 'param' && ref.owner
@@ -177,8 +207,8 @@ module Solargraph
177
207
 
178
208
  # @param ref [String]
179
209
  # @param api_map [ApiMap]
180
- # @param skip [Array]
181
- # @return [Array<YARD::Tags::Tag>, nil]
210
+ # @param skip [::Array]
211
+ # @return [::Array<YARD::Tags::Tag>, nil]
182
212
  def resolve_reference ref, api_map, skip
183
213
  return nil if skip.include?(ref)
184
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|