solargraph 0.58.3 → 0.60.4

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 (238) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +12 -5
  4. data/.github/workflows/plugins.yml +53 -37
  5. data/.github/workflows/rspec.yml +18 -28
  6. data/.github/workflows/typecheck.yml +6 -3
  7. data/.rubocop.yml +39 -6
  8. data/.rubocop_todo.yml +53 -966
  9. data/CHANGELOG.md +67 -0
  10. data/Gemfile +6 -1
  11. data/README.md +3 -3
  12. data/Rakefile +26 -23
  13. data/bin/solargraph +2 -1
  14. data/lib/solargraph/api_map/cache.rb +3 -3
  15. data/lib/solargraph/api_map/constants.rb +13 -4
  16. data/lib/solargraph/api_map/index.rb +42 -20
  17. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  18. data/lib/solargraph/api_map/store.rb +61 -36
  19. data/lib/solargraph/api_map.rb +191 -78
  20. data/lib/solargraph/bench.rb +2 -3
  21. data/lib/solargraph/complex_type/conformance.rb +176 -0
  22. data/lib/solargraph/complex_type/type_methods.rb +31 -18
  23. data/lib/solargraph/complex_type/unique_type.rb +225 -63
  24. data/lib/solargraph/complex_type.rb +190 -59
  25. data/lib/solargraph/convention/active_support_concern.rb +111 -111
  26. data/lib/solargraph/convention/base.rb +50 -50
  27. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
  28. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  29. data/lib/solargraph/convention/data_definition.rb +5 -2
  30. data/lib/solargraph/convention/gemfile.rb +1 -1
  31. data/lib/solargraph/convention/gemspec.rb +1 -1
  32. data/lib/solargraph/convention/rakefile.rb +1 -1
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  35. data/lib/solargraph/convention/struct_definition.rb +8 -4
  36. data/lib/solargraph/convention.rb +2 -2
  37. data/lib/solargraph/converters/dd.rb +2 -0
  38. data/lib/solargraph/converters/dl.rb +2 -0
  39. data/lib/solargraph/converters/dt.rb +2 -0
  40. data/lib/solargraph/converters/misc.rb +2 -0
  41. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  42. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  43. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  44. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  45. data/lib/solargraph/diagnostics/update_errors.rb +4 -8
  46. data/lib/solargraph/diagnostics.rb +55 -55
  47. data/lib/solargraph/doc_map.rb +39 -39
  48. data/lib/solargraph/environ.rb +52 -52
  49. data/lib/solargraph/equality.rb +4 -4
  50. data/lib/solargraph/gem_pins.rb +4 -15
  51. data/lib/solargraph/language_server/error_codes.rb +10 -10
  52. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  53. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  54. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  55. data/lib/solargraph/language_server/host/sources.rb +2 -1
  56. data/lib/solargraph/language_server/host.rb +35 -28
  57. data/lib/solargraph/language_server/message/base.rb +1 -1
  58. data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
  59. data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
  60. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  61. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  62. data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -7
  63. data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
  64. data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
  65. data/lib/solargraph/language_server/message/extended/search.rb +1 -1
  66. data/lib/solargraph/language_server/message/initialize.rb +20 -14
  67. data/lib/solargraph/language_server/message/initialized.rb +28 -28
  68. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  69. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  70. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +17 -10
  71. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  72. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  73. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  74. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +13 -6
  75. data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
  76. data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
  77. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  78. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  79. data/lib/solargraph/language_server/message/text_document.rb +28 -28
  80. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
  81. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
  82. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
  83. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  84. data/lib/solargraph/language_server/message.rb +1 -1
  85. data/lib/solargraph/language_server/progress.rb +143 -143
  86. data/lib/solargraph/language_server/request.rb +4 -2
  87. data/lib/solargraph/language_server/transport/adapter.rb +68 -68
  88. data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
  89. data/lib/solargraph/language_server/uri_helpers.rb +2 -2
  90. data/lib/solargraph/language_server.rb +20 -20
  91. data/lib/solargraph/library.rb +63 -40
  92. data/lib/solargraph/location.rb +17 -14
  93. data/lib/solargraph/logging.rb +22 -4
  94. data/lib/solargraph/page.rb +1 -1
  95. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  96. data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -108
  97. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  98. data/lib/solargraph/parser/node_processor.rb +8 -7
  99. data/lib/solargraph/parser/parser_gem/class_methods.rb +30 -14
  100. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
  101. data/lib/solargraph/parser/parser_gem/node_chainer.rb +51 -25
  102. data/lib/solargraph/parser/parser_gem/node_methods.rb +222 -72
  103. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
  104. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  105. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  106. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  107. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -12
  108. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
  109. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
  110. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  111. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
  112. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
  113. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  114. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  115. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  116. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  117. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +73 -40
  118. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  119. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  120. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  121. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  122. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  123. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  124. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
  125. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
  126. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  127. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  128. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  129. data/lib/solargraph/parser/parser_gem.rb +2 -0
  130. data/lib/solargraph/parser/region.rb +9 -3
  131. data/lib/solargraph/parser/snippet.rb +3 -1
  132. data/lib/solargraph/parser.rb +2 -0
  133. data/lib/solargraph/pin/base.rb +157 -85
  134. data/lib/solargraph/pin/base_variable.rb +273 -24
  135. data/lib/solargraph/pin/block.rb +29 -6
  136. data/lib/solargraph/pin/breakable.rb +7 -1
  137. data/lib/solargraph/pin/callable.rb +67 -23
  138. data/lib/solargraph/pin/closure.rb +7 -10
  139. data/lib/solargraph/pin/common.rb +36 -6
  140. data/lib/solargraph/pin/compound_statement.rb +55 -0
  141. data/lib/solargraph/pin/constant.rb +3 -5
  142. data/lib/solargraph/pin/conversions.rb +10 -4
  143. data/lib/solargraph/pin/delegated_method.rb +19 -8
  144. data/lib/solargraph/pin/documenting.rb +4 -2
  145. data/lib/solargraph/pin/instance_variable.rb +5 -1
  146. data/lib/solargraph/pin/keyword.rb +0 -4
  147. data/lib/solargraph/pin/local_variable.rb +15 -59
  148. data/lib/solargraph/pin/method.rb +208 -113
  149. data/lib/solargraph/pin/method_alias.rb +8 -0
  150. data/lib/solargraph/pin/namespace.rb +19 -12
  151. data/lib/solargraph/pin/parameter.rb +102 -36
  152. data/lib/solargraph/pin/proxy_type.rb +4 -1
  153. data/lib/solargraph/pin/reference/override.rb +1 -1
  154. data/lib/solargraph/pin/reference/require.rb +14 -14
  155. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  156. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  157. data/lib/solargraph/pin/reference.rb +20 -0
  158. data/lib/solargraph/pin/search.rb +8 -7
  159. data/lib/solargraph/pin/signature.rb +15 -12
  160. data/lib/solargraph/pin/singleton.rb +11 -11
  161. data/lib/solargraph/pin/symbol.rb +2 -1
  162. data/lib/solargraph/pin/until.rb +2 -4
  163. data/lib/solargraph/pin/while.rb +2 -4
  164. data/lib/solargraph/pin.rb +2 -0
  165. data/lib/solargraph/pin_cache.rb +22 -19
  166. data/lib/solargraph/position.rb +17 -10
  167. data/lib/solargraph/range.rb +16 -15
  168. data/lib/solargraph/rbs_map/conversions.rb +227 -238
  169. data/lib/solargraph/rbs_map/core_fills.rb +18 -11
  170. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  171. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  172. data/lib/solargraph/rbs_map.rb +76 -32
  173. data/lib/solargraph/rbs_translator.rb +206 -0
  174. data/lib/solargraph/server_methods.rb +1 -1
  175. data/lib/solargraph/shell.rb +330 -71
  176. data/lib/solargraph/source/chain/array.rb +3 -12
  177. data/lib/solargraph/source/chain/block_symbol.rb +13 -13
  178. data/lib/solargraph/source/chain/block_variable.rb +13 -13
  179. data/lib/solargraph/source/chain/call.rb +159 -89
  180. data/lib/solargraph/source/chain/class_variable.rb +1 -1
  181. data/lib/solargraph/source/chain/constant.rb +5 -1
  182. data/lib/solargraph/source/chain/global_variable.rb +1 -1
  183. data/lib/solargraph/source/chain/hash.rb +8 -5
  184. data/lib/solargraph/source/chain/head.rb +19 -19
  185. data/lib/solargraph/source/chain/if.rb +12 -10
  186. data/lib/solargraph/source/chain/instance_variable.rb +19 -1
  187. data/lib/solargraph/source/chain/link.rb +12 -22
  188. data/lib/solargraph/source/chain/literal.rb +22 -15
  189. data/lib/solargraph/source/chain/or.rb +10 -4
  190. data/lib/solargraph/source/chain/q_call.rb +2 -0
  191. data/lib/solargraph/source/chain/variable.rb +3 -1
  192. data/lib/solargraph/source/chain/z_super.rb +1 -3
  193. data/lib/solargraph/source/chain.rb +87 -43
  194. data/lib/solargraph/source/change.rb +12 -5
  195. data/lib/solargraph/source/cursor.rb +33 -18
  196. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  197. data/lib/solargraph/source/source_chainer.rb +56 -32
  198. data/lib/solargraph/source/updater.rb +5 -1
  199. data/lib/solargraph/source.rb +71 -43
  200. data/lib/solargraph/source_map/clip.rb +54 -30
  201. data/lib/solargraph/source_map/data.rb +4 -1
  202. data/lib/solargraph/source_map/mapper.rb +30 -133
  203. data/lib/solargraph/source_map.rb +35 -9
  204. data/lib/solargraph/type_checker/problem.rb +3 -1
  205. data/lib/solargraph/type_checker/rules.rb +81 -8
  206. data/lib/solargraph/type_checker.rb +208 -125
  207. data/lib/solargraph/version.rb +1 -1
  208. data/lib/solargraph/workspace/config.rb +14 -11
  209. data/lib/solargraph/workspace/gemspecs.rb +373 -0
  210. data/lib/solargraph/workspace/require_paths.rb +1 -0
  211. data/lib/solargraph/workspace.rb +50 -28
  212. data/lib/solargraph/yard_map/cache.rb +25 -25
  213. data/lib/solargraph/yard_map/directives/attribute_directive.rb +65 -0
  214. data/lib/solargraph/yard_map/directives/domain_directive.rb +30 -0
  215. data/lib/solargraph/yard_map/directives/method_directive.rb +51 -0
  216. data/lib/solargraph/yard_map/directives/override_directive.rb +30 -0
  217. data/lib/solargraph/yard_map/directives/parse_directive.rb +53 -0
  218. data/lib/solargraph/yard_map/directives/visibility_directive.rb +70 -0
  219. data/lib/solargraph/yard_map/directives.rb +35 -0
  220. data/lib/solargraph/yard_map/helpers.rb +8 -3
  221. data/lib/solargraph/yard_map/macro.rb +113 -0
  222. data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
  223. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  224. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  225. data/lib/solargraph/yard_map/mapper.rb +65 -9
  226. data/lib/solargraph/yard_map.rb +19 -18
  227. data/lib/solargraph/yard_tags.rb +2 -2
  228. data/lib/solargraph/yardoc.rb +7 -4
  229. data/lib/solargraph.rb +34 -10
  230. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  231. data/rbs/shims/ast/0/node.rbs +1 -1
  232. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  233. data/solargraph.gemspec +39 -35
  234. metadata +77 -41
  235. data/lib/solargraph/type_checker/checks.rb +0 -124
  236. data/lib/solargraph/type_checker/param_def.rb +0 -37
  237. data/lib/solargraph/yard_map/to_method.rb +0 -89
  238. data/rbs/fills/tuple/tuple.rbs +0 -149
