solargraph 0.54.1 → 0.56.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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/plugins.yml +2 -0
  3. data/.github/workflows/typecheck.yml +3 -1
  4. data/.gitignore +2 -0
  5. data/CHANGELOG.md +70 -0
  6. data/README.md +13 -3
  7. data/lib/solargraph/api_map/cache.rb +10 -1
  8. data/lib/solargraph/api_map/index.rb +175 -0
  9. data/lib/solargraph/api_map/store.rb +79 -126
  10. data/lib/solargraph/api_map.rb +247 -93
  11. data/lib/solargraph/bench.rb +17 -1
  12. data/lib/solargraph/complex_type/type_methods.rb +13 -1
  13. data/lib/solargraph/complex_type/unique_type.rb +118 -9
  14. data/lib/solargraph/complex_type.rb +48 -18
  15. data/lib/solargraph/convention/base.rb +3 -3
  16. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +60 -0
  17. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +100 -0
  18. data/lib/solargraph/convention/struct_definition.rb +101 -0
  19. data/lib/solargraph/convention.rb +5 -3
  20. data/lib/solargraph/doc_map.rb +274 -56
  21. data/lib/solargraph/equality.rb +33 -0
  22. data/lib/solargraph/gem_pins.rb +53 -37
  23. data/lib/solargraph/language_server/host/message_worker.rb +31 -11
  24. data/lib/solargraph/language_server/host.rb +24 -13
  25. data/lib/solargraph/language_server/message/base.rb +19 -12
  26. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -0
  27. data/lib/solargraph/language_server/message/extended/document.rb +5 -2
  28. data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
  29. data/lib/solargraph/language_server/message/initialize.rb +3 -1
  30. data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
  31. data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
  32. data/lib/solargraph/library.rb +13 -11
  33. data/lib/solargraph/location.rb +28 -0
  34. data/lib/solargraph/logging.rb +1 -0
  35. data/lib/solargraph/parser/comment_ripper.rb +12 -6
  36. data/lib/solargraph/parser/flow_sensitive_typing.rb +227 -0
  37. data/lib/solargraph/parser/node_methods.rb +15 -1
  38. data/lib/solargraph/parser/node_processor.rb +3 -1
  39. data/lib/solargraph/parser/parser_gem/class_methods.rb +16 -14
  40. data/lib/solargraph/parser/parser_gem/node_chainer.rb +17 -23
  41. data/lib/solargraph/parser/parser_gem/node_methods.rb +5 -3
  42. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
  43. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
  44. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +4 -2
  45. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +4 -2
  46. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +23 -2
  47. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
  48. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
  49. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
  50. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
  51. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +21 -0
  52. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
  53. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +4 -3
  54. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +29 -6
  55. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +41 -0
  56. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  57. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -3
  58. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +28 -16
  59. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +2 -1
  60. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
  61. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
  62. data/lib/solargraph/parser/parser_gem/node_processors.rb +10 -0
  63. data/lib/solargraph/parser/region.rb +1 -1
  64. data/lib/solargraph/parser.rb +1 -0
  65. data/lib/solargraph/pin/base.rb +326 -43
  66. data/lib/solargraph/pin/base_variable.rb +18 -10
  67. data/lib/solargraph/pin/block.rb +3 -3
  68. data/lib/solargraph/pin/breakable.rb +9 -0
  69. data/lib/solargraph/pin/callable.rb +77 -6
  70. data/lib/solargraph/pin/closure.rb +18 -1
  71. data/lib/solargraph/pin/common.rb +5 -0
  72. data/lib/solargraph/pin/delegated_method.rb +20 -1
  73. data/lib/solargraph/pin/documenting.rb +16 -0
  74. data/lib/solargraph/pin/keyword.rb +7 -2
  75. data/lib/solargraph/pin/local_variable.rb +15 -6
  76. data/lib/solargraph/pin/method.rb +172 -42
  77. data/lib/solargraph/pin/namespace.rb +17 -9
  78. data/lib/solargraph/pin/parameter.rb +61 -11
  79. data/lib/solargraph/pin/proxy_type.rb +12 -6
  80. data/lib/solargraph/pin/reference/override.rb +10 -6
  81. data/lib/solargraph/pin/reference/require.rb +2 -2
  82. data/lib/solargraph/pin/signature.rb +42 -0
  83. data/lib/solargraph/pin/singleton.rb +1 -1
  84. data/lib/solargraph/pin/symbol.rb +3 -2
  85. data/lib/solargraph/pin/until.rb +18 -0
  86. data/lib/solargraph/pin/while.rb +18 -0
  87. data/lib/solargraph/pin.rb +4 -1
  88. data/lib/solargraph/pin_cache.rb +185 -0
  89. data/lib/solargraph/position.rb +16 -0
  90. data/lib/solargraph/range.rb +16 -0
  91. data/lib/solargraph/rbs_map/conversions.rb +199 -66
  92. data/lib/solargraph/rbs_map/core_fills.rb +32 -16
  93. data/lib/solargraph/rbs_map/core_map.rb +34 -11
  94. data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
  95. data/lib/solargraph/rbs_map.rb +74 -16
  96. data/lib/solargraph/shell.rb +19 -18
  97. data/lib/solargraph/source/chain/array.rb +12 -8
  98. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  99. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  100. data/lib/solargraph/source/chain/call.rb +62 -25
  101. data/lib/solargraph/source/chain/constant.rb +1 -1
  102. data/lib/solargraph/source/chain/hash.rb +9 -3
  103. data/lib/solargraph/source/chain/head.rb +1 -1
  104. data/lib/solargraph/source/chain/if.rb +6 -1
  105. data/lib/solargraph/source/chain/link.rb +19 -5
  106. data/lib/solargraph/source/chain/literal.rb +27 -2
  107. data/lib/solargraph/source/chain/or.rb +1 -1
  108. data/lib/solargraph/source/chain/z_super.rb +1 -1
  109. data/lib/solargraph/source/chain.rb +106 -62
  110. data/lib/solargraph/source/cursor.rb +1 -11
  111. data/lib/solargraph/source/source_chainer.rb +2 -2
  112. data/lib/solargraph/source.rb +2 -1
  113. data/lib/solargraph/source_map/clip.rb +4 -2
  114. data/lib/solargraph/source_map/mapper.rb +9 -5
  115. data/lib/solargraph/source_map.rb +0 -17
  116. data/lib/solargraph/type_checker/checks.rb +4 -0
  117. data/lib/solargraph/type_checker.rb +41 -14
  118. data/lib/solargraph/version.rb +1 -1
  119. data/lib/solargraph/views/_method.erb +10 -10
  120. data/lib/solargraph/views/_namespace.erb +3 -3
  121. data/lib/solargraph/views/document.erb +10 -10
  122. data/lib/solargraph/workspace/config.rb +7 -3
  123. data/lib/solargraph/workspace.rb +16 -6
  124. data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -2
  125. data/lib/solargraph/yard_map/mapper/to_method.rb +55 -15
  126. data/lib/solargraph/yard_map/mapper/to_namespace.rb +5 -2
  127. data/lib/solargraph/yard_map/mapper.rb +5 -3
  128. data/lib/solargraph/yard_map/to_method.rb +4 -2
  129. data/lib/solargraph/yardoc.rb +6 -9
  130. data/lib/solargraph.rb +20 -1
  131. data/rbs/fills/tuple.rbs +150 -0
  132. data/rbs_collection.yaml +19 -0
  133. data/solargraph.gemspec +6 -5
  134. metadata +56 -29
  135. data/lib/solargraph/cache.rb +0 -77
