solargraph 0.54.0 → 0.54.2

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/lib/solargraph/api_map/store.rb +8 -4
  4. data/lib/solargraph/api_map.rb +74 -23
  5. data/lib/solargraph/complex_type/type_methods.rb +17 -11
  6. data/lib/solargraph/complex_type/unique_type.rb +72 -9
  7. data/lib/solargraph/complex_type.rb +66 -17
  8. data/lib/solargraph/language_server/host/message_worker.rb +45 -5
  9. data/lib/solargraph/language_server/host.rb +10 -10
  10. data/lib/solargraph/language_server/message/base.rb +18 -11
  11. data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
  12. data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
  13. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
  14. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
  15. data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
  16. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
  17. data/lib/solargraph/language_server/progress.rb +19 -2
  18. data/lib/solargraph/library.rb +29 -39
  19. data/lib/solargraph/location.rb +14 -1
  20. data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -7
  21. data/lib/solargraph/parser/parser_gem/node_methods.rb +1 -1
  22. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
  23. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -2
  24. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +8 -2
  25. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +1 -1
  26. data/lib/solargraph/parser.rb +2 -5
  27. data/lib/solargraph/pin/base.rb +16 -3
  28. data/lib/solargraph/pin/base_variable.rb +1 -1
  29. data/lib/solargraph/pin/block.rb +6 -26
  30. data/lib/solargraph/pin/callable.rb +147 -0
  31. data/lib/solargraph/pin/closure.rb +8 -3
  32. data/lib/solargraph/pin/common.rb +2 -6
  33. data/lib/solargraph/pin/conversions.rb +3 -2
  34. data/lib/solargraph/pin/instance_variable.rb +2 -2
  35. data/lib/solargraph/pin/method.rb +51 -31
  36. data/lib/solargraph/pin/namespace.rb +4 -4
  37. data/lib/solargraph/pin/parameter.rb +9 -11
  38. data/lib/solargraph/pin/proxy_type.rb +1 -1
  39. data/lib/solargraph/pin/signature.rb +3 -129
  40. data/lib/solargraph/pin.rb +4 -1
  41. data/lib/solargraph/range.rb +2 -4
  42. data/lib/solargraph/rbs_map/conversions.rb +76 -37
  43. data/lib/solargraph/rbs_map/core_fills.rb +6 -6
  44. data/lib/solargraph/shell.rb +17 -2
  45. data/lib/solargraph/source/chain/array.rb +6 -5
  46. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  47. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  48. data/lib/solargraph/source/chain/call.rb +81 -51
  49. data/lib/solargraph/source/chain/link.rb +9 -0
  50. data/lib/solargraph/source/chain/or.rb +1 -1
  51. data/lib/solargraph/source/chain.rb +41 -17
  52. data/lib/solargraph/source/cursor.rb +14 -2
  53. data/lib/solargraph/source.rb +102 -85
  54. data/lib/solargraph/source_map/clip.rb +4 -4
  55. data/lib/solargraph/source_map/data.rb +30 -0
  56. data/lib/solargraph/source_map.rb +28 -16
  57. data/lib/solargraph/type_checker/rules.rb +6 -1
  58. data/lib/solargraph/type_checker.rb +7 -7
  59. data/lib/solargraph/version.rb +1 -1
  60. data/lib/solargraph/views/environment.erb +3 -5
  61. data/solargraph.gemspec +4 -4
  62. metadata +20 -24
@@ -1,143 +1,17 @@
1
1
  module Solargraph
2
2
  module Pin
3
- class Signature < Base
4
- # @return [::Array<Parameter>]
5
- attr_reader :parameters
6
-
7
- # @return [ComplexType]
8
- attr_reader :return_type
9
-
10
- # @return [self]
11
- attr_reader :block
12
-
13
- # @param generics [Array<String>]
14
- # @param parameters [Array<Parameter>]
15
- # @param return_type [ComplexType]
16
- # @param block [Signature, nil]
17
- def initialize generics, parameters, return_type, block = nil
18
- @generics = generics
19
- @parameters = parameters
20
- @return_type = return_type
21
- @block = block
3
+ class Signature < Callable
4
+ def initialize **splat
5
+ super(**splat)
22
6
  end
23
7
 
24
8
  def generics
25
9
  @generics ||= [].freeze
26
10
  end
