solargraph 0.54.0 → 0.58.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 (200) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linting.yml +127 -0
  3. data/.github/workflows/plugins.yml +184 -6
  4. data/.github/workflows/rspec.yml +55 -5
  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 +1279 -0
  11. data/.yardopts +1 -0
  12. data/CHANGELOG.md +171 -0
  13. data/README.md +20 -6
  14. data/Rakefile +125 -13
  15. data/bin/solargraph +8 -5
  16. data/lib/solargraph/api_map/cache.rb +13 -3
  17. data/lib/solargraph/api_map/constants.rb +279 -0
  18. data/lib/solargraph/api_map/index.rb +193 -0
  19. data/lib/solargraph/api_map/source_to_yard.rb +13 -4
  20. data/lib/solargraph/api_map/store.rb +207 -132
  21. data/lib/solargraph/api_map.rb +394 -261
  22. data/lib/solargraph/bench.rb +18 -1
  23. data/lib/solargraph/complex_type/type_methods.rb +29 -12
  24. data/lib/solargraph/complex_type/unique_type.rb +205 -26
  25. data/lib/solargraph/complex_type.rb +126 -26
  26. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  27. data/lib/solargraph/convention/base.rb +20 -3
  28. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
  29. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
  30. data/lib/solargraph/convention/data_definition.rb +105 -0
  31. data/lib/solargraph/convention/gemspec.rb +3 -2
  32. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -0
  33. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -0
  34. data/lib/solargraph/convention/struct_definition.rb +164 -0
  35. data/lib/solargraph/convention.rb +36 -4
  36. data/lib/solargraph/diagnostics/rubocop.rb +6 -1
  37. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  38. data/lib/solargraph/doc_map.rb +316 -64
  39. data/lib/solargraph/environ.rb +9 -2
  40. data/lib/solargraph/equality.rb +34 -0
  41. data/lib/solargraph/gem_pins.rb +64 -38
  42. data/lib/solargraph/language_server/host/dispatch.rb +2 -0
  43. data/lib/solargraph/language_server/host/message_worker.rb +54 -5
  44. data/lib/solargraph/language_server/host.rb +36 -18
  45. data/lib/solargraph/language_server/message/base.rb +20 -12
  46. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -0
  47. data/lib/solargraph/language_server/message/extended/document.rb +5 -2
  48. data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
  49. data/lib/solargraph/language_server/message/initialize.rb +3 -1
  50. data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
  51. data/lib/solargraph/language_server/message/text_document/definition.rb +5 -3
  52. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
  53. data/lib/solargraph/language_server/message/text_document/formatting.rb +23 -2
  54. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
  55. data/lib/solargraph/language_server/message/text_document/type_definition.rb +4 -3
  56. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  57. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
  58. data/lib/solargraph/language_server/progress.rb +27 -2
  59. data/lib/solargraph/language_server/request.rb +4 -1
  60. data/lib/solargraph/library.rb +83 -73
  61. data/lib/solargraph/location.rb +45 -1
  62. data/lib/solargraph/logging.rb +12 -2
  63. data/lib/solargraph/page.rb +3 -0
  64. data/lib/solargraph/parser/comment_ripper.rb +20 -7
  65. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -0
  66. data/lib/solargraph/parser/node_processor/base.rb +10 -5
  67. data/lib/solargraph/parser/node_processor.rb +26 -8
  68. data/lib/solargraph/parser/parser_gem/class_methods.rb +10 -18
  69. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  70. data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -11
  71. data/lib/solargraph/parser/parser_gem/node_methods.rb +10 -19
  72. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
  73. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -0
  74. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +26 -20
  75. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +7 -4
  76. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +2 -1
  77. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
  78. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
  79. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
  80. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
  81. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -0
  82. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
  83. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -1
  84. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +14 -2
  85. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +8 -7
  86. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -0
  87. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -0
  88. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +3 -1
  89. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +16 -6
  90. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +64 -32
  91. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +3 -1
  92. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
  93. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
  94. data/lib/solargraph/parser/parser_gem/node_processors.rb +14 -0
  95. data/lib/solargraph/parser/region.rb +4 -1
  96. data/lib/solargraph/parser/snippet.rb +2 -0
  97. data/lib/solargraph/parser.rb +3 -5
  98. data/lib/solargraph/pin/base.rb +417 -42
  99. data/lib/solargraph/pin/base_variable.rb +21 -12
  100. data/lib/solargraph/pin/block.rb +9 -26
  101. data/lib/solargraph/pin/breakable.rb +9 -0
  102. data/lib/solargraph/pin/callable.rb +231 -0
  103. data/lib/solargraph/pin/closure.rb +30 -10
  104. data/lib/solargraph/pin/common.rb +12 -7
  105. data/lib/solargraph/pin/constant.rb +2 -0
  106. data/lib/solargraph/pin/conversions.rb +3 -2
  107. data/lib/solargraph/pin/delegated_method.rb +20 -1
  108. data/lib/solargraph/pin/documenting.rb +16 -0
  109. data/lib/solargraph/pin/instance_variable.rb +2 -2
  110. data/lib/solargraph/pin/keyword.rb +7 -2
  111. data/lib/solargraph/pin/local_variable.rb +15 -7
  112. data/lib/solargraph/pin/method.rb +241 -70
  113. data/lib/solargraph/pin/method_alias.rb +3 -0
  114. data/lib/solargraph/pin/namespace.rb +21 -13
  115. data/lib/solargraph/pin/parameter.rb +94 -32
  116. data/lib/solargraph/pin/proxy_type.rb +17 -7
  117. data/lib/solargraph/pin/reference/override.rb +24 -6
  118. data/lib/solargraph/pin/reference/require.rb +2 -2
  119. data/lib/solargraph/pin/reference/superclass.rb +5 -0
  120. data/lib/solargraph/pin/reference.rb +17 -0
  121. data/lib/solargraph/pin/search.rb +6 -1
  122. data/lib/solargraph/pin/signature.rb +39 -121
  123. data/lib/solargraph/pin/singleton.rb +1 -1
  124. data/lib/solargraph/pin/symbol.rb +8 -2
  125. data/lib/solargraph/pin/until.rb +18 -0
  126. data/lib/solargraph/pin/while.rb +18 -0
  127. data/lib/solargraph/pin.rb +8 -2
  128. data/lib/solargraph/pin_cache.rb +245 -0
  129. data/lib/solargraph/position.rb +19 -0
  130. data/lib/solargraph/range.rb +23 -4
  131. data/lib/solargraph/rbs_map/conversions.rb +315 -99
  132. data/lib/solargraph/rbs_map/core_fills.rb +50 -16
  133. data/lib/solargraph/rbs_map/core_map.rb +41 -11
  134. data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
  135. data/lib/solargraph/rbs_map.rb +87 -16
  136. data/lib/solargraph/shell.rb +117 -17
  137. data/lib/solargraph/source/chain/array.rb +13 -8
  138. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  139. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  140. data/lib/solargraph/source/chain/call.rb +135 -66
  141. data/lib/solargraph/source/chain/constant.rb +3 -66
  142. data/lib/solargraph/source/chain/hash.rb +9 -3
  143. data/lib/solargraph/source/chain/head.rb +1 -1
  144. data/lib/solargraph/source/chain/if.rb +7 -2
  145. data/lib/solargraph/source/chain/link.rb +38 -6
  146. data/lib/solargraph/source/chain/literal.rb +27 -2
  147. data/lib/solargraph/source/chain/or.rb +2 -2
  148. data/lib/solargraph/source/chain/z_super.rb +1 -1
  149. data/lib/solargraph/source/chain.rb +140 -63
  150. data/lib/solargraph/source/change.rb +2 -2
  151. data/lib/solargraph/source/cursor.rb +4 -4
  152. data/lib/solargraph/source/source_chainer.rb +3 -3
  153. data/lib/solargraph/source.rb +110 -89
  154. data/lib/solargraph/source_map/clip.rb +22 -28
  155. data/lib/solargraph/source_map/data.rb +34 -0
  156. data/lib/solargraph/source_map/mapper.rb +11 -7
  157. data/lib/solargraph/source_map.rb +50 -43
  158. data/lib/solargraph/type_checker/checks.rb +4 -0
  159. data/lib/solargraph/type_checker/param_def.rb +2 -0
  160. data/lib/solargraph/type_checker/rules.rb +35 -8
  161. data/lib/solargraph/type_checker.rb +331 -189
  162. data/lib/solargraph/version.rb +1 -1
  163. data/lib/solargraph/views/_method.erb +10 -10
  164. data/lib/solargraph/views/_namespace.erb +3 -3
  165. data/lib/solargraph/views/document.erb +10 -10
  166. data/lib/solargraph/views/environment.erb +3 -5
  167. data/lib/solargraph/workspace/config.rb +25 -5
  168. data/lib/solargraph/workspace/require_paths.rb +97 -0
  169. data/lib/solargraph/workspace.rb +53 -72
  170. data/lib/solargraph/yard_map/helpers.rb +29 -1
  171. data/lib/solargraph/yard_map/mapper/to_constant.rb +8 -5
  172. data/lib/solargraph/yard_map/mapper/to_method.rb +55 -19
  173. data/lib/solargraph/yard_map/mapper/to_namespace.rb +11 -7
  174. data/lib/solargraph/yard_map/mapper.rb +5 -3
  175. data/lib/solargraph/yard_map/to_method.rb +6 -3
  176. data/lib/solargraph/yardoc.rb +45 -10
  177. data/lib/solargraph.rb +35 -1
  178. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  179. data/rbs/fills/open3/0/open3.rbs +172 -0
  180. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  181. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  182. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  183. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  184. data/rbs/fills/tuple/tuple.rbs +149 -0
  185. data/rbs_collection.yaml +19 -0
  186. data/sig/shims/ast/0/node.rbs +5 -0
  187. data/sig/shims/ast/2.4/.rbs_meta.yaml +9 -0
  188. data/sig/shims/ast/2.4/ast.rbs +73 -0
  189. data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  190. data/sig/shims/parser/3.2.0.1/manifest.yaml +7 -0
  191. data/sig/shims/parser/3.2.0.1/parser.rbs +201 -0
  192. data/sig/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  193. data/sig/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  194. data/sig/shims/thor/1.2.0.1/manifest.yaml +7 -0
  195. data/sig/shims/thor/1.2.0.1/thor.rbs +17 -0
  196. data/solargraph.gemspec +32 -10
  197. metadata +237 -37
  198. data/lib/.rubocop.yml +0 -22
  199. data/lib/solargraph/cache.rb +0 -77
  200. data/lib/solargraph/parser/node_methods.rb +0 -83
