solargraph 0.58.3 → 0.59.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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +6 -5
  4. data/.github/workflows/plugins.yml +46 -34
  5. data/.github/workflows/rspec.yml +15 -28
  6. data/.github/workflows/typecheck.yml +3 -2
  7. data/.rubocop.yml +38 -6
  8. data/.rubocop_todo.yml +53 -966
  9. data/CHANGELOG.md +12 -0
  10. data/Gemfile +3 -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 +12 -3
  16. data/lib/solargraph/api_map/index.rb +29 -18
  17. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  18. data/lib/solargraph/api_map/store.rb +39 -28
  19. data/lib/solargraph/api_map.rb +156 -72
  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 +30 -18
  23. data/lib/solargraph/complex_type/unique_type.rb +216 -57
  24. data/lib/solargraph/complex_type.rb +171 -58
  25. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
  26. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  27. data/lib/solargraph/convention/data_definition.rb +5 -2
  28. data/lib/solargraph/convention/gemfile.rb +1 -1
  29. data/lib/solargraph/convention/gemspec.rb +1 -1
  30. data/lib/solargraph/convention/rakefile.rb +1 -1
  31. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  32. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  33. data/lib/solargraph/convention/struct_definition.rb +8 -4
  34. data/lib/solargraph/convention.rb +2 -2
  35. data/lib/solargraph/converters/dd.rb +2 -0
  36. data/lib/solargraph/converters/dl.rb +2 -0
  37. data/lib/solargraph/converters/dt.rb +2 -0
  38. data/lib/solargraph/converters/misc.rb +2 -0
  39. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  40. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  41. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  42. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  43. data/lib/solargraph/diagnostics/update_errors.rb +4 -8
  44. data/lib/solargraph/doc_map.rb +38 -39
  45. data/lib/solargraph/equality.rb +4 -4
  46. data/lib/solargraph/gem_pins.rb +6 -6
  47. data/lib/solargraph/language_server/error_codes.rb +10 -10
  48. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  49. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  50. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  51. data/lib/solargraph/language_server/host/sources.rb +2 -1
  52. data/lib/solargraph/language_server/host.rb +30 -22
  53. data/lib/solargraph/language_server/message/base.rb +1 -1
  54. data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
  55. data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
  56. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  57. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  58. data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -7
  59. data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
  60. data/lib/solargraph/language_server/message/extended/search.rb +1 -1
  61. data/lib/solargraph/language_server/message/initialize.rb +20 -14
  62. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  63. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  64. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +17 -10
  65. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  66. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  67. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  68. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +13 -6
  69. data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
  70. data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
  71. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  72. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  73. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
  74. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
  75. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
  76. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  77. data/lib/solargraph/language_server/message.rb +1 -1
  78. data/lib/solargraph/language_server/request.rb +4 -2
  79. data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
  80. data/lib/solargraph/language_server/uri_helpers.rb +2 -2
  81. data/lib/solargraph/library.rb +57 -38
  82. data/lib/solargraph/location.rb +17 -14
  83. data/lib/solargraph/logging.rb +22 -4
  84. data/lib/solargraph/page.rb +1 -1
  85. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  86. data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -108
  87. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  88. data/lib/solargraph/parser/node_processor.rb +8 -7
  89. data/lib/solargraph/parser/parser_gem/class_methods.rb +30 -14
  90. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
  91. data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
  92. data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
  93. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  94. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  95. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  96. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -12
  97. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  98. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
  99. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  100. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  101. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  102. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  103. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  104. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  105. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  106. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  107. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  108. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  109. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
  110. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  111. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  112. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  113. data/lib/solargraph/parser/parser_gem.rb +2 -0
  114. data/lib/solargraph/parser/region.rb +9 -3
  115. data/lib/solargraph/parser/snippet.rb +3 -1
  116. data/lib/solargraph/parser.rb +2 -0
  117. data/lib/solargraph/pin/base.rb +124 -80
  118. data/lib/solargraph/pin/base_variable.rb +273 -24
  119. data/lib/solargraph/pin/block.rb +29 -6
  120. data/lib/solargraph/pin/breakable.rb +7 -1
  121. data/lib/solargraph/pin/callable.rb +65 -21
  122. data/lib/solargraph/pin/closure.rb +7 -10
  123. data/lib/solargraph/pin/common.rb +24 -6
  124. data/lib/solargraph/pin/compound_statement.rb +55 -0
  125. data/lib/solargraph/pin/constant.rb +3 -5
  126. data/lib/solargraph/pin/conversions.rb +10 -4
  127. data/lib/solargraph/pin/delegated_method.rb +19 -8
  128. data/lib/solargraph/pin/documenting.rb +4 -2
  129. data/lib/solargraph/pin/instance_variable.rb +5 -1
  130. data/lib/solargraph/pin/keyword.rb +0 -4
  131. data/lib/solargraph/pin/local_variable.rb +15 -59
  132. data/lib/solargraph/pin/method.rb +156 -104
  133. data/lib/solargraph/pin/method_alias.rb +8 -0
  134. data/lib/solargraph/pin/namespace.rb +19 -12
  135. data/lib/solargraph/pin/parameter.rb +100 -36
  136. data/lib/solargraph/pin/proxy_type.rb +4 -1
  137. data/lib/solargraph/pin/reference/override.rb +1 -1
  138. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  139. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  140. data/lib/solargraph/pin/reference.rb +20 -0
  141. data/lib/solargraph/pin/search.rb +3 -2
  142. data/lib/solargraph/pin/signature.rb +15 -12
  143. data/lib/solargraph/pin/symbol.rb +2 -1
  144. data/lib/solargraph/pin/until.rb +2 -4
  145. data/lib/solargraph/pin/while.rb +2 -4
  146. data/lib/solargraph/pin.rb +2 -0
  147. data/lib/solargraph/pin_cache.rb +22 -19
  148. data/lib/solargraph/position.rb +17 -10
  149. data/lib/solargraph/range.rb +16 -15
  150. data/lib/solargraph/rbs_map/conversions.rb +358 -229
  151. data/lib/solargraph/rbs_map/core_fills.rb +18 -11
  152. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  153. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  154. data/lib/solargraph/rbs_map.rb +76 -32
  155. data/lib/solargraph/server_methods.rb +1 -1
  156. data/lib/solargraph/shell.rb +258 -66
  157. data/lib/solargraph/source/chain/array.rb +4 -2
  158. data/lib/solargraph/source/chain/call.rb +96 -56
  159. data/lib/solargraph/source/chain/class_variable.rb +1 -1
  160. data/lib/solargraph/source/chain/constant.rb +5 -1
  161. data/lib/solargraph/source/chain/global_variable.rb +1 -1
  162. data/lib/solargraph/source/chain/hash.rb +8 -5
  163. data/lib/solargraph/source/chain/if.rb +12 -10
  164. data/lib/solargraph/source/chain/instance_variable.rb +24 -1
  165. data/lib/solargraph/source/chain/link.rb +12 -22
  166. data/lib/solargraph/source/chain/literal.rb +9 -6
  167. data/lib/solargraph/source/chain/or.rb +10 -4
  168. data/lib/solargraph/source/chain/q_call.rb +2 -0
  169. data/lib/solargraph/source/chain/variable.rb +3 -1
  170. data/lib/solargraph/source/chain/z_super.rb +1 -3
  171. data/lib/solargraph/source/chain.rb +51 -38
  172. data/lib/solargraph/source/change.rb +12 -5
  173. data/lib/solargraph/source/cursor.rb +23 -17
  174. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  175. data/lib/solargraph/source/source_chainer.rb +56 -32
  176. data/lib/solargraph/source/updater.rb +5 -1
  177. data/lib/solargraph/source.rb +59 -35
  178. data/lib/solargraph/source_map/clip.rb +48 -29
  179. data/lib/solargraph/source_map/data.rb +4 -1
  180. data/lib/solargraph/source_map/mapper.rb +69 -42
  181. data/lib/solargraph/source_map.rb +21 -9
  182. data/lib/solargraph/type_checker/problem.rb +3 -1
  183. data/lib/solargraph/type_checker/rules.rb +81 -8
  184. data/lib/solargraph/type_checker.rb +195 -121
  185. data/lib/solargraph/version.rb +1 -1
  186. data/lib/solargraph/workspace/config.rb +14 -11
  187. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  188. data/lib/solargraph/workspace/require_paths.rb +1 -0
  189. data/lib/solargraph/workspace.rb +50 -28
  190. data/lib/solargraph/yard_map/helpers.rb +8 -3
  191. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  192. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  193. data/lib/solargraph/yard_map/mapper.rb +13 -8
  194. data/lib/solargraph/yard_map.rb +17 -18
  195. data/lib/solargraph/yard_tags.rb +2 -2
  196. data/lib/solargraph/yardoc.rb +7 -4
  197. data/lib/solargraph.rb +31 -8
  198. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  199. data/rbs/fills/tuple/tuple.rbs +28 -0
  200. data/rbs/shims/ast/0/node.rbs +1 -1
  201. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  202. data/solargraph.gemspec +37 -35
  203. metadata +41 -41
  204. data/lib/solargraph/type_checker/checks.rb +0 -124
  205. data/lib/solargraph/type_checker/param_def.rb +0 -37
  206. data/lib/solargraph/yard_map/to_method.rb +0 -89
