solargraph 0.51.1 → 0.52.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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -2
  3. data/CHANGELOG.md +31 -5
  4. data/lib/solargraph/api_map/cache.rb +2 -0
  5. data/lib/solargraph/api_map/store.rb +2 -2
  6. data/lib/solargraph/api_map.rb +11 -4
  7. data/lib/solargraph/complex_type/type_methods.rb +1 -1
  8. data/lib/solargraph/complex_type/unique_type.rb +19 -12
  9. data/lib/solargraph/complex_type.rb +24 -10
  10. data/lib/solargraph/documentor.rb +1 -1
  11. data/lib/solargraph/library.rb +12 -5
  12. data/lib/solargraph/parser/comment_ripper.rb +1 -0
  13. data/lib/solargraph/parser/legacy/class_methods.rb +2 -2
  14. data/lib/solargraph/parser/legacy/node_chainer.rb +18 -10
  15. data/lib/solargraph/parser/legacy/node_methods.rb +5 -3
  16. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +28 -13
  17. data/lib/solargraph/parser/legacy/node_processors.rb +22 -21
  18. data/lib/solargraph/parser/node_methods.rb +1 -0
  19. data/lib/solargraph/parser/region.rb +1 -1
  20. data/lib/solargraph/parser/rubyvm/class_methods.rb +1 -3
  21. data/lib/solargraph/parser/rubyvm/node_chainer.rb +5 -2
  22. data/lib/solargraph/parser.rb +2 -0
  23. data/lib/solargraph/pin/base.rb +1 -1
  24. data/lib/solargraph/pin/block.rb +2 -2
  25. data/lib/solargraph/pin/delegated_method.rb +1 -1
  26. data/lib/solargraph/pin/method.rb +63 -6
  27. data/lib/solargraph/pin/namespace.rb +10 -3
  28. data/lib/solargraph/pin/parameter.rb +9 -10
  29. data/lib/solargraph/pin/signature.rb +9 -1
  30. data/lib/solargraph/rbs_map/conversions.rb +86 -31
  31. data/lib/solargraph/rbs_map/core_fills.rb +9 -10
  32. data/lib/solargraph/rbs_map/core_map.rb +1 -1
  33. data/lib/solargraph/rbs_map.rb +2 -3
  34. data/lib/solargraph/source/chain/array.rb +29 -0
  35. data/lib/solargraph/source/chain/call.rb +14 -30
  36. data/lib/solargraph/source/chain/link.rb +1 -1
  37. data/lib/solargraph/source/chain/z_super.rb +1 -1
  38. data/lib/solargraph/source/chain.rb +9 -10
  39. data/lib/solargraph/source/source_chainer.rb +2 -0
  40. data/lib/solargraph/source.rb +3 -3
  41. data/lib/solargraph/source_map/clip.rb +0 -16
  42. data/lib/solargraph/source_map/mapper.rb +2 -1
  43. data/lib/solargraph/source_map.rb +2 -2
  44. data/lib/solargraph/type_checker.rb +18 -7
  45. data/lib/solargraph/version.rb +1 -1
  46. data/lib/solargraph/workspace.rb +2 -1
  47. data/lib/solargraph/yard_map/mapper.rb +1 -1
  48. data/lib/solargraph/yard_map.rb +6 -5
  49. data/lib/solargraph/yard_tags.rb +20 -0
  50. data/lib/solargraph.rb +2 -3
  51. data/solargraph.gemspec +3 -0
  52. metadata +32 -3
  53. data/lib/yard-solargraph.rb +0 -33
@@ -19,6 +19,8 @@ module Solargraph
19
19
 
20
20
  selected = rubyvm? ? Rubyvm : Legacy
21
21
  # include selected
22
+ # @!parse
23
+ # extend Solargraph::Parser::Legacy::ClassMethods
22
24
  extend selected::ClassMethods
23
25
 
24
26
  NodeMethods = (rubyvm? ? Rubyvm::NodeMethods : Legacy::NodeMethods)
@@ -217,7 +217,7 @@ module Solargraph
217
217
  end