@@ -4,38 +4,110 @@ module Solargraph
4
4
  module Pin
5
5
  # The base class for method and attribute pins.
6
6
  #
7
- class Method < Closure
7
+ class Method < Callable
8
8
  include Solargraph::Parser::NodeMethods
9
9
 
10
- # @return [::Array<Pin::Parameter>]
11
- attr_reader :parameters
12
-
13
10
  # @return [::Symbol] :public, :private, or :protected
14
11
  attr_reader :visibility
15
12
 
13
+ attr_writer :signatures
14
+
16
15
  # @return [Parser::AST::Node]
17
16
  attr_reader :node
18
17
 
19
18
  # @param visibility [::Symbol] :public, :protected, or :private
20
19
  # @param explicit [Boolean]
21
- # @param parameters [::Array<Pin::Parameter>]
22
- # @param block [Pin::Signature, nil, ::Symbol]
23
- # @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node, nil]
20
+ # @param block [Pin::Signature, nil, :undefined]
21
+ # @param node [Parser::AST::Node, nil]
24
22
  # @param attribute [Boolean]
25
23
  # @param signatures [::Array<Signature>, nil]
26
24
  # @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
+ def initialize visibility: :public, explicit: true, block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false,
26
+ **splat
29
27
  super(**splat)
30
28
  @visibility = visibility