@@ -22,8 +22,10 @@ module Solargraph
22
22
  # @param attribute [Boolean]
23
23
  # @param signatures [::Array<Signature>, nil]
24
24
  # @param anon_splat [Boolean]
25
+ # @param context [ComplexType, ComplexType::UniqueType, nil]
26
+ # @param [Hash{Symbol => Object}] splat
25
27
  def initialize visibility: :public, explicit: true, block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false,
26
- **splat
28
+ context: nil, **splat
27
29
  super(**splat)
28
30
  @visibility = visibility
29
31
  @explicit = explicit
@@ -32,31 +34,12 @@ module Solargraph
32
34
  @attribute = attribute
33
35
  @signatures = signatures
34
36
  @anon_splat = anon_splat
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
37
+ @context = context if context
55
38
  end
56
39
 
57
40
  # @param other [Pin::Method]
58
41
  # @return [::Symbol]
59
- def combine_visibility(other)
42
+ def combine_visibility other
60
43
  if dodgy_visibility_source? && !other.dodgy_visibility_source?
61
44
  other.visibility
62
45
  elsif other.dodgy_visibility_source? && !dodgy_visibility_source?
@@ -66,33 +49,18 @@ module Solargraph
66
49
  end
67
50
  end
68
51
 
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 = {})
52
+ def combine_with other, attrs = {}
84
53
  priority_choice = choose_priority(other)
