solargraph 0.54.4 → 0.57.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 (178) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linting.yml +125 -0
  3. data/.github/workflows/plugins.yml +149 -5
  4. data/.github/workflows/rspec.yml +39 -4
  5. data/.github/workflows/typecheck.yml +8 -3
  6. data/.gitignore +7 -0
  7. data/.overcommit.yml +72 -0
  8. data/.rspec +1 -0
  9. data/.rubocop.yml +66 -0
  10. data/.rubocop_todo.yml +2627 -0
  11. data/.yardopts +1 -0
  12. data/CHANGELOG.md +104 -0
  13. data/README.md +20 -6
  14. data/Rakefile +125 -13
  15. data/lib/solargraph/api_map/cache.rb +3 -2
  16. data/lib/solargraph/api_map/constants.rb +218 -0
  17. data/lib/solargraph/api_map/index.rb +44 -42
  18. data/lib/solargraph/api_map/source_to_yard.rb +10 -4
  19. data/lib/solargraph/api_map/store.rb +165 -32
  20. data/lib/solargraph/api_map.rb +319 -243
  21. data/lib/solargraph/bench.rb +18 -1
  22. data/lib/solargraph/complex_type/type_methods.rb +7 -1
  23. data/lib/solargraph/complex_type/unique_type.rb +105 -16
  24. data/lib/solargraph/complex_type.rb +40 -7
  25. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  26. data/lib/solargraph/convention/base.rb +20 -3
  27. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
  28. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
  29. data/lib/solargraph/convention/data_definition.rb +105 -0
  30. data/lib/solargraph/convention/gemspec.rb +3 -2
  31. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -0
  32. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -0
  33. data/lib/solargraph/convention/struct_definition.rb +164 -0
  34. data/lib/solargraph/convention.rb +35 -4
  35. data/lib/solargraph/diagnostics/rubocop.rb +6 -1
  36. data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -1
  37. data/lib/solargraph/doc_map.rb +313 -65
  38. data/lib/solargraph/environ.rb +9 -2
  39. data/lib/solargraph/gem_pins.rb +60 -38
  40. data/lib/solargraph/language_server/host/dispatch.rb +2 -0
  41. data/lib/solargraph/language_server/host/message_worker.rb +13 -7
  42. data/lib/solargraph/language_server/host.rb +14 -3
  43. data/lib/solargraph/language_server/message/base.rb +2 -1
  44. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -0
  45. data/lib/solargraph/language_server/message/extended/document.rb +5 -2
  46. data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
  47. data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
  48. data/lib/solargraph/language_server/message/text_document/formatting.rb +16 -2
  49. data/lib/solargraph/language_server/message/text_document/type_definition.rb +1 -0
  50. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  51. data/lib/solargraph/language_server/progress.rb +8 -0
  52. data/lib/solargraph/language_server/request.rb +1 -0
  53. data/lib/solargraph/library.rb +53 -32
  54. data/lib/solargraph/location.rb +23 -0
  55. data/lib/solargraph/logging.rb +12 -2
  56. data/lib/solargraph/page.rb +4 -0
  57. data/lib/solargraph/parser/comment_ripper.rb +20 -7
  58. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -0
  59. data/lib/solargraph/parser/node_methods.rb +16 -2
  60. data/lib/solargraph/parser/node_processor/base.rb +10 -5
  61. data/lib/solargraph/parser/node_processor.rb +26 -9
  62. data/lib/solargraph/parser/parser_gem/class_methods.rb +17 -15
  63. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  64. data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -11
  65. data/lib/solargraph/parser/parser_gem/node_methods.rb +8 -4
  66. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
  67. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
  68. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +4 -2
  69. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +7 -4
  70. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +2 -1
  71. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
  72. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
  73. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
  74. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
  75. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -0
  76. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
  77. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -1
  78. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +7 -1
  79. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +8 -7
  80. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +42 -0
  81. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -0
  82. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +3 -1
  83. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -3
  84. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +63 -30
  85. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +3 -1
  86. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
  87. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
  88. data/lib/solargraph/parser/parser_gem/node_processors.rb +14 -0
  89. data/lib/solargraph/parser/region.rb +4 -1
  90. data/lib/solargraph/parser/snippet.rb +2 -0
  91. data/lib/solargraph/parser.rb +1 -0
  92. data/lib/solargraph/pin/base.rb +360 -30
  93. data/lib/solargraph/pin/base_variable.rb +16 -10
  94. data/lib/solargraph/pin/block.rb +2 -0
  95. data/lib/solargraph/pin/breakable.rb +9 -0
  96. data/lib/solargraph/pin/callable.rb +83 -3
  97. data/lib/solargraph/pin/closure.rb +20 -1
  98. data/lib/solargraph/pin/common.rb +10 -1
  99. data/lib/solargraph/pin/constant.rb +2 -0
  100. data/lib/solargraph/pin/delegated_method.rb +21 -1
  101. data/lib/solargraph/pin/documenting.rb +16 -0
  102. data/lib/solargraph/pin/keyword.rb +7 -2
  103. data/lib/solargraph/pin/local_variable.rb +18 -6
  104. data/lib/solargraph/pin/method.rb +175 -46
  105. data/lib/solargraph/pin/method_alias.rb +3 -0
  106. data/lib/solargraph/pin/namespace.rb +17 -9
  107. data/lib/solargraph/pin/parameter.rb +78 -19
  108. data/lib/solargraph/pin/proxy_type.rb +13 -6
  109. data/lib/solargraph/pin/reference/override.rb +24 -6
  110. data/lib/solargraph/pin/reference/require.rb +2 -2
  111. data/lib/solargraph/pin/reference/superclass.rb +5 -0
  112. data/lib/solargraph/pin/reference.rb +26 -0
  113. data/lib/solargraph/pin/search.rb +3 -1
  114. data/lib/solargraph/pin/signature.rb +44 -0
  115. data/lib/solargraph/pin/singleton.rb +1 -1
  116. data/lib/solargraph/pin/symbol.rb +8 -2
  117. data/lib/solargraph/pin/until.rb +18 -0
  118. data/lib/solargraph/pin/while.rb +18 -0
  119. data/lib/solargraph/pin.rb +4 -1
  120. data/lib/solargraph/pin_cache.rb +245 -0
  121. data/lib/solargraph/position.rb +11 -0
  122. data/lib/solargraph/range.rb +10 -0
  123. data/lib/solargraph/rbs_map/conversions.rb +226 -70
  124. data/lib/solargraph/rbs_map/core_fills.rb +32 -16
  125. data/lib/solargraph/rbs_map/core_map.rb +37 -11
  126. data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
  127. data/lib/solargraph/rbs_map.rb +88 -18
  128. data/lib/solargraph/shell.rb +20 -18
  129. data/lib/solargraph/source/chain/array.rb +11 -7
  130. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  131. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  132. data/lib/solargraph/source/chain/call.rb +53 -23
  133. data/lib/solargraph/source/chain/constant.rb +1 -1
  134. data/lib/solargraph/source/chain/hash.rb +4 -3
  135. data/lib/solargraph/source/chain/head.rb +1 -1
  136. data/lib/solargraph/source/chain/if.rb +1 -1
  137. data/lib/solargraph/source/chain/link.rb +12 -1
  138. data/lib/solargraph/source/chain/literal.rb +22 -2
  139. data/lib/solargraph/source/chain/or.rb +1 -1
  140. data/lib/solargraph/source/chain/z_super.rb +1 -1
  141. data/lib/solargraph/source/chain.rb +84 -47
  142. data/lib/solargraph/source/change.rb +2 -2
  143. data/lib/solargraph/source/cursor.rb +2 -3
  144. data/lib/solargraph/source/source_chainer.rb +3 -3
  145. data/lib/solargraph/source.rb +5 -2
  146. data/lib/solargraph/source_map/clip.rb +4 -2
  147. data/lib/solargraph/source_map/data.rb +4 -0
  148. data/lib/solargraph/source_map/mapper.rb +13 -7
  149. data/lib/solargraph/source_map.rb +21 -31
  150. data/lib/solargraph/type_checker/checks.rb +4 -0
  151. data/lib/solargraph/type_checker/param_def.rb +2 -0
  152. data/lib/solargraph/type_checker/rules.rb +8 -0
  153. data/lib/solargraph/type_checker.rb +208 -128
  154. data/lib/solargraph/version.rb +1 -1
  155. data/lib/solargraph/views/_method.erb +10 -10
  156. data/lib/solargraph/views/_namespace.erb +3 -3
  157. data/lib/solargraph/views/document.erb +10 -10
  158. data/lib/solargraph/workspace/config.rb +1 -3
  159. data/lib/solargraph/workspace/require_paths.rb +98 -0
  160. data/lib/solargraph/workspace.rb +38 -52
  161. data/lib/solargraph/yard_map/helpers.rb +29 -1
  162. data/lib/solargraph/yard_map/mapper/to_constant.rb +7 -5
  163. data/lib/solargraph/yard_map/mapper/to_method.rb +53 -18
  164. data/lib/solargraph/yard_map/mapper/to_namespace.rb +9 -7
  165. data/lib/solargraph/yard_map/mapper.rb +4 -3
  166. data/lib/solargraph/yard_map/to_method.rb +4 -2
  167. data/lib/solargraph/yardoc.rb +22 -10
  168. data/lib/solargraph.rb +34 -1
  169. data/rbs/fills/tuple.rbs +149 -0
  170. data/rbs_collection.yaml +19 -0
  171. data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  172. data/sig/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  173. data/sig/shims/thor/1.2.0.1/manifest.yaml +7 -0
  174. data/sig/shims/thor/1.2.0.1/thor.rbs +17 -0
  175. data/solargraph.gemspec +15 -4
  176. metadata +157 -15
  177. data/lib/.rubocop.yml +0 -22
  178. data/lib/solargraph/cache.rb +0 -77