31
29
  @explicit = explicit
32
- @parameters = parameters
33
30
  @block = block
34
31
  @node = node
35
32
  @attribute = attribute
36
33
  @signatures = signatures
37
34
  @anon_splat = anon_splat
38
- @return_type = return_type
35
+ end
36
+
37
+ # @param signature_pins [Array<Pin::Signature>]
38
+ # @return [Array<Pin::Signature>]
39
+ def combine_all_signature_pins(*signature_pins)
40
+ # @type [Hash{Array => Array<Pin::Signature>}]
41
+ by_arity = {}
42
+ signature_pins.each do |signature_pin|
43
+ by_arity[signature_pin.arity] ||= []
44
+ by_arity[signature_pin.arity] << signature_pin
45
+ end
46
+ by_arity.transform_values! do |same_arity_pins|
47
+ # @param memo [Pin::Signature, nil]
48
+ # @param signature [Pin::Signature]
49
+ same_arity_pins.reduce(nil) do |memo, signature|
50
+ next signature if memo.nil?
51
+ memo.combine_with(signature)
52
+ end
53
+ end
54
+ by_arity.values.flatten
55
+ end
56
+
57
+ # @param other [Pin::Method]
58
+ # @return [::Symbol]
59
+ def combine_visibility(other)
60
+ if dodgy_visibility_source? && !other.dodgy_visibility_source?
61
+ other.visibility
62
+ elsif other.dodgy_visibility_source? && !dodgy_visibility_source?
63
+ visibility
64
+ else
65
+ assert_same(other, :visibility)
66
+ end
67
+ end
68
+
69
+ # @param other [Pin::Method]
70
+ # @return [Array<Pin::Signature>]
71
+ def combine_signatures(other)
72
+ all_undefined = signatures.all? { |sig| sig.return_type.undefined? }
73
+ other_all_undefined = other.signatures.all? { |sig| sig.return_type.undefined? }
74
+ if all_undefined && !other_all_undefined
75
+ other.signatures
76
+ elsif other_all_undefined && !all_undefined
77
+ signatures
78
+ else
79
+ combine_all_signature_pins(*signatures, *other.signatures)
80
+ end
81
+ end
82
+
83
+ def combine_with(other, attrs = {})
84
+ priority_choice = choose_priority(other)
85
+ return priority_choice unless priority_choice.nil?
86
+
87
+ sigs = combine_signatures(other)
88
+ parameters = if sigs.length > 0
89
+ [].freeze
90
+ else
91
+ choose(other, :parameters).clone.freeze
92
+ end
93
+ new_attrs = {
94
+ visibility: combine_visibility(other),
95
+ # @sg-ignore https://github.com/castwide/solargraph/pull/1050
96
+ explicit: explicit? || other.explicit?,
97
+ block: combine_blocks(other),
98
+ node: choose_node(other, :node),
99
+ attribute: prefer_rbs_location(other, :attribute?),
100
+ parameters: parameters,
101
+ signatures: sigs,
102
+ anon_splat: assert_same(other, :anon_splat?),
103
+ return_type: nil # pulled from signatures on first call
104
+ }.merge(attrs)
105
+ super(other, new_attrs)
106
+ end
107
+
108
+ # @param other [Pin::Method]
109
+ def == other
110
+ super && other.node == node
39
111
  end