@@ -15,6 +15,7 @@ module Solargraph
15
15
 
16
16
  # @param decl [::Symbol] :arg, :optarg, :kwarg, :kwoptarg, :restarg, :kwrestarg, :block, :blockarg
17
17
  # @param asgn_code [String, nil]
18
+ # @param [Hash{Symbol => Object}] splat
18
19
  def initialize decl: :arg, asgn_code: nil, **splat
19
20
  super(**splat)
20
21
  @asgn_code = asgn_code
@@ -29,21 +30,39 @@ module Solargraph
29
30
  super || closure&.type_location
30
31
  end
31
32
 
32
- def combine_with(other, attrs={})
33
- new_attrs = {
34
- decl: assert_same(other, :decl),
35
- presence: choose(other, :presence),
36
- asgn_code: choose(other, :asgn_code),
37
- }.merge(attrs)
38
- super(other, new_attrs)
33
+ def combine_with other, attrs = {}
34
+ # Parameters can be combined with local variables
35
+ new_attrs = if other.is_a?(Parameter)
36
+ {
37
+ decl: assert_same(other, :decl),
38
+ asgn_code: choose(other, :asgn_code)
39
+ }
40
+ else
41
+ {
42
+ decl: decl,
43
+ asgn_code: asgn_code
44
+ }
45
+ end
46
+ super(other, new_attrs.merge(attrs))
47
+ end
48
+
49
+ def combine_return_type other
50
+ out = super
51
+ if out&.undefined?
52
+ # allow our return_type method to provide a better type
53
+ # using :param tag
54
+ out = nil
55
+ end
56
+ out
39
57
  end