218
218
 
219
219
  def identity
220
- @identity ||= "#{closure.context.namespace}|#{name}"
220
+ @identity ||= "#{closure.path}|#{name}"
221
221
  end
222
222
 
223
223
  def inspect
@@ -58,10 +58,10 @@ module Solargraph
58
58
  return Solargraph::ComplexType.parse(closure.binder.namespace)
59
59
  end
60
60
  end
61
- # other case without early return, read block yieldself tags
61
+ # other case without early return, read block yieldreceiver tags
62
62
  receiver_pin = chain.define(api_map, self, locals).first
63
63
  if receiver_pin && receiver_pin.docstring
64
- ys = receiver_pin.docstring.tag(:yieldself)
64
+ ys = receiver_pin.docstring.tag(:yieldreceiver)
65
65
  if ys && ys.types && !ys.types.empty?
66
66
  target = if chain.links.first.is_a?(Source::Chain::Constant)
67
67
  receiver_pin.full_context.namespace
@@ -12,7 +12,7 @@ module Solargraph
12
12
  # to a method pin on that type.
13
13
  #
14
14
  # @param resolved_method [Method] an already resolved method pin.
15
- # @param receiver [Source::Chain] the source code used to resolve the receiver for this delegated method.
15
+ # @param receiver [Source::Chain, nil] the source code used to resolve the receiver for this delegated method.
16
16
  # @param receiver_method_name [String] the method name that will be called on the receiver (defaults to :name).
17
17
  def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat)
18
18
  raise ArgumentError, 'either :method or :receiver is required' if (method && receiver) || (!method && !receiver)
@@ -19,7 +19,7 @@ module Solargraph
19
19
  # @param visibility [::Symbol] :public, :protected, or :private
20
20
  # @param explicit [Boolean]
21
21
  # @param parameters [Array<Pin::Parameter>]
22
- # @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node]
22
+ # @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node, nil]
23
23
  # @param attribute [Boolean]
24
24
  def initialize visibility: :public, explicit: true, parameters: [], node: nil, attribute: false, signatures: nil, anon_splat: false, **splat
25
25
  super(**splat)
@@ -46,7 +46,38 @@ module Solargraph
46
46
  end
47
47
 
48
48
  def return_type
49
- @return_type ||= ComplexType.try_parse(*signatures.map(&:return_type).map(&:to_s))
49
+ @return_type ||= ComplexType.new(signatures.map(&:return_type).flat_map(&:items))
50
+ end
51
+
52
+ # @return [Signature]
53
+ def generate_signature(parameters, return_type)
54
+ block = nil
55
+ yieldparam_tags = docstring.tags(:yieldparam)
56
+ yieldreturn_tags = docstring.tags(:yieldreturn)
57
+ needs_block_param_signature =
58
+ parameters.last&.block? || !yieldreturn_tags.empty? || !yieldparam_tags.empty?
59
+ if needs_block_param_signature
60
+ yield_parameters = yieldparam_tags.map do |p|
61
+ name = p.name
62
+ decl = :arg
63
+ if name
64
+ decl = select_decl(name, false)
65
+ name = clean_param(name)
66
+ end
67
+ Pin::Parameter.new(
68
+ location: location,
69
+ closure: self,
70
+ comments: p.text,
71
+ name: name,
72
+ decl: decl,
73
+ presence: location ? location.range : nil,
74
+ return_type: ComplexType.try_parse(*p.types)
75
+ )
76
+ end
77
+ yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
78
+ block = Signature.new(yield_parameters, yield_return_type)
79
+ end
80
+ Signature.new(parameters, return_type, block)
50
81
  end
51
82
 
52
83
  # @return [Array<Signature>]
@@ -54,9 +85,9 @@ module Solargraph
54
85
  @signatures ||= begin
55
86
  top_type = generate_complex_type
56
87
  result = []