@@ -10,6 +10,8 @@ module Solargraph
10
10
  # @return [::Symbol] :public, :private, or :protected
11
11
  attr_reader :visibility
12
12
 
13
+ attr_writer :signatures
14
+
13
15
  # @return [Parser::AST::Node]
14
16
  attr_reader :node
15
17
 
@@ -20,7 +22,8 @@ module Solargraph
20
22
  # @param attribute [Boolean]
21
23
  # @param signatures [::Array<Signature>, nil]
22
24
  # @param anon_splat [Boolean]
23
- def initialize visibility: :public, explicit: true, block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false, **splat
25
+ def initialize visibility: :public, explicit: true, block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false,
26
+ **splat
24
27
  super(**splat)
25
28
  @visibility = visibility
26
29
  @explicit = explicit
@@ -31,6 +34,73 @@ module Solargraph
31
34
  @anon_splat = anon_splat
32
35
  end
33
36
 
37
+ # @return [Array<Pin::Signature>]
38
+ def combine_all_signature_pins(*signature_pins)
39
+ by_arity = {}
40
+ signature_pins.each do |signature_pin|
41
+ by_arity[signature_pin.arity] ||= []
42
+ by_arity[signature_pin.arity] << signature_pin
43
+ end
44
+ by_arity.transform_values! do |same_arity_pins|
45
+ same_arity_pins.reduce(nil) do |memo, signature|
46
+ next signature if memo.nil?
47
+ memo.combine_with(signature)
48
+ end
49
+ end
50
+ by_arity.values.flatten
51
+ end
52
+
53
+ # @param other [Pin::Method]
54
+ # @return [::Symbol]
55
+ def combine_visibility(other)
56
+ if dodgy_visibility_source? && !other.dodgy_visibility_source?
57
+ other.visibility
58
+ elsif other.dodgy_visibility_source? && !dodgy_visibility_source?
59
+ visibility
60
+ else
61
+ assert_same(other, :visibility)
62
+ end
63
+ end
64
+
65
+ # @param other [Pin::Method]
66
+ # @return [Array<Pin::Signature>]
67
+ def combine_signatures(other)
68
+ all_undefined = signatures.all? { |sig| sig.return_type.undefined? }
69
+ other_all_undefined = other.signatures.all? { |sig| sig.return_type.undefined? }
70
+ if all_undefined && !other_all_undefined
71
+ other.signatures
72
+ elsif other_all_undefined && !all_undefined
73
+ signatures
74
+ else
75
+ combine_all_signature_pins(*signatures, *other.signatures)
76
+ end
77
+ end
78
+
79
+ def combine_with(other, attrs = {})
80
+ priority_choice = choose_priority(other)
81
+ return priority_choice unless priority_choice.nil?
82
+
83
+ sigs = combine_signatures(other)
84
+ parameters = if sigs.length > 0
85
+ [].freeze
86
+ else
87
+ choose(other, :parameters).clone.freeze
88
+ end
89
+ new_attrs = {
90
+ visibility: combine_visibility(other),
91
+ explicit: explicit? || other.explicit?,
92
+ block: combine_blocks(other),
93
+ node: choose_node(other, :node),
94
+ attribute: prefer_rbs_location(other, :attribute?),
95
+ parameters: parameters,
96
+ signatures: sigs,
97
+ anon_splat: assert_same(other, :anon_splat?),
98
+ return_type: nil # pulled from signatures on first call
99
+ }.merge(attrs)
100
+ super(other, new_attrs)
101
+ end
102
+
103
+ # @param other [Pin::Method]
34
104
  def == other
