solargraph 0.32.5 → 0.33.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/.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
|