27
11
 
28
- # @return [String]
29
- def to_rbs
30
- rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs
31
- end
32
-
33
- # @return [String]
34
- def rbs_generics
35
- if generics.empty?
36
- return ''
37
- else
38
- return '[' + generics.map { |gen| gen.to_s }.join(', ') + '] '
39
- end
40
- end
41
-
42
- # @return [Array<String>]
43
- # @yieldparam [ComplexType]
44
- # @yieldreturn [ComplexType]
45
- # @return [self]
46
- def transform_types(&transform)
47
- # @todo 'super' alone should work here I think, but doesn't typecheck at level typed
48
- signature = super(&transform)
49
- signature.parameters = signature.parameters.map do |param|
50
- param.transform_types(&transform)
51
- end
52
- signature.block = block.transform_types(&transform) if signature.block?
53
- signature
54
- end
55
-
56
- # @param generics_to_resolve [Enumerable<String>]
57
- # @param arg_types [Array<ComplexType>, nil]
58
- # @param return_type_context [ComplexType, nil]
59
- # @param yield_arg_types [Array<ComplexType>, nil]
60
- # @param yield_return_type_context [ComplexType, nil]
61
- # @param context [ComplexType, nil]
62
- # @param resolved_generic_values [Hash{String => ComplexType}]
63
- # @return [self]
64
- def resolve_generics_from_context(generics_to_resolve,
65
- arg_types = nil,
66
- return_type_context = nil,
67
- yield_arg_types = nil,
68
- yield_return_type_context = nil,
69
- resolved_generic_values: {})
70
- signature = super(generics_to_resolve, return_type_context, resolved_generic_values: resolved_generic_values)
71
- signature.parameters = signature.parameters.each_with_index.map do |param, i|
72
- if arg_types.nil?
73
- param.dup
74
- else
75
- param.resolve_generics_from_context(generics_to_resolve,
76
- arg_types[i],
77
- resolved_generic_values: resolved_generic_values)
78
- end
79
- end
80
- signature.block = block.resolve_generics_from_context(generics_to_resolve,
81
- yield_arg_types,
82
- yield_return_type_context,
83
- resolved_generic_values: resolved_generic_values) if signature.block?
84
- signature
85
- end
86
-
87
- # @param generics_to_resolve [Enumerable<String>]
88
- # @param arg_types [Array<ComplexType>, nil]
89
- # @param return_type_context [ComplexType, nil]
90
- # @param yield_arg_types [Array<ComplexType>, nil]
91
- # @param yield_return_type_context [ComplexType, nil]
92
- # @param context [ComplexType, nil]
93
- # @param resolved_generic_values [Hash{String => ComplexType}]
94
- # @return [self]
95
- def resolve_generics_from_context_until_complete(generics_to_resolve,
96
- arg_types = nil,
97
- return_type_context = nil,
98
- yield_arg_types = nil,
99
- yield_return_type_context = nil,
100
- resolved_generic_values: {})
101
- # See
102
- # https://github.com/soutaro/steep/tree/master/lib/steep/type_inference
103
- # and
104
- # https://github.com/sorbet/sorbet/blob/master/infer/inference.cc
105
- # for other implementations
106
-
107
- return self if generics_to_resolve.empty?
108
-
109
- last_resolved_generic_values = resolved_generic_values.dup
110
- new_pin = resolve_generics_from_context(generics_to_resolve,
111
- arg_types,
112
- return_type_context,
113
- yield_arg_types,
114
- yield_return_type_context,
115
- resolved_generic_values: resolved_generic_values)
116
- if last_resolved_generic_values == resolved_generic_values
117
- # erase anything unresolved
118
- return new_pin.erase_generics(self.generics)
119
- end
120
- new_pin.resolve_generics_from_context_until_complete(generics_to_resolve,
121
- arg_types,
122
- return_type_context,
123
- yield_arg_types,
124
- yield_return_type_context,
125
- resolved_generic_values: resolved_generic_values)
126
- end
127
-
128
12
  def identity
129
13
  @identity ||= "signature#{object_id}"
130
14
  end
131
-
132
- def block?
133
- !!@block
134
- end
135
-
136
- protected
137
-
138
- attr_writer :block
139
-
140
- attr_writer :parameters
141
15
  end
142
16
  end
143
17
  end