85
54
  return priority_choice unless priority_choice.nil?
86
55
 
87
56
  sigs = combine_signatures(other)
88
- parameters = if sigs.length > 0
89
- [].freeze
90
- else
91
- choose(other, :parameters).clone.freeze
92
- end
57
+ parameters = if sigs.length.positive?
58
+ [].freeze
59
+ else
60
+ choose(other, :parameters).clone.freeze
61
+ end
93
62
  new_attrs = {
94
63
  visibility: combine_visibility(other),
95
- # @sg-ignore https://github.com/castwide/solargraph/pull/1050
96
64
  explicit: explicit? || other.explicit?,
97
65
  block: combine_blocks(other),
98
66
  node: choose_node(other, :node),
@@ -110,7 +78,7 @@ module Solargraph
110
78
  super && other.node == node
111
79
  end
112
80
 
113
- def transform_types(&transform)
81
+ def transform_types &transform
114
82
  # @todo 'super' alone should work here I think, but doesn't typecheck at level typed
115
83
  m = super(&transform)
116
84
  m.signatures = m.signatures.map do |sig|
@@ -125,14 +93,12 @@ module Solargraph
125
93
  def reset_generated!
126
94
  super
127
95
  unless signatures.empty?
128
- return_type = nil
129
96
  @block = :undefined
130
- parameters = []
97
+ []
131
98
  end
132
99
  block&.reset_generated!
133
100
  @signatures&.each(&:reset_generated!)
134
- signature_help = nil
135
- documentation = nil
101
+ nil
136
102
  end
137
103
 
138
104
  def all_rooted?
@@ -141,7 +107,7 @@ module Solargraph
141
107
 
142
108
  # @param signature [Pin::Signature]
143
109
  # @return [Pin::Method]
144
- def with_single_signature(signature)
110
+ def with_single_signature signature
145
111
  m = proxy signature.return_type
146
112
  m.reset_generated!
147
113
  # @todo populating the single parameters/return_type/block
@@ -160,6 +126,8 @@ module Solargraph
160
126
  !block.nil?
161
127
  end
162
128
 
129
+ # @sg-ignore flow sensitive typing needs to remove literal with
130
+ # this unless block
163
131
  # @return [Pin::Signature, nil]
164
132
  def block
165
133
  return @block unless @block == :undefined
@@ -175,16 +143,18 @@ module Solargraph
175
143
  end
176
144
 
177
145
  def return_type
178
- @return_type ||= ComplexType.new(signatures.map(&:return_type).flat_map(&:items))
146
+ @return_type ||= return_type_from_inline_rbs || ComplexType.new(signatures.map(&:return_type).flat_map(&:items))
179
147
  end
180
148
 
181
149
  # @param parameters [::Array<Parameter>]
182
- # @param return_type [ComplexType]
150
+ # @param return_type [ComplexType, nil]
151
+ # @param tag_docstring [YARD::Docstring] source of @yieldparam/@yieldreturn tags; pass an @overload tag's own docstring here
183
152
  # @return [Signature]
184
- def generate_signature(parameters, return_type)
153
+ def generate_signature parameters, return_type, tag_docstring = docstring
154
+ # @type [Pin::Signature, nil]
185
155
  block = nil
186
- yieldparam_tags = docstring.tags(:yieldparam)
187
- yieldreturn_tags = docstring.tags(:yieldreturn)
156
+ yieldparam_tags = tag_docstring.tags(:yieldparam)
157
+ yieldreturn_tags = tag_docstring.tags(:yieldreturn)
188
158
  generics = docstring.tags(:generic).map(&:name)
189
159
  needs_block_param_signature =
190
160
  parameters.last&.block? || !yieldreturn_tags.empty? || !yieldparam_tags.empty?
@@ -202,7 +172,7 @@ module Solargraph
202
172
  comments: p.text,
203
173
  name: name,
204
174
  decl: decl,
205
- presence: location ? location.range : nil,
175
+ presence: location&.range,
206
176
  return_type: ComplexType.try_parse(*p.types),
207
177
  source: source
208
178
  )