35
105
  super && other.node == node
36
106
  end
@@ -42,11 +112,24 @@ module Solargraph
42
112
  sig.transform_types(&transform)
43
113
  end
44
114
  m.block = block&.transform_types(&transform)
45
- m.signature_help = nil
46
- m.documentation = nil
115
+ m.reset_generated!
47
116
  m
48
117
  end
49
118
 
119
+ # @return [void]
120
+ def reset_generated!
121
+ super
122
+ unless signatures.empty?
123
+ return_type = nil
124
+ @block = :undefined
125
+ parameters = []
126
+ end
127
+ block&.reset_generated!
128
+ @signatures&.each(&:reset_generated!)
129
+ signature_help = nil
130
+ documentation = nil
131
+ end
132
+
50
133
  def all_rooted?
51
134
  super && parameters.all?(&:all_rooted?) && (!block || block&.all_rooted?) && signatures.all?(&:all_rooted?)
52
135
  end
@@ -55,8 +138,7 @@ module Solargraph
55
138
  # @return [Pin::Method]
56
139
  def with_single_signature(signature)
57
140
  m = proxy signature.return_type
58
- m.signature_help = nil
59
- m.documentation = nil
141
+ m.reset_generated!
60
142
  # @todo populating the single parameters/return_type/block
61
143
  # arguments here seems to be needed for some specs to pass,