@@ -3,7 +3,9 @@
3
3
  require 'yard'
4
4
 
5
5
  module Solargraph
6
- # The namespace for pins used in maps.
6
+ # The namespace for Pins used in SourceMaps.
7
+ #
8
+ # Pins represent declarations, from gems, Sources, and the Ruby core.
7
9
  #
8
10
  module Pin
9
11
  autoload :Common, 'solargraph/pin/common'
@@ -32,6 +34,7 @@ module Solargraph
32
34
  autoload :Singleton, 'solargraph/pin/singleton'
33
35
  autoload :KeywordParam, 'solargraph/pin/keyword_param'
34
36
  autoload :Search, 'solargraph/pin/search'
37
+ autoload :Callable, 'solargraph/pin/callable'
35
38
 
36
39
  ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil)
37
40
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- # A pair of positions that compose a section of text.
4
+ # A pair of Positions that compose a section of text in code.
5
5
  #
6
6
  class Range
7
7
  # @return [Position]
@@ -65,9 +65,7 @@ module Solargraph
65
65
  # @param node [Parser::AST::Node]
66
66
  # @return [Range, nil]
67
67
  def self.from_node node
68
- if Parser.rubyvm? && node.is_a?(RubyVM::AbstractSyntaxTree::Node)
69
- Solargraph::Range.from_to(node.first_lineno - 1, node.first_column, node.last_lineno - 1, node.last_column)
70
- elsif node&.loc && node.loc.expression
68
+ if node&.loc && node.loc.expression
71
69
  from_expr(node.loc.expression)
72
70
  end
73
71
  end
@@ -80,9 +80,12 @@ module Solargraph
80
80
  # @param closure [Pin::Namespace]
81
81
  # @return [void]
82
82
  def convert_self_type_to_pins decl, closure
83
+ type = build_type(decl.name, decl.args)
84
+ generic_values = type.all_params.map(&:to_s)
83
85
  include_pin = Solargraph::Pin::Reference::Include.new(
84
86
  name: decl.name.relative!.to_s,
85
- location: rbs_location_to_location(decl.location),
87
+ type_location: location_decl_to_pin_location(decl.location),
88
+ generic_values: generic_values,
86
89
  closure: closure
87
90
  )
88
91
  pins.push include_pin
@@ -144,6 +147,7 @@ module Solargraph
144
147
  name: decl.name.relative!.to_s,
145
148
  closure: Solargraph::Pin::ROOT_PIN,
146
149
  comments: decl.comment&.string,
150
+ type_location: location_decl_to_pin_location(decl.location),
147
151
  # @todo some type parameters in core/stdlib have default
148
152
  # values; Solargraph doesn't support that yet as so these
149
153
  # get treated as undefined if not specified
@@ -152,6 +156,7 @@ module Solargraph
152
156
  pins.push class_pin
153
157
  if decl.super_class
154
158
  pins.push Solargraph::Pin::Reference::Superclass.new(
159
+ type_location: location_decl_to_pin_location(decl.super_class.location),
155
160
  closure: class_pin,
156
161
  name: decl.super_class.name.relative!.to_s
157
162
  )
@@ -166,6 +171,7 @@ module Solargraph
166
171
  def interface_decl_to_pin decl, closure
