solargraph 0.39.0 → 0.40.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/.travis.yml +2 -7
- data/CHANGELOG.md +984 -0
- data/Rakefile +12 -1
- data/SPONSORS.md +6 -0
- data/lib/.rubocop.yml +21 -0
- data/lib/solargraph/api_map/cache.rb +4 -0
- data/lib/solargraph/api_map/store.rb +35 -51
- data/lib/solargraph/api_map.rb +94 -87
- data/lib/solargraph/{bundle.rb → bench.rb} +6 -2
- data/lib/solargraph/compat.rb +23 -0
- data/lib/solargraph/complex_type.rb +2 -2
- data/lib/solargraph/convention/base.rb +16 -8
- data/lib/solargraph/convention/gemfile.rb +2 -5
- data/lib/solargraph/convention/gemspec.rb +3 -6
- data/lib/solargraph/convention/rspec.rb +3 -6
- data/lib/solargraph/convention.rb +14 -5
- data/lib/solargraph/diagnostics/rubocop.rb +2 -1
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -1
- data/lib/solargraph/documentor.rb +4 -0
- data/lib/solargraph/environ.rb +11 -6
- data/lib/solargraph/language_server/host.rb +1 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +6 -1
- data/lib/solargraph/language_server/message/text_document/definition.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/formatting.rb +7 -3
- data/lib/solargraph/language_server/uri_helpers.rb +23 -3
- data/lib/solargraph/library.rb +22 -8
- data/lib/solargraph/parser/legacy/class_methods.rb +4 -0
- data/lib/solargraph/parser/legacy/node_chainer.rb +10 -7
- data/lib/solargraph/parser/legacy/node_methods.rb +16 -3
- data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +1 -1
- data/lib/solargraph/parser/legacy/node_processors/send_node.rb +48 -23
- data/lib/solargraph/parser/node_processor/base.rb +3 -0
- data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -2
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +11 -9
- data/lib/solargraph/parser/rubyvm/node_methods.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +35 -11
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +1 -1
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +52 -67
- data/lib/solargraph/parser/rubyvm/node_processors.rb +2 -0
- data/lib/solargraph/pin/base.rb +2 -2
- data/lib/solargraph/pin/base_variable.rb +1 -1
- data/lib/solargraph/pin/block.rb +28 -14
- data/lib/solargraph/pin/closure.rb +1 -1
- data/lib/solargraph/pin/common.rb +1 -1
- data/lib/solargraph/pin/constant.rb +1 -1
- data/lib/solargraph/pin/conversions.rb +3 -4
- data/lib/solargraph/pin/documenting.rb +6 -11
- data/lib/solargraph/pin/local_variable.rb +1 -1
- data/lib/solargraph/pin/method.rb +143 -9
- data/lib/solargraph/pin/method_alias.rb +2 -2
- data/lib/solargraph/pin/namespace.rb +1 -1
- data/lib/solargraph/pin/parameter.rb +2 -2
- data/lib/solargraph/pin/proxy_type.rb +1 -1
- data/lib/solargraph/pin.rb +0 -3
- data/lib/solargraph/position.rb +2 -14
- data/lib/solargraph/shell.rb +2 -1
- 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 +30 -0
- data/lib/solargraph/source/chain.rb +19 -36
- data/lib/solargraph/source/source_chainer.rb +2 -1
- data/lib/solargraph/source.rb +24 -9
- data/lib/solargraph/source_map/clip.rb +78 -44
- data/lib/solargraph/source_map/mapper.rb +41 -21
- data/lib/solargraph/source_map.rb +20 -2
- data/lib/solargraph/type_checker/param_def.rb +1 -1
- data/lib/solargraph/type_checker.rb +61 -42
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_name_type_tag.erb +1 -1
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map/core_fills.rb +185 -0
- data/lib/solargraph/yard_map/helpers.rb +16 -0
- data/lib/solargraph/{pin/yard_pin/constant.rb → yard_map/mapper/to_constant.rb} +6 -6
- data/lib/solargraph/yard_map/mapper/to_method.rb +78 -0
- data/lib/solargraph/{pin/yard_pin/namespace.rb → yard_map/mapper/to_namespace.rb} +6 -6
- data/lib/solargraph/yard_map/mapper.rb +17 -8
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +26 -15
- data/lib/solargraph/yard_map/stdlib_fills.rb +43 -0
- data/lib/solargraph/yard_map/to_method.rb +79 -0
- data/lib/solargraph/yard_map.rb +140 -92
- data/lib/solargraph.rb +5 -4
- data/solargraph.gemspec +5 -5
- data/yardoc/2.2.2.tar.gz +0 -0
- metadata +29 -41
- data/.rubocop.yml +0 -6
- data/lib/solargraph/core_fills.rb +0 -159
- data/lib/solargraph/pin/attribute.rb +0 -49
- data/lib/solargraph/pin/base_method.rb +0 -141
- data/lib/solargraph/pin/yard_pin/method.rb +0 -65
- data/lib/solargraph/pin/yard_pin/yard_mixin.rb +0 -26
- data/lib/solargraph/pin/yard_pin.rb +0 -12
- data/lib/solargraph/stdlib_fills.rb +0 -32
- data/travis-bundler.rb +0 -11
|
@@ -10,20 +10,7 @@ module Solargraph
|
|
|
10
10
|
def process
|
|
11
11
|
if node.children[0].nil?
|
|
12
12
|
if [:private, :public, :protected].include?(node.children[1])
|
|
13
|
-
|
|
14
|
-
node.children[2..-1].each do |child|
|
|
15
|
-
next unless child.is_a?(AST::Node) && (child.type == :sym || child.type == :str)
|
|
16
|
-
name = child.children[0].to_s
|
|
17
|
-
matches = pins.select{ |pin| pin.is_a?(Pin::BaseMethod) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)}
|
|
18
|
-
matches.each do |pin|
|
|
19
|
-
# @todo Smelly instance variable access
|
|
20
|
-
pin.instance_variable_set(:@visibility, node.children[1])
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
else
|
|
24
|
-
# @todo Smelly instance variable access
|
|
25
|
-
region.instance_variable_set(:@visibility, node.children[1])
|
|
26
|
-
end
|
|
13
|
+
process_visibility
|
|
27
14
|
elsif node.children[1] == :module_function
|
|
28
15
|
process_module_function
|
|
29
16
|
elsif [:attr_reader, :attr_writer, :attr_accessor].include?(node.children[1])
|
|
@@ -36,6 +23,8 @@ module Solargraph
|
|
|
36
23
|
process_prepend
|
|
37
24
|
elsif node.children[1] == :require
|
|
38
25
|
process_require
|
|
26
|
+
elsif node.children[1] == :autoload
|
|
27
|
+
process_autoload
|
|
39
28
|
elsif node.children[1] == :private_constant
|
|
40
29
|
process_private_constant
|
|
41
30
|
elsif node.children[1] == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
|
|
@@ -52,6 +41,27 @@ module Solargraph
|
|
|
52
41
|
|
|
53
42
|
private
|
|
54
43
|
|
|
44
|
+
# @return [void]
|
|
45
|
+
def process_visibility
|
|
46
|
+
if (node.children.length > 2)
|
|
47
|
+
node.children[2..-1].each do |child|
|
|
48
|
+
if child.is_a?(AST::Node) && (child.type == :sym || child.type == :str)
|
|
49
|
+
name = child.children[0].to_s
|
|
50
|
+
matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)}
|
|
51
|
+
matches.each do |pin|
|
|
52
|
+
# @todo Smelly instance variable access
|
|
53
|
+
pin.instance_variable_set(:@visibility, node.children[1])
|
|
54
|
+
end
|
|
55
|
+
else
|
|
56
|
+
process_children region.update(visibility: node.children[1])
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
# @todo Smelly instance variable access
|
|
61
|
+
region.instance_variable_set(:@visibility, node.children[1])
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
55
65
|
# @return [void]
|
|
56
66
|
def process_attribute
|
|
57
67
|
node.children[2..-1].each do |a|
|
|
@@ -59,26 +69,30 @@ module Solargraph
|
|
|
59
69
|
clos = region.closure
|
|
60
70
|
cmnt = comments_for(node)
|
|
61
71
|
if node.children[1] == :attr_reader || node.children[1] == :attr_accessor
|
|
62
|
-
pins.push Solargraph::Pin::
|
|
72
|
+
pins.push Solargraph::Pin::Method.new(
|
|
63
73
|
location: loc,
|
|
64
74
|
closure: clos,
|
|
65
75
|
name: a.children[0].to_s,
|
|
66
76
|
comments: cmnt,
|
|
67
|
-
access: :reader,
|
|
68
77
|
scope: region.scope || :instance,
|
|
69
|
-
visibility: region.visibility
|
|
78
|
+
visibility: region.visibility,
|
|
79
|
+
attribute: true
|
|
70
80
|
)
|
|
71
81
|
end
|
|
72
82
|
if node.children[1] == :attr_writer || node.children[1] == :attr_accessor
|
|
73
|
-
pins.push Solargraph::Pin::
|
|
83
|
+
pins.push Solargraph::Pin::Method.new(
|
|
74
84
|
location: loc,
|
|
75
85
|
closure: clos,
|
|
76
86
|
name: "#{a.children[0]}=",
|
|
77
87
|
comments: cmnt,
|
|
78
|
-
access: :writer,
|
|
79
88
|
scope: region.scope || :instance,
|
|
80
|
-
visibility: region.visibility
|
|
89
|
+
visibility: region.visibility,
|
|
90
|
+
attribute: true
|
|
81
91
|
)
|
|
92
|
+
pins.last.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last)
|
|
93
|
+
if pins.last.return_type.defined?
|
|
94
|
+
pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value')
|
|
95
|
+
end
|
|
82
96
|
end
|
|
83
97
|
end
|
|
84
98
|
end
|
|
@@ -88,7 +102,8 @@ module Solargraph
|
|
|
88
102
|
if node.children[2].is_a?(AST::Node) && node.children[2].type == :const
|
|
89
103
|
cp = region.closure
|
|
90
104
|
node.children[2..-1].each do |i|
|
|
91
|
-
|
|
105
|
+
type = region.scope == :class ? Pin::Reference::Extend : Pin::Reference::Include
|
|
106
|
+
pins.push type.new(
|
|
92
107
|
location: get_node_location(i),
|
|
93
108
|
closure: cp,
|
|
94
109
|
name: unpack_name(i)
|
|
@@ -138,6 +153,14 @@ module Solargraph
|
|
|
138
153
|
end
|
|
139
154
|
end
|
|
140
155
|
|
|
156
|
+
# @return [void]
|
|
157
|
+
def process_autoload
|
|
158
|
+
if node.children[3].is_a?(AST::Node) && node.children[3].type == :str
|
|
159
|
+
path = node.children[3].children[0].to_s
|
|
160
|
+
pins.push Pin::Reference::Require.new(get_node_location(node), path)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
141
164
|
# @return [void]
|
|
142
165
|
def process_module_function
|
|
143
166
|
if node.children[2].nil?
|
|
@@ -146,13 +169,14 @@ module Solargraph
|
|
|
146
169
|
elsif node.children[2].type == :sym || node.children[2].type == :str
|
|
147
170
|
node.children[2..-1].each do |x|
|
|
148
171
|
cn = x.children[0].to_s
|
|
149
|
-
ref = pins.select{|p|
|
|
172
|
+
ref = pins.select{ |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == cn }.first
|
|
150
173
|
unless ref.nil?
|
|
151
174
|
pins.delete ref
|
|
152
175
|
mm = Solargraph::Pin::Method.new(
|
|
153
176
|
location: ref.location,
|
|
154
177
|
closure: ref.closure,
|
|
155
178
|
name: ref.name,
|
|
179
|
+
parameters: ref.parameters,
|
|
156
180
|
comments: ref.comments,
|
|
157
181
|
scope: :class,
|
|
158
182
|
visibility: :public,
|
|
@@ -162,6 +186,7 @@ module Solargraph
|
|
|
162
186
|
location: ref.location,
|
|
163
187
|
closure: ref.closure,
|
|
164
188
|
name: ref.name,
|
|
189
|
+
parameters: ref.parameters,
|
|
165
190
|
comments: ref.comments,
|
|
166
191
|
scope: :instance,
|
|
167
192
|
visibility: :private,
|
|
@@ -216,7 +241,7 @@ module Solargraph
|
|
|
216
241
|
# @return [Boolean]
|
|
217
242
|
def process_private_class_method
|
|
218
243
|
if node.children[2].type == :sym || node.children[2].type == :str
|
|
219
|
-
ref = pins.select{|p|
|
|
244
|
+
ref = pins.select { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == node.children[2].children[0].to_s }.first
|
|
220
245
|
# HACK: Smelly instance variable access
|
|
221
246
|
ref.instance_variable_set(:@visibility, :private) unless ref.nil?
|
|
222
247
|
false
|
|
@@ -27,6 +27,7 @@ module Solargraph
|
|
|
27
27
|
@region = region
|
|
28
28
|
@pins = pins
|
|
29
29
|
@locals = locals
|
|
30
|
+
@processed_children = false
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
# Subclasses should override this method to generate new pins.
|
|
@@ -41,6 +42,8 @@ module Solargraph
|
|
|
41
42
|
# @param subregion [Region]
|
|
42
43
|
# @return [void]
|
|
43
44
|
def process_children subregion = region
|
|
45
|
+
return if @processed_children
|
|
46
|
+
@processed_children = true
|
|
44
47
|
node.children.each do |child|
|
|
45
48
|
next unless Parser.is_ast_node?(child)
|
|
46
49
|
NodeProcessor.process(child, subregion, pins, locals)
|
|
@@ -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
|
|
@@ -15,7 +15,7 @@ module Solargraph
|
|
|
15
15
|
def initialize node, filename = nil, in_block = false
|
|
16
16
|
@node = node
|
|
17
17
|
@filename = filename
|
|
18
|
-
@in_block = in_block
|
|
18
|
+
@in_block = in_block ? 1 : 0
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
# @return [Source::Chain]
|
|
@@ -52,25 +52,27 @@ module Solargraph
|
|
|
52
52
|
return generate_links(n.children[0]) if n.type == :SPLAT
|
|
53
53
|
result = []
|
|
54
54
|
if n.type == :ITER
|
|
55
|
-
@in_block
|
|
55
|
+
@in_block += 1
|
|
56
56
|
result.concat generate_links(n.children[0])
|
|
57
|
-
@in_block
|
|
57
|
+
@in_block -= 1
|
|
58
58
|
elsif n.type == :CALL || n.type == :OPCALL
|
|
59
59
|
n.children[0..-3].each do |c|
|
|
60
60
|
result.concat generate_links(c)
|
|
61
61
|
end
|
|
62
|
-
result.push Chain::Call.new(n.children[-2].to_s, node_to_argchains(n.children.last), @in_block || block_passed?(n))
|
|
62
|
+
result.push Chain::Call.new(n.children[-2].to_s, node_to_argchains(n.children.last), @in_block > 0 || block_passed?(n))
|
|
63
63
|
elsif n.type == :ATTRASGN
|
|
64
64
|
result.concat generate_links(n.children[0])
|
|
65
|
-
result.push Chain::Call.new(n.children[1].to_s, node_to_argchains(n.children[2]), @in_block || block_passed?(n))
|
|
65
|
+
result.push Chain::Call.new(n.children[1].to_s, node_to_argchains(n.children[2]), @in_block > 0 || block_passed?(n))
|
|
66
66
|
elsif n.type == :VCALL
|
|
67
|
-
result.push Chain::Call.new(n.children[0].to_s, [], @in_block || block_passed?(n))
|
|
67
|
+
result.push Chain::Call.new(n.children[0].to_s, [], @in_block > 0 || block_passed?(n))
|
|
68
68
|
elsif n.type == :FCALL
|
|
69
|
-
result.push Chain::Call.new(n.children[0].to_s, node_to_argchains(n.children[1]), @in_block || block_passed?(n))
|
|
69
|
+
result.push Chain::Call.new(n.children[0].to_s, node_to_argchains(n.children[1]), @in_block > 0 || 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 > 0 || block_passed?(n))
|
|
74
|
+
elsif n.type == :SUPER
|
|
75
|
+
result.push Chain::Call.new('super', node_to_argchains(n.children.last), @in_block > 0 || 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)
|
|
@@ -76,6 +76,10 @@ module Solargraph
|
|
|
76
76
|
if node.type == :ITER
|
|
77
77
|
result.push node.children[0]
|
|
78
78
|
node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
|
|
79
|
+
elsif node.type == :MASGN
|
|
80
|
+
# @todo We're treating a mass assignment as a call node, but the
|
|
81
|
+
# type checker still needs the logic to handle it.
|
|
82
|
+
result.push node
|
|
79
83
|
elsif [:CALL, :VCALL, :FCALL, :ATTRASGN, :OPCALL].include?(node.type)
|
|
80
84
|
result.push node
|
|
81
85
|
node.children.each { |child| result.concat call_nodes_from(child) }
|
|
@@ -91,6 +95,7 @@ module Solargraph
|
|
|
91
95
|
index = 0
|
|
92
96
|
until index > node.children[0].children.length - 2
|
|
93
97
|
k = node.children[0].children[index]
|
|
98
|
+
return {} unless node?(k)
|
|
94
99
|
v = node.children[0].children[index + 1]
|
|
95
100
|
result[k.children[0]] = Solargraph::Parser.chain(v)
|
|
96
101
|
index += 2
|
|
@@ -192,7 +197,7 @@ module Solargraph
|
|
|
192
197
|
result.push node
|
|
193
198
|
result.concat get_return_nodes_only(node.children[1])
|
|
194
199
|
elsif node.type == :CASE
|
|
195
|
-
node.children.each do |cc|
|
|
200
|
+
node.children[1..-1].each do |cc|
|
|
196
201
|
result.concat reduce_to_value_nodes(cc.children[1..-1])
|
|
197
202
|
end
|
|
198
203
|
else
|
|
@@ -6,17 +6,31 @@ module Solargraph
|
|
|
6
6
|
module NodeProcessors
|
|
7
7
|
class ArgsNode < Parser::NodeProcessor::Base
|
|
8
8
|
def process
|
|
9
|
-
if region.closure.is_a?(Pin::
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
if region.closure.is_a?(Pin::Method) || region.closure.is_a?(Pin::Block)
|
|
10
|
+
if region.lvars[0].nil?
|
|
11
|
+
node.children[0].times do |i|
|
|
12
|
+
locals.push Solargraph::Pin::Parameter.new(
|
|
13
|
+
location: region.closure.location,
|
|
14
|
+
closure: region.closure,
|
|
15
|
+
comments: comments_for(node),
|
|
16
|
+
name: extract_name(node.children[i + 1]),
|
|
17
|
+
presence: region.closure.location.range,
|
|
18
|
+
decl: :arg
|
|
19
|
+
)
|
|
20
|
+
region.closure.parameters.push locals.last
|
|
21
|
+
end
|
|
22
|
+
else
|
|
23
|
+
node.children[0].times do |i|
|
|
24
|
+
locals.push Solargraph::Pin::Parameter.new(
|
|
25
|
+
location: region.closure.location,
|
|
26
|
+
closure: region.closure,
|
|
27
|
+
comments: comments_for(node),
|
|
28
|
+
name: region.lvars[i].to_s,
|
|
29
|
+
presence: region.closure.location.range,
|
|
30
|
+
decl: :arg
|
|
31
|
+
)
|
|
32
|
+
region.closure.parameters.push locals.last
|
|
33
|
+
end
|
|
20
34
|
end
|
|
21
35
|
# @todo Optional args, keyword args, etc.
|
|
22
36
|
if node.children[6]
|
|
@@ -55,6 +69,16 @@ module Solargraph
|
|
|
55
69
|
end
|
|
56
70
|
process_children
|
|
57
71
|
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def extract_name var
|
|
76
|
+
if Parser.is_ast_node?(var)
|
|
77
|
+
var.children[0].to_s
|
|
78
|
+
else
|
|
79
|
+
var.to_s
|
|
80
|
+
end
|
|
81
|
+
end
|
|
58
82
|
end
|
|
59
83
|
end
|
|
60
84
|
end
|
|
@@ -19,7 +19,7 @@ module Solargraph
|
|
|
19
19
|
if region.visibility == :module_function
|
|
20
20
|
rng = Range.from_node(node)
|
|
21
21
|
named_path = named_path_pin(rng.start)
|
|
22
|
-
if named_path.is_a?(Pin::
|
|
22
|
+
if named_path.is_a?(Pin::Method)
|
|
23
23
|
pins.push Solargraph::Pin::InstanceVariable.new(
|
|
24
24
|
location: loc,
|
|
25
25
|
closure: Pin::Namespace.new(type: :module, closure: region.closure.closure, name: region.closure.name),
|
|
@@ -16,7 +16,12 @@ module Solargraph
|
|
|
16
16
|
presence: region.closure.location.range,
|
|
17
17
|
decl: require_keyword?(node) ? :kwarg : :kwoptarg
|
|
18
18
|
)
|
|
19
|
-
region.closure.parameters.
|
|
19
|
+
idx = region.closure.parameters.find_index { |par| [:kwrestarg, :blockarg].include?(par.decl) }
|
|
20
|
+
if idx
|
|
21
|
+
region.closure.parameters.insert idx, locals.last
|
|
22
|
+
else
|
|
23
|
+
region.closure.parameters.push locals.last
|
|
24
|
+
end
|
|
20
25
|
node.children[1] && NodeProcessor.process(node.children[1], region, pins, locals)
|
|
21
26
|
end
|
|
22
27
|
|
|
@@ -16,7 +16,12 @@ module Solargraph
|
|
|
16
16
|
presence: region.closure.location.range,
|
|
17
17
|
decl: :optarg
|
|
18
18
|
)
|
|
19
|
-
region.closure.parameters.
|
|
19
|
+
idx = region.closure.parameters.find_index { |par| par.decl != :arg }
|
|
20
|
+
if idx
|
|
21
|
+
region.closure.parameters.insert idx, locals.last
|
|
22
|
+
else
|
|
23
|
+
region.closure.parameters.push locals.last
|
|
24
|
+
end
|
|
20
25
|
node.children[1] && NodeProcessor.process(node.children[1], region, pins, locals)
|
|
21
26
|
end
|
|
22
27
|
end
|
|
@@ -9,30 +9,17 @@ module Solargraph
|
|
|
9
9
|
|
|
10
10
|
def process
|
|
11
11
|
if [:private, :public, :protected].include?(node.children[0])
|
|
12
|
-
|
|
13
|
-
node.children.last.children[0..-2].each do |child|
|
|
14
|
-
# next unless child.is_a?(AST::Node) && (child.type == :sym || child.type == :str)
|
|
15
|
-
next unless child.type == :LIT || child.type == :STR
|
|
16
|
-
name = child.children[0].to_s
|
|
17
|
-
matches = pins.select{ |pin| pin.is_a?(Pin::BaseMethod) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)}
|
|
18
|
-
matches.each do |pin|
|
|
19
|
-
# @todo Smelly instance variable access
|
|
20
|
-
pin.instance_variable_set(:@visibility, node.children[0])
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
else
|
|
24
|
-
# @todo Smelly instance variable access
|
|
25
|
-
region.instance_variable_set(:@visibility, node.children[0])
|
|
26
|
-
end
|
|
12
|
+
process_visibility
|
|
27
13
|
elsif node.children[0] == :module_function
|
|
28
14
|
process_module_function
|
|
29
15
|
elsif node.children[0] == :require
|
|
30
16
|
process_require
|
|
17
|
+
elsif node.children[0] == :autoload
|
|
18
|
+
process_autoload
|
|
31
19
|
elsif node.children[0] == :alias_method
|
|
32
20
|
process_alias_method
|
|
33
|
-
elsif node.children[0] == :private_class_method
|
|
34
|
-
|
|
35
|
-
return if process_private_class_method
|
|
21
|
+
elsif node.children[0] == :private_class_method
|
|
22
|
+
process_private_class_method
|
|
36
23
|
elsif [:attr_reader, :attr_writer, :attr_accessor].include?(node.children[0])
|
|
37
24
|
process_attribute
|
|
38
25
|
elsif node.children[0] == :include
|
|
@@ -43,52 +30,36 @@ module Solargraph
|
|
|
43
30
|
process_prepend
|
|
44
31
|
elsif node.children[0] == :private_constant
|
|
45
32
|
process_private_constant
|
|
33
|
+
elsif node.children[1] == :require && unpack_name(node.children[0]) == 'Bundler'
|
|
34
|
+
pins.push Pin::Reference::Require.new(Solargraph::Location.new(region.filename, Solargraph::Range.from_to(0, 0, 0, 0)), 'bundler/require')
|
|
46
35
|
end
|
|
47
36
|
process_children
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
# @return [void]
|
|
42
|
+
def process_visibility
|
|
43
|
+
if node.type == :FCALL && Parser.is_ast_node?(node.children.last)
|
|
44
|
+
node.children.last.children[0..-2].each do |child|
|
|
45
|
+
# next unless child.is_a?(AST::Node) && (child.type == :sym || child.type == :str)
|
|
46
|
+
if child.type == :LIT || child.type == :STR
|
|
47
|
+
name = child.children[0].to_s
|
|
48
|
+
matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)}
|
|
49
|
+
matches.each do |pin|
|
|
50
|
+
# @todo Smelly instance variable access
|
|
51
|
+
pin.instance_variable_set(:@visibility, node.children[0])
|
|
61
52
|
end
|
|
62
53
|
else
|
|
63
|
-
|
|
64
|
-
region.instance_variable_set(:@visibility, node.children[1])
|
|
54
|
+
process_children region.update(visibility: node.children[0])
|
|
65
55
|
end
|
|
66
|
-
elsif node.children[1] == :module_function
|
|
67
|
-
process_module_function
|
|
68
|
-
elsif [:attr_reader, :attr_writer, :attr_accessor].include?(node.children[1])
|
|
69
|
-
process_attribute
|
|
70
|
-
elsif node.children[1] == :include
|
|
71
|
-
process_include
|
|
72
|
-
elsif node.children[1] == :extend
|
|
73
|
-
process_extend
|
|
74
|
-
elsif node.children[1] == :require
|
|
75
|
-
process_require
|
|
76
|
-
elsif node.children[1] == :private_constant
|
|
77
|
-
process_private_constant
|
|
78
|
-
elsif node.children[1] == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
|
|
79
|
-
process_alias_method
|
|
80
|
-
elsif node.children[1] == :private_class_method && node.children[2].is_a?(AST::Node)
|
|
81
|
-
# Processing a private class can potentially handle children on its own
|
|
82
|
-
return if process_private_class_method
|
|
83
56
|
end
|
|
84
|
-
|
|
85
|
-
|
|
57
|
+
else
|
|
58
|
+
# @todo Smelly instance variable access
|
|
59
|
+
region.instance_variable_set(:@visibility, node.children[0])
|
|
86
60
|
end
|
|
87
|
-
process_children
|
|
88
61
|
end
|
|
89
62
|
|
|
90
|
-
private
|
|
91
|
-
|
|
92
63
|
# @return [void]
|
|
93
64
|
def process_attribute
|
|
94
65
|
return unless Parser.is_ast_node?(node.children[1])
|
|
@@ -98,26 +69,30 @@ module Solargraph
|
|
|
98
69
|
clos = region.closure
|
|
99
70
|
cmnt = comments_for(node)
|
|
100
71
|
if node.children[0] == :attr_reader || node.children[0] == :attr_accessor
|
|
101
|
-
pins.push Solargraph::Pin::
|
|
72
|
+
pins.push Solargraph::Pin::Method.new(
|
|
102
73
|
location: loc,
|
|
103
74
|
closure: clos,
|
|
104
75
|
name: a.children[0].to_s,
|
|
105
76
|
comments: cmnt,
|
|
106
|
-
access: :reader,
|
|
107
77
|
scope: region.scope || :instance,
|
|
108
|
-
visibility: region.visibility
|
|
78
|
+
visibility: region.visibility,
|
|
79
|
+
attribute: true
|
|
109
80
|
)
|
|
110
81
|
end
|
|
111
82
|
if node.children[0] == :attr_writer || node.children[0] == :attr_accessor
|
|
112
|
-
pins.push Solargraph::Pin::
|
|
83
|
+
pins.push Solargraph::Pin::Method.new(
|
|
113
84
|
location: loc,
|
|
114
85
|
closure: clos,
|
|
115
86
|
name: "#{a.children[0]}=",
|
|
116
87
|
comments: cmnt,
|
|
117
|
-
access: :writer,
|
|
118
88
|
scope: region.scope || :instance,
|
|
119
|
-
visibility: region.visibility
|
|
89
|
+
visibility: region.visibility,
|
|
90
|
+
attribute: true
|
|
120
91
|
)
|
|
92
|
+
pins.last.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last)
|
|
93
|
+
if pins.last.return_type.defined?
|
|
94
|
+
pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value')
|
|
95
|
+
end
|
|
121
96
|
end
|
|
122
97
|
end
|
|
123
98
|
end
|
|
@@ -127,7 +102,8 @@ module Solargraph
|
|
|
127
102
|
return unless Parser.is_ast_node?(node.children.last)
|
|
128
103
|
node.children.last.children[0..-2].each do |i|
|
|
129
104
|
next unless [:COLON2, :COLON3, :CONST].include?(i.type)
|
|
130
|
-
|
|
105
|
+
type = region.scope == :class ? Pin::Reference::Extend : Pin::Reference::Include
|
|
106
|
+
pins.push type.new(
|
|
131
107
|
location: get_node_location(i),
|
|
132
108
|
closure: region.closure,
|
|
133
109
|
name: unpack_name(i)
|
|
@@ -181,6 +157,15 @@ module Solargraph
|
|
|
181
157
|
end
|
|
182
158
|
end
|
|
183
159
|
|
|
160
|
+
# @return [void]
|
|
161
|
+
def process_autoload
|
|
162
|
+
return unless Parser.is_ast_node?(node.children[1]) && Parser.is_ast_node?(node.children[1].children[1])
|
|
163
|
+
arg = node.children[1].children[1]
|
|
164
|
+
if arg.type == :STR
|
|
165
|
+
pins.push Pin::Reference::Require.new(get_node_location(arg), arg.children[0])
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
184
169
|
# @return [void]
|
|
185
170
|
def process_module_function
|
|
186
171
|
if node.type == :VCALL
|
|
@@ -192,7 +177,7 @@ module Solargraph
|
|
|
192
177
|
node.children.last.children[0..-2].each do |x|
|
|
193
178
|
next unless [:LIT, :STR].include?(x.type)
|
|
194
179
|
cn = x.children[0].to_s
|
|
195
|
-
ref = pins.select{|p|
|
|
180
|
+
ref = pins.select { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == cn }.first
|
|
196
181
|
unless ref.nil?
|
|
197
182
|
pins.delete ref
|
|
198
183
|
mm = Solargraph::Pin::Method.new(
|
|
@@ -241,6 +226,7 @@ module Solargraph
|
|
|
241
226
|
|
|
242
227
|
# @return [void]
|
|
243
228
|
def process_private_constant
|
|
229
|
+
# @todo Bare `private_constant` causes an error
|
|
244
230
|
node.children.last.children[0..-2].each do |child|
|
|
245
231
|
if [:LIT, :STR].include?(child.type)
|
|
246
232
|
cn = child.children[0].to_s
|
|
@@ -268,19 +254,18 @@ module Solargraph
|
|
|
268
254
|
)
|
|
269
255
|
end
|
|
270
256
|
|
|
271
|
-
# @return [
|
|
257
|
+
# @return [void]
|
|
272
258
|
def process_private_class_method
|
|
259
|
+
return false unless Parser.is_ast_node?(node.children.last)
|
|
273
260
|
if node.children.last.children.first.type == :DEFN
|
|
274
261
|
process_children region.update(scope: :class, visibility: :private)
|
|
275
|
-
true
|
|
276
262
|
else
|
|
277
263
|
node.children.last.children[0..-2].each do |child|
|
|
278
264
|
if child.type == :LIT && child.children.first.is_a?(::Symbol)
|
|
279
265
|
sym_name = child.children.first.to_s
|
|
280
|
-
ref = pins.select{|p|
|
|
266
|
+
ref = pins.select { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == sym_name }.first
|
|
281
267
|
# HACK: Smelly instance variable access
|
|
282
268
|
ref.instance_variable_set(:@visibility, :private) unless ref.nil?
|
|
283
|
-
false
|
|
284
269
|
end
|
|
285
270
|
end
|
|
286
271
|
end
|
|
@@ -36,6 +36,7 @@ module Solargraph
|
|
|
36
36
|
register :RESBODY, Rubyvm::NodeProcessors::ResbodyNode
|
|
37
37
|
register :DEFN, Rubyvm::NodeProcessors::DefNode
|
|
38
38
|
register :DEFS, Rubyvm::NodeProcessors::DefsNode
|
|
39
|
+
register :CALL, Rubyvm::NodeProcessors::SendNode
|
|
39
40
|
register :FCALL, Rubyvm::NodeProcessors::SendNode
|
|
40
41
|
register :VCALL, Rubyvm::NodeProcessors::SendNode
|
|
41
42
|
register :CLASS, Rubyvm::NodeProcessors::NamespaceNode
|
|
@@ -53,6 +54,7 @@ module Solargraph
|
|
|
53
54
|
register :KW_ARG, Rubyvm::NodeProcessors::KwArgNode
|
|
54
55
|
register :ITER, Rubyvm::NodeProcessors::BlockNode
|
|
55
56
|
register :LAMBDA, Rubyvm::NodeProcessors::BlockNode
|
|
57
|
+
register :FOR, Rubyvm::NodeProcessors::BlockNode
|
|
56
58
|
register :OP_ASGN_OR, Rubyvm::NodeProcessors::OrasgnNode
|
|
57
59
|
register :LIT, Rubyvm::NodeProcessors::LitNode
|
|
58
60
|
end
|
data/lib/solargraph/pin/base.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Solargraph
|
|
|
23
23
|
|
|
24
24
|
# @param location [Solargraph::Location]
|
|
25
25
|
# @param kind [Integer]
|
|
26
|
-
# @param closure [
|
|
26
|
+
# @param closure [Solargraph::Pin::Closure]
|
|
27
27
|
# @param name [String]
|
|
28
28
|
# @param comments [String]
|
|
29
29
|
def initialize location: nil, closure: nil, name: '', comments: ''
|
|
@@ -38,7 +38,7 @@ module Solargraph
|
|
|
38
38
|
@comments ||= ''
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
# @return [String]
|
|
41
|
+
# @return [String, nil]
|
|
42
42
|
def filename
|
|
43
43
|
return nil if location.nil?
|
|
44
44
|
location.filename
|