40
112
 
41
113
  def transform_types(&transform)
@@ -44,21 +116,34 @@ module Solargraph
44
116
  m.signatures = m.signatures.map do |sig|
45
117
  sig.transform_types(&transform)
46
118
  end
47
- m.parameters = m.parameters.map do |param|
48
- param.transform_types(&transform)
49
- end
50
119
  m.block = block&.transform_types(&transform)
51
- m.signature_help = nil
52
- m.documentation = nil
120
+ m.reset_generated!
53
121
  m
54
122
  end
55
123
 
124
+ # @return [void]
125
+ def reset_generated!
126
+ super
127
+ unless signatures.empty?
128
+ return_type = nil
129
+ @block = :undefined
130
+ parameters = []
131
+ end
132
+ block&.reset_generated!
133
+ @signatures&.each(&:reset_generated!)
134
+ signature_help = nil
135
+ documentation = nil
136
+ end
137
+
138
+ def all_rooted?
139
+ super && parameters.all?(&:all_rooted?) && (!block || block&.all_rooted?) && signatures.all?(&:all_rooted?)
140
+ end
141
+
56
142
  # @param signature [Pin::Signature]
57
143
  # @return [Pin::Method]
58
144
  def with_single_signature(signature)
59
145
  m = proxy signature.return_type
60
- m.signature_help = nil
61
- m.documentation = nil
146
+ m.reset_generated!
62
147
  # @todo populating the single parameters/return_type/block