@@ -8,10 +8,27 @@ module Solargraph
8
8
 
9
9
  # @param scope [::Symbol] :class or :instance
10
10
  # @param generics [::Array<Pin::Parameter>, nil]
11
- def initialize scope: :class, generics: nil, **splat
11
+ def initialize scope: :class, generics: nil, generic_defaults: {}, **splat
12
12
  super(**splat)
13
13
  @scope = scope
14
14
  @generics = generics
15
+ @generic_defaults = generic_defaults
16
+ end
17
+
18
+ def generic_defaults
19
+ @generic_defaults ||= {}
20
+ end
21
+
22
+ # @param other [self]
23
+ # @param attrs [Hash{Symbol => Object}]
24
+ #
25
+ # @return [self]
26
+ def combine_with(other, attrs={})
27
+ new_attrs = {
28
+ scope: assert_same(other, :scope),
29
+ generics: generics.empty? ? other.generics : generics,
30
+ }.merge(attrs)
31
+ super(other, new_attrs)
15
32
  end
16
33
 
17
34
  def context
@@ -9,6 +9,11 @@ module Solargraph
9
9
  # @return [Pin::Closure, nil]
10
10
  attr_reader :closure
11
11
 
12
+ def closure
13
+ Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure
14
+ @closure
15
+ end
16
+
12
17
  # @return [String]
