solargraph 0.32.5 → 0.33.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +2 -11
- data/lib/solargraph.rb +1 -2
- data/lib/solargraph/api_map.rb +93 -63
- data/lib/solargraph/api_map/cache.rb +16 -1
- data/lib/solargraph/api_map/source_to_yard.rb +16 -7
- data/lib/solargraph/api_map/store.rb +55 -12
- data/lib/solargraph/complex_type.rb +58 -14
- data/lib/solargraph/complex_type/type_methods.rb +2 -2
- data/lib/solargraph/complex_type/unique_type.rb +33 -4
- data/lib/solargraph/core_fills.rb +40 -12
- data/lib/solargraph/diagnostics.rb +4 -3
- data/lib/solargraph/diagnostics/base.rb +6 -0
- data/lib/solargraph/diagnostics/require_not_found.rb +17 -10
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +2 -0
- data/lib/solargraph/diagnostics/type_check.rb +51 -0
- data/lib/solargraph/diagnostics/update_errors.rb +1 -0
- data/lib/solargraph/language_server/host.rb +55 -25
- data/lib/solargraph/language_server/host/diagnoser.rb +1 -2
- data/lib/solargraph/language_server/host/dispatch.rb +4 -8
- data/lib/solargraph/language_server/host/sources.rb +1 -1
- data/lib/solargraph/language_server/message.rb +1 -0
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +4 -2
- data/lib/solargraph/language_server/message/initialize.rb +9 -0
- data/lib/solargraph/language_server/message/initialized.rb +1 -0
- data/lib/solargraph/language_server/message/text_document.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/code_action.rb +15 -0
- data/lib/solargraph/language_server/message/text_document/completion.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/definition.rb +25 -5
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +4 -0
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +8 -4
- data/lib/solargraph/language_server/transport/adapter.rb +12 -15
- data/lib/solargraph/library.rb +23 -6
- data/lib/solargraph/location.rb +4 -0
- data/lib/solargraph/pin.rb +7 -3
- data/lib/solargraph/pin/attribute.rb +14 -13
- data/lib/solargraph/pin/base.rb +56 -43
- data/lib/solargraph/pin/base_method.rb +41 -18
- data/lib/solargraph/pin/base_variable.rb +17 -15
- data/lib/solargraph/pin/block.rb +22 -4
- data/lib/solargraph/pin/closure.rb +28 -0
- data/lib/solargraph/pin/common.rb +59 -0
- data/lib/solargraph/pin/constant.rb +4 -4
- data/lib/solargraph/pin/conversions.rb +8 -8
- data/lib/solargraph/pin/duck_method.rb +3 -3
- data/lib/solargraph/pin/instance_variable.rb +30 -0
- data/lib/solargraph/pin/keyword.rb +1 -1
- data/lib/solargraph/pin/local_variable.rb +3 -3
- data/lib/solargraph/pin/localized.rb +9 -5
- data/lib/solargraph/pin/method.rb +26 -40
- data/lib/solargraph/pin/method_alias.rb +9 -6
- data/lib/solargraph/pin/namespace.rb +33 -10
- data/lib/solargraph/pin/parameter.rb +150 -0
- data/lib/solargraph/pin/proxy_type.rb +8 -8
- data/lib/solargraph/pin/reference.rb +1 -12
- data/lib/solargraph/pin/reference/override.rb +18 -0
- data/lib/solargraph/pin/reference/require.rb +2 -1
- data/lib/solargraph/pin/singleton.rb +9 -0
- data/lib/solargraph/pin/symbol.rb +9 -4
- data/lib/solargraph/pin/yard_pin/constant.rb +12 -3
- data/lib/solargraph/pin/yard_pin/method.rb +18 -6
- data/lib/solargraph/pin/yard_pin/namespace.rb +13 -1
- data/lib/solargraph/position.rb +1 -1
- data/lib/solargraph/range.rb +4 -0
- data/lib/solargraph/shell.rb +83 -4
- data/lib/solargraph/source.rb +32 -12
- data/lib/solargraph/source/chain.rb +48 -28
- data/lib/solargraph/source/chain/call.rb +37 -38
- data/lib/solargraph/source/chain/constant.rb +1 -1
- data/lib/solargraph/source/chain/head.rb +2 -8
- data/lib/solargraph/source/chain/instance_variable.rb +1 -1
- data/lib/solargraph/source/chain/link.rb +2 -0
- data/lib/solargraph/source/cursor.rb +59 -24
- data/lib/solargraph/source/node_chainer.rb +0 -2
- data/lib/solargraph/source/node_methods.rb +12 -6
- data/lib/solargraph/source/source_chainer.rb +38 -44
- data/lib/solargraph/source_map.rb +11 -18
- data/lib/solargraph/source_map/clip.rb +13 -15
- data/lib/solargraph/source_map/mapper.rb +37 -26
- data/lib/solargraph/source_map/node_processor.rb +13 -8
- data/lib/solargraph/source_map/node_processor/alias_node.rb +8 -8
- data/lib/solargraph/source_map/node_processor/args_node.rb +10 -16
- data/lib/solargraph/source_map/node_processor/base.rb +47 -4
- data/lib/solargraph/source_map/node_processor/block_node.rb +9 -4
- data/lib/solargraph/source_map/node_processor/casgn_node.rb +7 -2
- data/lib/solargraph/source_map/node_processor/cvasgn_node.rb +8 -3
- data/lib/solargraph/source_map/node_processor/def_node.rb +45 -38
- data/lib/solargraph/source_map/node_processor/defs_node.rb +16 -6
- data/lib/solargraph/source_map/node_processor/gvasgn_node.rb +8 -1
- data/lib/solargraph/source_map/node_processor/ivasgn_node.rb +20 -6
- data/lib/solargraph/source_map/node_processor/lvasgn_node.rb +10 -4
- data/lib/solargraph/source_map/node_processor/namespace_node.rb +18 -12
- data/lib/solargraph/source_map/node_processor/orasgn_node.rb +1 -1
- data/lib/solargraph/source_map/node_processor/resbody_node.rb +30 -0
- data/lib/solargraph/source_map/node_processor/sclass_node.rb +7 -1
- data/lib/solargraph/source_map/node_processor/send_node.rb +102 -52
- data/lib/solargraph/source_map/node_processor/sym_node.rb +4 -1
- data/lib/solargraph/source_map/region.rb +9 -8
- data/lib/solargraph/type_checker.rb +282 -0
- data/lib/solargraph/type_checker/param_def.rb +47 -0
- data/lib/solargraph/type_checker/problem.rb +25 -0
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +1 -1
- data/lib/solargraph/workspace.rb +2 -2
- data/lib/solargraph/workspace/config.rb +0 -8
- data/lib/solargraph/yard_map.rb +25 -69
- data/lib/solargraph/yard_map/core_docs.rb +8 -3
- data/lib/solargraph/yard_map/core_gen.rb +1 -3
- data/lib/solargraph/yard_map/mapper.rb +85 -0
- data/lib/yard-solargraph.rb +2 -0
- metadata +14 -14
- data/lib/solargraph/diagnostics/type_not_defined.rb +0 -108
- data/lib/solargraph/live_map.rb +0 -126
- data/lib/solargraph/live_map/cache.rb +0 -38
- data/lib/solargraph/pin/block_parameter.rb +0 -103
- data/lib/solargraph/pin/method_parameter.rb +0 -40
- data/lib/solargraph/pin/plugin/method.rb +0 -25
- data/lib/solargraph/plugin.rb +0 -8
- data/lib/solargraph/plugin/base.rb +0 -41
- data/lib/solargraph/plugin/canceler.rb +0 -11
- data/lib/solargraph/plugin/process.rb +0 -172
- data/lib/solargraph/plugin/runtime.rb +0 -134
- data/lib/yard-coregen.rb +0 -16
@@ -8,47 +8,51 @@ module Solargraph
|
|
8
8
|
# @return [Array<Chain>]
|
9
9
|
attr_reader :arguments
|
10
10
|
|
11
|
+
# @param word [String]
|
12
|
+
# @param arguments [Array<Chain>]
|
11
13
|
def initialize word, arguments = []
|
12
14
|
@word = word
|
13
15
|
@arguments = arguments
|
14
16
|
end
|
15
17
|
|
18
|
+
# @param api_map [ApiMap]
|
19
|
+
# @param name_pin [Pin::Base]
|
20
|
+
# @param locals [Array<Pin::Base>]
|
16
21
|
def resolve api_map, name_pin, locals
|
17
22
|
found = locals.select{|p| p.name == word}
|
18
23
|
return inferred_pins(found, api_map, name_pin.context, locals) unless found.empty?
|
19
|
-
pins = api_map.get_method_stack(name_pin.
|
24
|
+
pins = api_map.get_method_stack(name_pin.binder.namespace, word, scope: name_pin.binder.scope)
|
20
25
|
return [] if pins.empty?
|
21
|
-
pins.unshift virtual_new_pin(pins.first, name_pin.context) if external_constructor?(pins.first, name_pin.context)
|
22
26
|
inferred_pins(pins, api_map, name_pin.context, locals)
|
23
27
|
end
|
24
28
|
|
25
29
|
private
|
26
30
|
|
27
|
-
# Create a `new` pin to facilitate type inference. This is necessary for
|
28
|
-
# classes from YARD and classes in the namespace that do not have an
|
29
|
-
# `initialize` method.
|
30
|
-
#
|
31
|
-
# @param new_pin [Solargraph::Pin::Base]
|
32
|
-
# @param context [Solargraph::ComplexType]
|
33
|
-
# @return [Pin::Method]
|
34
|
-
def virtual_new_pin new_pin, context
|
35
|
-
case new_pin.path
|
36
|
-
when 'Class.new'
|
37
|
-
Pin::ProxyType.anonymous(ComplexType.try_parse('Class<Object>'))
|
38
|
-
when 'Class#new'
|
39
|
-
Pin::ProxyType.anonymous(ComplexType.try_parse(context.namespace == 'Class' ? 'Object' : context.namespace))
|
40
|
-
else
|
41
|
-
Pin::ProxyType.anonymous(ComplexType.try_parse(context.namespace))
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
31
|
def inferred_pins pins, api_map, context, locals
|
46
32
|
result = pins.map do |p|
|
47
|
-
if CoreFills::METHODS_RETURNING_SELF.include?(p.path)
|
48
|
-
next Solargraph::Pin::Method.new(p.location, p.namespace, p.name, "@return [#{context.tag}]", p.scope, p.visibility, p.parameters, p.node)
|
49
|
-
end
|
50
33
|
if CoreFills::METHODS_RETURNING_SUBTYPES.include?(p.path) && !context.subtypes.empty?
|
51
|
-
next Solargraph::Pin::Method.new(
|
34
|
+
next Solargraph::Pin::Method.new(
|
35
|
+
location: p.location,
|
36
|
+
closure: p.closure,
|
37
|
+
name: p.name,
|
38
|
+
comments: "@return [#{context.subtypes.first.tag}]",
|
39
|
+
scope: p.scope,
|
40
|
+
visibility: p.visibility,
|
41
|
+
args: p.parameters,
|
42
|
+
node: p.node
|
43
|
+
)
|
44
|
+
end
|
45
|
+
if CoreFills::METHODS_RETURNING_VALUE_TYPES.include?(p.path) && !context.value_types.empty?
|
46
|
+
next Solargraph::Pin::Method.new(
|
47
|
+
location: p.location,
|
48
|
+
closure: p.closure,
|
49
|
+
name: p.name,
|
50
|
+
comments: "@return [#{context.value_types.first.tag}]",
|
51
|
+
scope: p.scope,
|
52
|
+
visibility: p.visibility,
|
53
|
+
args: p.parameters,
|
54
|
+
node: p.node
|
55
|
+
)
|
52
56
|
end
|
53
57
|
if p.kind == Pin::METHOD && !p.macros.empty?
|
54
58
|
result = process_macro(p, api_map, context, locals)
|
@@ -57,18 +61,13 @@ module Solargraph
|
|
57
61
|
result = process_directive(p, api_map, context, locals)
|
58
62
|
next result unless result.return_type.undefined?
|
59
63
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
p
|
65
|
+
end
|
66
|
+
result.map do |pin|
|
67
|
+
next pin if pin.return_type.undefined?
|
68
|
+
selfy = pin.return_type.self_to(context.namespace)
|
69
|
+
selfy == pin.return_type ? pin : pin.proxy(selfy)
|
66
70
|
end
|
67
|
-
result
|
68
|
-
end
|
69
|
-
|
70
|
-
def external_constructor? pin, context
|
71
|
-
pin.path == 'Class#new' || (pin.name == 'new' && pin.scope == :class && pin.docstring.tag(:return).nil?)
|
72
71
|
end
|
73
72
|
|
74
73
|
# @param pin [Pin::Method]
|
@@ -80,7 +79,7 @@ module Solargraph
|
|
80
79
|
result = inner_process_macro(pin, macro, api_map, context, locals)
|
81
80
|
return result unless result.return_type.undefined?
|
82
81
|
end
|
83
|
-
Pin::ProxyType.
|
82
|
+
Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
|
84
83
|
end
|
85
84
|
|
86
85
|
def process_directive pin, api_map, context, locals
|
@@ -90,7 +89,7 @@ module Solargraph
|
|
90
89
|
result = inner_process_macro(pin, macro, api_map, context, locals)
|
91
90
|
return result unless result.return_type.undefined?
|
92
91
|
end
|
93
|
-
Pin::ProxyType.
|
92
|
+
Pin::ProxyType.anonymous ComplexType::UNDEFINED
|
94
93
|
end
|
95
94
|
|
96
95
|
def inner_process_macro pin, macro, api_map, context, locals
|
@@ -106,7 +105,7 @@ module Solargraph
|
|
106
105
|
unless tag.nil? || tag.types.nil?
|
107
106
|
return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
|
108
107
|
end
|
109
|
-
Pin::ProxyType.
|
108
|
+
Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
|
110
109
|
end
|
111
110
|
end
|
112
111
|
end
|
@@ -7,24 +7,18 @@ module Solargraph
|
|
7
7
|
# @note Chain::Head is only intended to handle `self` and `super`.
|
8
8
|
class Head < Link
|
9
9
|
def resolve api_map, name_pin, locals
|
10
|
-
return [
|
10
|
+
return [name_pin] if word == 'self'
|
11
11
|
return super_pins(api_map, name_pin) if word == 'super'
|
12
12
|
[]
|
13
13
|
end
|
14
14
|
|
15
15
|
private
|
16
16
|
|
17
|
-
# @param context [ComplexType]
|
18
|
-
# @return [Pin::ProxyType]
|
19
|
-
def self_pin(context)
|
20
|
-
Pin::ProxyType.anonymous(context)
|
21
|
-
end
|
22
|
-
|
23
17
|
# @param api_map [ApiMap]
|
24
18
|
# @param name_pin [Pin::Base]
|
25
19
|
# @return [Array<Pin::Base>]
|
26
20
|
def super_pins api_map, name_pin
|
27
|
-
pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.
|
21
|
+
pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
|
28
22
|
pins.reject{|p| p.path == name_pin.path}
|
29
23
|
end
|
30
24
|
end
|
@@ -3,7 +3,7 @@ module Solargraph
|
|
3
3
|
class Chain
|
4
4
|
class InstanceVariable < Link
|
5
5
|
def resolve api_map, name_pin, locals
|
6
|
-
api_map.get_instance_variable_pins(name_pin.
|
6
|
+
api_map.get_instance_variable_pins(name_pin.binder.namespace, name_pin.binder.scope).select{|p| p.name == word}
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -55,6 +55,7 @@ module Solargraph
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
# @return [Boolean]
|
58
59
|
def start_of_constant?
|
59
60
|
source.code[offset-2, 2] == '::'
|
60
61
|
end
|
@@ -75,9 +76,19 @@ module Solargraph
|
|
75
76
|
@chain ||= SourceChainer.chain(source, position)
|
76
77
|
end
|
77
78
|
|
79
|
+
# True if the statement at the cursor is an argument to a previous
|
80
|
+
# method.
|
81
|
+
#
|
82
|
+
# Given the code `process(foo)`, a cursor pointing at `foo` would
|
83
|
+
# identify it as an argument being passed to the `process` method.
|
84
|
+
#
|
85
|
+
# If #argument? is true, the #recipient method will return a cursor that
|
86
|
+
# points to the method receiving the argument.
|
87
|
+
#
|
78
88
|
# @return [Boolean]
|
79
89
|
def argument?
|
80
|
-
@argument ||= !signature_position.nil?
|
90
|
+
# @argument ||= !signature_position.nil?
|
91
|
+
@argument ||= !recipient.nil?
|
81
92
|
end
|
82
93
|
|
83
94
|
# @return [Boolean]
|
@@ -90,12 +101,28 @@ module Solargraph
|
|
90
101
|
@string ||= source.string_at?(position)
|
91
102
|
end
|
92
103
|
|
104
|
+
# Get a cursor pointing to the method that receives the current statement
|
105
|
+
# as an argument.
|
106
|
+
#
|
93
107
|
# @return [Cursor, nil]
|
94
108
|
def recipient
|
95
|
-
|
96
|
-
|
109
|
+
@recipient ||= begin
|
110
|
+
result = nil
|
111
|
+
node = recipient_node
|
112
|
+
unless node.nil?
|
113
|
+
result = if node.children[1].is_a?(AST::Node)
|
114
|
+
pos = Range.from_node(node.children[1]).start
|
115
|
+
Cursor.new(source, Position.new(pos.line, pos.column - 1))
|
116
|
+
else
|
117
|
+
Cursor.new(source, Range.from_node(node).ending)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
result
|
121
|
+
end
|
97
122
|
end
|
123
|
+
alias receiver recipient
|
98
124
|
|
125
|
+
# @return [Position]
|
99
126
|
def node_position
|
100
127
|
@node_position ||= begin
|
101
128
|
if start_of_word.empty?
|
@@ -111,6 +138,22 @@ module Solargraph
|
|
111
138
|
end
|
112
139
|
end
|
113
140
|
|
141
|
+
# @return [Parser::AST::Node, nil]
|
142
|
+
def recipient_node
|
143
|
+
return nil if source.code[offset-1] == ')' || source.code[0..offset] =~ /[^,][ \t]*?\n[ \t]*?\Z/
|
144
|
+
return nil if first_char_offset < offset && source.code[first_char_offset..offset-1] =~ /\)[\s]*\Z/
|
145
|
+
pos = Position.from_offset(source.code, first_char_offset)
|
146
|
+
tree = source.tree_at(pos.line, pos.character)
|
147
|
+
if tree[0] && tree[0].type == :send
|
148
|
+
rng = Range.from_node(tree[0])
|
149
|
+
return tree[0] if (rng.contain?(position) || offset + 1 == Position.to_offset(source.code, rng.ending)) && source.code[offset] =~ /[ \t\)\,'")]/
|
150
|
+
return tree[0] if (source.code[0..offset-1] =~ /\([\s]*\Z/ || source.code[0..offset-1] =~ /[a-z0-9_][ \t]+\Z/i)
|
151
|
+
end
|
152
|
+
return tree[1] if tree[1] && tree[1].type == :send
|
153
|
+
return tree[3] if tree[1] && tree[3] && tree[1].type == :pair && tree[3].type == :send
|
154
|
+
nil
|
155
|
+
end
|
156
|
+
|
114
157
|
private
|
115
158
|
|
116
159
|
# @return [Integer]
|
@@ -118,6 +161,19 @@ module Solargraph
|
|
118
161
|
@offset ||= Position.to_offset(source.code, position)
|
119
162
|
end
|
120
163
|
|
164
|
+
# @return [Integer]
|
165
|
+
def first_char_offset
|
166
|
+
@first_char_position ||= begin
|
167
|
+
if source.code[offset - 1] == ')'
|
168
|
+
position
|
169
|
+
else
|
170
|
+
index = offset - 1
|
171
|
+
index -= 1 while index > 0 && source.code[index].strip.empty?
|
172
|
+
index
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
121
177
|
# A regular expression to find the start of a word from an offset.
|
122
178
|
#
|
123
179
|
# @return [Regexp]
|
@@ -131,27 +187,6 @@ module Solargraph
|
|
131
187
|
def end_word_pattern
|
132
188
|
/^([a-z0-9_]|[^\u0000-\u007F])*[\?\!]?/i
|
133
189
|
end
|
134
|
-
|
135
|
-
def signature_position
|
136
|
-
if @signature_position.nil?
|
137
|
-
open_parens = 0
|
138
|
-
cursor = offset - 1
|
139
|
-
while cursor >= 0
|
140
|
-
break if cursor < 0
|
141
|
-
if source.code[cursor] == ')'
|
142
|
-
open_parens -= 1
|
143
|
-
elsif source.code[cursor] == '('
|
144
|
-
open_parens += 1
|
145
|
-
end
|
146
|
-
break if open_parens == 1
|
147
|
-
cursor -= 1
|
148
|
-
end
|
149
|
-
if cursor >= 0
|
150
|
-
@signature_position = Position.from_offset(source.code, cursor)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
@signature_position
|
154
|
-
end
|
155
190
|
end
|
156
191
|
end
|
157
192
|
end
|
@@ -43,8 +43,6 @@ module Solargraph
|
|
43
43
|
def generate_links n
|
44
44
|
return [] unless n.is_a?(Parser::AST::Node)
|
45
45
|
return generate_links(n.children[0]) if n.type == :begin
|
46
|
-
# @todo This might not be right. It's weird either way.
|
47
|
-
# return generate_links(n.children[2] || n.children[0]) if n.type == :block
|
48
46
|
result = []
|
49
47
|
if n.type == :block
|
50
48
|
result.concat generate_links(n.children[0])
|
@@ -52,7 +52,7 @@ module Solargraph
|
|
52
52
|
# @return [String]
|
53
53
|
def infer_literal_node_type node
|
54
54
|
return nil unless node.kind_of?(AST::Node)
|
55
|
-
if node.type == :str
|
55
|
+
if node.type == :str || node.type == :dstr
|
56
56
|
return 'String'
|
57
57
|
elsif node.type == :array
|
58
58
|
return 'Array'
|
@@ -66,7 +66,7 @@ module Solargraph
|
|
66
66
|
return 'Symbol'
|
67
67
|
elsif node.type == :regexp
|
68
68
|
return 'Regexp'
|
69
|
-
# @todo
|
69
|
+
# @todo Support `nil` keyword in types
|
70
70
|
# elsif node.type == :nil
|
71
71
|
# return 'NilClass'
|
72
72
|
end
|
@@ -142,7 +142,7 @@ module Solargraph
|
|
142
142
|
class << self
|
143
143
|
CONDITIONAL = [:if, :unless]
|
144
144
|
REDUCEABLE = [:begin, :kwbegin]
|
145
|
-
SKIPPABLE = [:def, :defs, :class, :sclass, :module]
|
145
|
+
SKIPPABLE = [:def, :defs, :class, :sclass, :module, :block]
|
146
146
|
|
147
147
|
# @param node [Parser::AST::Node]
|
148
148
|
# @return [Array<Parser::AST::Node>]
|
@@ -157,6 +157,8 @@ module Solargraph
|
|
157
157
|
result.concat reduce_to_value_nodes(node.children)
|
158
158
|
elsif node.type == :return
|
159
159
|
result.concat reduce_to_value_nodes([node.children[0]])
|
160
|
+
elsif node.type == :block
|
161
|
+
result.concat reduce_to_value_nodes(node.children[0..-2])
|
160
162
|
else
|
161
163
|
result.push node
|
162
164
|
end
|
@@ -184,8 +186,9 @@ module Solargraph
|
|
184
186
|
end
|
185
187
|
|
186
188
|
def get_return_nodes_only parent
|
189
|
+
return [] unless parent.is_a?(Parser::AST::Node)
|
187
190
|
result = []
|
188
|
-
nodes = parent.children.select{|n| n.is_a?(AST::Node)}
|
191
|
+
nodes = parent.children.select{|n| n.is_a?(Parser::AST::Node)}
|
189
192
|
nodes.each do |node|
|
190
193
|
next if SKIPPABLE.include?(node.type)
|
191
194
|
if node.type == :return
|
@@ -203,8 +206,9 @@ module Solargraph
|
|
203
206
|
def reduce_to_value_nodes nodes
|
204
207
|
result = []
|
205
208
|
nodes.each do |node|
|
206
|
-
|
207
|
-
|
209
|
+
if !node.is_a?(Parser::AST::Node)
|
210
|
+
result.push nil
|
211
|
+
elsif REDUCEABLE.include?(node.type)
|
208
212
|
result.concat get_return_nodes_from_children(node)
|
209
213
|
elsif CONDITIONAL.include?(node.type)
|
210
214
|
result.concat reduce_to_value_nodes(node.children[1..-1])
|
@@ -212,6 +216,8 @@ module Solargraph
|
|
212
216
|
result.concat get_return_nodes(node.children[0])
|
213
217
|
elsif node.type == :and || node.type == :or
|
214
218
|
result.concat reduce_to_value_nodes(node.children)
|
219
|
+
elsif node.type == :block
|
220
|
+
result.concat get_return_nodes_only(node.children[2])
|
215
221
|
else
|
216
222
|
result.push node
|
217
223
|
end
|
@@ -67,7 +67,7 @@ module Solargraph
|
|
67
67
|
|
68
68
|
# @return [String]
|
69
69
|
def phrase
|
70
|
-
@phrase ||= source.code[signature_data
|
70
|
+
@phrase ||= source.code[signature_data..offset-1]
|
71
71
|
end
|
72
72
|
|
73
73
|
# @return [String]
|
@@ -120,63 +120,57 @@ module Solargraph
|
|
120
120
|
brackets = 0
|
121
121
|
squares = 0
|
122
122
|
parens = 0
|
123
|
-
signature = ''
|
124
123
|
index -=1
|
125
124
|
in_whitespace = false
|
126
125
|
while index >= 0
|
127
126
|
pos = Position.from_offset(@source.code, index)
|
128
127
|
break if index > 0 and @source.comment_at?(pos)
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
break
|
142
|
-
end
|
143
|
-
end
|
144
|
-
if char == ')'
|
145
|
-
parens -=1
|
146
|
-
elsif char == ']'
|
147
|
-
squares -=1
|
148
|
-
elsif char == '}'
|
149
|
-
brackets -= 1
|
150
|
-
elsif char == '('
|
151
|
-
parens += 1
|
152
|
-
elsif char == '{'
|
153
|
-
brackets += 1
|
154
|
-
elsif char == '['
|
155
|
-
squares += 1
|
156
|
-
signature = ".[]#{signature}" if parens.zero? and brackets.zero? and squares.zero? and @source.code[index-2] != '%'
|
128
|
+
break if brackets > 0 or parens > 0 or squares > 0
|
129
|
+
char = @source.code[index, 1]
|
130
|
+
break if char.nil? # @todo Is this the right way to handle this?
|
131
|
+
if brackets.zero? and parens.zero? and squares.zero? and [' ', "\r", "\n", "\t"].include?(char)
|
132
|
+
in_whitespace = true
|
133
|
+
else
|
134
|
+
if brackets.zero? and parens.zero? and squares.zero? and in_whitespace
|
135
|
+
unless char == '.' or @source.code[index+1..-1].strip.start_with?('.')
|
136
|
+
old = @source.code[index+1..-1]
|
137
|
+
nxt = @source.code[index+1..-1].lstrip
|
138
|
+
index += (@source.code[index+1..-1].length - @source.code[index+1..-1].lstrip.length)
|
139
|
+
break
|
157
140
|
end
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
141
|
+
end
|
142
|
+
if char == ')'
|
143
|
+
parens -=1
|
144
|
+
elsif char == ']'
|
145
|
+
squares -=1
|
146
|
+
elsif char == '}'
|
147
|
+
brackets -= 1
|
148
|
+
elsif char == '('
|
149
|
+
parens += 1
|
150
|
+
elsif char == '{'
|
151
|
+
brackets += 1
|
152
|
+
elsif char == '['
|
153
|
+
squares += 1
|
154
|
+
end
|
155
|
+
if brackets.zero? and parens.zero? and squares.zero?
|
156
|
+
break if ['"', "'", ',', ';', '%'].include?(char)
|
157
|
+
break if ['!', '?'].include?(char) && index < offset - 1
|
158
|
+
break if char == '$'
|
159
|
+
if char == '@'
|
160
|
+
index -= 1
|
161
|
+
if @source.code[index, 1] == '@'
|
164
162
|
index -= 1
|
165
|
-
if @source.code[index, 1] == '@'
|
166
|
-
index -= 1
|
167
|
-
signature = "@#{signature}"
|
168
|
-
end
|
169
|
-
break
|
170
163
|
end
|
171
|
-
elsif parens == 1 || brackets == 1 || squares == 1
|
172
164
|
break
|
173
165
|
end
|
174
|
-
|
166
|
+
elsif parens == 1 || brackets == 1 || squares == 1
|
167
|
+
break
|
175
168
|
end
|
169
|
+
in_whitespace = false
|
176
170
|
end
|
177
171
|
index -= 1
|
178
172
|
end
|
179
|
-
|
173
|
+
index + 1
|
180
174
|
end
|
181
175
|
end
|
182
176
|
end
|