solargraph 0.39.0 → 0.39.1
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/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
|