solargraph 0.53.4 → 0.54.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/lib/solargraph/api_map/cache.rb +2 -12
- data/lib/solargraph/api_map/store.rb +14 -5
- data/lib/solargraph/api_map.rb +67 -24
- data/lib/solargraph/complex_type/type_methods.rb +70 -39
- data/lib/solargraph/complex_type/unique_type.rb +187 -73
- data/lib/solargraph/complex_type.rb +105 -40
- data/lib/solargraph/doc_map.rb +19 -3
- data/lib/solargraph/gem_pins.rb +9 -1
- data/lib/solargraph/language_server/host/dispatch.rb +8 -1
- data/lib/solargraph/language_server/host/message_worker.rb +29 -3
- data/lib/solargraph/language_server/host/sources.rb +1 -61
- data/lib/solargraph/language_server/host.rb +21 -68
- data/lib/solargraph/language_server/message/base.rb +1 -1
- data/lib/solargraph/language_server/message/initialize.rb +14 -0
- 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 +1 -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 +135 -0
- data/lib/solargraph/language_server.rb +1 -0
- data/lib/solargraph/library.rb +144 -113
- data/lib/solargraph/location.rb +14 -1
- data/lib/solargraph/parser/node_processor/base.rb +3 -2
- data/lib/solargraph/parser/node_processor.rb +1 -0
- data/lib/solargraph/parser/parser_gem/class_methods.rb +3 -7
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -7
- data/lib/solargraph/parser/parser_gem/node_methods.rb +1 -5
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -2
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +53 -0
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +6 -4
- data/lib/solargraph/parser/parser_gem/node_processors.rb +2 -0
- data/lib/solargraph/parser.rb +2 -5
- data/lib/solargraph/pin/base.rb +15 -1
- data/lib/solargraph/pin/base_variable.rb +35 -6
- data/lib/solargraph/pin/block.rb +48 -11
- 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/delegated_method.rb +5 -1
- data/lib/solargraph/pin/documenting.rb +2 -0
- data/lib/solargraph/pin/instance_variable.rb +2 -2
- data/lib/solargraph/pin/method.rb +54 -32
- data/lib/solargraph/pin/namespace.rb +4 -4
- data/lib/solargraph/pin/parameter.rb +14 -39
- 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/range.rb +2 -4
- data/lib/solargraph/rbs_map/conversions.rb +79 -42
- data/lib/solargraph/rbs_map/core_fills.rb +6 -6
- data/lib/solargraph/rbs_map.rb +11 -3
- data/lib/solargraph/shell.rb +35 -15
- data/lib/solargraph/source/chain/array.rb +6 -5
- 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 +78 -50
- data/lib/solargraph/source/chain/link.rb +9 -0
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain.rb +60 -16
- data/lib/solargraph/source/cursor.rb +13 -2
- data/lib/solargraph/source/updater.rb +1 -0
- data/lib/solargraph/source.rb +102 -129
- data/lib/solargraph/source_map/clip.rb +4 -4
- data/lib/solargraph/source_map/data.rb +30 -0
- data/lib/solargraph/source_map/mapper.rb +3 -2
- data/lib/solargraph/source_map.rb +37 -15
- data/lib/solargraph/type_checker/rules.rb +6 -1
- data/lib/solargraph/type_checker.rb +50 -25
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +2 -1
- data/lib/solargraph/workspace.rb +13 -0
- metadata +6 -3
- data/lib/solargraph/language_server/host/cataloger.rb +0 -57
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,57 +83,12 @@ 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
|
|
95
|
-
# Start synchronizing the source. This method updates the code without
|
96
|
-
# parsing a new AST. The resulting Source object will be marked not
|
97
|
-
# synchronized (#synchronized? == false).
|
98
|
-
#
|
99
|
-
# @param updater [Source::Updater]
|
100
|
-
# @return [Source]
|
101
|
-
def start_synchronize updater
|
102
|
-
raise 'Invalid synchronization' unless updater.filename == filename
|
103
|
-
real_code = updater.write(@code)
|
104
|
-
src = Source.allocate
|
105
|
-
src.filename = filename
|
106
|
-
src.code = real_code
|
107
|
-
src.version = updater.version
|
108
|
-
src.parsed = parsed?
|
109
|
-
src.repaired = updater.repair(@repaired)
|
110
|
-
src.synchronized = false
|
111
|
-
src.node = @node
|
112
|
-
src.comments = @comments
|
113
|
-
src.error_ranges = error_ranges
|
114
|
-
src.last_updater = updater
|
115
|
-
return src.finish_synchronize unless real_code.lines.length == @code.lines.length
|
116
|
-
src
|
117
|
-
end
|
118
|
-
|
119
|
-
# Finish synchronizing a source that was updated via #start_synchronize.
|
120
|
-
# This method returns self if the source is already synchronized. Otherwise
|
121
|
-
# it parses the AST and returns a new synchronized Source.
|
122
|
-
#
|
123
|
-
# @return [Source]
|
124
|
-
def finish_synchronize
|
125
|
-
return self if synchronized?
|
126
|
-
synced = Source.new(@code, filename)
|
127
|
-
if synced.parsed?
|
128
|
-
synced.version = version
|
129
|
-
return synced
|
130
|
-
end
|
131
|
-
synced = Source.new(@repaired, filename)
|
132
|
-
synced.error_ranges.concat (error_ranges + last_updater.changes.map(&:range))
|
133
|
-
synced.code = @code
|
134
|
-
synced.synchronized = true
|
135
|
-
synced.version = version
|
136
|
-
synced
|
137
|
-
end
|
138
|
-
|
139
92
|
# Synchronize the Source with an update. This method applies changes to the
|
140
93
|
# code, parses the new code's AST, and returns the resulting Source object.
|
141
94
|
#
|
@@ -148,68 +101,53 @@ module Solargraph
|
|
148
101
|
@version = updater.version
|
149
102
|
return self
|
150
103
|
end
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
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)
|
155
108
|
end
|
156
|
-
incr_code = updater.repair(@repaired)
|
157
|
-
synced = Source.new(incr_code, filename)
|
158
|
-
synced.error_ranges.concat (error_ranges + updater.changes.map(&:range))
|
159
|
-
synced.code = real_code
|
160
|
-
synced.version = updater.version
|
161
|
-
synced
|
162
109
|
end
|
163
110
|
|
164
111
|
# @param position [Position, Array(Integer, Integer)]
|
165
112
|
# @return [Source::Cursor]
|
166
113
|
def cursor_at position
|
114
|
+
finalize
|
167
115
|
Cursor.new(self, position)
|
168
116
|
end
|
169
117
|
|
170
118
|
# @return [Boolean]
|
171
119
|
def parsed?
|
120
|
+
finalize
|
172
121
|
@parsed
|
173
122
|
end
|
174
123
|
|
175
124
|
def repaired?
|
176
|
-
|
125
|
+
code != @repaired
|
177
126
|
end
|
178
127
|
|
179
128
|
# @param position [Position]
|
180
129
|
# @return [Boolean]
|
181
130
|
def string_at? position
|
182
|
-
if
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
return true if [:STR, :str].include?(node.type) && range.include?(position) && range.start != position
|
199
|
-
if node.type == :dstr
|
200
|
-
inner = node_at(position.line, position.column)
|
201
|
-
next if inner.nil?
|
202
|
-
inner_range = Range.from_node(inner)
|
203
|
-
next unless range.include?(inner_range.ending)
|
204
|
-
return true if inner.type == :str
|
205
|
-
inner_code = at(Solargraph::Range.new(inner_range.start, position))
|
206
|
-
return true if (inner.type == :dstr && inner_range.ending.character <= position.character) && !inner_code.end_with?('}') ||
|
207
|
-
(inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
|
208
|
-
end
|
209
|
-
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?('}'))
|
210
147
|
end
|
211
|
-
|
148
|
+
break if range.ending.line > position.line
|
212
149
|
end
|
150
|
+
false
|
213
151
|
end
|
214
152
|
|
215
153
|
# @return [::Array<Range>]
|
@@ -243,8 +181,8 @@ module Solargraph
|
|
243
181
|
# @return [String]
|
244
182
|
def code_for(node)
|
245
183
|
rng = Range.from_node(node)
|
246
|
-
b = Position.line_char_to_offset(
|
247
|
-
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)
|
248
186
|
frag = code[b..e-1].to_s
|
249
187
|
frag.strip.gsub(/,$/, '')
|
250
188
|
end
|
@@ -269,15 +207,9 @@ module Solargraph
|
|
269
207
|
Location.new(filename, range)
|
270
208
|
end
|
271
209
|
|
272
|
-
FOLDING_NODE_TYPES =
|
273
|
-
%i[
|
274
|
-
CLASS SCLASS MODULE DEFN DEFS IF WHILE UNLESS ITER STR HASH ARRAY LIST
|
275
|
-
].freeze
|
276
|
-
else
|
277
|
-
%i[
|
210
|
+
FOLDING_NODE_TYPES = %i[
|
278
211
|
class sclass module def defs if str dstr array while unless kwbegin hash block
|
279
212
|
].freeze
|
280
|
-
end
|
281
213
|
|
282
214
|
# Get an array of ranges that can be folded, e.g., the range of a class
|
283
215
|
# definition or an if condition.
|
@@ -295,8 +227,7 @@ module Solargraph
|
|
295
227
|
end
|
296
228
|
|
297
229
|
def synchronized?
|
298
|
-
|
299
|
-
@synchronized
|
230
|
+
true
|
300
231
|
end
|
301
232
|
|
302
233
|
# Get a hash of comments grouped by the line numbers of the associated code.
|
@@ -306,8 +237,9 @@ module Solargraph
|
|
306
237
|
@associated_comments ||= begin
|
307
238
|
result = {}
|
308
239
|
buffer = String.new('')
|
240
|
+
# @type [Integer, nil]
|
309
241
|
last = nil
|
310
|
-
|
242
|
+
comments.each_pair do |num, snip|
|
311
243
|
if !last || num == last + 1
|
312
244
|
buffer.concat "#{snip.text}\n"
|
313
245
|
else
|
@@ -339,12 +271,9 @@ module Solargraph
|
|
339
271
|
def inner_folding_ranges top, result = [], parent = nil
|
340
272
|
return unless Parser.is_ast_node?(top)
|
341
273
|
if FOLDING_NODE_TYPES.include?(top.type)
|
342
|
-
|
343
|
-
|
344
|
-
range
|
345
|
-
if result.empty? || range.start.line > result.last.start.line
|
346
|
-
result.push range unless range.ending.line - range.start.line < 2
|
347
|
-
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
|
348
277
|
end
|
349
278
|
end
|
350
279
|
top.children.each do |child|
|
@@ -385,12 +314,12 @@ module Solargraph
|
|
385
314
|
|
386
315
|
# @return [Array<Parser::AST::Node>]
|
387
316
|
def string_nodes
|
388
|
-
@string_nodes ||= string_nodes_in(
|
317
|
+
@string_nodes ||= string_nodes_in(node)
|
389
318
|
end
|
390
319
|
|
391
320
|
# @return [Array<Range>]
|
392
321
|
def comment_ranges
|
393
|
-
@comment_ranges ||=
|
322
|
+
@comment_ranges ||= comments.values.map(&:range)
|
394
323
|
end
|
395
324
|
|
396
325
|
# Get an array of foldable comment block ranges. Blocks are excluded if
|
@@ -446,16 +375,58 @@ module Solargraph
|
|
446
375
|
|
447
376
|
protected
|
448
377
|
|
378
|
+
def changes
|
379
|
+
@changes ||= []
|
380
|
+
end
|
381
|
+
|
449
382
|
# @return [String]
|
450
383
|
attr_writer :filename
|
451
384
|
|
452
385
|
# @return [Integer]
|
453
386
|
attr_writer :version
|
454
387
|
|
388
|
+
def finalize
|
389
|
+
return if @finalized && changes.empty?
|
390
|
+
|
391
|
+
changes.each do |change|
|
392
|
+
@code = change.write(@code)
|
393
|
+
end
|
394
|
+
@finalized = true
|
395
|
+
begin
|
396
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
|
397
|
+
@parsed = true
|
398
|
+
@repaired = @code
|
399
|
+
rescue Parser::SyntaxError, EncodingError => e
|
400
|
+
@node = nil
|
401
|
+
@comments = {}
|
402
|
+
@parsed = false
|
403
|
+
ensure
|
404
|
+
@code.freeze
|
405
|
+
end
|
406
|
+
if !@parsed && !changes.empty?
|
407
|
+
changes.each do |change|
|
408
|
+
@repaired = change.repair(@repaired)
|
409
|
+
end
|
410
|
+
error_ranges.concat(changes.map(&:range))
|
411
|
+
begin
|
412
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename)
|
413
|
+
@parsed = true
|
414
|
+
rescue Parser::SyntaxError, EncodingError => e
|
415
|
+
@node = nil
|
416
|
+
@comments = {}
|
417
|
+
@parsed = false
|
418
|
+
end
|
419
|
+
elsif @parsed
|
420
|
+
error_ranges.clear
|
421
|
+
end
|
422
|
+
changes.clear
|
423
|
+
end
|
424
|
+
|
455
425
|
# @param val [String]
|
456
426
|
# @return [String]
|
457
427
|
def code=(val)
|
458
|
-
@code_lines= nil
|
428
|
+
@code_lines = nil
|
429
|
+
@finalized = false
|
459
430
|
@code = val
|
460
431
|
end
|
461
432
|
|
@@ -466,7 +437,12 @@ module Solargraph
|
|
466
437
|
attr_writer :error_ranges
|
467
438
|
|
468
439
|
# @return [String]
|
469
|
-
|
440
|
+
attr_writer :repaired
|
441
|
+
|
442
|
+
def repaired
|
443
|
+
finalize
|
444
|
+
@repaired
|
445
|
+
end
|
470
446
|
|
471
447
|
# @return [Boolean]
|
472
448
|
attr_writer :parsed
|
@@ -477,9 +453,6 @@ module Solargraph
|
|
477
453
|
# @return [Boolean]
|
478
454
|
attr_writer :synchronized
|
479
455
|
|
480
|
-
# @return [Source::Updater]
|
481
|
-
attr_accessor :last_updater
|
482
|
-
|
483
456
|
private
|
484
457
|
|
485
458
|
# @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]
|
@@ -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
|
@@ -144,7 +144,7 @@ module Solargraph
|
|
144
144
|
)
|
145
145
|
end
|
146
146
|
if t.nil? || t.include?('w')
|
147
|
-
|
147
|
+
method_pin = Solargraph::Pin::Method.new(
|
148
148
|
location: location,
|
149
149
|
closure: namespace,
|
150
150
|
name: "#{directive.tag.name}=",
|
@@ -153,7 +153,8 @@ module Solargraph
|
|
153
153
|
visibility: :public,
|
154
154
|
attribute: true
|
155
155
|
)
|
156
|
-
pins.
|
156
|
+
pins.push method_pin
|
157
|
+
method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last)
|
157
158
|
if pins.last.return_type.defined?
|
158
159
|
pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value')
|
159
160
|
end
|
@@ -4,40 +4,51 @@ require 'yard'
|
|
4
4
|
require 'solargraph/yard_tags'
|
5
5
|
|
6
6
|
module Solargraph
|
7
|
-
# An index of
|
7
|
+
# An index of Pins and other ApiMap-related data for a single Source
|
8
|
+
# that can be queried.
|
8
9
|
#
|
9
10
|
class SourceMap
|
10
11
|
autoload :Mapper, 'solargraph/source_map/mapper'
|
11
12
|
autoload :Clip, 'solargraph/source_map/clip'
|
12
13
|
autoload :Completion, 'solargraph/source_map/completion'
|
14
|
+
autoload :Data, 'solargraph/source_map/data'
|
13
15
|
|
14
16
|
# @return [Source]
|
15
17
|
attr_reader :source
|
16
18
|
|
17
19
|
# @return [Array<Pin::Base>]
|
18
|
-
|
20
|
+
def pins
|
21
|
+
data.pins
|
22
|
+
end
|
19
23
|
|
20
24
|
# @return [Array<Pin::LocalVariable>]
|
21
|
-
|
25
|
+
def locals
|
26
|
+
data.locals
|
27
|
+
end
|
22
28
|
|
23
29
|
# @param source [Source]
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# HACK: Keep the library from changing this
|
28
|
-
@source = source.dup
|
29
|
-
@pins = pins
|
30
|
-
@locals = locals
|
30
|
+
def initialize source
|
31
|
+
@source = source
|
32
|
+
|
31
33
|
environ.merge Convention.for_local(self) unless filename.nil?
|
32
34
|
self.convention_pins = environ.pins
|
33
|
-
@pin_class_hash = pins.to_set.classify(&:class).transform_values(&:to_a)
|
34
35
|
@pin_select_cache = {}
|
35
36
|
end
|
36
37
|
|
37
38
|
# @param klass [Class]
|
38
39
|
# @return [Array<Pin::Base>]
|
39
40
|
def pins_by_class klass
|
40
|
-
@pin_select_cache[klass] ||=
|
41
|
+
@pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
|
42
|
+
end
|
43
|
+
|
44
|
+
# A hash representing the state of the source map's API.
|
45
|
+
#
|
46
|
+
# ApiMap#catalog uses this value to determine whether it needs to clear its
|
47
|
+
# cache.
|
48
|
+
#
|
49
|
+
# @return [Integer]
|
50
|
+
def api_hash
|
51
|
+
@api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select { |pin| pin.namespace.to_s > '' } + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node) + locals).hash
|
41
52
|
end
|
42
53
|
|
43
54
|
# @return [String]
|
@@ -107,10 +118,13 @@ module Solargraph
|
|
107
118
|
_locate_pin line, character, Pin::Namespace, Pin::Method, Pin::Block
|
108
119
|
end
|
109
120
|
|
121
|
+
# @todo Candidate for deprecation
|
122
|
+
#
|
110
123
|
# @param other_map [SourceMap]
|
111
124
|
# @return [Boolean]
|
112
125
|
def try_merge! other_map
|
113
126
|
return false if pins.length != other_map.pins.length || locals.length != other_map.locals.length || requires.map(&:name).uniq.sort != other_map.requires.map(&:name).uniq.sort
|
127
|
+
|
114
128
|
pins.each_index do |i|
|
115
129
|
return false unless pins[i].try_merge!(other_map.pins[i])
|
116
130
|
end
|
@@ -151,16 +165,24 @@ module Solargraph
|
|
151
165
|
SourceMap.map(source)
|
152
166
|
end
|
153
167
|
|
168
|
+
# @deprecated
|
154
169
|
# @param source [Source]
|
155
170
|
# @return [SourceMap]
|
156
171
|
def map source
|
157
|
-
|
158
|
-
new(source, *result)
|
172
|
+
new(source)
|
159
173
|
end
|
160
174
|
end
|
161
175
|
|
162
176
|
private
|
163
177
|
|
178
|
+
def pin_class_hash
|
179
|
+
@pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
|
180
|
+
end
|
181
|
+
|
182
|
+
def data
|
183
|
+
@data ||= Data.new(source)
|
184
|
+
end
|
185
|
+
|
164
186
|
# @return [Array<Pin::Base>]
|
165
187
|
def convention_pins
|
166
188
|
@convention_pins || []
|
@@ -169,7 +191,7 @@ module Solargraph
|
|
169
191
|
# @param pins [Array<Pin::Base>]
|
170
192
|
# @return [Array<Pin::Base>]
|
171
193
|
def convention_pins=(pins)
|
172
|
-
# unmemoizing the document_symbols in case it was called from any of
|
194
|
+
# unmemoizing the document_symbols in case it was called from any of conventions
|
173
195
|
@document_symbols = nil
|
174
196
|
@convention_pins = pins
|
175
197
|
end
|
@@ -9,7 +9,8 @@ module Solargraph
|
|
9
9
|
normal: 0,
|
10
10
|
typed: 1,
|
11
11
|
strict: 2,
|
12
|
-
strong: 3
|
12
|
+
strong: 3,
|
13
|
+
alpha: 4
|
13
14
|
}.freeze
|
14
15
|
|
15
16
|
# @return [Symbol]
|
@@ -52,6 +53,10 @@ module Solargraph
|
|
52
53
|
def validate_tags?
|
53
54
|
rank > LEVELS[:normal]
|
54
55
|
end
|
56
|
+
|
57
|
+
def require_all_return_types_match_inferred?
|
58
|
+
rank >= LEVELS[:alpha]
|
59
|
+
end
|
55
60
|
end
|
56
61
|
end
|
57
62
|
end
|