62
144
  # even though we have a signature with the same information.
@@ -116,13 +198,18 @@ module Solargraph
116
198
  name: name,
117
199
  decl: decl,
118
200
  presence: location ? location.range : nil,
119
- return_type: ComplexType.try_parse(*p.types)
201
+ return_type: ComplexType.try_parse(*p.types),
202
+ source: source
120
203
  )
121
204
  end
122
205
  yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
123
- block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type)
206
+ block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type, source: source,
207
+ closure: self, location: location, type_location: type_location)
124
208
  end
125
- Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block)
209
+ signature = Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block, closure: self, source: source,
210
+ location: location, type_location: type_location)
211
+ block.closure = signature if block
212
+ signature
126
213
  end
127
214
 
128
215
  # @return [::Array<Signature>]
@@ -137,6 +224,14 @@ module Solargraph
137
224
  end
138
225
  end
139
226
 
227
+ # @param return_type [ComplexType]
228
+ # @return [self]
229
+ def proxy_with_signatures return_type
230
+ out = proxy return_type
231
+ out.signatures = out.signatures.map { |sig| sig.proxy return_type }
232
+ out
233
+ end
234
+
140
235
  # @return [String, nil]
141
236
  def detail
142
237
  # This property is not cached in an instance variable because it can
@@ -163,12 +258,12 @@ module Solargraph
163
258
  end
164
259
  end
165
260
 
166
- def desc
261
+ def inner_desc
167
262
  # ensure the signatures line up when logged
168
263
  if signatures.length > 1
169
- "\n#{to_rbs}\n"
264
+ path + " \n#{to_rbs}\n"
170
265
  else
171
- to_rbs
266
+ super
172
267
  end
173
268
  end
174
269
 
@@ -188,21 +283,35 @@ module Solargraph
188
283
  @path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}"
189
284
  end
190
285
 
286
+ # @return [String]
287
+ def method_name
288
+ name
289
+ end
290
+
191
291
  def typify api_map
292
+ logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context.rooted_tags}, return_type=#{return_type.rooted_tags}) - starting" }
192
293
  decl = super
193
- return decl unless decl.undefined?
294
+ unless decl.undefined?
295
+ logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context}) => #{decl.rooted_tags.inspect} - decl found" }
296
+ return decl
297
+ end
194
298
  type = see_reference(api_map) || typify_from_super(api_map)