167
172
  class_pin = Solargraph::Pin::Namespace.new(
168
173
  type: :module,
174
+ type_location: location_decl_to_pin_location(decl.location),
169
175
  name: decl.name.relative!.to_s,
170
176
  closure: Solargraph::Pin::ROOT_PIN,
171
177
  comments: decl.comment&.string,
@@ -185,6 +191,7 @@ module Solargraph
185
191
  module_pin = Solargraph::Pin::Namespace.new(
186
192
  type: :module,
187
193
  name: decl.name.relative!.to_s,
194
+ type_location: location_decl_to_pin_location(decl.location),
188
195
  closure: Solargraph::Pin::ROOT_PIN,
189
196
  comments: decl.comment&.string,
190
197
  generics: decl.type_params.map(&:name).map(&:to_s),
@@ -199,10 +206,11 @@ module Solargraph
199
206
  # @param name [String]
200
207
  # @param tag [String]
201
208
  # @param comments [String]
209
+ # @param decl [RBS::AST::Declarations::ClassAlias, RBS::AST::Declarations::Constant, RBS::AST::Declarations::ModuleAlias]
202
210
  # @param base [String, nil] Optional conversion of tag to base<tag>
203
211
  #
204
212
  # @return [Solargraph::Pin::Constant]
205
- def create_constant(name, tag, comments, base = nil)
213
+ def create_constant(name, tag, comments, decl, base = nil)
206
214
  parts = name.split('::')
207
215
  if parts.length > 1
208
216
  name = parts.last
@@ -214,10 +222,12 @@ module Solargraph
214
222
  constant_pin = Solargraph::Pin::Constant.new(
215
223
  name: name,
216
224
  closure: closure,
225
+ type_location: location_decl_to_pin_location(decl.location),
217
226
  comments: comments
218
227
  )
219
228
  tag = "#{base}<#{tag}>" if base
220
- constant_pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', tag))
229
+ rooted_tag = ComplexType.parse(tag).force_rooted.rooted_tags
230
+ constant_pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
221
231
  constant_pin
222
232
  end
223
233
 
@@ -228,7 +238,7 @@ module Solargraph
228
238
  new_name = decl.new_name.relative!.to_s
229
239
  old_name = decl.old_name.relative!.to_s
230
240
 
231
- pins.push create_constant(new_name, old_name, decl.comment&.string, 'Class')
241
+ pins.push create_constant(new_name, old_name, decl.comment&.string, decl, 'Class')
232
242
  end
233
243
 
234
244
  # @param decl [RBS::AST::Declarations::ModuleAlias]
@@ -238,14 +248,14 @@ module Solargraph
238
248
  new_name = decl.new_name.relative!.to_s
239
249
  old_name = decl.old_name.relative!.to_s
240
250
 
241
- pins.push create_constant(new_name, old_name, decl.comment&.string, 'Module')
251
+ pins.push create_constant(new_name, old_name, decl.comment&.string, decl, 'Module')
242
252
  end
243
253
 
244
254
  # @param decl [RBS::AST::Declarations::Constant]
245
255
  # @return [void]
246
256
  def constant_decl_to_pin decl
247
257
  tag = other_type_to_tag(decl.type)
248
- pins.push create_constant(decl.name.relative!.to_s, tag, decl.comment&.string)
258
+ pins.push create_constant(decl.name.relative!.to_s, tag, decl.comment&.string, decl)
249
259
  end
250
260
 
251
261
  # @param decl [RBS::AST::Declarations::Global]
@@ -253,13 +263,13 @@ module Solargraph
253
263
  def global_decl_to_pin decl
254
264
  closure = Solargraph::Pin::ROOT_PIN
255
265
  name = decl.name.to_s
256
- tag = other_type_to_tag(decl.type)
257
266
  pin = Solargraph::Pin::GlobalVariable.new(
258
267
  name: name,
259
268
  closure: closure,
260
269
  comments: decl.comment&.string,
261
270
  )
262
- pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', tag))
271
+ rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
272
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
263
273
  pins.push pin
264
274
  end
265
275
 
@@ -276,6 +286,7 @@ module Solargraph
276
286
  pin = Solargraph::Pin::Method.new(
277
287
  name: decl.name.to_s,
278
288
  closure: closure,
289
+ type_location: location_decl_to_pin_location(decl.location),
279
290
  comments: decl.comment&.string,
280
291
  scope: :instance,
281
292
  signatures: [],
@@ -295,6 +306,7 @@ module Solargraph
295
306
  name: decl.name.to_s,
296
307
  closure: closure,
297
308
  comments: decl.comment&.string,
309
+ type_location: location_decl_to_pin_location(decl.location),
298
310
  scope: :class,
299
311
  signatures: [],
300
312
  generics: generics
@@ -310,42 +322,42 @@ module Solargraph
310
322
  def method_def_to_sigs decl, pin
311
323
  decl.overloads.map do |overload|
312
324
  generics = overload.method_type.type_params.map(&:to_s)
313
- parameters, return_type = parts_of_function(overload.method_type, pin)
325
+ signature_parameters, signature_return_type = parts_of_function(overload.method_type, pin)
314
326
  block = if overload.method_type.block
315
- Pin::Signature.new(generics, *parts_of_function(overload.method_type.block, pin))
316
- end
317
- return_type = ComplexType.try_parse(method_type_to_tag(overload.method_type))
318
- Pin::Signature.new(generics, parameters, return_type, block)
327
+ block_parameters, block_return_type = parts_of_function(overload.method_type.block, pin)
328
+ Pin::Signature.new(generics: generics, parameters: block_parameters, return_type: block_return_type)
329
+ end
330
+ Pin::Signature.new(generics: generics, parameters: signature_parameters, return_type: signature_return_type, block: block)
319
331
  end
320
332
  end
321
333
 
322
334
  # @param location [RBS::Location, nil]
323
335
  # @return [Solargraph::Location, nil]
324
- def rbs_location_to_location(location)
336
+ def location_decl_to_pin_location(location)
325
337
  return nil if location&.name.nil?
326
338
 
327
339
  start_pos = Position.new(location.start_line - 1, location.start_column)
328
340
  end_pos = Position.new(location.end_line - 1, location.end_column)
329
341
  range = Range.new(start_pos, end_pos)
330
- Location.new(location.name, range)
342
+ Location.new(location.name.to_s, range)
331
343
  end
332
344
 
333
345
  # @param type [RBS::MethodType,RBS::Types::Block]
334
346
  # @param pin [Pin::Method]
335
- # @return [Array<Array<Pin::Parameter>, ComplexType>]
347
+ # @return [Array(Array<Pin::Parameter>, ComplexType)]
336
348
  def parts_of_function type, pin
337
- return [[Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin)], ComplexType.try_parse(method_type_to_tag(type))] if defined?(RBS::Types::UntypedFunction) && type.type.is_a?(RBS::Types::UntypedFunction)
349
+ return [[Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin)], ComplexType.try_parse(method_type_to_tag(type)).force_rooted] if defined?(RBS::Types::UntypedFunction) && type.type.is_a?(RBS::Types::UntypedFunction)
338
350
 
339
351
  parameters = []
340
352
  arg_num = -1
341
353
  type.type.required_positionals.each do |param|
342
354
  name = param.name ? param.name.to_s : "arg#{arg_num += 1}"
343
- parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
355
+ parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted)
344
356
  end