57
- result.push Signature.new(parameters, top_type) if top_type.defined?
58
- result.concat(overloads.map { |meth| Signature.new(meth.parameters, meth.return_type) })
59
- result.push Signature.new(parameters, top_type) if result.empty?
88
+ result.push generate_signature(parameters, top_type) if top_type.defined?
89
+ result.concat(overloads.map { |meth| generate_signature(meth.parameters, meth.return_type) }) unless overloads.empty?
90
+ result.push generate_signature(parameters, top_type) if result.empty?
60
91
  result
61
92
  end
62
93
  end
@@ -115,6 +146,32 @@ module Solargraph
115
146
  end
116
147
  @documentation += lines.join("\n")
117
148
  end
149
+ yieldparam_tags = docstring.tags(:yieldparam)
150
+ unless yieldparam_tags.nil? or yieldparam_tags.empty?
151
+ @documentation += "\n\n" unless @documentation.empty?
152
+ @documentation += "Block Params:\n"
153
+ lines = []
154
+ yieldparam_tags.each do |p|
155
+ l = "* #{p.name}"
156
+ l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? or p.types.empty?
157
+ l += " #{p.text}"
158
+ lines.push l
159
+ end
160
+ @documentation += lines.join("\n")
161
+ end
162
+ yieldreturn_tags = docstring.tags(:yieldreturn)
163
+ unless yieldreturn_tags.empty?
164
+ @documentation += "\n\n" unless @documentation.empty?
165
+ @documentation += "Block Returns:\n"
166
+ lines = []
167
+ yieldreturn_tags.each do |r|
168
+ l = "*"
169
+ l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty?
170
+ l += " #{r.text}"
171
+ lines.push l
172
+ end
173
+ @documentation += lines.join("\n")
174
+ end
118
175
  return_tags = docstring.tags(:return)
119
176
  unless return_tags.empty?
120
177
  @documentation += "\n\n" unless @documentation.empty?
@@ -337,7 +394,7 @@ module Solargraph
337
394
  return if example_tags.empty?
338
395
  @documentation += "\n\nExamples:\n\n```ruby\n"
339
396
  @documentation += example_tags.map do |tag|
340
- (tag.name ? "# #{tag.name}\n" : '') +
397
+ (tag.name && !tag.name.empty? ? "# #{tag.name}\n" : '') +
341
398
  "#{tag.text}\n"
342
399
  end
343
400
  .join("\n")
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'solargraph/yard_tags'
4
+
3
5
  module Solargraph
4
6
  module Pin
5
7
  class Namespace < Closure
@@ -9,12 +11,12 @@ module Solargraph
9
11
  # @return [::Symbol] :class or :module
10
12
  attr_reader :type
11
13
 
12
- attr_reader :parameters
14
+ attr_reader :generics
13
15
 
14
16
  # @param type [::Symbol] :class or :module
15
17
  # @param visibility [::Symbol] :public or :private
16
18
  # @param gates [Array<String>]
17
- def initialize type: :class, visibility: :public, gates: [''], parameters: [], **splat
19
+ def initialize type: :class, visibility: :public, gates: [''], generics: nil, **splat
18
20
  # super(location, namespace, name, comments)
19
21
  super(**splat)
20
22
  @type = type
@@ -38,7 +40,7 @@ module Solargraph
38
40
  @closure = Pin::Namespace.new(name: closure_name, gates: [parts.join('::')])
39
41
  @context = nil
40
42
  end
41
- @parameters = parameters
43
+ @generics = generics
42
44
  end
43
45
 
44
46
  def namespace
@@ -89,6 +91,11 @@ module Solargraph
89
91
  [path] + @open_gates
90
92
  end
91
93
  end
94
+
95
+ # @return [Array<String>]
96
+ def generics
97
+ @generics ||= docstring.tags(:generic).map(&:name)
98
+ end
92
99
  end
93
100
  end
94
101
  end
@@ -123,17 +123,16 @@ module Solargraph
123
123
  clip = api_map.clip_at(location.filename, location.range.start)
124
124
  locals = clip.locals - [self]
125
125
  meths = chain.define(api_map, closure, locals)