63
148
  # arguments here seems to be needed for some specs to pass,
64
149
  # even though we have a signature with the same information.
@@ -71,15 +156,14 @@ module Solargraph
71
156
  m
72
157
  end
73
158
 
159
+ def block?
160
+ !block.nil?
161
+ end
162
+
74
163
  # @return [Pin::Signature, nil]
75
164
  def block
76
165
  return @block unless @block == :undefined
77
- @block = signatures.first.block
78
- end
79
-
80
- # @return [::Array<String>]
81
- def parameter_names
82
- @parameter_names ||= parameters.map(&:name)
166
+ @block = signatures.first&.block
83
167
  end
84
168
 
85
169
  def completion_item_kind
@@ -119,13 +203,18 @@ module Solargraph
119
203
  name: name,
120
204
  decl: decl,
121
205
  presence: location ? location.range : nil,
122
- return_type: ComplexType.try_parse(*p.types)
206
+ return_type: ComplexType.try_parse(*p.types),
207
+ source: source
123
208
  )
124
209
  end
125
210
  yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
126
- block = Signature.new(generics, yield_parameters, yield_return_type)
211
+ block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type, source: source,
212
+ closure: self, location: location, type_location: type_location)
127
213
  end
128
- Signature.new(generics, parameters, return_type, block)
214
+ signature = Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block, closure: self, source: source,
215
+ location: location, type_location: type_location)
216
+ block.closure = signature if block
217
+ signature
129
218
  end
130
219
 
131
220
  # @return [::Array<Signature>]
@@ -140,6 +229,14 @@ module Solargraph
140
229
  end
141
230
  end
142
231
 
232
+ # @param return_type [ComplexType]
233
+ # @return [self]
234
+ def proxy_with_signatures return_type
235
+ out = proxy return_type
236
+ out.signatures = out.signatures.map { |sig| sig.proxy return_type }
237
+ out
238
+ end
239
+
143
240
  # @return [String, nil]
144
241
  def detail
145
242
  # This property is not cached in an instance variable because it can
@@ -166,12 +263,12 @@ module Solargraph
166
263
  end
167
264
  end
168
265
 
169
- def desc
266
+ def inner_desc
170
267
  # ensure the signatures line up when logged
171
268
  if signatures.length > 1
172
- "\n#{to_rbs}\n"
269
+ path + " \n#{to_rbs}\n"
173
270
  else
174
- to_rbs
271
+ super
175
272
  end
176
273
  end
177
274
 
@@ -191,21 +288,35 @@ module Solargraph
191
288
  @path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}"
192
289
  end
193
290
 
291
+ # @return [String]
292
+ def method_name
293
+ name
294
+ end
295
+
194
296
  def typify api_map
297
+ logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context.rooted_tags}, return_type=#{return_type.rooted_tags}) - starting" }
195
298
  decl = super
196
- return decl unless decl.undefined?
299
+ unless decl.undefined?
300
+ logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context}) => #{decl.rooted_tags.inspect} - decl found" }
301
+ return decl
302
+ end
197
303
  type = see_reference(api_map) || typify_from_super(api_map)