345
357
  type.type.optional_positionals.each do |param|
346
358
  name = param.name ? param.name.to_s : "arg#{arg_num += 1}"
347
359
  parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin,
348
- return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
360
+ return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted)
349
361
  end
350
362
  if type.type.rest_positionals
351
363
  name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "arg#{arg_num += 1}"
@@ -358,18 +370,20 @@ module Solargraph
358
370
  type.type.required_keywords.each do |orig, param|
359
371
  name = orig ? orig.to_s : "arg#{arg_num += 1}"
360
372
  parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin,
361
- return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
373
+ return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted)
362
374
  end
363
375
  type.type.optional_keywords.each do |orig, param|
364
376
  name = orig ? orig.to_s : "arg#{arg_num += 1}"
365
377
  parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin,
366
- return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
378
+ return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted)
367
379
  end
368
380
  if type.type.rest_keywords
369
381
  name = type.type.rest_keywords.name ? type.type.rest_keywords.name.to_s : "arg#{arg_num += 1}"
370
382
  parameters.push Solargraph::Pin::Parameter.new(decl: :kwrestarg, name: type.type.rest_keywords.name.to_s, closure: pin)
371
383
  end
372
- return_type = ComplexType.try_parse(method_type_to_tag(type))
384
+
385
+ rooted_tag = method_type_to_tag(type)
386
+ return_type = ComplexType.try_parse(rooted_tag).force_rooted
373
387
  [parameters, return_type]
374
388
  end
375
389
 
@@ -379,12 +393,14 @@ module Solargraph
379
393
  def attr_reader_to_pin(decl, closure)
380
394
  pin = Solargraph::Pin::Method.new(
381
395
  name: decl.name.to_s,
396
+ type_location: location_decl_to_pin_location(decl.location),
382
397
  closure: closure,
383
398
  comments: decl.comment&.string,
384
399
  scope: :instance,
385
400
  attribute: true
386
401
  )
387
- pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', other_type_to_tag(decl.type)))
402
+ rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
403
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
388
404
  pins.push pin
389
405
  end
390
406
 
@@ -394,12 +410,14 @@ module Solargraph
394
410
  def attr_writer_to_pin(decl, closure)