126
+ receiver_type = chain.base.infer(api_map, closure, locals)
126
127
  meths.each do |meth|
127
- if meth.docstring.has_tag?(:yieldparam_single_parameter)
128
- type = chain.base.infer(api_map, closure, locals)
129
- if type.defined? && !type.subtypes.empty?
130
- bmeth = chain.base.define(api_map, closure, locals).first
131
- return type.subtypes.first.qualify(api_map, bmeth.context.namespace)
132
- end
133
- else
134
- yps = meth.docstring.tags(:yieldparam)
135
- unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
136
- return ComplexType.try_parse(yps[index].types.first).self_to(chain.base.infer(api_map, closure, locals).namespace).qualify(api_map, meth.context.namespace)
128
+ yps = meth.docstring.tags(:yieldparam)
129
+ unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
130
+ yield_type = ComplexType.try_parse(yps[index].types.first)
131
+ if yield_type.generic? && receiver_type.defined?
132
+ namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
133
+ return yield_type.resolve_generics(namespace_pin, receiver_type)
134
+ else
135
+ return yield_type.self_to(chain.base.infer(api_map, closure, locals).namespace).qualify(api_map, meth.context.namespace)
137
136
  end
138
137
  end
139
138
  end
@@ -1,20 +1,28 @@
1
1
  module Solargraph
2
2
  module Pin
3
- class Signature
3
+ class Signature < Base
4
4
  # @return [Array<Parameter>]
5
5
  attr_reader :parameters
6
6
 
7
7
  # @return [ComplexType]
8
8
  attr_reader :return_type
9
9
 
10
+ # @return [self]
10
11
  attr_reader :block
11
12
 
13
+ # @param parameters [Array<Parameter>]
14
+ # @param return_type [ComplexType]
15
+ # @param block [Signature, nil]
12
16
  def initialize parameters, return_type, block = nil
13
17
  @parameters = parameters
14
18
  @return_type = return_type
15
19
  @block = block
16
20
  end
17
21
 
22
+ def identity
23
+ @identity ||= "signature#{object_id}"
24
+ end
25
+
18
26
  def block?
19
27
  !!@block
20
28
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rbs'
4
+
3
5
  module Solargraph
4
6
  class RbsMap
5
7
  # Functions for converting RBS declarations to Solargraph pins
@@ -25,15 +27,42 @@ module Solargraph
25
27
 
26
28
  private
27
29
 
30
+ # @return Hash{String => RBS::AST::Declarations::TypeAlias}
28
31
  def type_aliases
29
32
  @type_aliases ||= {}
30
33
  end
31
34
 
35
+ # @param loader [RBS::EnvironmentLoader]
36
+ # @return [void]
37
+ def load_environment_to_pins(loader)
38
+ environment = RBS::Environment.from_loader(loader).resolve_type_names
39
+ cursor = pins.length
40
+ environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
41
+ added_pins = pins[cursor..-1]
42
+ add_back_implicit_pins(added_pins)
43
+ end
44
+
45
+ # @param added_pins [Range<Pin>]
46
+ # @return [void]
47
+ def add_back_implicit_pins(added_pins)
48
+ added_pins.each do |pin|
49
+ pin.source = :rbs
50
+ next unless pin.is_a?(Pin::Namespace) && pin.type == :class
51
+ next if pins.any? { |p| p.path == "#{pin.path}.new"}
52
+ pins.push Solargraph::Pin::Method.new(
53
+ location: nil,
54
+ closure: pin,
55
+ name: 'new',
56
+ comments: pin.comments,
57
+ scope: :class
58
+ )
59
+ end
60
+ end
61
+
32
62
  # @param decl [RBS::AST::Declarations::Base]
33
63
  # @param closure [Pin::Closure]
34
64
  # @return [void]
35
65
  def convert_decl_to_pin decl, closure
36
- cursor = pins.length
37
66
  case decl
38
67
  when RBS::AST::Declarations::Class
39
68
  class_decl_to_pin decl
@@ -46,18 +75,10 @@ module Solargraph
46
75
  module_decl_to_pin decl