@@ -219,14 +189,11 @@ module Solargraph
219
189
 
220
190
  # @return [::Array<Signature>]
221
191
  def signatures
222
- @signatures ||= begin
223
- top_type = generate_complex_type
224
- result = []
225
- result.push generate_signature(parameters, top_type) if top_type.defined?
226
- result.concat(overloads.map { |meth| generate_signature(meth.parameters, meth.return_type) }) unless overloads.empty?
227
- result.push generate_signature(parameters, @return_type || ComplexType::UNDEFINED) if result.empty?
228
- result
229
- end
192
+ @signatures ||= if inline_rbs.empty?
193
+ signatures_from_yard
194
+ else
195
+ signatures_from_inline_rbs
196
+ end
230
197
  end
231
198
 
232
199
  # @param return_type [ComplexType]
@@ -243,11 +210,18 @@ module Solargraph
243
210
  # change when pins get proxied.
244
211
  detail = String.new
245
212
  detail += if signatures.length > 1
246
- "(*) "
247
- else
248
- "(#{signatures.first.parameters.map(&:full).join(', ')}) " unless signatures.first.parameters.empty?
249
- end.to_s
250
- detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
213
+ '(*) '
214
+ else
215
+ "(#{signatures.first.parameters.map(&:full).join(', ')}) " unless signatures.first.parameters.empty?
216
+ end.to_s
217
+ # @sg-ignore Need to add nil check here
218
+ unless return_type.undefined?
219
+ detail += "=#{if probed?
220
+ '~'
221
+ else
222
+ (proxied? ? '^' : '>')
223
+ end} #{return_type}"
224
+ end
251
225
  detail.strip!