40
58
 
41
59
  def keyword?
42
- [:kwarg, :kwoptarg].include?(decl)
60
+ %i[kwarg kwoptarg].include?(decl)
43
61
  end
44
62
 
45
63
  def kwrestarg?
46
- decl == :kwrestarg || (assignment && [:HASH, :hash].include?(assignment.type))
64
+ # @sg-ignore flow sensitive typing needs to handle attrs
65
+ decl == :kwrestarg || (assignment && %i[HASH hash].include?(assignment.type))
47
66
  end
48
67
 
49
68
  def needs_consistent_name?
@@ -52,26 +71,31 @@ module Solargraph
52
71
 
53
72
  # @return [String]
54
73
  def arity_decl
55
- name = (self.name || '(anon)')
56
- type = (return_type&.to_rbs || 'untyped')
74
+ name = self.name || '(anon)'
75
+ return_type&.to_rbs || 'untyped'
57
76
  case decl
58
77
  when :arg
59
- ""
78
+ ''
60
79
  when :optarg
61
- "?"
80
+ '?'
62
81
  when :kwarg
63
82
  "#{name}:"
64
83
  when :kwoptarg
65
84
  "?#{name}:"
66
85
  when :restarg
67
- "*"
86
+ '*'
68
87
  when :kwrestarg
69
- "**"
88
+ '**'
70
89
  else
71
90
  "(unknown decl: #{decl})"
72
91
  end
73
92
  end
74
93
 
94
+ # @return [String]
95
+ def type_arity_decl
96
+ arity_decl + return_type.items.count.to_s
97
+ end
98
+
75
99
  def arg?
76
100
  decl == :arg
77
101
  end
@@ -80,12 +104,20 @@ module Solargraph
80
104
  decl == :restarg
81
105
  end
82
106
 
107
+ def mandatory_positional?
108
+ decl == :arg
109
+ end
110
+
111
+ def positional?
112
+ !keyword?
113
+ end
114
+
83
115
  def rest?
84
- decl == :restarg || decl == :kwrestarg
116
+ %i[restarg kwrestarg].include?(decl)
85
117
  end
86
118
 
87
119
  def block?
88
- [:block, :blockarg].include?(decl)
120
+ %i[block blockarg].include?(decl)
89
121
  end
90
122
 
91
123
  def to_rbs
@@ -123,6 +155,11 @@ module Solargraph
123
155
  end
124
156
  end
125
157
 
158
+ def reset_generated!
159
+ @return_type = nil if param_tag
160
+ super
161
+ end
162
+
126
163
  # @return [String]
127
164
  def full
128
165
  full_name + case decl
@@ -135,50 +172,67 @@ module Solargraph
135
172
  end