47
76
  when RBS::AST::Declarations::Constant
48
77
  constant_decl_to_pin decl
49
- end
50
- pins[cursor..-1].each do |pin|
51
- pin.source = :rbs
52
- next unless pin.is_a?(Pin::Namespace) && pin.type == :class
53
- next if pins.any? { |p| p.path == "#{pin.path}.new"}
54
- pins.push Solargraph::Pin::Method.new(
55
- location: nil,
56
- closure: pin.closure,
57
- name: 'new',
58
- comments: pin.comments,
59
- scope: :class
60
- )
78
+ when RBS::AST::Declarations::ClassAlias
79
+ class_alias_decl_to_pin decl
80
+ else
81
+ Solargraph.logger.info "Skipping declaration #{decl.class}"
61
82
  end
62
83
  end
63
84
 
@@ -106,7 +127,7 @@ module Solargraph
106
127
  name: decl.name.relative!.to_s,
107
128
  closure: Solargraph::Pin::ROOT_PIN,
108
129
  comments: decl.comment&.string,
109
- parameters: decl.type_params.map(&:name).map(&:to_s)
130
+ generics: decl.type_params.map(&:name).map(&:to_s)
110
131
  )
111
132
  pins.push class_pin
112
133
  if decl.super_class
@@ -142,16 +163,20 @@ module Solargraph
142
163
  type: :module,
143
164
  name: decl.name.relative!.to_s,
144
165
  closure: Solargraph::Pin::ROOT_PIN,
145
- comments: decl.comment&.string
166
+ comments: decl.comment&.string,
167
+ generics: decl.type_params.map(&:name).map(&:to_s),
146
168
  )
147
169
  pins.push module_pin
148
170
  convert_members_to_pin decl, module_pin
149
171
  end
150
172
 
151
- # @param decl [RBS::AST::Declarations::Constant]
152
- # @return [void]
153
- def constant_decl_to_pin decl
154
- parts = decl.name.relative!.to_s.split('::')
173
+ # @param name [String]
174
+ # @param tag [String]
175
+ # @param comments [String]
176
+ #
177
+ # @return [Solargraph::Pin::Constant]
178
+ def create_constant(name, tag, comments)
179
+ parts = name.split('::')
155
180
  if parts.length > 1
156
181
  name = parts.last
157
182
  closure = pins.select { |pin| pin && pin.path == parts[0..-2].join('::') }.first
@@ -159,15 +184,31 @@ module Solargraph
159
184
  name = parts.first
160
185
  closure = Solargraph::Pin::ROOT_PIN
161
186
  end
162
- pin = Solargraph::Pin::Constant.new(
187
+ constant_pin = Solargraph::Pin::Constant.new(
163
188
  name: name,
164
189
  closure: closure,
165
- comments: decl.comment&.string
190
+ comments: comments
166
191
  )
167
- tag = other_type_to_tag(decl.type)
168
192
  # @todo Class or Module?
169
- pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', "Class<#{tag}>"))
170
- pins.push pin
193
+ constant_pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', "Class<#{tag}>"))
194
+ constant_pin
195
+ end
196
+
197
+ # @param decl [RBS::AST::Declarations::ClassAlias]
198
+ # @return [void]
199
+ def class_alias_decl_to_pin decl
200
+ # See https://www.rubydoc.info/gems/rbs/3.4.3/RBS/AST/Declarations/ClassAlias
201
+ new_name = decl.new_name.relative!.to_s
202
+ old_name = decl.old_name.relative!.to_s
203
+
204
+ pins.push create_constant(new_name, old_name, decl.comment&.string)
205
+ end
206
+
207
+ # @param decl [RBS::AST::Declarations::Constant]
208
+ # @return [void]
209
+ def constant_decl_to_pin decl
210
+ tag = other_type_to_tag(decl.type)
211
+ pins.push create_constant(decl.name.relative!.to_s, tag, decl.comment&.string)
171
212
  end
172
213
 
173
214
  # @param decl [RBS::AST::Members::MethodDefinition]
@@ -243,7 +284,8 @@ module Solargraph
243
284
  end
244
285
  type.type.optional_positionals.each do |param|
245
286
  name = param.name ? param.name.to_s : "arg#{arg_num += 1}"
246
- parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin)
287
+ parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin,
288
+ return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
247
289
  end