13
18
  def name
14
19
  @name ||= ''
@@ -24,8 +24,26 @@ module Solargraph
24
24
  @receiver_method_name = receiver_method_name
25
25
  end
26
26
 
27
- %i[comments parameters return_type location].each do |method|
27
+ def inner_desc
28
+ "#{name} => #{@receiver_chain}##{@receiver_method_name}"
29
+ end
30
+
31
+ def location
32
+ return super if super
33
+
34
+ @resolved_method&.send(:location)
35
+ end
36
+
37
+
38
+ def type_location
39
+ return super if super
40
+
41
+ @resolved_method&.send(:type_location)
42
+ end
43
+
44
+ %i[comments parameters return_type signatures].each do |method|
28
45
  define_method(method) do
46
+ # @sg-ignore Need to set context correctly in define_method blocks
29
47
  @resolved_method ? @resolved_method.send(method) : super()
30
48
  end
31
49
  end
@@ -34,6 +52,7 @@ module Solargraph
34
52
  # @param api_map [ApiMap]
35
53
  define_method(method) do |api_map|
36
54
  resolve_method(api_map)
55
+ # @sg-ignore Need to set context correctly in define_method blocks
37
56
  @resolved_method ? @resolved_method.send(method, api_map) : super(api_map)
38
57
  end
39
58
  end
@@ -9,6 +9,22 @@ require 'solargraph/converters/dt'
9
9
  require 'solargraph/converters/dd'
10
10
  require 'solargraph/converters/misc'
11
11
 
12
+ # @todo upstream this definition
13
+
14
+ # @!parse
15
+ # module ::Kramdown
16
+ # class Document
17
+ # # @return [String]
18
+ # def to_html; end
19
+ # end
20
+ # end
21
+ # module ReverseMarkdown
22
+ # # @param input [String]
23
+ # # @param options [Hash]
24
+ # # @return [String]
25
+ # def self.convert(input, options = {}); end
26
+ # end
27
+
12
28
  module Solargraph
13
29
  module Pin
14
30
  # A module to add the Pin::Base#documentation method.
@@ -3,8 +3,13 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class Keyword < Base
6
- def initialize name
7
- super(name: name)
6
+ def initialize(name, **kwargs)
7
+ # @sg-ignore "Unrecognized keyword argument kwargs to Solargraph::Pin::Base#initialize"
8
+ super(name: name, **kwargs)
9
+ end
10
+
11
+ def closure
12
+ @closure ||= Pin::ROOT_PIN
8
13
  end
9
14
 
10
15
  def name
@@ -6,20 +6,29 @@ module Solargraph
6
6
  # @return [Range]
7
7
  attr_reader :presence
8
8
 