136
173
  end
137
174
 
175
+ # @sg-ignore super always sets @return_type to something
138
176
  # @return [ComplexType]
139
177
  def return_type
140
178
  if @return_type.nil?
141
179
  @return_type = ComplexType::UNDEFINED
142
180
  found = param_tag
143
- @return_type = ComplexType.try_parse(*found.types) unless found.nil? or found.types.nil?
181
+ @return_type = ComplexType.try_parse(*found.types) unless found.nil? || found.types.nil?
182
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
144
183
  if @return_type.undefined?
145
- if decl == :restarg
184
+ case decl
185
+ when :restarg
146
186
  @return_type = ComplexType.try_parse('::Array')
147
- elsif decl == :kwrestarg
187
+ when :kwrestarg
148
188
  @return_type = ComplexType.try_parse('::Hash')
149
- elsif decl == :blockarg
189
+ when :blockarg
150
190
  @return_type = ComplexType.try_parse('::Proc')
151
191
  end
152
192
  end
153
193
  end
154
194
  super
155
- @return_type
156
195
  end
157
196
 
158
197
  # The parameter's zero-based location in the block's signature.
159
198
  #
199
+ # @sg-ignore Need to add nil check here
160
200
  # @return [Integer]
161
201
  def index
162
- # @type [Method, Block]
163
202
  method_pin = closure
203
+ # @sg-ignore Need to add nil check here
164
204
  method_pin.parameter_names.index(name)
165
205
  end
166
206
 
167
207
  # @param api_map [ApiMap]
168
208
  def typify api_map
169
- return return_type.qualify(api_map, *closure.gates) unless return_type.undefined?
170
- closure.is_a?(Pin::Block) ? typify_block_param(api_map) : typify_method_param(api_map)
209
+ new_type = super
210
+ return new_type if new_type.defined?
211
+
212
+ # sniff based on param tags
213
+ new_type = closure.is_a?(Pin::Block) ? typify_block_param(api_map) : typify_method_param(api_map)
214
+
215
+ return adjust_type api_map, new_type.self_to_type(full_context) if new_type.defined?
216
+
217
+ adjust_type api_map, super.self_to_type(full_context)
171
218
  end
172
219
 
173
220
  # @param atype [ComplexType]
174
221
  # @param api_map [ApiMap]
175
- def compatible_arg?(atype, api_map)
222
+ def compatible_arg? atype, api_map
176
223
  # make sure we get types from up the method
177
224
  # inheritance chain if we don't have them on this pin
178
225
  ptype = typify api_map
179
- ptype.undefined? || ptype.can_assign?(api_map, atype) || ptype.generic?
226
+ return true if ptype.undefined?
227
+
228
+ return true if atype.conforms_to?(api_map,
229
+ ptype,
230
+ :method_call,
231
+ %i[allow_empty_params allow_undefined])
232
+ ptype.generic?
180
233
  end
181
234
 
235
+ # @sg-ignore flow sensitive typing needs to handle attrs
182
236
  def documentation
183
237
  tag = param_tag
184
238
  return '' if tag.nil? || tag.text.nil?
@@ -187,12 +241,19 @@ module Solargraph
187
241
 
188
242
  private
189
243
 
244
+ def generate_complex_type
245
+ nil
246
+ end
247
+
190
248
  # @return [YARD::Tags::Tag, nil]
191
249
  def param_tag
250
+ # @sg-ignore Need to add nil check here
192
251
  params = closure.docstring.tags(:param)
252
+ # @sg-ignore Need to add nil check here
193
253
  params.each do |p|
194
254
  return p if p.name == name
195
255
  end
256
+ # @sg-ignore Need to add nil check here
196
257
  params[index] if index && params[index] && (params[index].name.nil? || params[index].name.empty?)
197
258
  end
198
259
 
@@ -200,15 +261,14 @@ module Solargraph
200
261
  # @return [ComplexType]
201
262
  def typify_block_param api_map
202
263
  block_pin = closure
203
- if block_pin.is_a?(Pin::Block) && block_pin.receiver
204
- return block_pin.typify_parameters(api_map)[index]
205
- end
264
+ return block_pin.typify_parameters(api_map)[index] if block_pin.is_a?(Pin::Block) && block_pin.receiver && index
206
265
  ComplexType::UNDEFINED
207
266
  end
208
267
 
209
268
  # @param api_map [ApiMap]
210
269
  # @return [ComplexType]
211
270
  def typify_method_param api_map
271
+ # @sg-ignore Need to add nil check here
212
272
  meths = api_map.get_method_stack(closure.full_context.tag, closure.name, scope: closure.scope)
