solargraph 0.54.0 → 0.54.5
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/CHANGELOG.md +45 -0
- data/lib/solargraph/api_map/cache.rb +10 -1
- data/lib/solargraph/api_map/index.rb +167 -0
- data/lib/solargraph/api_map/store.rb +72 -121
- data/lib/solargraph/api_map.rb +94 -36
- data/lib/solargraph/bench.rb +17 -1
- data/lib/solargraph/complex_type/type_methods.rb +17 -11
- data/lib/solargraph/complex_type/unique_type.rb +93 -10
- data/lib/solargraph/complex_type.rb +68 -18
- data/lib/solargraph/convention.rb +1 -0
- data/lib/solargraph/doc_map.rb +1 -0
- data/lib/solargraph/equality.rb +33 -0
- data/lib/solargraph/language_server/host/message_worker.rb +48 -5
- data/lib/solargraph/language_server/host.rb +12 -11
- data/lib/solargraph/language_server/message/base.rb +19 -12
- data/lib/solargraph/language_server/message/initialize.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
- data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
- data/lib/solargraph/language_server/progress.rb +19 -2
- data/lib/solargraph/library.rb +31 -41
- data/lib/solargraph/location.rb +21 -1
- data/lib/solargraph/parser/node_methods.rb +1 -1
- data/lib/solargraph/parser/node_processor.rb +1 -0
- data/lib/solargraph/parser/parser_gem/class_methods.rb +2 -6
- data/lib/solargraph/parser/parser_gem/node_methods.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +8 -2
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +1 -1
- data/lib/solargraph/parser.rb +2 -5
- data/lib/solargraph/pin/base.rb +41 -17
- data/lib/solargraph/pin/base_variable.rb +4 -3
- data/lib/solargraph/pin/block.rb +6 -26
- data/lib/solargraph/pin/callable.rb +147 -0
- data/lib/solargraph/pin/closure.rb +8 -3
- data/lib/solargraph/pin/common.rb +2 -6
- data/lib/solargraph/pin/conversions.rb +3 -2
- data/lib/solargraph/pin/instance_variable.rb +2 -2
- data/lib/solargraph/pin/method.rb +57 -31
- data/lib/solargraph/pin/namespace.rb +5 -5
- data/lib/solargraph/pin/parameter.rb +11 -12
- data/lib/solargraph/pin/proxy_type.rb +1 -1
- data/lib/solargraph/pin/signature.rb +3 -129
- data/lib/solargraph/pin.rb +4 -1
- data/lib/solargraph/position.rb +7 -0
- data/lib/solargraph/range.rb +9 -4
- data/lib/solargraph/rbs_map/conversions.rb +77 -38
- data/lib/solargraph/rbs_map/core_fills.rb +6 -6
- data/lib/solargraph/rbs_map.rb +1 -0
- data/lib/solargraph/shell.rb +19 -2
- data/lib/solargraph/source/chain/array.rb +7 -6
- data/lib/solargraph/source/chain/block_symbol.rb +1 -1
- data/lib/solargraph/source/chain/block_variable.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +90 -55
- data/lib/solargraph/source/chain/hash.rb +5 -0
- data/lib/solargraph/source/chain/if.rb +5 -0
- data/lib/solargraph/source/chain/link.rb +26 -5
- data/lib/solargraph/source/chain/literal.rb +5 -0
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain.rb +68 -30
- data/lib/solargraph/source/cursor.rb +3 -2
- data/lib/solargraph/source.rb +104 -86
- data/lib/solargraph/source_map/clip.rb +5 -5
- data/lib/solargraph/source_map/data.rb +30 -0
- data/lib/solargraph/source_map.rb +28 -16
- data/lib/solargraph/type_checker/rules.rb +6 -1
- data/lib/solargraph/type_checker.rb +15 -15
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +7 -3
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -0
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
- data/lib/solargraph/yard_map/mapper.rb +1 -0
- data/lib/solargraph/yardoc.rb +1 -1
- data/lib/solargraph.rb +1 -0
- data/solargraph.gemspec +5 -5
- metadata +29 -25
@@ -5,10 +5,17 @@ require 'solargraph/source/chain/link'
|
|
5
5
|
|
6
6
|
module Solargraph
|
7
7
|
class Source
|
8
|
-
#
|
9
|
-
#
|
8
|
+
#
|
9
|
+
# Represents an expression as a single call chain at the parse
|
10
|
+
# tree level, made up of constants, variables, and method calls,
|
11
|
+
# each represented as a Link object.
|
12
|
+
#
|
13
|
+
# Computes Pins and/or ComplexTypes representing the interpreted
|
14
|
+
# expression.
|
10
15
|
#
|
11
16
|
class Chain
|
17
|
+
include Equality
|
18
|
+
|
12
19
|
autoload :Link, 'solargraph/source/chain/link'
|
13
20
|
autoload :Call, 'solargraph/source/chain/call'
|
14
21
|
autoload :QCall, 'solargraph/source/chain/q_call'
|
@@ -40,6 +47,11 @@ module Solargraph
|
|
40
47
|
|
41
48
|
attr_reader :node
|
42
49
|
|
50
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
51
|
+
protected def equality_fields
|
52
|
+
[links, node]
|
53
|
+
end
|
54
|
+
|
43
55
|
# @param node [Parser::AST::Node, nil]
|
44
56
|
# @param links [::Array<Chain::Link>]
|
45
57
|
# @param splat [Boolean]
|
@@ -61,13 +73,31 @@ module Solargraph
|
|
61
73
|
@base ||= Chain.new(links[0..-2])
|
62
74
|
end
|
63
75
|
|
76
|
+
# Determine potential Pins returned by this chain of words
|
77
|
+
#
|
64
78
|
# @param api_map [ApiMap]
|
65
|
-
# @param name_pin [Pin::
|
66
|
-
#
|
79
|
+
# @param name_pin [Pin::Closure] the surrounding closure pin for
|
80
|
+
# the statement represented by this chain for type resolution
|
81
|
+
# and method pin lookup.
|
82
|
+
#
|
83
|
+
# For method calls (Chain::Call objects) as the first element
|
84
|
+
# in the chain, 'name_pin.binder' should return the
|
85
|
+
# ComplexType representing the LHS / "self type" of the call.
|
67
86
|
#
|
68
|
-
# @
|
87
|
+
# @param locals [::Enumerable<Pin::LocalVariable>] Any local
|
88
|
+
# variables / method parameters etc visible by the statement
|
89
|
+
#
|
90
|
+
# @return [::Array<Pin::Base>] Pins representing possible return
|
91
|
+
# types of this method.
|
69
92
|
def define api_map, name_pin, locals
|
70
93
|
return [] if undefined?
|
94
|
+
|
95
|
+
# working_pin is the surrounding closure pin for the link
|
96
|
+
# being processed, whose #binder method will provide the LHS /
|
97
|
+
# 'self type' of the next link (same as the #return_type method
|
98
|
+
# --the type of the result so far).
|
99
|
+
#
|
100
|
+
# @todo ProxyType uses 'type' for the binder, but '
|
71
101
|
working_pin = name_pin
|
72
102
|
links[0..-2].each do |link|
|
73
103
|
pins = link.resolve(api_map, working_pin, locals)
|
@@ -75,37 +105,34 @@ module Solargraph
|
|
75
105
|
return [] if type.undefined?
|
76
106
|
working_pin = Pin::ProxyType.anonymous(type)
|
77
107
|
end
|
78
|
-
links.last.last_context =
|
108
|
+
links.last.last_context = working_pin
|
79
109
|
links.last.resolve(api_map, working_pin, locals)
|
80
110
|
end
|
81
111
|
|
82
112
|
# @param api_map [ApiMap]
|
83
113
|
# @param name_pin [Pin::Base]
|
84
|
-
# @param locals [::
|
114
|
+
# @param locals [::Array<Pin::LocalVariable>]
|
85
115
|
# @return [ComplexType]
|
86
116
|
# @sg-ignore
|
87
117
|
def infer api_map, name_pin, locals
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
@@inference_cache = {}
|
118
|
+
cache_key = [node, node&.location, links, name_pin&.return_type, locals]
|
119
|
+
if @@inference_invalidation_key == api_map.hash
|
120
|
+
cached = @@inference_cache[cache_key]
|
121
|
+
return cached if cached
|
122
|
+
else
|
94
123
|
@@inference_invalidation_key = api_map.hash
|
124
|
+
@@inference_cache = {}
|
95
125
|
end
|
96
|
-
|
97
|
-
|
126
|
+
out = infer_uncached api_map, name_pin, locals
|
127
|
+
logger.debug { "Chain#infer() - caching result - cache_key_hash=#{cache_key.hash}, links.map(&:hash)=#{links.map(&:hash)}, links=#{links}, cache_key.map(&:hash) = #{cache_key.map(&:hash)}, cache_key=#{cache_key}" }
|
128
|
+
@@inference_cache[cache_key] = out
|
98
129
|
end
|
99
130
|
|
100
131
|
# @param api_map [ApiMap]
|
101
132
|
# @param name_pin [Pin::Base]
|
102
|
-
# @param locals [::
|
133
|
+
# @param locals [::Array<Pin::LocalVariable>]
|
103
134
|
# @return [ComplexType]
|
104
135
|
def infer_uncached api_map, name_pin, locals
|
105
|
-
from_here = base.infer(api_map, name_pin, locals) unless links.length == 1
|
106
|
-
if from_here
|
107
|
-
name_pin = name_pin.proxy(from_here)
|
108
|
-
end
|
109
136
|
pins = define(api_map, name_pin, locals)
|
110
137
|
type = infer_first_defined(pins, links.last.last_context, api_map, locals)
|
111
138
|
maybe_nil(type)
|
@@ -137,6 +164,16 @@ module Solargraph
|
|
137
164
|
links.any?(&:nullable?)
|
138
165
|
end
|
139
166
|
|
167
|
+
include Logging
|
168
|
+
|
169
|
+
def desc
|
170
|
+
links.map(&:desc).to_s
|
171
|
+
end
|
172
|
+
|
173
|
+
def to_s
|
174
|
+
desc
|
175
|
+
end
|
176
|
+
|
140
177
|
private
|
141
178
|
|
142
179
|
# @param pins [::Array<Pin::Base>]
|
@@ -151,9 +188,9 @@ module Solargraph
|
|
151
188
|
# @param pin [Pin::Base]
|
152
189
|
pins.each do |pin|
|
153
190
|
# Avoid infinite recursion
|
154
|
-
next if @@inference_stack.include?(pin
|
191
|
+
next if @@inference_stack.include?(pin)
|
155
192
|
|
156
|
-
@@inference_stack.push pin
|
193
|
+
@@inference_stack.push pin
|
157
194
|
type = pin.typify(api_map)
|
158
195
|
@@inference_stack.pop
|
159
196
|
if type.defined?
|
@@ -161,7 +198,7 @@ module Solargraph
|
|
161
198
|
# @todo even at strong, no typechecking complaint
|
162
199
|
# happens when a [Pin::Base,nil] is passed into a method
|
163
200
|
# that accepts only [Pin::Namespace] as an argument
|
164
|
-
type = type.resolve_generics(pin.closure, context.
|
201
|
+
type = type.resolve_generics(pin.closure, context.binder)
|
165
202
|
end
|
166
203
|
if type.defined?
|
167
204
|
possibles.push type
|
@@ -177,9 +214,9 @@ module Solargraph
|
|
177
214
|
# @param pin [Pin::Base]
|
178
215
|
pins.each do |pin|
|
179
216
|
# Avoid infinite recursion
|
180
|
-
next if @@inference_stack.include?(pin
|
217
|
+
next if @@inference_stack.include?(pin)
|
181
218
|
|
182
|
-
@@inference_stack.push pin
|
219
|
+
@@inference_stack.push pin
|
183
220
|
type = pin.probe(api_map)
|
184
221
|
@@inference_stack.pop
|
185
222
|
if type.defined?
|
@@ -192,14 +229,15 @@ module Solargraph
|
|
192
229
|
return ComplexType::UNDEFINED if possibles.empty?
|
193
230
|
|
194
231
|
type = if possibles.length > 1
|
195
|
-
|
196
|
-
|
232
|
+
# Move nil to the end by convention
|
233
|
+
sorted = possibles.sort { |a, _| a.tag == 'nil' ? 1 : 0 }
|
234
|
+
ComplexType.new(sorted.uniq)
|
197
235
|
else
|
198
|
-
ComplexType.
|
236
|
+
ComplexType.new(possibles)
|
199
237
|
end
|
200
238
|
return type if context.nil? || context.return_type.undefined?
|
201
239
|
|
202
|
-
type.
|
240
|
+
type.self_to_type(context.return_type)
|
203
241
|
end
|
204
242
|
|
205
243
|
# @param type [ComplexType]
|
@@ -207,7 +245,7 @@ module Solargraph
|
|
207
245
|
def maybe_nil type
|
208
246
|
return type if type.undefined? || type.void? || type.nullable?
|
209
247
|
return type unless nullable?
|
210
|
-
ComplexType.
|
248
|
+
ComplexType.new(type.items + [ComplexType::NIL])
|
211
249
|
end
|
212
250
|
end
|
213
251
|
end
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Solargraph
|
4
4
|
class Source
|
5
|
-
# Information about a
|
6
|
-
# there.
|
5
|
+
# Information about a single Position in a Source, including the
|
6
|
+
# word located there.
|
7
7
|
#
|
8
8
|
class Cursor
|
9
9
|
# @return [Position]
|
@@ -35,6 +35,7 @@ module Solargraph
|
|
35
35
|
# The part of the word before the current position. Given the text
|
36
36
|
# `foo.bar`, the start_of_word at position(0, 6) is `ba`.
|
37
37
|
#
|
38
|
+
# @sg-ignore Improve resolution of String#match below
|
38
39
|
# @return [String]
|
39
40
|
def start_of_word
|
40
41
|
@start_of_word ||= begin
|
data/lib/solargraph/source.rb
CHANGED
@@ -19,13 +19,22 @@ module Solargraph
|
|
19
19
|
attr_reader :filename
|
20
20
|
|
21
21
|
# @return [String]
|
22
|
-
|
22
|
+
def code
|
23
|
+
finalize
|
24
|
+
@code
|
25
|
+
end
|
23
26
|
|
24
|
-
# @return [Parser::AST::Node]
|
25
|
-
|
27
|
+
# @return [Parser::AST::Node, nil]
|
28
|
+
def node
|
29
|
+
finalize
|
30
|
+
@node
|
31
|
+
end
|
26
32
|
|
27
33
|
# @return [Hash{Integer => Array<String>}]
|
28
|
-
|
34
|
+
def comments
|
35
|
+
finalize
|
36
|
+
@comments
|
37
|
+
end
|
29
38
|
|
30
39
|
# @todo Deprecate?
|
31
40
|
# @return [Integer]
|
@@ -39,17 +48,6 @@ module Solargraph
|
|
39
48
|
@repaired = code
|
40
49
|
@filename = filename
|
41
50
|
@version = version
|
42
|
-
@domains = []
|
43
|
-
begin
|
44
|
-
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
|
45
|
-
@parsed = true
|
46
|
-
rescue Parser::SyntaxError, EncodingError => e
|
47
|
-
@node = nil
|
48
|
-
@comments = {}
|
49
|
-
@parsed = false
|
50
|
-
ensure
|
51
|
-
@code.freeze
|
52
|
-
end
|
53
51
|
end
|
54
52
|
|
55
53
|
# @param range [Solargraph::Range]
|
@@ -64,9 +62,9 @@ module Solargraph
|
|
64
62
|
# @param c2 [Integer]
|
65
63
|
# @return [String]
|
66
64
|
def from_to l1, c1, l2, c2
|
67
|
-
b = Solargraph::Position.line_char_to_offset(
|
68
|
-
e = Solargraph::Position.line_char_to_offset(
|
69
|
-
|
65
|
+
b = Solargraph::Position.line_char_to_offset(code, l1, c1)
|
66
|
+
e = Solargraph::Position.line_char_to_offset(code, l2, c2)
|
67
|
+
code[b..e-1]
|
70
68
|
end
|
71
69
|
|
72
70
|
# Get the nearest node that contains the specified index.
|
@@ -85,10 +83,9 @@ module Solargraph
|
|
85
83
|
# @param column [Integer]
|
86
84
|
# @return [Array<AST::Node>]
|
87
85
|
def tree_at(line, column)
|
88
|
-
# offset = Position.line_char_to_offset(@code, line, column)
|
89
86
|
position = Position.new(line, column)
|
90
87
|
stack = []
|
91
|
-
inner_tree_at
|
88
|
+
inner_tree_at node, position, stack
|
92
89
|
stack
|
93
90
|
end
|
94
91
|
|
@@ -104,68 +101,53 @@ module Solargraph
|
|
104
101
|
@version = updater.version
|
105
102
|
return self
|
106
103
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
104
|
+
Source.new(@code, filename, updater.version).tap do |src|
|
105
|
+
src.repaired = @repaired
|
106
|
+
src.error_ranges.concat error_ranges
|
107
|
+
src.changes.concat(changes + updater.changes)
|
111
108
|
end
|
112
|
-
incr_code = updater.repair(@repaired)
|
113
|
-
synced = Source.new(incr_code, filename)
|
114
|
-
synced.error_ranges.concat (error_ranges + updater.changes.map(&:range))
|
115
|
-
synced.code = real_code
|
116
|
-
synced.version = updater.version
|
117
|
-
synced
|
118
109
|
end
|
119
110
|
|
120
111
|
# @param position [Position, Array(Integer, Integer)]
|
121
112
|
# @return [Source::Cursor]
|
122
113
|
def cursor_at position
|
114
|
+
finalize
|
123
115
|
Cursor.new(self, position)
|
124
116
|
end
|
125
117
|
|
126
118
|
# @return [Boolean]
|
127
119
|
def parsed?
|
120
|
+
finalize
|
128
121
|
@parsed
|
129
122
|
end
|
130
123
|
|
131
124
|
def repaired?
|
132
|
-
|
125
|
+
code != @repaired
|
133
126
|
end
|
134
127
|
|
135
128
|
# @param position [Position]
|
136
129
|
# @return [Boolean]
|
137
130
|
def string_at? position
|
138
|
-
if
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
return true if [:STR, :str].include?(node.type) && range.include?(position) && range.start != position
|
155
|
-
if node.type == :dstr
|
156
|
-
inner = node_at(position.line, position.column)
|
157
|
-
next if inner.nil?
|
158
|
-
inner_range = Range.from_node(inner)
|
159
|
-
next unless range.include?(inner_range.ending)
|
160
|
-
return true if inner.type == :str
|
161
|
-
inner_code = at(Solargraph::Range.new(inner_range.start, position))
|
162
|
-
return true if (inner.type == :dstr && inner_range.ending.character <= position.character) && !inner_code.end_with?('}') ||
|
163
|
-
(inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
|
164
|
-
end
|
165
|
-
break if range.ending.line > position.line
|
131
|
+
return false if Position.to_offset(code, position) >= code.length
|
132
|
+
string_nodes.each do |node|
|
133
|
+
range = Range.from_node(node)
|
134
|
+
next if range.ending.line < position.line
|
135
|
+
break if range.ending.line > position.line
|
136
|
+
return true if node.type == :str && range.include?(position) && range.start != position
|
137
|
+
return true if [:STR, :str].include?(node.type) && range.include?(position) && range.start != position
|
138
|
+
if node.type == :dstr
|
139
|
+
inner = node_at(position.line, position.column)
|
140
|
+
next if inner.nil?
|
141
|
+
inner_range = Range.from_node(inner)
|
142
|
+
next unless range.include?(inner_range.ending)
|
143
|
+
return true if inner.type == :str
|
144
|
+
inner_code = at(Solargraph::Range.new(inner_range.start, position))
|
145
|
+
return true if (inner.type == :dstr && inner_range.ending.character <= position.character) && !inner_code.end_with?('}') ||
|
146
|
+
(inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
|
166
147
|
end
|
167
|
-
|
148
|
+
break if range.ending.line > position.line
|
168
149
|
end
|
150
|
+
false
|
169
151
|
end
|
170
152
|
|
171
153
|
# @return [::Array<Range>]
|
@@ -199,8 +181,8 @@ module Solargraph
|
|
199
181
|
# @return [String]
|
200
182
|
def code_for(node)
|
201
183
|
rng = Range.from_node(node)
|
202
|
-
b = Position.line_char_to_offset(
|
203
|
-
e = Position.line_char_to_offset(
|
184
|
+
b = Position.line_char_to_offset(code, rng.start.line, rng.start.column)
|
185
|
+
e = Position.line_char_to_offset(code, rng.ending.line, rng.ending.column)
|
204
186
|
frag = code[b..e-1].to_s
|
205
187
|
frag.strip.gsub(/,$/, '')
|
206
188
|
end
|
@@ -225,15 +207,9 @@ module Solargraph
|
|
225
207
|
Location.new(filename, range)
|
226
208
|
end
|
227
209
|
|
228
|
-
FOLDING_NODE_TYPES =
|
229
|
-
%i[
|
230
|
-
CLASS SCLASS MODULE DEFN DEFS IF WHILE UNLESS ITER STR HASH ARRAY LIST
|
231
|
-
].freeze
|
232
|
-
else
|
233
|
-
%i[
|
210
|
+
FOLDING_NODE_TYPES = %i[
|
234
211
|
class sclass module def defs if str dstr array while unless kwbegin hash block
|
235
212
|
].freeze
|
236
|
-
end
|
237
213
|
|
238
214
|
# Get an array of ranges that can be folded, e.g., the range of a class
|
239
215
|
# definition or an if condition.
|
@@ -251,8 +227,7 @@ module Solargraph
|
|
251
227
|
end
|
252
228
|
|
253
229
|
def synchronized?
|
254
|
-
|
255
|
-
@synchronized
|
230
|
+
true
|
256
231
|
end
|
257
232
|
|
258
233
|
# Get a hash of comments grouped by the line numbers of the associated code.
|
@@ -262,8 +237,9 @@ module Solargraph
|
|
262
237
|
@associated_comments ||= begin
|
263
238
|
result = {}
|
264
239
|
buffer = String.new('')
|
240
|
+
# @type [Integer, nil]
|
265
241
|
last = nil
|
266
|
-
|
242
|
+
comments.each_pair do |num, snip|
|
267
243
|
if !last || num == last + 1
|
268
244
|
buffer.concat "#{snip.text}\n"
|
269
245
|
else
|
@@ -295,12 +271,9 @@ module Solargraph
|
|
295
271
|
def inner_folding_ranges top, result = [], parent = nil
|
296
272
|
return unless Parser.is_ast_node?(top)
|
297
273
|
if FOLDING_NODE_TYPES.include?(top.type)
|
298
|
-
|
299
|
-
|
300
|
-
range
|
301
|
-
if result.empty? || range.start.line > result.last.start.line
|
302
|
-
result.push range unless range.ending.line - range.start.line < 2
|
303
|
-
end
|
274
|
+
range = Range.from_node(top)
|
275
|
+
if result.empty? || range.start.line > result.last.start.line
|
276
|
+
result.push range unless range.ending.line - range.start.line < 2
|
304
277
|
end
|
305
278
|
end
|
306
279
|
top.children.each do |child|
|
@@ -334,19 +307,19 @@ module Solargraph
|
|
334
307
|
|
335
308
|
# A hash of line numbers and their associated comments.
|
336
309
|
#
|
337
|
-
# @return [Hash{Integer => Array<String
|
310
|
+
# @return [Hash{Integer => Array<String>, nil}]
|
338
311
|
def stringified_comments
|
339
312
|
@stringified_comments ||= {}
|
340
313
|
end
|
341
314
|
|
342
315
|
# @return [Array<Parser::AST::Node>]
|
343
316
|
def string_nodes
|
344
|
-
@string_nodes ||= string_nodes_in(
|
317
|
+
@string_nodes ||= string_nodes_in(node)
|
345
318
|
end
|
346
319
|
|
347
320
|
# @return [Array<Range>]
|
348
321
|
def comment_ranges
|
349
|
-
@comment_ranges ||=
|
322
|
+
@comment_ranges ||= comments.values.map(&:range)
|
350
323
|
end
|
351
324
|
|
352
325
|
# Get an array of foldable comment block ranges. Blocks are excluded if
|
@@ -402,16 +375,59 @@ module Solargraph
|
|
402
375
|
|
403
376
|
protected
|
404
377
|
|
378
|
+
# @return [Array<Change>]
|
379
|
+
def changes
|
380
|
+
@changes ||= []
|
381
|
+
end
|
382
|
+
|
405
383
|
# @return [String]
|
406
384
|
attr_writer :filename
|
407
385
|
|
408
386
|
# @return [Integer]
|
409
387
|
attr_writer :version
|
410
388
|
|
389
|
+
def finalize
|
390
|
+
return if @finalized && changes.empty?
|
391
|
+
|
392
|
+
changes.each do |change|
|
393
|
+
@code = change.write(@code)
|
394
|
+
end
|
395
|
+
@finalized = true
|
396
|
+
begin
|
397
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
|
398
|
+
@parsed = true
|
399
|
+
@repaired = @code
|
400
|
+
rescue Parser::SyntaxError, EncodingError => e
|
401
|
+
@node = nil
|
402
|
+
@comments = {}
|
403
|
+
@parsed = false
|
404
|
+
ensure
|
405
|
+
@code.freeze
|
406
|
+
end
|
407
|
+
if !@parsed && !changes.empty?
|
408
|
+
changes.each do |change|
|
409
|
+
@repaired = change.repair(@repaired)
|
410
|
+
end
|
411
|
+
error_ranges.concat(changes.map(&:range))
|
412
|
+
begin
|
413
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename)
|
414
|
+
@parsed = true
|
415
|
+
rescue Parser::SyntaxError, EncodingError => e
|
416
|
+
@node = nil
|
417
|
+
@comments = {}
|
418
|
+
@parsed = false
|
419
|
+
end
|
420
|
+
elsif @parsed
|
421
|
+
error_ranges.clear
|
422
|
+
end
|
423
|
+
changes.clear
|
424
|
+
end
|
425
|
+
|
411
426
|
# @param val [String]
|
412
427
|
# @return [String]
|
413
428
|
def code=(val)
|
414
|
-
@code_lines= nil
|
429
|
+
@code_lines = nil
|
430
|
+
@finalized = false
|
415
431
|
@code = val
|
416
432
|
end
|
417
433
|
|
@@ -422,7 +438,12 @@ module Solargraph
|
|
422
438
|
attr_writer :error_ranges
|
423
439
|
|
424
440
|
# @return [String]
|
425
|
-
|
441
|
+
attr_writer :repaired
|
442
|
+
|
443
|
+
def repaired
|
444
|
+
finalize
|
445
|
+
@repaired
|
446
|
+
end
|
426
447
|
|
427
448
|
# @return [Boolean]
|
428
449
|
attr_writer :parsed
|
@@ -433,9 +454,6 @@ module Solargraph
|
|
433
454
|
# @return [Boolean]
|
434
455
|
attr_writer :synchronized
|
435
456
|
|
436
|
-
# @return [Source::Updater]
|
437
|
-
attr_accessor :last_updater
|
438
|
-
|
439
457
|
private
|
440
458
|
|
441
459
|
# @return [Array<String>]
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Solargraph
|
4
4
|
class SourceMap
|
5
|
-
# A static analysis tool for obtaining definitions,
|
6
|
-
# signatures, and type inferences from a
|
5
|
+
# A static analysis tool for obtaining definitions, Completions,
|
6
|
+
# signatures, and type inferences from a Cursor.
|
7
7
|
#
|
8
8
|
class Clip
|
9
9
|
# @param api_map [ApiMap]
|
@@ -40,7 +40,7 @@ module Solargraph
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
# @return [Array<Pin::
|
43
|
+
# @return [Array<Pin::Method>]
|
44
44
|
def signify
|
45
45
|
return [] unless cursor.argument?
|
46
46
|
chain = Parser.chain(cursor.recipient_node, cursor.filename)
|
@@ -53,10 +53,10 @@ module Solargraph
|
|
53
53
|
if result.tag == 'Class'
|
54
54
|
# HACK: Exception to return BasicObject from Class#new
|
55
55
|
dfn = cursor.chain.define(api_map, block, locals).first
|
56
|
-
return ComplexType.try_parse('BasicObject') if dfn && dfn.path == 'Class#new'
|
56
|
+
return ComplexType.try_parse('::BasicObject') if dfn && dfn.path == 'Class#new'
|
57
57
|
end
|
58
58
|
return result unless result.tag == 'self'
|
59
|
-
|
59
|
+
cursor.chain.base.infer(api_map, block, locals)
|
60
60
|
end
|
61
61
|
|
62
62
|
# Get an array of all the locals that are visible from the cursors's
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class SourceMap
|
5
|
+
class Data
|
6
|
+
def initialize source
|
7
|
+
@source = source
|
8
|
+
end
|
9
|
+
|
10
|
+
def pins
|
11
|
+
generate
|
12
|
+
@pins || []
|
13
|
+
end
|
14
|
+
|
15
|
+
def locals
|
16
|
+
generate
|
17
|
+
@locals || []
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def generate
|
23
|
+
return if @generated
|
24
|
+
|
25
|
+
@generated = true
|
26
|
+
@pins, @locals = Mapper.map(@source)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|