248
290
  if type.type.rest_positionals
249
291
  name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "arg#{arg_num += 1}"
@@ -253,13 +295,15 @@ module Solargraph
253
295
  name = param.name ? param.name.to_s : "arg#{arg_num += 1}"
254
296
  parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin)
255
297
  end
256
- type.type.required_keywords.each do |orig, _param|
298
+ type.type.required_keywords.each do |orig, param|
257
299
  name = orig ? orig.to_s : "arg#{arg_num += 1}"
258
- parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin)
300
+ parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin,
301
+ return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
259
302
  end
260
- type.type.optional_keywords.each do |orig, _param|
303
+ type.type.optional_keywords.each do |orig, param|
261
304
  name = orig ? orig.to_s : "arg#{arg_num += 1}"
262
- parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin)
305
+ parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin,
306
+ return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
263
307
  end
264
308
  if type.type.rest_keywords
265
309
  name = type.type.rest_keywords.name ? type.type.rest_keywords.name.to_s : "arg#{arg_num += 1}"
@@ -329,6 +373,7 @@ module Solargraph
329
373
  )
330
374
  end
331
375
 
376
+ # @param decl [RBS::AST::Members::Alias]
332
377
  def alias_to_pin decl, closure
333
378
  pins.push Solargraph::Pin::MethodAlias.new(
334
379
  name: decl.new_name.to_s,
@@ -345,6 +390,8 @@ module Solargraph
345
390
  'NilClass' => 'nil'
346
391
  }
347
392
 
393
+ # @param type [RBS::AST::Members::MethodDefinition::Overload]
394
+ # @return [String]
348
395
  def method_type_to_tag type
349
396
  if type_aliases.key?(type.type.return_type.to_s)
350
397
  other_type_to_tag(type_aliases[type.type.return_type.to_s].type)
@@ -378,16 +425,24 @@ module Solargraph
378
425
  elsif type.is_a?(RBS::Types::Bases::Void)
379
426
  'void'
380
427
  elsif type.is_a?(RBS::Types::Variable)
381
- "param<#{type.name}>"
428
+ "#{Solargraph::ComplexType::GENERIC_TAG_NAME}<#{type.name}>"
382
429
  elsif type.is_a?(RBS::Types::ClassInstance) #&& !type.args.empty?
383
430
  base = RBS_TO_YARD_TYPE[type.name.relative!.to_s] || type.name.relative!.to_s
384
431
  params = type.args.map { |a| other_type_to_tag(a) }.reject { |t| t == 'undefined' }
385
432
  return base if params.empty?
386
433
  "#{base}<#{params.join(', ')}>"
434
+ elsif type.is_a?(RBS::Types::Bases::Instance)
435
+ 'self'
436
+ elsif type.is_a?(RBS::Types::Bases::Top) || type.is_a?(RBS::Types::Bases::Bottom)
437
+ 'self'
438
+ elsif type.is_a?(RBS::Types::Intersection)
439
+ type.types.map { |member| other_type_to_tag(member) }.join(', ')
440
+ elsif type.is_a?(RBS::Types::Proc)
441
+ 'Proc'
387
442
  elsif type.respond_to?(:name) && type.name.respond_to?(:relative!)
388
443
  RBS_TO_YARD_TYPE[type.name.relative!.to_s] || type.name.relative!.to_s
389
444
  else
390
- Solargraph.logger.warn "Unrecognized RBS type: #{type.class} #{type}"
445
+ Solargraph.logger.warn "Unrecognized RBS type: #{type.class} at #{type.location}"
391
446
  'undefined'
392
447
  end
393
448
  end
@@ -16,8 +16,10 @@ module Solargraph
16
16
  ].map { |k| Pin::Keyword.new(k) }