252
226
  return nil if detail.empty?
253
227
  detail
@@ -257,7 +231,7 @@ module Solargraph
257
231
  def signature_help
258
232
  @signature_help ||= signatures.map do |sig|
259
233
  {
260
- label: name + '(' + sig.parameters.map(&:full).join(', ') + ')',
234
+ label: "#{name}(#{sig.parameters.map(&:full).join(', ')})",
261
235
  documentation: documentation
262
236
  }
263
237
  end
@@ -276,6 +250,7 @@ module Solargraph
276
250
  return nil if signatures.empty?
277
251
 
278
252
  rbs = "def #{name}: #{signatures.first.to_rbs}"
253
+ # @sg-ignore Need to add nil check here
279
254
  signatures[1..].each do |sig|
280
255
  rbs += "\n"
281
256
  rbs += (' ' * (4 + name.length))
@@ -285,7 +260,7 @@ module Solargraph
285
260
  end
286
261
 
287
262
  def path
288
- @path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}"
263
+ @path ||= "#{namespace}#{scope == :instance ? '#' : '.'}#{name}"
289
264
  end
290
265
 
291
266
  # @return [String]
@@ -294,15 +269,33 @@ module Solargraph
294
269
  end
295
270
 
296
271
  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" }
298
- decl = super
272
+ logger.debug do
273
+ # @sg-ignore Need to add nil check here
274
+ "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context.rooted_tags}, return_type=#{return_type.rooted_tags}) - starting"
275
+ end
276
+ decl = if macro_names?
277
+ types = macro_names.flat_map do |mac|
278
+ directive = api_map.named_macro(mac)
279
+ next unless directive
280
+ macro = Solargraph::YardMap::Macro.from_directive(directive, self)
281
+ expanded = macro.macro_object.expand([name, *parameter_names])
282
+ docstring = Solargraph::Source.parse_docstring(expanded).to_docstring
283
+ docstring.tags(:return).flat_map(&:types)
284
+ end
285
+ ComplexType.try_parse(*types)
286
+ else
287
+ super
288
+ end
299
289
  unless decl.undefined?
300
- logger.debug { "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context}) => #{decl.rooted_tags.inspect} - decl found" }
290
+ logger.debug do
291
+ "Method#typify(self=#{self}, binder=#{binder}, closure=#{closure}, context=#{context}) => #{decl.rooted_tags.inspect} - decl found"
292
+ end
301
293
  return decl
302
294
  end
303
295
  type = see_reference(api_map) || typify_from_super(api_map)
304
296
  logger.debug { "Method#typify(self=#{self}) - type=#{type&.rooted_tags.inspect}" }
305
297
  unless type.nil?
298
+ # @sg-ignore Need to add nil check here
306
299
  qualified = type.qualify(api_map, *closure.gates)
307
300
  logger.debug { "Method#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
308
301
  return qualified
@@ -314,26 +307,26 @@ module Solargraph
314
307
  if @documentation.nil?
315
308
  method_docs ||= super || ''
316
309
  param_tags = docstring.tags(:param)
317
- unless param_tags.nil? or param_tags.empty?
310
+ unless param_tags.nil? || param_tags.empty?
318
311
  method_docs += "\n\n" unless method_docs.empty?
319
312
  method_docs += "Params:\n"
320
313
  lines = []
321
314
  param_tags.each do |p|
322
315
  l = "* #{p.name}"
323
- l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? or p.types.empty?
316
+ l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? || p.types.empty?
324
317
  l += " #{p.text}"
325
318
  lines.push l
326
319
  end
327
320
  method_docs += lines.join("\n")
328
321
  end
329
322
  yieldparam_tags = docstring.tags(:yieldparam)
330
- unless yieldparam_tags.nil? or yieldparam_tags.empty?
323
+ unless yieldparam_tags.nil? || yieldparam_tags.empty?
331
324
  method_docs += "\n\n" unless method_docs.empty?
332
325
  method_docs += "Block Params:\n"
333
326
  lines = []
334
327
  yieldparam_tags.each do |p|
335
328
  l = "* #{p.name}"
336
- l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? or p.types.empty?
329
+ l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? || p.types.empty?
337
330
  l += " #{p.text}"
338
331
  lines.push l
339
332
  end
@@ -345,8 +338,8 @@ module Solargraph
345
338
  method_docs += "Block Returns:\n"
346
339
  lines = []
347
340
  yieldreturn_tags.each do |r|
348
- l = "*"
349
- l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty?
341
+ l = '*'
342
+ l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? || r.types.empty?
350
343
  l += " #{r.text}"
351
344
  lines.push l
352
345
  end
@@ -358,8 +351,8 @@ module Solargraph
358
351
  method_docs += "Returns:\n"
359
352
  lines = []
360
353
  return_tags.each do |r|
361
- l = "*"
362
- l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty?
354
+ l = '*'
355
+ l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? || r.types.empty?
363
356
  l += " #{r.text}"
364
357
  lines.push l
365
358
  end
@@ -396,7 +389,7 @@ module Solargraph
396
389
  attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
397
390
  end
398
391
 
399
- # @return [::Array<Pin::Method>]
392
+ # @return [::Array<Pin::Signature>]
400
393
  def overloads
401
394
  # Ignore overload tags with nil parameters. If it's not an array, the
402
395
  # tag's source is likely malformed.
@@ -414,14 +407,14 @@ module Solargraph
414
407
  comments: tag.docstring.all.to_s,
415
408
  name: name,
416
409
  decl: decl,
417
- presence: location ? location.range : nil,
410
+ presence: location&.range,
418
411
  return_type: param_type_from_name(tag, src.first),
419
412
  source: :overloads
420
413
  )