9
+ def presence_certain?
10
+ @presence_certain
11
+ end
12
+
9
13
  # @param assignment [AST::Node, nil]
10
14
  # @param presence [Range, nil]
15
+ # @param presence_certain [Boolean]
11
16
  # @param splat [Hash]
12
- def initialize assignment: nil, presence: nil, **splat
17
+ def initialize assignment: nil, presence: nil, presence_certain: false, **splat
13
18
  super(**splat)
14
19
  @assignment = assignment
15
20
  @presence = presence
21
+ @presence_certain = presence_certain
16
22
  end
17
23
 
18
- # @param pin [self]
19
- def try_merge! pin
20
- return false unless super
21
- @presence = pin.presence
22
- true
24
+ def combine_with(other, attrs={})
25
+ new_attrs = {
26
+ assignment: assert_same(other, :assignment),
27
+ presence_certain: assert_same(other, :presence_certain?),
28
+ }.merge(attrs)
29
+ new_attrs[:presence] = assert_same(other, :presence) unless attrs.key?(:presence)
30
+
31
+ super(other, new_attrs)
23
32
  end
24
33
 
25
34
  # @param other_closure [Pin::Closure]
@@ -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
 
@@ -31,6 +33,74 @@ module Solargraph
31
33
  @anon_splat = anon_splat
32
34
  end
33
35
 
36
+ # @return [Array<Pin::Signature>]
37
+ def combine_all_signature_pins(*signature_pins)
38
+ by_arity = {}
39
+ signature_pins.each do |signature_pin|
40
+ by_arity[signature_pin.arity] ||= []
41
+ by_arity[signature_pin.arity] << signature_pin
42
+ end
43
+ by_arity.transform_values! do |same_arity_pins|
44
+ same_arity_pins.reduce(nil) do |memo, signature|
45
+ next signature if memo.nil?
46
+ memo.combine_with(signature)
47
+ end
48
+ end
49
+ by_arity.values.flatten
50
+ end
51
+
52
+ # @param other [Pin::Method]
53
+ # @return [Symbol]
54
+ def combine_visibility(other)
55
+ if dodgy_visibility_source? && !other.dodgy_visibility_source?
56
+ other.visibility
57
+ elsif other.dodgy_visibility_source? && !dodgy_visibility_source?
58
+ visibility
59
+ else
60
+ assert_same(other, :visibility)
61
+ end
62
+ end
63
+
64
+ # @param other [Pin::Method]
65
+ # @return [Array<Pin::Signature>]
66
+ def combine_signatures(other)
67
+ all_undefined = signatures.all? { |sig| sig.return_type.undefined? }
68
+ other_all_undefined = other.signatures.all? { |sig| sig.return_type.undefined? }
69
+ if all_undefined && !other_all_undefined
70
+ other.signatures
71
+ elsif other_all_undefined && !all_undefined
72
+ signatures
73
+ else
74
+ combine_all_signature_pins(*signatures, *other.signatures)
75
+ end
76
+ end
77
+
78
+ def combine_with(other, attrs = {})
79
+ sigs = combine_signatures(other)
80
+ parameters = if sigs.length > 0
81
+ [].freeze
82
+ else
83
+ choose(other, :parameters).clone.freeze
84
+ end
85
+ new_attrs = {
86
+ visibility: combine_visibility(other),
87
+ explicit: explicit? || other.explicit?,
88
+ block: combine_blocks(other),
89
+ node: choose_node(other, :node),
90
+ attribute: prefer_rbs_location(other, :attribute?),
91
+ parameters: parameters,
92
+ signatures: sigs,
93
+ anon_splat: assert_same(other, :anon_splat?),
94
+ return_type: nil # pulled from signatures on first call
95
+ }.merge(attrs)
96
+ super(other, new_attrs)
97
+ end
98
+
99
+ # @param other [Pin::Method]
100
+ def == other
101
+ super && other.node == node
102
+ end
103
+
34
104
  def transform_types(&transform)