395
411
  pin = Solargraph::Pin::Method.new(
396
412
  name: "#{decl.name.to_s}=",
413
+ type_location: location_decl_to_pin_location(decl.location),
397
414
  closure: closure,
398
415
  comments: decl.comment&.string,
399
416
  scope: :instance,
400
417
  attribute: true
401
418
  )
402
- pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', other_type_to_tag(decl.type)))
419
+ rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
420
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
403
421
  pins.push pin
404
422
  end
405
423
 
@@ -418,9 +436,11 @@ module Solargraph
418
436
  pin = Solargraph::Pin::InstanceVariable.new(
419
437
  name: decl.name.to_s,
420
438
  closure: closure,
439
+ type_location: location_decl_to_pin_location(decl.location),
421
440
  comments: decl.comment&.string
422
441
  )
423
- pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', other_type_to_tag(decl.type)))
442
+ rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
443
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
424
444
  pins.push pin
425
445
  end
426
446
 
@@ -434,7 +454,8 @@ module Solargraph
434
454
  closure: closure,
435
455
  comments: decl.comment&.string
436
456
  )
437
- pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', other_type_to_tag(decl.type)))
457
+ rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
458
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
438
459
  pins.push pin
439
460
  end
440
461
 
@@ -448,7 +469,8 @@ module Solargraph
448
469
  closure: closure,
449
470
  comments: decl.comment&.string
450
471
  )
451
- pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', other_type_to_tag(decl.type)))
472
+ rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
473
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
452
474
  pins.push pin
453
475
  end
454
476
 
@@ -456,10 +478,11 @@ module Solargraph
456
478
  # @param closure [Pin::Namespace]
457
479
  # @return [void]
458
480
  def include_to_pin decl, closure
459
- type = generic_type(decl.name, decl.args)
481
+ type = build_type(decl.name, decl.args)
460
482
  generic_values = type.all_params.map(&:to_s)
461
483
  pins.push Solargraph::Pin::Reference::Include.new(
462
484
  name: decl.name.relative!.to_s,
485
+ type_location: location_decl_to_pin_location(decl.location),
463
486
  generic_values: generic_values,
464
487
  closure: closure
465
488
  )
@@ -471,6 +494,7 @@ module Solargraph
471
494
  def prepend_to_pin decl, closure
472
495
  pins.push Solargraph::Pin::Reference::Prepend.new(
473
496
  name: decl.name.relative!.to_s,
497
+ type_location: location_decl_to_pin_location(decl.location),
474
498
  closure: closure
475
499
  )
476
500
  end
@@ -481,6 +505,7 @@ module Solargraph
481
505
  def extend_to_pin decl, closure
482
506
  pins.push Solargraph::Pin::Reference::Extend.new(
483
507
  name: decl.name.relative!.to_s,
508
+ type_location: location_decl_to_pin_location(decl.location),
484
509
  closure: closure
485
510
  )
486
511
  end
@@ -491,6 +516,7 @@ module Solargraph
491
516
  def alias_to_pin decl, closure
492
517
  pins.push Solargraph::Pin::MethodAlias.new(
493
518
  name: decl.new_name.to_s,
519
+ type_location: location_decl_to_pin_location(decl.location),
494
520
  original: decl.old_name.to_s,
495
521
  closure: closure
496
522
  )
@@ -517,10 +543,10 @@ module Solargraph
517
543
  # @param type_name [RBS::TypeName]
518
544
  # @param type_args [Enumerable<RBS::Types::Bases::Base>]
519
545
  # @return [ComplexType::UniqueType]
520
- def generic_type(type_name, type_args)
546
+ def build_type(type_name, type_args = [])
521
547
  base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
522
548
  params = type_args.map { |a| other_type_to_tag(a) }.reject { |t| t == 'undefined' }.map do |t|
523
- ComplexType.try_parse(t)
549
+ ComplexType.try_parse(t).force_rooted
524
550
  end
525
551
  if base == 'Hash' && params.length == 2
526
552
  ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: true, parameters_type: :hash)
@@ -532,8 +558,8 @@ module Solargraph
532
558
  # @param type_name [RBS::TypeName]
533
559
  # @param type_args [Enumerable<RBS::Types::Bases::Base>]
534
560
  # @return [String]
535
- def generic_type_tag(type_name, type_args)
536
- generic_type(type_name, type_args).tag
561
+ def type_tag(type_name, type_args = [])
562
+ build_type(type_name, type_args).tags
537
563
  end