17
17
 
18
18
  MISSING = [
19
- Solargraph::Pin::Method.new(name: 'tap', scope: :instance, closure: Solargraph::Pin::Namespace.new(name: 'Object')),
20
- Solargraph::Pin::Method.new(name: 'class', scope: :instance, closure: Solargraph::Pin::Namespace.new(name: 'Object'), comments: '@return [Class<self>]')
19
+ Solargraph::Pin::Method.new(name: 'tap', scope: :instance,
20
+ closure: Solargraph::Pin::Namespace.new(name: 'Object')),
21
+ Solargraph::Pin::Method.new(name: 'class', scope: :instance,
22
+ closure: Solargraph::Pin::Namespace.new(name: 'Object'), comments: '@return [Class<self>]')
21
23
  ]
22
24
 
23
25
  YIELDPARAMS = [
@@ -27,7 +29,7 @@ module Solargraph
27
29
  )),
28
30
  Override.from_comment('String#each_line', %(
29
31
  @yieldparam [String]
30
- )),
32
+ ))
31
33
  ]
32
34
 
33
35
  methods_with_yieldparam_subtypes = %w[
@@ -39,16 +41,14 @@ module Solargraph
39
41
  ]
40
42
 
41
43
  YIELDPARAM_SINGLE_PARAMETERS = methods_with_yieldparam_subtypes.map do |path|
42
- Override.from_comment(path, %(
43
- @yieldparam_single_parameter
44
- ))
44
+ Override.from_comment(path, <<~DOC
45
+ @yieldparam [generic<Elem>]
46
+ DOC
47
+ )
45
48
  end
46
49
 
47
50
  CLASS_RETURN_TYPES = [
48
- Override.method_return('Class#new', 'self'),
49
- Override.method_return('Class.new', 'Class<BasicObject>'),
50
51
  Override.method_return('Class#allocate', 'self'),
51
- Override.method_return('Class.allocate', 'Class<BasicObject>'),
52
52
  ]
53
53
 
54
54
  # HACK: Add Errno exception classes
@@ -64,4 +64,3 @@ module Solargraph
64
64
  end
65
65
  end
66
66
  end
67
-
@@ -14,7 +14,7 @@ module Solargraph
14
14
  else
15
15
  loader = RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
16
16
  environment = RBS::Environment.from_loader(loader).resolve_type_names
17
- environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
17
+ load_environment_to_pins(loader)
18
18
  pins.concat RbsMap::CoreFills::ALL
19
19
  processed = ApiMap::Store.new(pins).pins.reject { |p| p.is_a?(Solargraph::Pin::Reference::Override) }
20
20
  pins.replace processed
@@ -24,8 +24,7 @@ module Solargraph
24
24
  loader = RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
25
25
  add_library loader, library
26
26
  return unless resolved?
27
- environment = RBS::Environment.from_loader(loader).resolve_type_names
28
- environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
27
+ load_environment_to_pins(loader)
29
28
  end
30
29
 
31
30
  def path_pin path
@@ -57,7 +56,7 @@ module Solargraph
57
56
  # @return [Boolean] true if adding the library succeeded
58
57
  def add_library loader, library
59
58
  @resolved = if loader.has_library?(library: library, version: nil)
60
- loader.add library: library
59
+ loader.add library: library, version: nil
61
60
  Solargraph.logger.info "#{short_name} successfully loaded library #{library}"
62
61
  true
63
62
  else
@@ -0,0 +1,29 @@
1
+ module Solargraph
2
+ class Source
3
+ class Chain
4
+ class Array < Literal
5
+ # @param type [String]
6
+ def initialize children
7
+ super('::Array')
8
+ @children = children
9
+ end
10
+
11
+ def word
12
+ @word ||= "<#{@type}>"
13
+ end
14
+
15
+ def resolve api_map, name_pin, locals
16
+ child_types = @children.map do |child|
17
+ child.infer(api_map, name_pin, locals).tag
18
+ end
19
+ type = if child_types.uniq.length == 1 && child_types.first != 'undefined'
20
+ "::Array<#{child_types.first}>"
21
+ else
22
+ '::Array'
23
+ end
24
+ [Pin::ProxyType.anonymous(ComplexType.try_parse(type))]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -11,7 +11,7 @@ module Solargraph
11
11
  attr_reader :arguments