35
105
  # @todo 'super' alone should work here I think, but doesn't typecheck at level typed
36
106
  m = super(&transform)
@@ -38,11 +108,24 @@ module Solargraph
38
108
  sig.transform_types(&transform)
39
109
  end
40
110
  m.block = block&.transform_types(&transform)
41
- m.signature_help = nil
42
- m.documentation = nil
111
+ m.reset_generated!
43
112
  m
44
113
  end
45
114
 
115
+ # @return [void]
116
+ def reset_generated!
117
+ super
118
+ unless signatures.empty?
119
+ return_type = nil
120
+ @block = :undefined
121
+ parameters = []
122
+ end
123
+ block&.reset_generated!
124
+ @signatures&.each(&:reset_generated!)
125
+ signature_help = nil
126
+ documentation = nil
127
+ end
128
+
46
129
  def all_rooted?
47
130
  super && parameters.all?(&:all_rooted?) && (!block || block&.all_rooted?) && signatures.all?(&:all_rooted?)
48
131
  end
@@ -51,8 +134,7 @@ module Solargraph
51
134
  # @return [Pin::Method]
52
135
  def with_single_signature(signature)
53
136
  m = proxy signature.return_type
54
- m.signature_help = nil
55
- m.documentation = nil
137
+ m.reset_generated!
56
138
  # @todo populating the single parameters/return_type/block
57
139
  # arguments here seems to be needed for some specs to pass,
58
140
  # even though we have a signature with the same information.
@@ -112,13 +194,16 @@ module Solargraph
112
194
  name: name,
113
195
  decl: decl,
114
196
  presence: location ? location.range : nil,
115
- return_type: ComplexType.try_parse(*p.types)
197
+ return_type: ComplexType.try_parse(*p.types),
198
+ source: source
116
199
  )
117
200
  end
118
201
  yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
119
- block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type)
202
+ block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type, source: source, closure: self)
120
203
  end
121
- Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block)
204
+ signature = Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block, closure: self, source: source)
205
+ block.closure = signature if block
206
+ signature
122
207
  end
123
208
 
124
209
  # @return [::Array<Signature>]
@@ -133,6 +218,14 @@ module Solargraph
133
218
  end
134
219
  end
135
220
 
221
+ # @param return_type [ComplexType]
222
+ # @return [self]
223
+ def proxy_with_signatures return_type
224
+ out = proxy return_type
225
+ out.signatures = out.signatures.map { |sig| sig.proxy return_type }
226
+ out
227
+ end
228
+
136
229
  # @return [String, nil]
137
230
  def detail
138
231
  # This property is not cached in an instance variable because it can
@@ -159,12 +252,12 @@ module Solargraph
159
252
  end
160
253
  end
161
254
 
162
- def desc
255
+ def inner_desc
163
256
  # ensure the signatures line up when logged
164
257
  if signatures.length > 1
165
- "\n#{to_rbs}\n"
258
+ path + " \n#{to_rbs}\n"
166
259
  else
167
- to_rbs
260
+ super
168
261
  end
169
262
  end
170
263
 
@@ -184,21 +277,36 @@ module Solargraph
184
277
  @path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}"
185
278
  end
186
279
 
280
+ # @return [String]
281
+ def method_name
282
+ name
283
+ end
284
+
187
285
  def typify api_map
286
+ logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context.rooted_tags}, return_type=#{return_type.rooted_tags}) - starting" }
188
287
  decl = super
189
- return decl unless decl.undefined?
288
+ unless decl.undefined?
289
+ logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context}) => #{decl.rooted_tags.inspect} - decl found" }
290
+ return decl
291
+ end
190
292
  type = see_reference(api_map) || typify_from_super(api_map)