198
- return type.qualify(api_map, namespace) unless type.nil?
199
- name.end_with?('?') ? ComplexType::BOOLEAN : ComplexType::UNDEFINED
304
+ logger.debug { "Method#typify(self=#{self}) - type=#{type&.rooted_tags.inspect}" }
305
+ unless type.nil?
306
+ qualified = type.qualify(api_map, *closure.gates)
307
+ logger.debug { "Method#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
308
+ return qualified
309
+ end
310
+ super
200
311
  end
201
312
 
202
313
  def documentation
203
314
  if @documentation.nil?
204
- @documentation ||= super || ''
315
+ method_docs ||= super || ''
205
316
  param_tags = docstring.tags(:param)
206
317
  unless param_tags.nil? or param_tags.empty?
207
- @documentation += "\n\n" unless @documentation.empty?
208
- @documentation += "Params:\n"
318
+ method_docs += "\n\n" unless method_docs.empty?
319
+ method_docs += "Params:\n"
209
320
  lines = []
210
321
  param_tags.each do |p|
211
322
  l = "* #{p.name}"
@@ -213,12 +324,12 @@ module Solargraph
213
324
  l += " #{p.text}"
214
325
  lines.push l
215
326
  end
216
- @documentation += lines.join("\n")
327
+ method_docs += lines.join("\n")
217
328
  end
218
329
  yieldparam_tags = docstring.tags(:yieldparam)
219
330
  unless yieldparam_tags.nil? or yieldparam_tags.empty?
220
- @documentation += "\n\n" unless @documentation.empty?
221
- @documentation += "Block Params:\n"
331
+ method_docs += "\n\n" unless method_docs.empty?
332
+ method_docs += "Block Params:\n"
222
333
  lines = []
223
334
  yieldparam_tags.each do |p|
224
335
  l = "* #{p.name}"
@@ -226,12 +337,12 @@ module Solargraph
226
337
  l += " #{p.text}"
227
338
  lines.push l
228
339
  end
229
- @documentation += lines.join("\n")
340
+ method_docs += lines.join("\n")
230
341
  end
231
342
  yieldreturn_tags = docstring.tags(:yieldreturn)
232
343
  unless yieldreturn_tags.empty?
233
- @documentation += "\n\n" unless @documentation.empty?
234
- @documentation += "Block Returns:\n"
344
+ method_docs += "\n\n" unless method_docs.empty?
345
+ method_docs += "Block Returns:\n"
235
346
  lines = []
236
347
  yieldreturn_tags.each do |r|
237
348
  l = "*"
@@ -239,12 +350,12 @@ module Solargraph
239
350
  l += " #{r.text}"
240
351
  lines.push l
241
352
  end
242
- @documentation += lines.join("\n")
353
+ method_docs += lines.join("\n")
243
354
  end
244
355
  return_tags = docstring.tags(:return)
245
356
  unless return_tags.empty?
246
- @documentation += "\n\n" unless @documentation.empty?
247
- @documentation += "Returns:\n"
357
+ method_docs += "\n\n" unless method_docs.empty?
358
+ method_docs += "Returns:\n"
248
359
  lines = []
249
360
  return_tags.each do |r|
250
361
  l = "*"
@@ -252,10 +363,11 @@ module Solargraph
252
363
  l += " #{r.text}"
253
364
  lines.push l
254
365
  end
255
- @documentation += lines.join("\n")
366
+ method_docs += lines.join("\n")
256
367
  end
257
- @documentation += "\n\n" unless @documentation.empty?
258
- @documentation += "Visibility: #{visibility}"
368
+ method_docs += "\n\n" unless method_docs.empty?
369
+ method_docs += "Visibility: #{visibility}"
370
+ @documentation = method_docs
259
371
  concat_example_tags
260
372
  end
261
373
  @documentation.to_s
@@ -269,10 +381,14 @@ module Solargraph
269
381
  @attribute
270
382
  end
271
383
 
384
+ # @parm other [self]
272
385
  def nearly? other
273
- return false unless super
274
- parameters == other.parameters and
275
- scope == other.scope and
386
+ super &&
387
+ # @sg-ignore https://github.com/castwide/solargraph/pull/1050
388
+ parameters == other.parameters &&
389
+ # @sg-ignore https://github.com/castwide/solargraph/pull/1050
390
+ scope == other.scope &&
391
+ # @sg-ignore https://github.com/castwide/solargraph/pull/1050
276
392
  visibility == other.visibility
277
393
  end
278
394
 
@@ -280,20 +396,17 @@ module Solargraph
280
396
  attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
281
397
  end
282
398
 
283
- def try_merge! pin
284
- return false unless super
285
- @node = pin.node
286
- true
287
- end
288
-
289
399
  # @return [::Array<Pin::Method>]
290
400
  def overloads
291
401
  # Ignore overload tags with nil parameters. If it's not an array, the
292
402
  # tag's source is likely malformed.
403
+
404
+ # @param tag [YARD::Tags::OverloadTag]
293
405
  @overloads ||= docstring.tags(:overload).select(&:parameters).map do |tag|
294
406
  Pin::Signature.new(
295
- generics,
296
- tag.parameters.map do |src|
407
+ generics: generics,
408
+ # @param src [Array(String, String)]
409
+ parameters: tag.parameters.map do |src|
297
410
  name, decl = parse_overload_param(src.first)
298
411
  Pin::Parameter.new(
299
412
  location: location,
@@ -302,10 +415,13 @@ module Solargraph
302
415
  name: name,
303
416
  decl: decl,
304
417
  presence: location ? location.range : nil,
305
- return_type: param_type_from_name(tag, src.first)
418
+ return_type: param_type_from_name(tag, src.first),
419
+ source: :overloads
306
420
  )
307
421
  end,
308
- ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
422
+ closure: self,
423
+ return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types)),
424
+ source: :overloads,
309
425
  )
