solargraph 0.39.0 → 0.39.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/solargraph/parser/legacy/class_methods.rb +4 -0
- data/lib/solargraph/parser/legacy/node_chainer.rb +5 -2
- data/lib/solargraph/parser/legacy/node_methods.rb +7 -3
- data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -2
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +4 -2
- data/lib/solargraph/source/chain.rb +1 -0
- data/lib/solargraph/source/chain/call.rb +9 -0
- data/lib/solargraph/source/chain/head.rb +14 -8
- data/lib/solargraph/source/chain/z_super.rb +184 -0
- data/lib/solargraph/type_checker.rb +25 -1
- data/lib/solargraph/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b287c1f54a79a771b343e16110cc0640a948abd0a6a5d7f187cd43e7bbea8b45
|
4
|
+
data.tar.gz: 9b425158e5ee4f420c0ea84397d7d171f1893f2e49aed6ebbb3c7f920618679d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7c6214462ba598bfd184367c39d05264f82a5b0f94503ffe55ab321b8a8e7c8ef9da470780a7608b47c2360b8dc647d05a0546ff4ecddc6005ff2b015371629
|
7
|
+
data.tar.gz: 6810ce41c48475b6875b1337f56f3cd4553abba55e51a0c42158678a6545a4255e0c2ae96b51961fe4c23bee95afb3c8a78322db93a36ac85506a433ee73aaf8
|
@@ -73,8 +73,11 @@ module Solargraph
|
|
73
73
|
end
|
74
74
|
elsif n.type == :self
|
75
75
|
result.push Chain::Head.new('self')
|
76
|
-
elsif
|
77
|
-
result.push Chain::
|
76
|
+
elsif n.type == :zsuper
|
77
|
+
result.push Chain::ZSuper.new('super', @in_block || block_passed?(n))
|
78
|
+
elsif n.type == :super
|
79
|
+
args = n.children.map { |c| NodeChainer.chain(c) }
|
80
|
+
result.push Chain::Call.new('super', args, @in_block || block_passed?(n))
|
78
81
|
elsif n.type == :const
|
79
82
|
const = unpack_name(n)
|
80
83
|
result.push Chain::Constant.new(const)
|
@@ -126,7 +126,7 @@ module Solargraph
|
|
126
126
|
result.push node
|
127
127
|
node.children[0].children[2..-1].each { |child| result.concat call_nodes_from(child) }
|
128
128
|
node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
|
129
|
-
elsif node.type
|
129
|
+
elsif [:send, :super, :zsuper].include?(node.type)
|
130
130
|
result.push node
|
131
131
|
node.children[2..-1].each { |child| result.concat call_nodes_from(child) }
|
132
132
|
else
|
@@ -210,8 +210,12 @@ module Solargraph
|
|
210
210
|
result.concat get_return_nodes_only(node.children[2])
|
211
211
|
elsif node.type == :case
|
212
212
|
node.children[1..-1].each do |cc|
|
213
|
-
|
214
|
-
|
213
|
+
if cc.nil?
|
214
|
+
result.push NIL_NODE
|
215
|
+
else
|
216
|
+
result.concat reduce_to_value_nodes(cc.children[1..-2]) unless cc.children.length < 1
|
217
|
+
result.concat reduce_to_value_nodes([cc.children.last])
|
218
|
+
end
|
215
219
|
end
|
216
220
|
else
|
217
221
|
result.push node
|
@@ -8,7 +8,7 @@ module Solargraph
|
|
8
8
|
# @param filename [String]
|
9
9
|
# @return [Array(Parser::AST::Node, Array<Parser::Source::Comment>)]
|
10
10
|
def parse_with_comments code, filename = nil
|
11
|
-
node = RubyVM::AbstractSyntaxTree.parse(code)
|
11
|
+
node = RubyVM::AbstractSyntaxTree.parse(code).children[2]
|
12
12
|
comments = CommentRipper.new(code).parse
|
13
13
|
[node, comments]
|
14
14
|
rescue ::SyntaxError => e
|
@@ -20,7 +20,7 @@ module Solargraph
|
|
20
20
|
# @param line [Integer]
|
21
21
|
# @return [Parser::AST::Node]
|
22
22
|
def parse code, filename = nil, line = 0
|
23
|
-
RubyVM::AbstractSyntaxTree.parse(code)
|
23
|
+
RubyVM::AbstractSyntaxTree.parse(code).children[2]
|
24
24
|
rescue ::SyntaxError => e
|
25
25
|
raise Parser::SyntaxError, e.message
|
26
26
|
end
|
@@ -83,6 +83,10 @@ module Solargraph
|
|
83
83
|
NodeChainer.chain *args
|
84
84
|
end
|
85
85
|
|
86
|
+
def chain_string *args
|
87
|
+
NodeChainer.load_string *args
|
88
|
+
end
|
89
|
+
|
86
90
|
def process_node *args
|
87
91
|
Solargraph::Parser::NodeProcessor.process *args
|
88
92
|
end
|
@@ -69,8 +69,10 @@ module Solargraph
|
|
69
69
|
result.push Chain::Call.new(n.children[0].to_s, node_to_argchains(n.children[1]), @in_block || block_passed?(n))
|
70
70
|
elsif n.type == :SELF
|
71
71
|
result.push Chain::Head.new('self')
|
72
|
-
elsif
|
73
|
-
result.push Chain::
|
72
|
+
elsif n.type == :ZSUPER
|
73
|
+
result.push Chain::ZSuper.new('super', @in_block || block_passed?(n))
|
74
|
+
elsif n.type == :SUPER
|
75
|
+
result.push Chain::Call.new('super', node_to_argchains(n.children.last), @in_block || block_passed?(n))
|
74
76
|
elsif [:COLON2, :COLON3, :CONST].include?(n.type)
|
75
77
|
const = unpack_name(n)
|
76
78
|
result.push Chain::Constant.new(const)
|
@@ -20,6 +20,7 @@ module Solargraph
|
|
20
20
|
autoload :Head, 'solargraph/source/chain/head'
|
21
21
|
autoload :Or, 'solargraph/source/chain/or'
|
22
22
|
autoload :BlockVariable, 'solargraph/source/chain/block_variable'
|
23
|
+
autoload :ZSuper, 'solargraph/source/chain/z_super'
|
23
24
|
|
24
25
|
@@inference_stack = []
|
25
26
|
@@inference_depth = 0
|
@@ -28,6 +28,7 @@ module Solargraph
|
|
28
28
|
# @param name_pin [Pin::Base]
|
29
29
|
# @param locals [Array<Pin::Base>]
|
30
30
|
def resolve api_map, name_pin, locals
|
31
|
+
return super_pins(api_map, name_pin) if word == 'super'
|
31
32
|
found = if head?
|
32
33
|
locals.select { |p| p.name == word }
|
33
34
|
else
|
@@ -188,6 +189,14 @@ module Solargraph
|
|
188
189
|
return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.first.start_with?('*'))
|
189
190
|
true
|
190
191
|
end
|
192
|
+
|
193
|
+
# @param api_map [ApiMap]
|
194
|
+
# @param name_pin [Pin::Base]
|
195
|
+
# @return [Array<Pin::Base>]
|
196
|
+
def super_pins api_map, name_pin
|
197
|
+
pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
|
198
|
+
pins.reject{|p| p.path == name_pin.path}
|
199
|
+
end
|
191
200
|
end
|
192
201
|
end
|
193
202
|
end
|
@@ -10,19 +10,25 @@ module Solargraph
|
|
10
10
|
class Head < Link
|
11
11
|
def resolve api_map, name_pin, locals
|
12
12
|
return [Pin::ProxyType.anonymous(name_pin.binder)] if word == 'self'
|
13
|
-
return super_pins(api_map, name_pin) if word == 'super'
|
13
|
+
# return super_pins(api_map, name_pin) if word == 'super'
|
14
14
|
[]
|
15
15
|
end
|
16
16
|
|
17
|
+
# @todo This is temporary. Chain heads need to handle arguments to
|
18
|
+
# `super`.
|
19
|
+
# def arguments
|
20
|
+
# []
|
21
|
+
# end
|
22
|
+
|
17
23
|
private
|
18
24
|
|
19
|
-
# @param api_map [ApiMap]
|
20
|
-
# @param name_pin [Pin::Base]
|
21
|
-
# @return [Array<Pin::Base>]
|
22
|
-
def super_pins api_map, name_pin
|
23
|
-
|
24
|
-
|
25
|
-
end
|
25
|
+
# # @param api_map [ApiMap]
|
26
|
+
# # @param name_pin [Pin::Base]
|
27
|
+
# # @return [Array<Pin::Base>]
|
28
|
+
# def super_pins api_map, name_pin
|
29
|
+
# pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
|
30
|
+
# pins.reject{|p| p.path == name_pin.path}
|
31
|
+
# end
|
26
32
|
end
|
27
33
|
end
|
28
34
|
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
class Chain
|
6
|
+
class ZSuper < Call
|
7
|
+
# @return [String]
|
8
|
+
attr_reader :word
|
9
|
+
|
10
|
+
# @return [Array<Chain>]
|
11
|
+
attr_reader :arguments
|
12
|
+
|
13
|
+
# @param word [String]
|
14
|
+
# @param arguments [Array<Chain>]
|
15
|
+
# @param with_block [Boolean] True if the chain is inside a block
|
16
|
+
# @param head [Boolean] True if the call is the start of its chain
|
17
|
+
def initialize word, with_block = false
|
18
|
+
super(word, [], with_block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def with_block?
|
22
|
+
@with_block
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param api_map [ApiMap]
|
26
|
+
# @param name_pin [Pin::Base]
|
27
|
+
# @param locals [Array<Pin::Base>]
|
28
|
+
def resolve api_map, name_pin, locals
|
29
|
+
return super_pins(api_map, name_pin)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# @param pins [Array<Pin::Base>]
|
35
|
+
# @param api_map [ApiMap]
|
36
|
+
# @param context [ComplexType]
|
37
|
+
# @param locals [Pin::LocalVariable]
|
38
|
+
# @return [Array<Pin::Base>]
|
39
|
+
def inferred_pins pins, api_map, context, locals
|
40
|
+
result = pins.map do |p|
|
41
|
+
overloads = p.docstring.tags(:overload)
|
42
|
+
# next p if overloads.empty?
|
43
|
+
type = ComplexType::UNDEFINED
|
44
|
+
# @param [YARD::Tags::OverloadTag]
|
45
|
+
overloads.each do |ol|
|
46
|
+
next unless arguments_match(arguments, ol.parameters)
|
47
|
+
next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
|
48
|
+
match = true
|
49
|
+
arguments.each_with_index do |arg, idx|
|
50
|
+
achain = arguments[idx]
|
51
|
+
next if achain.nil?
|
52
|
+
param = ol.parameters[idx]
|
53
|
+
if param.nil?
|
54
|
+
match = false unless ol.parameters.last && ol.parameters.last.first.start_with?('*')
|
55
|
+
break
|
56
|
+
end
|
57
|
+
par = ol.tags(:param).select { |pp| pp.name == param.first }.first
|
58
|
+
next if par.nil? || par.types.nil? || par.types.empty?
|
59
|
+
atype = achain.infer(api_map, Pin::ProxyType.anonymous(context), locals)
|
60
|
+
other = ComplexType.try_parse(*par.types)
|
61
|
+
# @todo Weak type comparison
|
62
|
+
unless atype.tag == other.tag || api_map.super_and_sub?(other.tag, atype.tag)
|
63
|
+
match = false
|
64
|
+
break
|
65
|
+
end
|
66
|
+
end
|
67
|
+
if match
|
68
|
+
type = extra_return_type(ol, context)
|
69
|
+
type = ComplexType.try_parse(*ol.tag(:return).types).self_to(context.to_s).qualify(api_map, context.namespace) if ol.has_tag?(:return) && ol.tag(:return).types && !ol.tag(:return).types.empty? && (type.nil? || type.undefined?)
|
70
|
+
type ||= ComplexType::UNDEFINED
|
71
|
+
end
|
72
|
+
break if type.defined?
|
73
|
+
end
|
74
|
+
next p.proxy(type) if type.defined?
|
75
|
+
type = extra_return_type(p.docstring, context)
|
76
|
+
if type
|
77
|
+
next Solargraph::Pin::Method.new(
|
78
|
+
location: p.location,
|
79
|
+
closure: p.closure,
|
80
|
+
name: p.name,
|
81
|
+
comments: "@return [#{context.subtypes.first.to_s}]",
|
82
|
+
scope: p.scope,
|
83
|
+
visibility: p.visibility,
|
84
|
+
parameters: p.parameters,
|
85
|
+
node: p.node
|
86
|
+
)
|
87
|
+
end
|
88
|
+
if p.is_a?(Pin::Method) && !p.macros.empty?
|
89
|
+
result = process_macro(p, api_map, context, locals)
|
90
|
+
next result unless result.return_type.undefined?
|
91
|
+
elsif !p.directives.empty?
|
92
|
+
result = process_directive(p, api_map, context, locals)
|
93
|
+
next result unless result.return_type.undefined?
|
94
|
+
end
|
95
|
+
p
|
96
|
+
end
|
97
|
+
result.map do |pin|
|
98
|
+
next pin if pin.return_type.undefined?
|
99
|
+
selfy = pin.return_type.self_to(context.tag)
|
100
|
+
selfy == pin.return_type ? pin : pin.proxy(selfy)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# @param pin [Pin::Method]
|
105
|
+
# @param api_map [ApiMap]
|
106
|
+
# @param context [ComplexType]
|
107
|
+
# @param locals [Pin::Base]
|
108
|
+
# @return [Pin::Base]
|
109
|
+
def process_macro pin, api_map, context, locals
|
110
|
+
pin.macros.each do |macro|
|
111
|
+
result = inner_process_macro(pin, macro, api_map, context, locals)
|
112
|
+
return result unless result.return_type.undefined?
|
113
|
+
end
|
114
|
+
Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
|
115
|
+
end
|
116
|
+
|
117
|
+
# @param pin [Pin::Method]
|
118
|
+
# @param api_map [ApiMap]
|
119
|
+
# @param context [ComplexType]
|
120
|
+
# @param locals [Pin::Base]
|
121
|
+
# @return [Pin::ProxyType]
|
122
|
+
def process_directive pin, api_map, context, locals
|
123
|
+
pin.directives.each do |dir|
|
124
|
+
macro = api_map.named_macro(dir.tag.name)
|
125
|
+
next if macro.nil?
|
126
|
+
result = inner_process_macro(pin, macro, api_map, context, locals)
|
127
|
+
return result unless result.return_type.undefined?
|
128
|
+
end
|
129
|
+
Pin::ProxyType.anonymous ComplexType::UNDEFINED
|
130
|
+
end
|
131
|
+
|
132
|
+
# @param pin [Pin]
|
133
|
+
# @param macro [YARD::Tags::MacroDirective]
|
134
|
+
# @param api_map [ApiMap]
|
135
|
+
# @param context [ComplexType]
|
136
|
+
# @param locals [Array<Pin::Base>]
|
137
|
+
# @return [Pin::ProxyType]
|
138
|
+
def inner_process_macro pin, macro, api_map, context, locals
|
139
|
+
vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
|
140
|
+
txt = macro.tag.text.clone
|
141
|
+
if txt.empty? && macro.tag.name
|
142
|
+
named = api_map.named_macro(macro.tag.name)
|
143
|
+
txt = named.tag.text.clone if named
|
144
|
+
end
|
145
|
+
i = 1
|
146
|
+
vals.each do |v|
|
147
|
+
txt.gsub!(/\$#{i}/, v.context.namespace)
|
148
|
+
i += 1
|
149
|
+
end
|
150
|
+
docstring = Solargraph::Source.parse_docstring(txt).to_docstring
|
151
|
+
tag = docstring.tag(:return)
|
152
|
+
unless tag.nil? || tag.types.nil?
|
153
|
+
return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
|
154
|
+
end
|
155
|
+
Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
|
156
|
+
end
|
157
|
+
|
158
|
+
# @param docstring [YARD::Docstring]
|
159
|
+
# @param context [ComplexType]
|
160
|
+
# @return [ComplexType]
|
161
|
+
def extra_return_type docstring, context
|
162
|
+
if docstring.has_tag?(:return_single_parameter) && context.subtypes.one?
|
163
|
+
return context.subtypes.first
|
164
|
+
elsif docstring.has_tag?(:return_value_parameter) && context.value_types.one?
|
165
|
+
return context.value_types.first
|
166
|
+
end
|
167
|
+
nil
|
168
|
+
end
|
169
|
+
|
170
|
+
# @param arguments [Array<Chain>]
|
171
|
+
# @param parameters [Array<String>]
|
172
|
+
# @return [Boolean]
|
173
|
+
def arguments_match arguments, parameters
|
174
|
+
argcount = arguments.length
|
175
|
+
# argcount -= 1 if !arguments.empty? && arguments.last.links.first.word.start_with?('&')
|
176
|
+
parcount = parameters.length
|
177
|
+
parcount -= 1 if !parameters.empty? && parameters.last.first.start_with?('&')
|
178
|
+
return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.first.start_with?('*'))
|
179
|
+
true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -248,7 +248,11 @@ module Solargraph
|
|
248
248
|
if pins.first.is_a?(Pin::BaseMethod)
|
249
249
|
# @type [Pin::BaseMethod]
|
250
250
|
pin = pins.first
|
251
|
-
|
251
|
+
if base.links.last.is_a?(Solargraph::Source::Chain::ZSuper)
|
252
|
+
ap = arity_problems_for(pin, fake_args_for(block_pin), location)
|
253
|
+
else
|
254
|
+
ap = arity_problems_for(pin, base.links.last.arguments, location)
|
255
|
+
end
|
252
256
|
unless ap.empty?
|
253
257
|
result.concat ap
|
254
258
|
break
|
@@ -470,5 +474,25 @@ module Solargraph
|
|
470
474
|
pin.docstring.has_tag?(:abstract) ||
|
471
475
|
(pin.closure && pin.closure.docstring.has_tag?(:abstract))
|
472
476
|
end
|
477
|
+
|
478
|
+
def fake_args_for(pin)
|
479
|
+
args = []
|
480
|
+
with_opts = false
|
481
|
+
with_block = false
|
482
|
+
pin.parameters.each do |pin|
|
483
|
+
if [:kwarg, :kwoptarg, :kwrestarg].include?(pin.decl)
|
484
|
+
with_opts = true
|
485
|
+
elsif pin.decl == :block
|
486
|
+
with_block = true
|
487
|
+
elsif pin.decl == :restarg
|
488
|
+
args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)], nil, true)
|
489
|
+
else
|
490
|
+
args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)])
|
491
|
+
end
|
492
|
+
end
|
493
|
+
args.push Solargraph::Parser.chain_string('{}') if with_opts
|
494
|
+
args.push Solargraph::Parser.chain_string('&') if with_block
|
495
|
+
args
|
496
|
+
end
|
473
497
|
end
|
474
498
|
end
|
data/lib/solargraph/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solargraph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.39.
|
4
|
+
version: 0.39.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
@@ -513,6 +513,7 @@ files:
|
|
513
513
|
- lib/solargraph/source/chain/literal.rb
|
514
514
|
- lib/solargraph/source/chain/or.rb
|
515
515
|
- lib/solargraph/source/chain/variable.rb
|
516
|
+
- lib/solargraph/source/chain/z_super.rb
|
516
517
|
- lib/solargraph/source/change.rb
|
517
518
|
- lib/solargraph/source/cursor.rb
|
518
519
|
- lib/solargraph/source/encoding_fixes.rb
|