538
564
 
539
565
  # @param type [RBS::Types::Bases::Base]
@@ -549,7 +575,7 @@ module Solargraph
549
575
  elsif type.is_a?(RBS::Types::Tuple)
550
576
  "Array(#{type.types.map { |t| other_type_to_tag(t) }.join(', ')})"
551
577
  elsif type.is_a?(RBS::Types::Literal)
552
- "#{type.literal}"
578
+ type.literal.to_s
553
579
  elsif type.is_a?(RBS::Types::Union)
554
580
  type.types.map { |t| other_type_to_tag(t) }.join(', ')
555
581
  elsif type.is_a?(RBS::Types::Record)
@@ -564,7 +590,7 @@ module Solargraph
564
590
  elsif type.is_a?(RBS::Types::Variable)
565
591
  "#{Solargraph::ComplexType::GENERIC_TAG_NAME}<#{type.name}>"
566
592
  elsif type.is_a?(RBS::Types::ClassInstance) #&& !type.args.empty?
567
- generic_type_tag(type.name, type.args)
593
+ type_tag(type.name, type.args)
568
594
  elsif type.is_a?(RBS::Types::Bases::Instance)
569
595
  'self'
570
596
  elsif type.is_a?(RBS::Types::Bases::Top)
@@ -581,8 +607,18 @@ module Solargraph
581
607
  type.types.map { |member| other_type_to_tag(member) }.join(', ')
582
608
  elsif type.is_a?(RBS::Types::Proc)
583
609
  'Proc'
584
- elsif type.respond_to?(:name) && type.name.respond_to?(:relative!)
585
- RBS_TO_YARD_TYPE[type.name.relative!.to_s] || type.name.relative!.to_s
610
+ elsif type.is_a?(RBS::Types::Alias)
611
+ # type-level alias use - e.g., 'bool' in "type bool = true | false"
612
+ # @todo ensure these get resolved after processing all aliases
613
+ # @todo handle recursive aliases
614
+ type_tag(type.name, type.args)
615
+ elsif type.is_a?(RBS::Types::Interface)
616
+ # represents a mix-in module which can be considered a
617
+ # subtype of a consumer of it
618
+ type_tag(type.name, type.args)
619
+ elsif type.is_a?(RBS::Types::ClassSingleton)
620
+ # e.g., singleton(String)
621
+ type_tag(type.name)
586
622
  else
587
623
  Solargraph.logger.warn "Unrecognized RBS type: #{type.class} at #{type.location}"
588
624
  'undefined'
@@ -595,9 +631,12 @@ module Solargraph
595
631
  def add_mixins decl, namespace
596
632
  decl.each_mixin do |mixin|
597
633
  klass = mixin.is_a?(RBS::AST::Members::Include) ? Pin::Reference::Include : Pin::Reference::Extend
634
+ type = build_type(mixin.name, mixin.args)
635
+ generic_values = type.all_params.map(&:to_s)
598
636
  pins.push klass.new(
599
637
  name: mixin.name.relative!.to_s,
600
- location: rbs_location_to_location(mixin.location),
638
+ type_location: location_decl_to_pin_location(mixin.location),
639
+ generic_values: generic_values,
601
640
  closure: namespace
602
641
  )
603
642
  end
@@ -19,17 +19,17 @@ module Solargraph
19
19
  Solargraph::Pin::Method.new(name: 'tap', scope: :instance,
20
20
  closure: Solargraph::Pin::Namespace.new(name: 'Object')),
21
21
  Solargraph::Pin::Method.new(name: 'class', scope: :instance,
22
- closure: Solargraph::Pin::Namespace.new(name: 'Object'), comments: '@return [Class<self>]')
22
+ closure: Solargraph::Pin::Namespace.new(name: 'Object'), comments: '@return [::Class<self>]')
23
23
  ]
24
24
 