310
426
  end
311
427
  @overloads
@@ -315,18 +431,58 @@ module Solargraph
315
431
  @anon_splat
316
432
  end
317
433
 
318
- protected
434
+ # @param api_map [ApiMap]
435
+ # @return [self]
436
+ def resolve_ref_tag api_map
437
+ return self if @resolved_ref_tag
438
+
439
+ @resolved_ref_tag = true
440
+ return self unless docstring.ref_tags.any?
441
+ docstring.ref_tags.each do |tag|
442
+ ref = if tag.owner.to_s.start_with?(/[#.]/)
443
+ api_map.get_methods(namespace)
444
+ .select { |pin| pin.path.end_with?(tag.owner.to_s) }
445
+ .first
446
+ else
447
+ # @todo Resolve relative namespaces
448
+ api_map.get_path_pins(tag.owner.to_s).first
449
+ end
450
+ next unless ref
319
451
 
320
- attr_writer :block
452
+ docstring.add_tag(*ref.docstring.tags(:param))
453
+ end
454
+ self
455
+ end
456
+
457
+ # @param api_map [ApiMap]
458
+ # @return [Array<Pin::Method>]
459
+ def rest_of_stack api_map
460
+ api_map.get_method_stack(method_namespace, method_name, scope: scope).reject { |pin| pin.path == path }
461
+ end
321
462
 
322
- attr_writer :parameters
463
+ protected
323
464
 
324
- attr_writer :signatures
465
+ attr_writer :block
325
466
 
326
467
  attr_writer :signature_help
327
468
 
328
469
  attr_writer :documentation
329
470
 
471
+ def dodgy_visibility_source?
472
+ # as of 2025-03-12, the RBS generator used for
473
+ # e.g. activesupport did not understand 'private' markings
474
+ # inside 'class << self' blocks, but YARD did OK at it
475
+ source == :rbs && scope == :class && type_location&.filename&.include?('generated') && return_type.undefined? ||
476
+ # YARD's RBS generator seems to miss a lot of should-be protected instance methods
477
+ source == :rbs && scope == :instance && namespace.start_with?('YARD::') ||
478
+ # private on attr_readers seems to be broken in Prism's auto-generator script
479
+ source == :rbs && scope == :instance && namespace.start_with?('Prism::') ||
480
+ # The RBS for the RBS gem itself seems to use private as a
481
+ # 'is this a public API' concept, more aggressively than the
482
+ # actual code. Let's respect that and ignore the actual .rb file.
483
+ source == :yardoc && scope == :instance && namespace.start_with?('RBS::')
484
+ end
485
+
330
486
  private
331
487
 
332
488
  # @param name [String]
@@ -362,6 +518,7 @@ module Solargraph
362
518
  #
363
519
  # @return [ComplexType]
364
520
  def param_type_from_name(tag, name)
521
+ # @param t [YARD::Tags::Tag]
365
522
  param = tag.tags(:param).select { |t| t.name == name }.first
366
523
  return ComplexType::UNDEFINED unless param
367
524
  ComplexType.try_parse(*param.types)
@@ -377,8 +534,12 @@ module Solargraph
377
534
  # @param api_map [ApiMap]
378
535
  # @return [ComplexType, nil]
379
536
  def see_reference api_map
537
+ # This should actually be an intersection type
538
+ # @param ref [YARD::Tags::Tag, Solargraph::Yard::Tags::RefTag]
380
539
  docstring.ref_tags.each do |ref|
540
+ # @sg-ignore ref should actually be an intersection type
381
541
  next unless ref.tag_name == 'return' && ref.owner
542
+ # @sg-ignore ref should actually be an intersection type
382
543
  result = resolve_reference(ref.owner.to_s, api_map)
383
544
  return result unless result.nil?
384
545
  end
@@ -387,10 +548,15 @@ module Solargraph
387
548
  resolve_reference match[1], api_map
388
549
  end
389
550
 
551
+ # @return [String]
552
+ def method_namespace
553
+ namespace
554
+ end
555
+
390
556
  # @param api_map [ApiMap]
391
557
  # @return [ComplexType, nil]
392
558
  def typify_from_super api_map
393
- stack = api_map.get_method_stack(namespace, name, scope: scope).reject { |pin| pin.path == path }
559
+ stack = rest_of_stack api_map
394
560
  return nil if stack.empty?
395
561
  stack.each do |pin|
396
562
  return pin.return_type unless pin.return_type.undefined?
@@ -402,11 +568,11 @@ module Solargraph
402
568
  # @param api_map [ApiMap]
403
569
  # @return [ComplexType, nil]
404
570
  def resolve_reference ref, api_map
405
- parts = ref.split(/[\.#]/)
571
+ parts = ref.split(/[.#]/)
406
572
  if parts.first.empty? || parts.one?
407
573
  path = "#{namespace}#{ref}"
408
574
  else
409
- fqns = api_map.qualify(parts.first, namespace)
575
+ fqns = api_map.qualify(parts.first, *gates)
410
576
  return ComplexType::UNDEFINED if fqns.nil?
411
577
  path = fqns + ref[parts.first.length] + parts.last
412
578
  end
@@ -452,7 +618,7 @@ module Solargraph
452
618
  end
453
619
  result.push ComplexType::NIL if has_nil
454
620
  return ComplexType::UNDEFINED if result.empty?
455
- ComplexType.try_parse(*result.map(&:tag).uniq)
621
+ ComplexType.new(result.uniq)
456
622
  end
457
623
 
458
624
  # @param [ApiMap] api_map
@@ -467,7 +633,7 @@ module Solargraph
467
633
  types.push type if type.defined?
468
634
  end
469
635
  return ComplexType::UNDEFINED if types.empty?
470
- ComplexType.try_parse(*types.map(&:tag).uniq)
636
+ ComplexType.new(types.uniq)
471
637
  end
472
638
 
473
639
  # When YARD parses an overload tag, it includes rest modifiers in the parameters names.
@@ -475,6 +641,7 @@ module Solargraph
475
641
  # @param name [String]
476
642
  # @return [::Array(String, ::Symbol)]
477
643
  def parse_overload_param(name)
644
+ # @todo this needs to handle mandatory vs not args, kwargs, blocks, etc
478
645
  if name.start_with?('**')
479
646
  [name[2..-1], :kwrestarg]
480
647
  elsif name.start_with?('*')
@@ -496,6 +663,10 @@ module Solargraph
496
663
  .join("\n")
497
664
  .concat("```\n")
498
665
  end
666
+
667
+ protected
668
+
669
+ attr_writer :return_type
499
670
  end
500
671
  end
501
672
  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
- "#{@type.to_s} #{generics_as_rbs}#{return_type.to_rbs}"
52
+ "#{@type.to_s} #{return_type.all_params.first.to_rbs}#{rbs_generics}".strip
45
53
  end
46
54
 
47
- def desc
48
- if name.nil?
55
+ def inner_desc
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
 
@@ -57,7 +65,7 @@ module Solargraph
57
65
  end
58
66
 
59
67
  def full_context
60
- @full_context ||= ComplexType.try_parse("#{type.to_s.capitalize}<#{path}>")
68
+ @full_context ||= ComplexType.try_parse("::#{type.to_s.capitalize}<#{path}>")
61
69
  end
62
70
 
63
71
  def binder
@@ -83,7 +91,7 @@ module Solargraph
83
91
  end
84
92
 
85
93
  def return_type
86
- @return_type ||= ComplexType.try_parse( (type == :class ? 'Class' : 'Module') + "<#{path}>" )
94
+ @return_type ||= ComplexType.try_parse( (type == :class ? '::Class' : '::Module') + "<::#{path}>")
87
95
  end
88
96
 
89
97
  # @return [Array<String>]