solargraph 0.51.2 → 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.
- checksums.yaml +4 -4
- data/.yardopts +2 -2
- data/CHANGELOG.md +25 -5
- data/lib/solargraph/api_map/cache.rb +2 -0
- data/lib/solargraph/api_map/store.rb +2 -2
- data/lib/solargraph/api_map.rb +11 -4
- data/lib/solargraph/complex_type/type_methods.rb +1 -1
- data/lib/solargraph/complex_type/unique_type.rb +20 -13
- data/lib/solargraph/complex_type.rb +13 -9
- data/lib/solargraph/documentor.rb +1 -1
- data/lib/solargraph/library.rb +12 -5
- data/lib/solargraph/parser/comment_ripper.rb +1 -0
- data/lib/solargraph/parser/legacy/class_methods.rb +2 -2
- data/lib/solargraph/parser/legacy/node_chainer.rb +9 -4
- data/lib/solargraph/parser/legacy/node_methods.rb +5 -3
- data/lib/solargraph/parser/node_methods.rb +1 -0
- data/lib/solargraph/parser/region.rb +1 -1
- data/lib/solargraph/parser/rubyvm/class_methods.rb +1 -3
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +5 -2
- data/lib/solargraph/parser.rb +2 -0
- data/lib/solargraph/pin/base.rb +1 -1
- data/lib/solargraph/pin/block.rb +2 -2
- data/lib/solargraph/pin/delegated_method.rb +1 -1
- data/lib/solargraph/pin/method.rb +62 -5
- data/lib/solargraph/pin/namespace.rb +10 -3
- data/lib/solargraph/pin/parameter.rb +9 -10
- data/lib/solargraph/pin/signature.rb +9 -1
- data/lib/solargraph/rbs_map/conversions.rb +86 -31
- data/lib/solargraph/rbs_map/core_fills.rb +9 -10
- data/lib/solargraph/rbs_map/core_map.rb +1 -1
- data/lib/solargraph/rbs_map.rb +2 -3
- data/lib/solargraph/source/chain/array.rb +29 -0
- data/lib/solargraph/source/chain/call.rb +14 -30
- data/lib/solargraph/source/chain/link.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +1 -1
- data/lib/solargraph/source/chain.rb +9 -10
- data/lib/solargraph/source/source_chainer.rb +2 -0
- data/lib/solargraph/source.rb +3 -3
- data/lib/solargraph/source_map/clip.rb +0 -16
- data/lib/solargraph/source_map/mapper.rb +2 -1
- data/lib/solargraph/source_map.rb +2 -2
- data/lib/solargraph/type_checker.rb +18 -7
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +2 -1
- data/lib/solargraph/yard_map/mapper.rb +1 -1
- data/lib/solargraph/yard_map.rb +6 -5
- data/lib/solargraph/yard_tags.rb +20 -0
- data/lib/solargraph.rb +2 -3
- data/solargraph.gemspec +1 -0
- metadata +18 -3
- data/lib/yard-solargraph.rb +0 -33
@@ -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 :
|
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: [''],
|
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
|
-
@
|
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
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
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
|
152
|
-
# @
|
153
|
-
|
154
|
-
|
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
|
-
|
187
|
+
constant_pin = Solargraph::Pin::Constant.new(
|
163
188
|
name: name,
|
164
189
|
closure: closure,
|
165
|
-
comments:
|
190
|
+
comments: comments
|
166
191
|
)
|
167
|
-
tag = other_type_to_tag(decl.type)
|
168
192
|
# @todo Class or Module?
|
169
|
-
|
170
|
-
|
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,
|
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,
|
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
|
-
"
|
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,
|
20
|
-
|
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
|
-
@
|
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
|
-
|
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
|
data/lib/solargraph/rbs_map.rb
CHANGED
@@ -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
|
-
|
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
|
@@ -23,6 +23,7 @@ module Solargraph
|
|
23
23
|
autoload :BlockVariable, 'solargraph/source/chain/block_variable'
|
24
24
|
autoload :ZSuper, 'solargraph/source/chain/z_super'
|
25
25
|
autoload :Hash, 'solargraph/source/chain/hash'
|
26
|
+
autoload :Array, 'solargraph/source/chain/array'
|
26
27
|
|
27
28
|
@@inference_stack = []
|
28
29
|
@@inference_depth = 0
|
@@ -30,12 +31,12 @@ module Solargraph
|
|
30
31
|
UNDEFINED_CALL = Chain::Call.new('<undefined>')
|
31
32
|
UNDEFINED_CONSTANT = Chain::Constant.new('<undefined>')
|
32
33
|
|
33
|
-
# @return [Array<Source::Chain::Link>]
|
34
|
+
# @return [::Array<Source::Chain::Link>]
|
34
35
|
attr_reader :links
|
35
36
|
|
36
37
|
attr_reader :node
|
37
38
|
|
38
|
-
# @param links [Array<Chain::Link>]
|
39
|
+
# @param links [::Array<Chain::Link>]
|
39
40
|
def initialize links, node = nil, splat = false
|
40
41
|
@links = links.clone
|
41
42
|
@links.push UNDEFINED_CALL if @links.empty?
|
@@ -57,7 +58,7 @@ module Solargraph
|
|
57
58
|
# @param api_map [ApiMap]
|
58
59
|
# @param name_pin [Pin::Base]
|
59
60
|
# @param locals [Array<Pin::Base>]
|
60
|
-
# @return [Array<Pin::Base>]
|
61
|
+
# @return [::Array<Pin::Base>]
|
61
62
|
def define api_map, name_pin, locals
|
62
63
|
return [] if undefined?
|
63
64
|
working_pin = name_pin
|
@@ -122,17 +123,13 @@ module Solargraph
|
|
122
123
|
pins.each do |pin|
|
123
124
|
# Avoid infinite recursion
|
124
125
|
next if @@inference_stack.include?(pin.identity)
|
126
|
+
|
125
127
|
@@inference_stack.push pin.identity
|
126
128
|
type = pin.typify(api_map)
|
127
129
|
@@inference_stack.pop
|
128
130
|
if type.defined?
|
129
|
-
if type.
|
130
|
-
type = type.
|
131
|
-
# idx = pin.closure.parameters.index(type.subtypes.first.name)
|
132
|
-
# next if idx.nil?
|
133
|
-
# param_type = context.return_type.all_params[idx]
|
134
|
-
# next unless param_type
|
135
|
-
# type = ComplexType.try_parse(param_type.to_s)
|
131
|
+
if type.generic?
|
132
|
+
type = type.resolve_generics(pin.closure, context.return_type)
|
136
133
|
end
|
137
134
|
if type.defined?
|
138
135
|
possibles.push type
|
@@ -143,10 +140,12 @@ module Solargraph
|
|
143
140
|
if possibles.empty?
|
144
141
|
# Limit method inference recursion
|
145
142
|
return ComplexType::UNDEFINED if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
|
143
|
+
|
146
144
|
@@inference_depth += 1
|
147
145
|
pins.each do |pin|
|
148
146
|
# Avoid infinite recursion
|
149
147
|
next if @@inference_stack.include?(pin.identity)
|
148
|
+
|
150
149
|
@@inference_stack.push pin.identity
|
151
150
|
type = pin.probe(api_map)
|
152
151
|
@@inference_stack.pop
|
@@ -47,6 +47,8 @@ module Solargraph
|
|
47
47
|
elsif source.parsed? && source.repaired? && end_of_phrase == '.'
|
48
48
|
node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2]
|
49
49
|
node = Parser.parse(fixed_phrase) if node.nil?
|
50
|
+
elsif source.repaired?
|
51
|
+
node = Parser.parse(fixed_phrase)
|
50
52
|
else
|
51
53
|
node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2] unless source.error_ranges.any?{|r| r.nil? || r.include?(fixed_position)}
|
52
54
|
# Exception for positions that chain literal nodes in unsynchronized sources
|
data/lib/solargraph/source.rb
CHANGED
@@ -33,7 +33,7 @@ module Solargraph
|
|
33
33
|
attr_reader :version
|
34
34
|
|
35
35
|
# @param code [String]
|
36
|
-
# @param filename [String]
|
36
|
+
# @param filename [String, nil]
|
37
37
|
# @param version [Integer]
|
38
38
|
def initialize code, filename = nil, version = 0
|
39
39
|
@code = normalize(code)
|
@@ -332,7 +332,7 @@ module Solargraph
|
|
332
332
|
|
333
333
|
# @param top [Parser::AST::Node]
|
334
334
|
# @param result [Array<Range>]
|
335
|
-
# @param parent [Symbol]
|
335
|
+
# @param parent [Symbol, nil]
|
336
336
|
# @return [void]
|
337
337
|
def inner_folding_ranges top, result = [], parent = nil
|
338
338
|
return unless Parser.is_ast_node?(top)
|
@@ -503,7 +503,7 @@ module Solargraph
|
|
503
503
|
end
|
504
504
|
|
505
505
|
# @param code [String]
|
506
|
-
# @param filename [String]
|
506
|
+
# @param filename [String, nil]
|
507
507
|
# @param version [Integer]
|
508
508
|
# @return [Solargraph::Source]
|
509
509
|
def load_string code, filename = nil, version = 0
|
@@ -115,21 +115,6 @@ module Solargraph
|
|
115
115
|
@context_pin ||= source_map.locate_named_path_pin(cursor.node_position.line, cursor.node_position.character)
|
116
116
|
end
|
117
117
|
|
118
|
-
# @return [Array<Pin::Base>]
|
119
|
-
def yielded_self_pins
|
120
|
-
return [] unless block.is_a?(Pin::Block) && block.receiver
|
121
|
-
chain = Parser.chain(block.receiver, source_map.source.filename)
|
122
|
-
receiver_pin = chain.define(api_map, context_pin, locals).first
|
123
|
-
return [] if receiver_pin.nil?
|
124
|
-
result = []
|
125
|
-
ys = receiver_pin.docstring.tag(:yieldpublic)
|
126
|
-
unless ys.nil? || ys.types.empty?
|
127
|
-
ysct = ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
|
128
|
-
result.concat api_map.get_complex_type_methods(ysct, '', false)
|
129
|
-
end
|
130
|
-
result
|
131
|
-
end
|
132
|
-
|
133
118
|
# @return [Array<Pin::KeywordParam]
|
134
119
|
def complete_keyword_parameters
|
135
120
|
return [] unless cursor.argument? && cursor.chain.links.one? && cursor.word =~ /^[a-z0-9_]*:?$/
|
@@ -226,7 +211,6 @@ module Solargraph
|
|
226
211
|
result.concat api_map.get_methods('Kernel')
|
227
212
|
# result.concat ApiMap.keywords
|
228
213
|
result.concat api_map.keyword_pins.to_a
|
229
|
-
result.concat yielded_self_pins
|
230
214
|
end
|
231
215
|
end
|
232
216
|
package_completions(result)
|