191
- return type.qualify(api_map, namespace) unless type.nil?
192
- name.end_with?('?') ? ComplexType::BOOLEAN : ComplexType::UNDEFINED
293
+ logger.debug { "Method#typify(self=#{self}) - type=#{type&.rooted_tags.inspect}" }
294
+ unless type.nil?
295
+ qualified = type.qualify(api_map, namespace)
296
+ logger.debug { "Method#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
297
+ return qualified
298
+ end
299
+ super
193
300
  end
194
301
 
302
+ # @sg-ignore
195
303
  def documentation
196
304
  if @documentation.nil?
197
- @documentation ||= super || ''
305
+ method_docs ||= super || ''
198
306
  param_tags = docstring.tags(:param)
199
307
  unless param_tags.nil? or param_tags.empty?
200
- @documentation += "\n\n" unless @documentation.empty?
201
- @documentation += "Params:\n"
308
+ method_docs += "\n\n" unless method_docs.empty?
309
+ method_docs += "Params:\n"
202
310
  lines = []
203
311
  param_tags.each do |p|
204
312
  l = "* #{p.name}"
@@ -206,12 +314,12 @@ module Solargraph
206
314
  l += " #{p.text}"
207
315
  lines.push l
208
316
  end
209
- @documentation += lines.join("\n")
317
+ method_docs += lines.join("\n")
210
318
  end
211
319
  yieldparam_tags = docstring.tags(:yieldparam)
212
320
  unless yieldparam_tags.nil? or yieldparam_tags.empty?
213
- @documentation += "\n\n" unless @documentation.empty?
214
- @documentation += "Block Params:\n"
321
+ method_docs += "\n\n" unless method_docs.empty?
322
+ method_docs += "Block Params:\n"
215
323
  lines = []
216
324
  yieldparam_tags.each do |p|
217
325
  l = "* #{p.name}"
@@ -219,12 +327,12 @@ module Solargraph
219
327
  l += " #{p.text}"
220
328
  lines.push l
221
329
  end
222
- @documentation += lines.join("\n")
330
+ method_docs += lines.join("\n")
223
331
  end
224
332
  yieldreturn_tags = docstring.tags(:yieldreturn)
225
333
  unless yieldreturn_tags.empty?
226
- @documentation += "\n\n" unless @documentation.empty?
227
- @documentation += "Block Returns:\n"
334
+ method_docs += "\n\n" unless method_docs.empty?
335
+ method_docs += "Block Returns:\n"
228
336
  lines = []
229
337
  yieldreturn_tags.each do |r|
230
338
  l = "*"
@@ -232,12 +340,12 @@ module Solargraph
232
340
  l += " #{r.text}"
233
341
  lines.push l
234
342
  end
235
- @documentation += lines.join("\n")
343
+ method_docs += lines.join("\n")
236
344
  end
237
345
  return_tags = docstring.tags(:return)
238
346
  unless return_tags.empty?
239
- @documentation += "\n\n" unless @documentation.empty?
240
- @documentation += "Returns:\n"
347
+ method_docs += "\n\n" unless method_docs.empty?
348
+ method_docs += "Returns:\n"
241
349
  lines = []
242
350
  return_tags.each do |r|
243
351
  l = "*"
@@ -245,10 +353,11 @@ module Solargraph
245
353
  l += " #{r.text}"
246
354
  lines.push l
247
355
  end
248
- @documentation += lines.join("\n")
356
+ method_docs += lines.join("\n")
249
357
  end
250
- @documentation += "\n\n" unless @documentation.empty?
251
- @documentation += "Visibility: #{visibility}"
358
+ method_docs += "\n\n" unless method_docs.empty?
359
+ method_docs += "Visibility: #{visibility}"
360
+ @documentation = method_docs
252
361
  concat_example_tags
253
362
  end
254
363
  @documentation.to_s
@@ -262,6 +371,7 @@ module Solargraph
262
371
  @attribute
263
372
  end
264
373
 
374
+ # @parm other [Method]
265
375
  def nearly? other
266
376
  super &&
267
377
  parameters == other.parameters &&
@@ -273,13 +383,6 @@ module Solargraph
273
383
  attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
274
384
  end
275
385
 
276
- def try_merge! pin
277
- return false unless super
278
- @node = pin.node
279
- @resolved_ref_tag = false
280
- true
281
- end
282
-
283
386
  # @return [::Array<Pin::Method>]
284
387
  def overloads
285
388
  # Ignore overload tags with nil parameters. If it's not an array, the
@@ -296,10 +399,13 @@ module Solargraph
296
399
  name: name,
297
400
  decl: decl,
298
401
  presence: location ? location.range : nil,
299
- return_type: param_type_from_name(tag, src.first)
402
+ return_type: param_type_from_name(tag, src.first),
403
+ source: :overloads
300
404
  )