213
273
  # meths.shift # Ignore the first one
214
274
  meths.each do |meth|
@@ -219,10 +279,14 @@ module Solargraph
219
279
  found = p
220
280
  break
221
281
  end
222
- if found.nil? and !index.nil?
223
- found = params[index] if params[index] && (params[index].name.nil? || params[index].name.empty?)
282
+ if found.nil? && !index.nil? && params[index] && (params[index].name.nil? || params[index].name.empty?)
283
+ found = params[index]
284
+ end
285
+ unless found.nil? || found.types.nil?
286
+ return ComplexType.try_parse(*found.types).qualify(api_map,
287
+ # @sg-ignore Need to add nil check here
288
+ *meth.closure.gates)
224
289
  end
225
- return ComplexType.try_parse(*found.types).qualify(api_map, *meth.closure.gates) unless found.nil? || found.types.nil?
226
290
  end
227
291
  ComplexType::UNDEFINED
228
292
  end
@@ -230,6 +294,7 @@ module Solargraph
230
294
  # @param heredoc [YARD::Docstring]
231
295
  # @param api_map [ApiMap]
232
296
  # @param skip [::Array]
297
+ #
233
298
  # @return [::Array<YARD::Tags::Tag>]
234
299
  def see_reference heredoc, api_map, skip = []
235
300
  # This should actually be an intersection type
@@ -237,7 +302,7 @@ module Solargraph
237
302
  heredoc.ref_tags.each do |ref|
238
303
  # @sg-ignore ref should actually be an intersection type
239
304
  next unless ref.tag_name == 'param' && ref.owner
240
- # @sg-ignore ref should actually be an intersection type
305
+ # @todo ref should actually be an intersection type
241
306
  result = resolve_reference(ref.owner.to_s, api_map, skip)
242
307
  return result unless result.nil?
243
308
  end
@@ -257,14 +322,13 @@ module Solargraph
257
322
  else
258
323
  fqns = api_map.qualify(parts.first, namespace)
259
324
  return nil if fqns.nil?
325
+ # @sg-ignore Need to add nil check here
260
326
  path = fqns + ref[parts.first.length] + parts.last
261
327
  end
262
328
  pins = api_map.get_path_pins(path)
263
329
  pins.each do |pin|
264
330
  params = pin.docstring.tags(:param)
265
331
  return params unless params.empty?
266
- end
267
- pins.each do |pin|
268
332
  params = see_reference(pin.docstring, api_map, skip)
269
333
  return params unless params.empty?
270
334
  end
@@ -3,10 +3,11 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class ProxyType < Base
6
- # @param return_type [ComplexType]
6
+ # @param return_type [ComplexType, ComplexType::UniqueType]
7
7
  # @param gates [Array<String>, nil] Namespaces to try while resolving non-rooted types
8
8
  # @param binder [ComplexType, ComplexType::UniqueType, nil]
9
9
  # @param gates [Array<String>, nil]
10
+ # @param [Hash{Symbol => Object}] splat
10
11
  def initialize return_type: ComplexType::UNDEFINED, binder: nil, gates: nil, **splat
11
12
  super(**splat)
12
13
  @gates = gates
@@ -22,9 +23,11 @@ module Solargraph
22
23
  # @param closure [Pin::Namespace, nil] Used as the closure for this pin
23
24
  # @param binder [ComplexType, ComplexType::UniqueType, nil]
24
25
  # @return [ProxyType]
26
+ # @param [Hash{Symbol => Object}] kwargs
25
27
  def self.anonymous context, closure: nil, binder: nil, **kwargs
26
28
  unless closure
27
29
  parts = context.namespace.split('::')
30
+ # @sg-ignore Need to add nil check here
28
31
  namespace = parts[0..-2].join('::').to_s
29
32
  closure = Solargraph::Pin::Namespace.new(name: namespace, source: :proxy_type)
30
33
  end
@@ -7,7 +7,7 @@ module Solargraph
7
7
  # @return [::Array<YARD::Tags::Tag>]
8
8
  attr_reader :tags
9
9
 
10
- # @return [::Array<Symbol>]
10
+ # @return [::Array<::Symbol>]
11
11
  attr_reader :delete
12
12
 
13
13
  def closure
@@ -6,7 +6,9 @@ module Solargraph
6
6
  # A Superclass reference pin.
7
7
  #
8
8
  class Superclass < Reference
9
+ # @sg-ignore Need to add nil check here
9
10
  def reference_gates
11
+ # @sg-ignore Need to add nil check here
10
12
  @reference_gates ||= closure.gates - [closure.path]