421
414
  end,
422
415
  closure: self,
423
416
  return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types)),
424
- source: :overloads,
417
+ source: :overloads
425
418
  )
426
419
  end
427
420
  @overloads
@@ -440,13 +433,13 @@ module Solargraph
440
433
  return self unless docstring.ref_tags.any?
441
434
  docstring.ref_tags.each do |tag|
442
435
  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
436
+ api_map.get_methods(namespace)
437
+ .select { |pin| pin.path.end_with?(tag.owner.to_s) }
438
+ .first
439
+ else
440
+ # @todo Resolve relative namespaces
441
+ api_map.get_path_pins(tag.owner.to_s).first
442
+ end
450
443
  next unless ref
451
444
 
452
445
  docstring.add_tag(*ref.docstring.tags(:param))
@@ -462,29 +455,93 @@ module Solargraph
462
455
 
463
456
  protected
464
457
 
465
- attr_writer :block
466
-
467
- attr_writer :signature_help
468
-
469
- attr_writer :documentation
458
+ attr_writer :block, :signature_help, :documentation, :return_type
470
459
 
471
460
  def dodgy_visibility_source?
472
461
  # as of 2025-03-12, the RBS generator used for
473
462
  # e.g. activesupport did not understand 'private' markings
474
463
  # inside 'class << self' blocks, but YARD did OK at it
475
- source == :rbs && scope == :class && type_location&.filename&.include?('generated') && return_type.undefined? ||
464
+ # @sg-ignore Need to add nil check here
465
+ (source == :rbs && scope == :class && type_location&.filename&.include?('generated') && return_type.undefined?) ||
476
466
  # YARD's RBS generator seems to miss a lot of should-be protected instance methods
477
- source == :rbs && scope == :instance && namespace.start_with?('YARD::') ||
467
+ (source == :rbs && scope == :instance && namespace.start_with?('YARD::')) ||
478
468
  # private on attr_readers seems to be broken in Prism's auto-generator script
479
- source == :rbs && scope == :instance && namespace.start_with?('Prism::') ||
469
+ (source == :rbs && scope == :instance && namespace.start_with?('Prism::')) ||
480
470
  # The RBS for the RBS gem itself seems to use private as a
481
471
  # 'is this a public API' concept, more aggressively than the
482
472
  # actual code. Let's respect that and ignore the actual .rb file.
483
- source == :yardoc && scope == :instance && namespace.start_with?('RBS::')
473
+ (source == :yardoc && scope == :instance && namespace.start_with?('RBS::'))
484
474
  end
485
475
 
486
476
  private
487
477
 