301
405
  end,
302
- return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
406
+ closure: self,
407
+ return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types)),
408
+ source: :overloads,
303
409
  )
304
410
  end
305
411
  @overloads
@@ -309,7 +415,7 @@ module Solargraph
309
415
  @anon_splat
310
416
  end
311
417
 
312
- # @param [ApiMap]
418
+ # @param api_map [ApiMap]
313
419
  # @return [self]
314
420
  def resolve_ref_tag api_map
315
421
  return self if @resolved_ref_tag
@@ -332,16 +438,35 @@ module Solargraph
332
438
  self
333
439
  end
334
440
 
441
+ # @param api_map [ApiMap]
442
+ # @return [Array<Pin::Method>]
443
+ def rest_of_stack api_map
444
+ api_map.get_method_stack(method_namespace, method_name, scope: scope).reject { |pin| pin.path == path }
445
+ end
446
+
335
447
  protected
336
448
 
337
449
  attr_writer :block
338
450
 
339
- attr_writer :signatures
340
-
341
451
  attr_writer :signature_help
342
452
 
343
453
  attr_writer :documentation
344
454
 
455
+ def dodgy_visibility_source?
456
+ # as of 2025-03-12, the RBS generator used for
457
+ # e.g. activesupport did not understand 'private' markings
458
+ # inside 'class << self' blocks, but YARD did OK at it
459
+ source == :rbs && scope == :class && type_location&.filename&.include?('generated') && return_type.undefined? ||
460
+ # YARD's RBS generator seems to miss a lot of should-be protected instance methods
461
+ source == :rbs && scope == :instance && namespace.start_with?('YARD::') ||
462
+ # private on attr_readers seems to be broken in Prism's auto-generator script
463
+ source == :rbs && scope == :instance && namespace.start_with?('Prism::') ||
464
+ # The RBS for the RBS gem itself seems to use private as a
465
+ # 'is this a public API' concept, more aggressively than the
466
+ # actual code. Let's respect that and ignore the actual .rb file.
467
+ source == :yardoc && scope == :instance && namespace.start_with?('RBS::')
468
+ end
469
+
345
470
  private
346
471
 
347
472
  # @param name [String]
@@ -402,10 +527,15 @@ module Solargraph
402
527
  resolve_reference match[1], api_map
403
528
  end
404
529
 
530
+ # @return [String]
531
+ def method_namespace
532
+ namespace
533
+ end
534
+
405
535
  # @param api_map [ApiMap]
406
536
  # @return [ComplexType, nil]
407
537
  def typify_from_super api_map
408
- stack = api_map.get_method_stack(namespace, name, scope: scope).reject { |pin| pin.path == path }
538
+ stack = rest_of_stack api_map
409
539
  return nil if stack.empty?
410
540
  stack.each do |pin|
411
541
  return pin.return_type unless pin.return_type.undefined?
@@ -515,7 +645,7 @@ module Solargraph
515
645
 
516
646
  protected
517
647
 
518
- attr_writer :signatures
648
+ attr_writer :return_type
519
649
  end
520
650
  end
521
651
  end
@@ -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
- to_rbs
59
+ super
52
60
  end
53
61
  end
54
62