11
13
  end
12
14
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class Reference
6
+ class TypeAlias < Reference
7
+ # @param return_type [ComplexType]
8
+ # @param [Hash{Symbol => Object}] splat
9
+ def initialize return_type:, **splat
10
+ super(**splat)
11
+ @return_type = return_type
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -9,10 +9,28 @@ module Solargraph
9
9
  autoload :Prepend, 'solargraph/pin/reference/prepend'
10
10
  autoload :Extend, 'solargraph/pin/reference/extend'
11
11
  autoload :Override, 'solargraph/pin/reference/override'
12
+ autoload :TypeAlias, 'solargraph/pin/reference/type_alias'
12
13
 
13
14
  attr_reader :generic_values
14
15
 
16
+ # A Reference is a pin that associates a type with another type.
17
+ # The existing type is marked as the closure. The name of the
18
+ # type we're associating with it is the 'name' field, and
19
+ # subtypes are in the 'generic_values' field.
20
+ #
21
+ # These pins are a little different - the name is a rooted name,
22
+ # which may be relative or absolute, preceded with ::, not a
23
+ # fully qualified namespace, which is implicitly in the root
24
+ # namespace and is never preceded by ::.
25
+ #
26
+ # @todo can the above be represented in a less subtle way?
27
+ # @todo consider refactoring so that we can replicate more
28
+ # complex types like Hash{String => Integer} and has both key
29
+ # types and subtypes.
30
+ #
31
+ # @param name [String] rooted name of the referenced type
15
32
  # @param generic_values [Array<String>]
33
+ # @param [Hash{Symbol => Object}] splat
16
34
  def initialize generic_values: [], **splat
17
35
  super(**splat)
18
36
  @generic_values = generic_values
@@ -30,8 +48,10 @@ module Solargraph
30
48
  )
31
49
  end
32
50
 
51
+ # @sg-ignore Need to add nil check here
33
52
  # @return [Array<String>]
34
53
  def reference_gates
54
+ # @sg-ignore Need to add nil check here
35
55
  closure.gates
36
56
  end
37
57
  end
@@ -46,14 +46,15 @@ module Solargraph
46
46
  # @param b [self]
47
47
  # @sg-ignore https://github.com/castwide/solargraph/pull/1050
48
48
  .sort { |a, b| b.match <=> a.match }
49
- .map(&:pin)
49
+ .map(&:pin)
50
50
  end
51
51
 
52
52
  # @param str1 [String]
53
53
  # @param str2 [String]
54
+ #
54
55
  # @return [Float]
55
56
  def fuzzy_string_match str1, str2
56
- return 1.0 + (str2.length.to_f / str1.length.to_f) if str1.downcase.include?(str2.downcase)
57
+ return 1.0 + (str2.length.to_f / str1.length) if str1.downcase.include?(str2.downcase)
57
58
  JaroWinkler.similarity(str1, str2, ignore_case: true)
58
59
  end
59
60
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Solargraph
2
4
  module Pin
3
5
  class Signature < Callable
@@ -5,11 +7,8 @@ module Solargraph
5
7
  # to the method pin
6
8
  attr_writer :closure
7
9
 
8
- def initialize **splat
9
- super(**splat)
10
- end
11
-
12
10
  def generics
11
+ # @type [Array<::String, nil>]
13
12
  @generics ||= [].freeze
14
13
  end
15
14
 
@@ -17,8 +16,7 @@ module Solargraph
17
16
  @identity ||= "signature#{object_id}"
18
17
  end
19
18
 
20
- attr_writer :closure
21
-
19
+ # @ sg-ignore need boolish support for ? methods
22
20
  def dodgy_return_type_source?
23
21
  super || closure&.dodgy_return_type_source?
24
22
  end
@@ -32,8 +30,11 @@ module Solargraph
32
30
  end
33
31
 
34
32
  def typify api_map
33
+ # @sg-ignore Need to add nil check here
35
34
  if return_type.defined?
35
+ # @sg-ignore Need to add nil check here
36
36
  qualified = return_type.qualify(api_map, closure.namespace)
37
+ # @sg-ignore Need to add nil check here
37
38
  logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
38
39
  return qualified
39
40
  end
@@ -44,13 +45,15 @@ module Solargraph
44
45
  method_stack = closure.rest_of_stack api_map
45
46
  logger.debug { "Signature#typify(self=#{self}) - method_stack: #{method_stack}" }
46
47
  method_stack.each do |pin|