12
12
 
13
13
  # @param word [String]
14
- # @param arguments [Array<Chain>]
14
+ # @param arguments [::Array<Chain>]
15
15
  # @param with_block [Boolean] True if the chain is inside a block
16
16
  # @param head [Boolean] True if the call is the start of its chain
17
17
  def initialize word, arguments = [], with_block = false
@@ -26,9 +26,10 @@ module Solargraph
26
26
 
27
27
  # @param api_map [ApiMap]
28
28
  # @param name_pin [Pin::Base]
29
- # @param locals [Array<Pin::Base>]
29
+ # @param locals [::Array<Pin::Base>]
30
30
  def resolve api_map, name_pin, locals
31
31
  return super_pins(api_map, name_pin) if word == 'super'
32
+ return yield_pins(api_map, name_pin) if word == 'yield'
32
33
  found = if head?
33
34
  locals.select { |p| p.name == word }
34
35
  else
@@ -75,27 +76,12 @@ module Solargraph
75
76
  end
76
77
  end
77
78
  if match
78
- type = extra_return_type(p.docstring, context)
79
- break if type
80
79
  type = with_params(ol.return_type.self_to(context.to_s), context).qualify(api_map, context.namespace) if ol.return_type.defined?
81
80
  type ||= ComplexType::UNDEFINED
82
81
  end
83
82
  break if type.defined?
84
83
  end
85
84
  next p.proxy(type) if type.defined?
86
- type = extra_return_type(p.docstring, context)
87
- if type
88
- next Solargraph::Pin::Method.new(
89
- location: p.location,
90
- closure: p.closure,
91
- name: p.name,
92
- comments: "@return [#{context.subtypes.first.to_s}]",
93
- scope: p.scope,
94
- visibility: p.visibility,
95
- parameters: p.parameters,
96
- node: p.node
97
- )
98
- end
99
85
  if p.is_a?(Pin::Method) && !p.macros.empty?
100
86
  result = process_macro(p, api_map, context, locals)
101
87
  next result unless result.return_type.undefined?
@@ -170,18 +156,6 @@ module Solargraph
170
156
  Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
171
157
  end
172
158
 
173
- # @param docstring [YARD::Docstring]
174
- # @param context [ComplexType]
175
- # @return [ComplexType]
176
- def extra_return_type docstring, context
177
- if docstring.has_tag?(:return_single_parameter) #&& context.subtypes.one?
178
- return context.subtypes.first || ComplexType::UNDEFINED
179
- elsif docstring.has_tag?(:return_value_parameter) && context.value_types.one?
180
- return context.value_types.first
181
- end
182
- nil
183
- end
184
-
185
159
  # @param arguments [Array<Chain>]
186
160
  # @param signature [Pin::Signature]
187
161
  # @return [Boolean]
@@ -197,12 +171,22 @@ module Solargraph
197
171
 
198
172
  # @param api_map [ApiMap]
199
173
  # @param name_pin [Pin::Base]
200
- # @return [Array<Pin::Base>]
174
+ # @return [::Array<Pin::Base>]
201
175
  def super_pins api_map, name_pin
202
176
  pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.context.scope)
203
177
  pins.reject{|p| p.path == name_pin.path}
204
178
  end
205
179
 
180
+ # @param api_map [ApiMap]
181
+ # @param name_pin [Pin::Base]
182
+ # @return [::Array<Pin::Base>]
183
+ def yield_pins api_map, name_pin
184
+ method_pin = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.context.scope).first
185
+ return [] if method_pin.nil?
186
+
187
+ method_pin.signatures.map(&:block).compact
188
+ end
189
+
206
190
  # @param type [ComplexType]
207
191
  # @param context [ComplexType]
208
192
  def with_params type, context