478
+ # @param other [Pin::Method]
479
+ # @return [Array<Pin::Signature>]
480
+ def combine_signatures other
481
+ all_undefined = signatures.all? { |sig| !sig.return_type&.defined? }
482
+ other_all_undefined = other.signatures.all? { |sig| !sig.return_type&.defined? }
483
+ if all_undefined && !other_all_undefined
484
+ other.signatures
485
+ elsif other_all_undefined && !all_undefined
486
+ signatures
487
+ else
488
+ combine_signatures_by_type_arity(*signatures, *other.signatures)
489
+ end
490
+ end
491
+
492
+ # @param signature_pins [Array<Pin::Signature>]
493
+ #
494
+ # @return [Array<Pin::Signature>]
495
+ def combine_signatures_by_type_arity(*signature_pins)
496
+ # @type [Hash{Array => Array<Pin::Signature>}]
497
+ by_type_arity = {}
498
+ signature_pins.each do |signature_pin|
499
+ by_type_arity[signature_pin.type_arity] ||= []
500
+ by_type_arity[signature_pin.type_arity] << signature_pin
501
+ end
502
+
503
+ by_type_arity.transform_values! do |same_type_arity_signatures|
504
+ combine_same_type_arity_signatures same_type_arity_signatures
505
+ end
506
+ by_type_arity.values.flatten
507
+ end
508
+
509
+ # @param same_type_arity_signatures [Array<Pin::Signature>]
510
+ #
511
+ # @return [Array<Pin::Signature>]
512
+ def combine_same_type_arity_signatures same_type_arity_signatures
513
+ # This is an O(n^2) operation, so bail out if n is not small
514
+ return same_type_arity_signatures if same_type_arity_signatures.length > 10
515
+
516
+ # @param old_signatures [Array<Pin::Signature>]
517
+ # @param new_signature [Pin::Signature]
518
+ same_type_arity_signatures.reduce([]) do |old_signatures, new_signature|
519
+ next old_signatures + [new_signature] if old_signatures.empty?
520
+
521
+ merged = false
522
+ combined = old_signatures.map do |old_signature|
523
+ potential_new_signature = old_signature.combine_with(new_signature)
524
+
525
+ if potential_new_signature.type_arity == old_signature.type_arity
526
+ # the number of types in each parameter and return type
527
+ # match, so we found compatible signatures to merge. If
528
+ # we increased the number of types, we'd potentially
529
+ # have taken away the ability to use parameter types to
530
+ # choose the correct return type (while Ruby doesn't
531
+ # dispatch based on type, RBS does distinguish overloads
532
+ # based on types, not just arity, allowing for type
533
+ # information describing how methods behave based on
534
+ # their input types)
535
+ merged = true
536
+ potential_new_signature
537
+ else
538
+ old_signature
539
+ end
540
+ end
541
+ merged ? combined : old_signatures + [new_signature]
542
+ end
543
+ end
544
+
488
545
  # @param name [String]
489
546
  # @param asgn [Boolean]
490
547
  #
@@ -517,7 +574,7 @@ module Solargraph
517
574
  # @param name [String]
518
575
  #
519
576
  # @return [ComplexType]
520
- def param_type_from_name(tag, name)
577
+ def param_type_from_name tag, name
521
578
  # @param t [YARD::Tags::Tag]
522
579
  param = tag.tags(:param).select { |t| t.name == name }.first
523
580
  return ComplexType::UNDEFINED unless param
@@ -528,23 +585,24 @@ module Solargraph
528
585
  def generate_complex_type
529
586
  tags = docstring.tags(:return).map(&:types).flatten.compact
530
587
  return ComplexType::UNDEFINED if tags.empty?
531
- ComplexType.try_parse *tags
588
+ ComplexType.try_parse(*tags)
532
589
  end
533
590
 
534
591
  # @param api_map [ApiMap]
535
- # @return [ComplexType, nil]
592
+ # @return [ComplexType, ComplexType::UniqueType, nil]
536
593
  def see_reference api_map
537
594
  # This should actually be an intersection type
538
- # @param ref [YARD::Tags::Tag, Solargraph::Yard::Tags::RefTag]
595
+ # @param ref [YARD::Tags::Tag, YARD::Tags::RefTag]
539
596
  docstring.ref_tags.each do |ref|
540
597
  # @sg-ignore ref should actually be an intersection type
541
598
  next unless ref.tag_name == 'return' && ref.owner
542
- # @sg-ignore ref should actually be an intersection type
599
+ # @sg-ignore should actually be an intersection type
543
600
  result = resolve_reference(ref.owner.to_s, api_map)
544
601
  return result unless result.nil?
545
602
  end
546
603
  match = comments.match(/^[ \t]*\(see (.*)\)/m)
547
604
  return nil if match.nil?
605
+ # @sg-ignore Need to add nil check here
548
606
  resolve_reference match[1], api_map
549
607
  end
550
608
 
@@ -559,6 +617,7 @@ module Solargraph
559
617
  stack = rest_of_stack api_map
560
618
  return nil if stack.empty?
561
619
  stack.each do |pin|
620
+ # @sg-ignore Need to add nil check here
562
621
  return pin.return_type unless pin.return_type.undefined?
563
622
  end
564
623
  nil
@@ -566,7 +625,7 @@ module Solargraph
566
625
 
567
626
  # @param ref [String]
568
627
  # @param api_map [ApiMap]
569
- # @return [ComplexType, nil]
628
+ # @return [ComplexType, ComplexType::UniqueType, nil]
570
629
  def resolve_reference ref, api_map