47
- sig = pin.signatures.find { |s| s.arity == self.arity }
48
+ sig = pin.signatures.find { |s| s.arity == arity }
48
49
  next unless sig
49
- unless sig.return_type.undefined?
50
- qualified = sig.return_type.qualify(api_map, closure.namespace)
51
- logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
52
- return qualified
53
- end
50
+ # @sg-ignore Need to add nil check here
51
+ next if sig.return_type.undefined?
52
+ # @sg-ignore Need to add nil check here
53
+ qualified = sig.return_type.qualify(api_map, closure.namespace)
54
+ # @sg-ignore Need to add nil check here
55
+ logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
56
+ return qualified
54
57
  end
55
58
  out = super
56
59
  logger.debug { "Signature#typify(self=#{self}) => #{out}" }
@@ -3,8 +3,9 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class Symbol < Base
6
- # @param location [Solargraph::Location]
6
+ # @param location [Solargraph::Location, nil]
7
7
  # @param name [String]
8
+ # @param [Hash{Symbol => Object}] kwargs
8
9
  def initialize(location, name, **kwargs)
9
10
  # @sg-ignore "Unrecognized keyword argument kwargs to Solargraph::Pin::Base#initialize"
10
11
  super(location: location, name: name, **kwargs)
@@ -2,13 +2,11 @@
2
2
 
3
3
  module Solargraph
4
4
  module Pin
5
- class Until < Base
5
+ class Until < CompoundStatement
6
6
  include Breakable
7
7
 
8
- # @param receiver [Parser::AST::Node, nil]
9
8
  # @param node [Parser::AST::Node, nil]
10
- # @param context [ComplexType, nil]
11
- # @param args [::Array<Parameter>]
9
+ # @param [Hash{Symbol => Object}] splat
12
10
  def initialize node: nil, **splat
13
11
  super(**splat)
14
12
  @node = node
@@ -2,13 +2,11 @@
2
2
 
3
3
  module Solargraph
4
4
  module Pin
5
- class While < Base
5
+ class While < CompoundStatement
6
6
  include Breakable
7
7
 
8
- # @param receiver [Parser::AST::Node, nil]
9
8
  # @param node [Parser::AST::Node, nil]
10
- # @param context [ComplexType, nil]
11
- # @param args [::Array<Parameter>]
9
+ # @param [Hash{Symbol => Object}] splat
12
10
  def initialize node: nil, **splat
13
11
  super(**splat)
14
12
  @node = node
@@ -38,6 +38,8 @@ module Solargraph
38
38
  autoload :Until, 'solargraph/pin/until'
39
39
  autoload :While, 'solargraph/pin/while'
40
40
  autoload :Callable, 'solargraph/pin/callable'
41
+ autoload :CompoundStatement,
42
+ 'solargraph/pin/compound_statement'
41
43
 
42
44
  ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil, source: :pin_rb)
43
45
  end
@@ -1,5 +1,6 @@
1
1
  require 'yard-activesupport-concern'
2
2
  require 'fileutils'
3
+ require 'pathname' # @todo Required by RBS but not loaded in some use cases
3
4
  require 'rbs'
4
5
 
5
6
  module Solargraph
@@ -84,40 +85,40 @@ module Solargraph
84
85
 
85
86
  # @param gemspec [Gem::Specification]
86
87
  # @return [Array<Pin::Base>, nil]
87
- def deserialize_yard_gem(gemspec)
88
+ def deserialize_yard_gem gemspec
88
89
  load(yard_gem_path(gemspec))
89
90
  end
90
91
 
91
92
  # @param gemspec [Gem::Specification]
92
93
  # @param pins [Array<Pin::Base>]
93
94
  # @return [void]
94
- def serialize_yard_gem(gemspec, pins)
95
+ def serialize_yard_gem gemspec, pins
95
96
  save(yard_gem_path(gemspec), pins)
96
97
  end
97
98
 
98
99
  # @param gemspec [Gem::Specification]
99
100
  # @return [Boolean]
100
- def has_yard?(gemspec)
101
+ def has_yard? gemspec
101
102
  exist?(yard_gem_path(gemspec))
102
103
  end
103
104
 
104
105
  # @param gemspec [Gem::Specification]
105
106
  # @param hash [String, nil]
106
107
  # @return [String]
107
- def rbs_collection_path(gemspec, hash)
108
+ def rbs_collection_path gemspec, hash
108
109
  File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser")
109
110
  end
110
111
 
111
112
  # @param gemspec [Gem::Specification]
112
113
  # @return [String]
113
- def rbs_collection_path_prefix(gemspec)
114
+ def rbs_collection_path_prefix gemspec
114
115
  File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-")