195
- return type.qualify(api_map, namespace) unless type.nil?
196
- name.end_with?('?') ? ComplexType::BOOLEAN : ComplexType::UNDEFINED
299
+ logger.debug { "Method#typify(self=#{self}) - type=#{type&.rooted_tags.inspect}" }
300
+ unless type.nil?
301
+ qualified = type.qualify(api_map, namespace)
302
+ logger.debug { "Method#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
303
+ return qualified
304
+ end
305
+ super
197
306
  end
198
307
 
199
308
  def documentation
200
309
  if @documentation.nil?
201
- @documentation ||= super || ''
310
+ method_docs ||= super || ''
202
311
  param_tags = docstring.tags(:param)
203
312
  unless param_tags.nil? or param_tags.empty?
204
- @documentation += "\n\n" unless @documentation.empty?
205
- @documentation += "Params:\n"
313
+ method_docs += "\n\n" unless method_docs.empty?
314
+ method_docs += "Params:\n"
206
315
  lines = []
207
316
  param_tags.each do |p|
208
317
  l = "* #{p.name}"
@@ -210,12 +319,12 @@ module Solargraph
210
319
  l += " #{p.text}"
211
320
  lines.push l
212
321
  end
213
- @documentation += lines.join("\n")
322
+ method_docs += lines.join("\n")
214
323
  end
215
324
  yieldparam_tags = docstring.tags(:yieldparam)
216
325
  unless yieldparam_tags.nil? or yieldparam_tags.empty?
217
- @documentation += "\n\n" unless @documentation.empty?
218
- @documentation += "Block Params:\n"
326
+ method_docs += "\n\n" unless method_docs.empty?
327
+ method_docs += "Block Params:\n"
219
328
  lines = []
220
329
  yieldparam_tags.each do |p|
221
330
  l = "* #{p.name}"
@@ -223,12 +332,12 @@ module Solargraph
223
332
  l += " #{p.text}"
224
333
  lines.push l
225
334
  end
226
- @documentation += lines.join("\n")
335
+ method_docs += lines.join("\n")
227
336
  end
228
337
  yieldreturn_tags = docstring.tags(:yieldreturn)
229
338
  unless yieldreturn_tags.empty?
230
- @documentation += "\n\n" unless @documentation.empty?
231
- @documentation += "Block Returns:\n"
339
+ method_docs += "\n\n" unless method_docs.empty?
340
+ method_docs += "Block Returns:\n"
232
341
  lines = []
233
342
  yieldreturn_tags.each do |r|
234
343
  l = "*"
@@ -236,12 +345,12 @@ module Solargraph
236
345
  l += " #{r.text}"
237
346
  lines.push l
238
347
  end
239
- @documentation += lines.join("\n")
348
+ method_docs += lines.join("\n")
240
349
  end
241
350
  return_tags = docstring.tags(:return)
242
351
  unless return_tags.empty?
243
- @documentation += "\n\n" unless @documentation.empty?
244
- @documentation += "Returns:\n"
352
+ method_docs += "\n\n" unless method_docs.empty?
353
+ method_docs += "Returns:\n"
245
354
  lines = []
246
355
  return_tags.each do |r|
247
356
  l = "*"
@@ -249,10 +358,11 @@ module Solargraph
249
358
  l += " #{r.text}"
250
359
  lines.push l
251
360
  end
252
- @documentation += lines.join("\n")
361
+ method_docs += lines.join("\n")
253
362
  end
254
- @documentation += "\n\n" unless @documentation.empty?
255
- @documentation += "Visibility: #{visibility}"
363
+ method_docs += "\n\n" unless method_docs.empty?
364
+ method_docs += "Visibility: #{visibility}"
365
+ @documentation = method_docs
256
366
  concat_example_tags
257
367
  end
258
368
  @documentation.to_s
@@ -278,14 +388,6 @@ module Solargraph
278
388
  attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
279
389
  end
280
390
 
281
- # @param pin [Pin::Method]
282
- def try_merge! pin
283
- return false unless super
284
- @node = pin.node
285
- @resolved_ref_tag = false
286
- true
287
- end
288
-
289
391
  # @return [::Array<Pin::Method>]
290
392
  def overloads
291
393
  # Ignore overload tags with nil parameters. If it's not an array, the
@@ -302,10 +404,13 @@ module Solargraph
302
404
  name: name,
303
405
  decl: decl,
304
406
  presence: location ? location.range : nil,
305
- return_type: param_type_from_name(tag, src.first)
407
+ return_type: param_type_from_name(tag, src.first),
408
+ source: :overloads
306
409
  )
307
410
  end,
308
- return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
411
+ closure: self,
412
+ return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types)),
413
+ source: :overloads,
309
414
  )
310
415
  end
311
416
  @overloads
@@ -315,7 +420,7 @@ module Solargraph
315
420
  @anon_splat
316
421
  end
317
422
 
318
- # @param [ApiMap]
423
+ # @param api_map [ApiMap]
319
424
  # @return [self]
320
425
  def resolve_ref_tag api_map
321
426
  return self if @resolved_ref_tag