571
630
  parts = ref.split(/[.#]/)
572
631
  if parts.first.empty? || parts.one?
@@ -574,6 +633,7 @@ module Solargraph
574
633
  else
575
634
  fqns = api_map.qualify(parts.first, *gates)
576
635
  return ComplexType::UNDEFINED if fqns.nil?
636
+ # @sg-ignore Need to add nil check here
577
637
  path = fqns + ref[parts.first.length] + parts.last
578
638
  end
579
639
  pins = api_map.get_path_pins(path)
@@ -589,7 +649,7 @@ module Solargraph
589
649
  return nil if node.nil?
590
650
  return node.children[1].children.last if node.type == :DEFN
591
651
  return node.children[2].children.last if node.type == :DEFS
592
- return node.children[2] if node.type == :def || node.type == :DEFS
652
+ return node.children[2] if %i[def DEFS].include?(node.type)
593
653
  return node.children[3] if node.type == :defs
594
654
  nil
595
655
  end
@@ -602,16 +662,18 @@ module Solargraph
602
662
  has_nil = false
603
663
  return ComplexType::NIL if method_body_node.nil?
604
664
  returns_from_method_body(method_body_node).each do |n|
605
- if n.nil? || [:NIL, :nil].include?(n.type)
665
+ if n.nil? || %i[NIL nil].include?(n.type)
606
666
  has_nil = true
607
667
  next
608
668
  end
609
669
  rng = Range.from_node(n)
610
670
  next unless rng
611
671
  clip = api_map.clip_at(
672
+ # @sg-ignore Need to add nil check here
612
673
  location.filename,
613
674
  rng.ending
614
675
  )
676
+ # @sg-ignore Need to add nil check here
615
677
  chain = Solargraph::Parser.chain(n, location.filename)
616
678
  type = chain.infer(api_map, self, clip.locals)
617
679
  result.push type unless type.undefined?
@@ -640,12 +702,12 @@ module Solargraph
640
702
  #
641
703
  # @param name [String]
642
704
  # @return [::Array(String, ::Symbol)]
643
- def parse_overload_param(name)
705
+ def parse_overload_param name
644
706
  # @todo this needs to handle mandatory vs not args, kwargs, blocks, etc
645
707
  if name.start_with?('**')
646
- [name[2..-1], :kwrestarg]
708
+ [name[2..], :kwrestarg]
647
709
  elsif name.start_with?('*')
648
- [name[1..-1], :restarg]
710
+ [name[1..], :restarg]
649
711
  else
650
712
  [name, :arg]
651
713
  end
@@ -664,9 +726,42 @@ module Solargraph
664
726
  .concat("```\n")
665
727
  end
666
728
 
667
- protected
729
+ # @return [ComplexType, nil]
730
+ def return_type_from_inline_rbs
731
+ return nil if inline_rbs.empty?
732
+ method_type = RBS::Parser.parse_method_type(inline_rbs)
733
+ RbsTranslator.to_complex_type(method_type.type.return_type)
734
+ rescue RBS::ParsingError
735
+ nil
736
+ end
668
737
 
669
- attr_writer :return_type
738
+ # @return [Array<Pin::Signature>]
739
+ def signatures_from_inline_rbs
740
+ method_type = RBS::Parser.parse_method_type(inline_rbs)
741
+ [RbsTranslator.to_signature(method_type, self, parameter_names)]
742
+ rescue RBS::ParsingError
743
+ signatures_from_yard
744
+ end
745
+
746
+ # @return [Array<Pin::Signature>]
747
+ def signatures_from_yard
748
+ top_type = generate_complex_type
749
+ result = []
750
+ result.push generate_signature(parameters, top_type) if top_type.defined?
751
+ # @param meth [Pin::Signature]
752
+ # @param tag [YARD::Tags::OverloadTag]
753
+ result.concat(overloads.zip(docstring.tags(:overload).select(&:parameters)).map { |meth, tag| generate_signature(meth.parameters, meth.return_type, tag.docstring) }) unless overloads.empty?
754
+ result.push generate_signature(parameters, @return_type || ComplexType::UNDEFINED) if result.empty?
755
+ result
756
+ end
757
+
758
+ # @return [String]
759
+ def inline_rbs
760
+ comments.lines
761
+ .select { |line| line.start_with?(': ') }
762
+ .map { |line| line[2..].strip }
763
+ .join("\n")
764
+ end
670
765
  end
671
766
  end
672
767
  end
@@ -26,6 +26,14 @@ module Solargraph
26
26
  :public
27
27
  end
28
28
 
29
+ def to_rbs
30
+ if scope == :class
31
+ "alias self.#{name} self.#{original}"
32
+ else
33
+ "alias #{name} #{original}"
34
+ end
35
+ end
36
+
29
37
  def path
30
38
  @path ||= namespace + (scope == :instance ? '#' : '.') + name
31
39
  end