115
116
  end
116
117
 
117
118
  # @param gemspec [Gem::Specification]
118
119
  # @param hash [String, nil]
119
120
  # @return [Array<Pin::Base>, nil]
120
- def deserialize_rbs_collection_gem(gemspec, hash)
121
+ def deserialize_rbs_collection_gem gemspec, hash
121
122
  load(rbs_collection_path(gemspec, hash))
122
123
  end
123
124
 
@@ -125,20 +126,20 @@ module Solargraph
125
126
  # @param hash [String, nil]
126
127
  # @param pins [Array<Pin::Base>]n
127
128
  # @return [void]
128
- def serialize_rbs_collection_gem(gemspec, hash, pins)
129
+ def serialize_rbs_collection_gem gemspec, hash, pins
129
130
  save(rbs_collection_path(gemspec, hash), pins)
130
131
  end
131
132
 
132
133
  # @param gemspec [Gem::Specification]
133
134
  # @param hash [String, nil]
134
135
  # @return [String]
135
- def combined_path(gemspec, hash)
136
+ def combined_path gemspec, hash
136
137
  File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser")
137
138
  end
138
139
 
139
140
  # @param gemspec [Gem::Specification]
140
141
  # @return [String]
141
- def combined_path_prefix(gemspec)
142
+ def combined_path_prefix gemspec
142
143
  File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-")
143
144
  end
144
145
 
@@ -146,7 +147,7 @@ module Solargraph
146
147
  # @param hash [String, nil]
147
148
  # @param pins [Array<Pin::Base>]
148
149
  # @return [void]
149
- def serialize_combined_gem(gemspec, hash, pins)
150
+ def serialize_combined_gem gemspec, hash, pins
150
151
  save(combined_path(gemspec, hash), pins)
151
152
  end
152
153
 
@@ -160,7 +161,7 @@ module Solargraph
160
161
  # @param gemspec [Gem::Specification]
161
162
  # @param hash [String, nil]
162
163
  # @return [Boolean]
163
- def has_rbs_collection?(gemspec, hash)
164
+ def has_rbs_collection? gemspec, hash
164
165
  exist?(rbs_collection_path(gemspec, hash))
165
166
  end
166
167
 
@@ -175,9 +176,9 @@ module Solargraph
175
176
  end
176
177
 
177
178
  # @param gemspec [Gem::Specification]
178
- # @param out [IO, nil]
179
+ # @param out [IO, StringIO, nil]
179
180
  # @return [void]
180
- def uncache_gem(gemspec, out: nil)
181
+ def uncache_gem gemspec, out: nil
181
182
  uncache(yardoc_path(gemspec), out: out)
182
183
  uncache_by_prefix(rbs_collection_path_prefix(gemspec), out: out)
183
184
  uncache(yard_gem_path(gemspec), out: out)
@@ -192,6 +193,7 @@ module Solargraph
192
193
  private
193
194
 
194
195
  # @param file [String]
196
+ # @sg-ignore Marshal.load returns Object; we know it's Array<Pin::Base>
195
197
  # @return [Array<Solargraph::Pin::Base>, nil]
196
198
  def load file
197
199
  return nil unless File.file?(file)
@@ -220,24 +222,25 @@ module Solargraph
220
222
 
221
223
  # @param path_segments [Array<String>]
222
224
  # @return [void]
225
+ # @param [Object, nil] out
223
226
  def uncache *path_segments, out: nil
224
227
  path = File.join(*path_segments)
225
- if File.exist?(path)
226
- FileUtils.rm_rf path, secure: true
227
- out.puts "Clearing pin cache in #{path}" unless out.nil?
228
- end
228
+ return unless File.exist?(path)
229
+ FileUtils.rm_rf path, secure: true
230
+ out&.puts "Clearing pin cache in #{path}"
229
231
  end
230
232
 
231
233
  # @return [void]
232
234
  # @param path_segments [Array<String>]
235
+ # @param [Object, nil] out
233
236
  def uncache_by_prefix *path_segments, out: nil
234
237
  path = File.join(*path_segments)
235
238
  glob = "#{path}*"
236
- out.puts "Clearing pin cache in #{glob}" unless out.nil?
239
+ out&.puts "Clearing pin cache in #{glob}"
237
240
  Dir.glob(glob).each do |file|
238
241
  next unless File.file?(file)
239
242
  FileUtils.rm_rf file, secure: true
240
- out.puts "Clearing pin cache in #{file}" unless out.nil?
243
+ out&.puts "Clearing pin cache in #{file}"
241
244
  end
242
245
  end
243
246
  end