25
25
  OVERRIDES = [
26
26
  Override.from_comment('BasicObject#instance_eval', '@yieldreceiver [self]'),
27
27
  Override.from_comment('BasicObject#instance_exec', '@yieldreceiver [self]'),
28
- Override.from_comment('Module#define_method', '@yieldreceiver [Object<self>]'),
29
- Override.from_comment('Module#class_eval', '@yieldreceiver [Class<self>]'),
30
- Override.from_comment('Module#class_exec', '@yieldreceiver [Class<self>]'),
31
- Override.from_comment('Module#module_eval', '@yieldreceiver [Module<self>]'),
32
- Override.from_comment('Module#module_exec', '@yieldreceiver [Module<self>]'),
28
+ Override.from_comment('Module#define_method', '@yieldreceiver [::Object<self>]'),
29
+ Override.from_comment('Module#class_eval', '@yieldreceiver [::Class<self>]'),
30
+ Override.from_comment('Module#class_exec', '@yieldreceiver [::Class<self>]'),
31
+ Override.from_comment('Module#module_eval', '@yieldreceiver [::Module<self>]'),
32
+ Override.from_comment('Module#module_exec', '@yieldreceiver [::Module<self>]'),
33
33
  # RBS does not define Class with a generic, so all calls to
34
34
  # generic() return an 'untyped'. We can do better:
35
35
  Override.method_return('Class#allocate', 'self')
@@ -89,7 +89,7 @@ module Solargraph
89
89
  )
90
90
  # @return [void]
91
91
  def clear
92
- puts "Deleting the cached documentation"
92
+ puts "Deleting all cached documentation (gems, core and stdlib)"
93
93
  Solargraph::Cache.clear
94
94
  end
95
95
  map 'clear-cache' => :clear
@@ -105,11 +105,26 @@ module Solargraph
105
105
  Cache.save('gems', "#{spec.name}-#{spec.version}.ser", pins)
106
106
  end
107
107
 
108
- desc 'uncache GEM [...GEM]', "Delete cached gem documentation"
108
+ desc 'uncache GEM [...GEM]', "Delete specific cached gem documentation"
109
+ long_desc %(
110
+ Specify one or more gem names to clear. 'core' or 'stdlib' may
111
+ also be specified to clear cached system documentation.
112
+ Documentation will be regenerated as needed.
113
+ )
109
114
  # @return [void]
110
115
  def uncache *gems
111
116
  raise ArgumentError, 'No gems specified.' if gems.empty?
112
117
  gems.each do |gem|
118
+ if gem == 'core'
119
+ Cache.uncache("core.ser")
120
+ next
121
+ end
122
+
123
+ if gem == 'stdlib'
124
+ Cache.uncache("stdlib")
125
+ next
126
+ end
127
+
113
128
  spec = Gem::Specification.find_by_name(gem)
114
129
  Cache.uncache('gems', "#{spec.name}-#{spec.version}.ser")
115
130
  Cache.uncache('gems', "#{spec.name}-#{spec.version}.yardoc")
@@ -17,14 +17,15 @@ module Solargraph
17
17
  # @param locals [Enumerable<Pin::LocalVariable>]
18
18
  def resolve api_map, name_pin, locals
19
19
  child_types = @children.map do |child|
20
- child.infer(api_map, name_pin, locals).tag
20
+ child.infer(api_map, name_pin, locals)
21
21
  end
22
- type = if child_types.uniq.length == 1 && child_types.first != 'undefined'
23
- "::Array<#{child_types.first}>"
22
+
23
+ type = if child_types.uniq.length == 1 && child_types.first.defined?
24
+ ComplexType::UniqueType.new('Array', [], child_types.uniq, rooted: true, parameters_type: :list)
24
25
  else
25
- '::Array'
26
+ ComplexType::UniqueType.new('Array', rooted: true)
26
27
  end
27
- [Pin::ProxyType.anonymous(ComplexType.try_parse(type))]
28
+ [Pin::ProxyType.anonymous(type)]
28
29
  end
29
30
  end
30
31
  end
@@ -5,7 +5,7 @@ module Solargraph
5
5
  class Chain
6
6
  class BlockSymbol < Link
7
7
  def resolve api_map, name_pin, locals
8
- [Pin::ProxyType.anonymous(ComplexType.try_parse('Proc'))]
8
+ [Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'))]
9
9
  end
10
10
  end
11
11
  end
@@ -5,7 +5,7 @@ module Solargraph
5
5
  class Chain
6
6
  class BlockVariable < Link
7
7
  def resolve api_map, name_pin, locals
8
- [Pin::ProxyType.anonymous(ComplexType.try_parse('Proc'))]
8
+ [Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'))]
9
9
  end
10
10
  end
11
11
  end