@@ -323,7 +428,7 @@ module Solargraph
323
428
  @resolved_ref_tag = true
324
429
  return self unless docstring.ref_tags.any?
325
430
  docstring.ref_tags.each do |tag|
326
- ref = if tag.owner.to_s.start_with?(/[#\.]/)
431
+ ref = if tag.owner.to_s.start_with?(/[#.]/)
327
432
  api_map.get_methods(namespace)
328
433
  .select { |pin| pin.path.end_with?(tag.owner.to_s) }
329
434
  .first
@@ -338,16 +443,35 @@ module Solargraph
338
443
  self
339
444
  end
340
445
 
446
+ # @param api_map [ApiMap]
447
+ # @return [Array<Pin::Method>]
448
+ def rest_of_stack api_map
449
+ api_map.get_method_stack(method_namespace, method_name, scope: scope).reject { |pin| pin.path == path }
450
+ end
451
+
341
452
  protected
342
453
 
343
454
  attr_writer :block
344
455
 
345
- attr_writer :signatures
346
-
347
456
  attr_writer :signature_help
348
457
 
349
458
  attr_writer :documentation
350
459
 
460
+ def dodgy_visibility_source?
461
+ # as of 2025-03-12, the RBS generator used for
462
+ # e.g. activesupport did not understand 'private' markings
463
+ # inside 'class << self' blocks, but YARD did OK at it
464
+ source == :rbs && scope == :class && type_location&.filename&.include?('generated') && return_type.undefined? ||
465
+ # YARD's RBS generator seems to miss a lot of should-be protected instance methods
466
+ source == :rbs && scope == :instance && namespace.start_with?('YARD::') ||
467
+ # private on attr_readers seems to be broken in Prism's auto-generator script
468
+ source == :rbs && scope == :instance && namespace.start_with?('Prism::') ||
469
+ # The RBS for the RBS gem itself seems to use private as a
470
+ # 'is this a public API' concept, more aggressively than the
471
+ # actual code. Let's respect that and ignore the actual .rb file.
472
+ source == :yardoc && scope == :instance && namespace.start_with?('RBS::')
473
+ end
474
+
351
475
  private
352
476
 
353
477
  # @param name [String]
@@ -408,10 +532,15 @@ module Solargraph
408
532
  resolve_reference match[1], api_map
409
533
  end
410
534
 
535
+ # @return [String]
536
+ def method_namespace
537
+ namespace
538
+ end
539
+
411
540
  # @param api_map [ApiMap]
412
541
  # @return [ComplexType, nil]
413
542
  def typify_from_super api_map
414
- stack = api_map.get_method_stack(namespace, name, scope: scope).reject { |pin| pin.path == path }
543
+ stack = rest_of_stack api_map
415
544
  return nil if stack.empty?
416
545
  stack.each do |pin|
417
546
  return pin.return_type unless pin.return_type.undefined?
@@ -423,7 +552,7 @@ module Solargraph
423
552
  # @param api_map [ApiMap]
424
553
  # @return [ComplexType, nil]
425
554
  def resolve_reference ref, api_map
426
- parts = ref.split(/[\.#]/)
555
+ parts = ref.split(/[.#]/)
427
556
  if parts.first.empty? || parts.one?
428
557
  path = "#{namespace}#{ref}"
429
558
  else
@@ -521,7 +650,7 @@ module Solargraph
521
650
 
522
651
  protected
523
652
 
524
- attr_writer :signatures
653
+ attr_writer :return_type
525
654
  end
526
655
  end
527
656
  end
@@ -13,6 +13,9 @@ module Solargraph
13
13
  # @return [String]
14
14
  attr_reader :original
15
15
 
16
+ # @param scope [::Symbol]
17
+ # @param original [String, nil] The name of the original method
18
+ # @param splat [Hash] Additional options supported by superclasses
16
19
  def initialize scope: :instance, original: nil, **splat
17
20
  super(**splat)
18
21
  @scope = scope
@@ -11,44 +11,52 @@ module Solargraph
11
11
  # @return [::Symbol] :class or :module
12
12
  attr_reader :type
13
13
 
14
+ # does not assert like super, as a namespace without a closure
15
+ # may be the root level namespace, or it may not yet be
16
+ # qualified
17
+ attr_reader :closure
18
+
14
19
  # @param type [::Symbol] :class or :module
15
20
  # @param visibility [::Symbol] :public or :private
16
21
  # @param gates [::Array<String>]
17
- def initialize type: :class, visibility: :public, gates: [''], **splat
22
+ # @param name [String]
23
+ def initialize type: :class, visibility: :public, gates: [''], name: '', **splat
18
24
  # super(location, namespace, name, comments)
19
- super(**splat)
25
+ super(**splat, name: name)
20
26
  @type = type
21
27
  @visibility = visibility
22
28
  if name.start_with?('::')
23
- @name = name[2..-1]
29
+ # @type [String]
30
+ name = name[2..-1] || ''
24
31
  @closure = Solargraph::Pin::ROOT_PIN
25
32
  end
26
33
  @open_gates = gates
27
- if @name.include?('::')
34
+ if name.include?('::')
28
35
  # In this case, a chained namespace was opened (e.g., Foo::Bar)
29
36
  # but Foo does not exist.
30
- parts = @name.split('::')
31
- @name = parts.pop
37
+ parts = name.split('::')
38
+ name = parts.pop
32
39
  closure_name = if [Solargraph::Pin::ROOT_PIN, nil].include?(closure)
33
40
  ''
34
41
  else
35
42
  closure.full_context.namespace + '::'
36
43
  end
37
44
  closure_name += parts.join('::')
38
- @closure = Pin::Namespace.new(name: closure_name, gates: [parts.join('::')])
45
+ @closure = Pin::Namespace.new(name: closure_name, gates: [parts.join('::')], source: :namespace)
39
46
  @context = nil
40
47
  end
48
+ @name = name
41
49
  end
42
50
 
43
51
  def to_rbs
44
52
  "#{@type.to_s} #{return_type.all_params.first.to_rbs}#{rbs_generics}".strip
45
53
  end
46
54
 
47
- def desc
55
+ def inner_desc
48
56
  if name.nil? || name.empty?
49
57
  '(top-level)'
50
58
  else
51
- return_type.rooted_tags
59
+ super
52
60
  end
53
61
  end
54
62
 
@@ -9,14 +9,33 @@ module Solargraph
9
9
  # @return [String]
10
10
  attr_reader :asgn_code
11
11
 
12
+ # allow this to be set to the method after the method itself has
13
+ # been created
14
+ attr_writer :closure
15
+
12
16
  # @param decl [::Symbol] :arg, :optarg, :kwarg, :kwoptarg, :restarg, :kwrestarg, :block, :blockarg
13
17
  # @param asgn_code [String, nil]
14
- # @param return_type [ComplexType, nil]
15
- def initialize decl: :arg, asgn_code: nil, return_type: nil, **splat
18
+ def initialize decl: :arg, asgn_code: nil, **splat
16
19
  super(**splat)
17
20
  @asgn_code = asgn_code
18
21
  @decl = decl
19
- @return_type = return_type
22
+ end
23
+
24
+ def type_location
25
+ super || closure&.type_location
26
+ end
27
+
28
+ def location
29
+ super || closure&.type_location
30
+ end
31
+
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)
20
39
  end
21
40
 
22
41
  def keyword?
@@ -27,6 +46,32 @@ module Solargraph
27
46
  decl == :kwrestarg || (assignment && [:HASH, :hash].include?(assignment.type))
28
47
  end
29
48
 
49
+ def needs_consistent_name?
50
+ keyword?
51
+ end
52
+
53
+ # @return [String]
54
+ def arity_decl
55
+ name = (self.name || '(anon)')
56
+ type = (return_type&.to_rbs || 'untyped')
57
+ case decl
58
+ when :arg
59
+ ""
60
+ when :optarg
61
+ "?"
62
+ when :kwarg
63
+ "#{name}:"
64
+ when :kwoptarg
65
+ "?#{name}:"
66
+ when :restarg
67
+ "*"
68
+ when :kwrestarg
69
+ "**"
70
+ else
71
+ "(unknown decl: #{decl})"
72
+ end
73
+ end
74
+
30
75
  def arg?
31
76
  decl == :arg
32
77
  end
@@ -60,15 +105,13 @@ module Solargraph
60
105
  end
61
106
  end
62
107
 
63
- # @return [String]
64
- def full
108
+ # @return [String] the full name of the parameter, including any
109
+ # declarative symbols such as `*` or `:` indicating type of
110
+ # parameter. This is used in method signatures.
111
+ def full_name
65
112
  case decl
66
- when :optarg
67
- "#{name} = #{asgn_code || '?'}"
68
- when :kwarg
113
+ when :kwarg, :kwoptarg
69
114
  "#{name}:"
70
- when :kwoptarg
71
- "#{name}: #{asgn_code || '?'}"
72
115
  when :restarg
73
116
  "*#{name}"
74
117
  when :kwrestarg
@@ -80,6 +123,18 @@ module Solargraph
80
123
  end
81
124
  end
82
125
 
126
+ # @return [String]
127
+ def full
128
+ full_name + case decl
129
+ when :optarg
130
+ " = #{asgn_code || '?'}"
131
+ when :kwoptarg
132
+ " #{asgn_code || '?'}"
133
+ else
134
+ ''
135
+ end
136
+ end
137
+
83
138
  # @return [ComplexType]
84
139
  def return_type
85
140
  if @return_type.nil?
@@ -115,18 +170,21 @@ module Solargraph
115
170
  closure.is_a?(Pin::Block) ? typify_block_param(api_map) : typify_method_param(api_map)
116
171
  end
117
172
 
173
+ # @param atype [ComplexType]
174
+ # @param api_map [ApiMap]
175
+ def compatible_arg?(atype, api_map)
176
+ # make sure we get types from up the method
177
+ # inheritance chain if we don't have them on this pin
178
+ ptype = typify api_map
179
+ ptype.undefined? || ptype.can_assign?(api_map, atype) || ptype.generic?
180
+ end
181
+
118
182
  def documentation
119
183
  tag = param_tag
120
184
  return '' if tag.nil? || tag.text.nil?
121
185
  tag.text
122
186
  end
123
187
 
124
- # @param pin [Pin::Parameter]
125
- def try_merge! pin
126
- return false unless super && closure == pin.closure
127
- true
128
- end
129
-
130
188
  private
131
189
 
132
190
  # @return [YARD::Tags::Tag, nil]
@@ -141,8 +199,9 @@ module Solargraph
141
199
  # @param api_map [ApiMap]
142
200
  # @return [ComplexType]
143
201
  def typify_block_param api_map
144
- if closure.is_a?(Pin::Block) && closure.receiver
145
- return closure.typify_parameters(api_map)[index]
202
+ block_pin = closure
203
+ if block_pin.is_a?(Pin::Block) && block_pin.receiver
204
+ return block_pin.typify_parameters(api_map)[index]
146
205
  end
147
206
  ComplexType::UNDEFINED
148
207
  end
@@ -188,7 +247,7 @@ module Solargraph
188
247
  def resolve_reference ref, api_map, skip
189
248
  return nil if skip.include?(ref)
190
249
  skip.push ref
191
- parts = ref.split(/[\.#]/)
250
+ parts = ref.split(/[.#]/)
192
251
  if parts.first.empty?
193
252
  path = "#{namespace}#{ref}"
194
253
  else
@@ -4,24 +4,31 @@ module Solargraph
4
4
  module Pin
5
5
  class ProxyType < Base
6
6
  # @param return_type [ComplexType]
7
- def initialize return_type: ComplexType::UNDEFINED, **splat
7
+ # @param binder [ComplexType, ComplexType::UniqueType, nil]
8
+ def initialize return_type: ComplexType::UNDEFINED, binder: nil, **splat
8
9
  super(**splat)
9
10
  @return_type = return_type
11
+ @binder = binder if binder
10
12
  end
11
13
 
12
14
  def context
13
15
  @return_type
14
16
  end
15
17
 
16
- # @param return_type [ComplexType]
18
+ # @param context [ComplexType, ComplexType::UniqueType] Used as context for this pin
19
+ # @param closure [Pin::Namespace, nil] Used as the closure for this pin
20
+ # @param binder [ComplexType, ComplexType::UniqueType, nil]
17
21
  # @return [ProxyType]
18
- def self.anonymous return_type
19
- parts = return_type.namespace.split('::')
20
- namespace = parts[0..-2].join('::').to_s
22
+ def self.anonymous context, closure: nil, binder: nil, **kwargs
23
+ unless closure
24
+ parts = context.namespace.split('::')
25
+ namespace = parts[0..-2].join('::').to_s
26
+ closure = Solargraph::Pin::Namespace.new(name: namespace, source: :proxy_type)
27
+ end
21
28
  # name = parts.last.to_s
22
29
  # ProxyType.new(nil, namespace, name, return_type)
23
30
  ProxyType.new(
24
- closure: Solargraph::Pin::Namespace.new(name: namespace), return_type: return_type
31
+ closure: closure, return_type: context, binder: binder || context, **kwargs
25
32
  )
26
33
  end
27
34
  end