solargraph 0.52.0 → 0.53.4
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/.github/workflows/plugins.yml +40 -0
- data/.github/workflows/rspec.yml +1 -3
- data/.github/workflows/typecheck.yml +34 -0
- data/CHANGELOG.md +53 -0
- data/README.md +13 -16
- data/SPONSORS.md +1 -7
- data/lib/solargraph/api_map/cache.rb +59 -21
- data/lib/solargraph/api_map/source_to_yard.rb +17 -10
- data/lib/solargraph/api_map/store.rb +45 -9
- data/lib/solargraph/api_map.rb +178 -113
- data/lib/solargraph/bench.rb +3 -2
- data/lib/solargraph/cache.rb +29 -5
- data/lib/solargraph/complex_type/type_methods.rb +53 -8
- data/lib/solargraph/complex_type/unique_type.rb +171 -58
- data/lib/solargraph/complex_type.rb +62 -9
- data/lib/solargraph/convention.rb +0 -1
- data/lib/solargraph/converters/dd.rb +5 -0
- data/lib/solargraph/converters/dl.rb +3 -0
- data/lib/solargraph/converters/dt.rb +3 -0
- data/lib/solargraph/diagnostics/rubocop.rb +8 -7
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/diagnostics.rb +2 -2
- data/lib/solargraph/doc_map.rb +171 -0
- data/lib/solargraph/gem_pins.rb +64 -0
- data/lib/solargraph/language_server/host/cataloger.rb +1 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
- data/lib/solargraph/language_server/host/dispatch.rb +15 -5
- data/lib/solargraph/language_server/host/message_worker.rb +4 -0
- data/lib/solargraph/language_server/host/sources.rb +7 -4
- data/lib/solargraph/language_server/host.rb +35 -7
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
- data/lib/solargraph/language_server/message/initialize.rb +5 -2
- data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
- data/lib/solargraph/language_server/message/text_document.rb +0 -1
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
- data/lib/solargraph/language_server/transport/adapter.rb +16 -1
- data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
- data/lib/solargraph/library.rb +71 -12
- data/lib/solargraph/location.rb +1 -0
- data/lib/solargraph/page.rb +6 -0
- data/lib/solargraph/parser/comment_ripper.rb +3 -0
- data/lib/solargraph/parser/node_methods.rb +47 -8
- data/lib/solargraph/parser/node_processor/base.rb +9 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +29 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +42 -34
- data/lib/solargraph/parser/{legacy → parser_gem}/node_methods.rb +201 -29
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/args_node.rb +4 -1
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +7 -20
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
- data/lib/solargraph/parser/parser_gem.rb +12 -0
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +8 -11
- data/lib/solargraph/pin/base.rb +63 -8
- data/lib/solargraph/pin/base_variable.rb +7 -3
- data/lib/solargraph/pin/block.rb +26 -38
- data/lib/solargraph/pin/closure.rb +17 -2
- data/lib/solargraph/pin/common.rb +7 -3
- data/lib/solargraph/pin/conversions.rb +33 -3
- data/lib/solargraph/pin/documenting.rb +25 -34
- data/lib/solargraph/pin/instance_variable.rb +4 -0
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +110 -16
- data/lib/solargraph/pin/namespace.rb +16 -10
- data/lib/solargraph/pin/parameter.rb +41 -10
- data/lib/solargraph/pin/reference/override.rb +2 -2
- data/lib/solargraph/pin/reference.rb +8 -0
- data/lib/solargraph/pin/search.rb +3 -3
- data/lib/solargraph/pin/signature.rb +114 -2
- data/lib/solargraph/pin.rb +0 -1
- data/lib/solargraph/range.rb +2 -2
- data/lib/solargraph/rbs_map/conversions.rb +213 -61
- data/lib/solargraph/rbs_map/core_fills.rb +12 -28
- data/lib/solargraph/rbs_map/core_map.rb +2 -12
- data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
- data/lib/solargraph/rbs_map.rb +24 -12
- data/lib/solargraph/shell.rb +62 -59
- data/lib/solargraph/source/chain/array.rb +4 -1
- data/lib/solargraph/source/chain/block_symbol.rb +13 -0
- data/lib/solargraph/source/chain/call.rb +95 -26
- data/lib/solargraph/source/chain/constant.rb +15 -1
- data/lib/solargraph/source/chain/if.rb +23 -0
- data/lib/solargraph/source/chain/link.rb +7 -1
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +2 -2
- data/lib/solargraph/source/chain.rb +20 -4
- data/lib/solargraph/source/change.rb +3 -0
- data/lib/solargraph/source/cursor.rb +2 -0
- data/lib/solargraph/source/source_chainer.rb +6 -5
- data/lib/solargraph/source.rb +15 -16
- data/lib/solargraph/source_map/clip.rb +14 -9
- data/lib/solargraph/source_map/mapper.rb +10 -0
- data/lib/solargraph/source_map.rb +12 -10
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker.rb +96 -21
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +8 -6
- data/lib/solargraph/workspace.rb +15 -2
- data/lib/solargraph/yard_map/cache.rb +6 -0
- data/lib/solargraph/yard_map/helpers.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +16 -3
- data/lib/solargraph/yard_map/to_method.rb +11 -4
- data/lib/solargraph/yard_map.rb +0 -292
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +4 -1
- data/solargraph.gemspec +2 -2
- metadata +35 -58
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/documentor.rb +0 -76
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
- data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
- data/lib/solargraph/parser/legacy.rb +0 -12
- data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -151
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -163
- data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
- data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
- data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
- data/lib/solargraph/parser/rubyvm.rb +0 -40
- data/lib/solargraph/rbs_map/core_signs.rb +0 -33
@@ -8,6 +8,17 @@ module Solargraph
|
|
8
8
|
# A common module for running language servers in Backport.
|
9
9
|
#
|
10
10
|
module Adapter
|
11
|
+
# This runs in the context of Backport::Adapter, which
|
12
|
+
# provides write() - but if we didn't hide this behind a parse
|
13
|
+
# tag, it would override the one in the class.
|
14
|
+
#
|
15
|
+
# @!method write(text)
|
16
|
+
# @abstract
|
17
|
+
# Write the change to the specified text.
|
18
|
+
# @param text [String] The text to be changed.
|
19
|
+
# @return [String] The updated text.
|
20
|
+
|
21
|
+
# @return [void]
|
11
22
|
def opening
|
12
23
|
@host = Solargraph::LanguageServer::Host.new
|
13
24
|
@host.add_observer self
|
@@ -18,15 +29,18 @@ module Solargraph
|
|
18
29
|
end
|
19
30
|
end
|
20
31
|
|
32
|
+
# @return [void]
|
21
33
|
def closing
|
22
34
|
@host.stop
|
23
35
|
end
|
24
36
|
|
25
37
|
# @param data [String]
|
38
|
+
# @return [void]
|
26
39
|
def receiving data
|
27
40
|
@data_reader.receive data
|
28
41
|
end
|
29
42
|
|
43
|
+
# @return [void]
|
30
44
|
def update
|
31
45
|
if @host.stopped?
|
32
46
|
shutdown
|
@@ -38,12 +52,13 @@ module Solargraph
|
|
38
52
|
|
39
53
|
private
|
40
54
|
|
41
|
-
# @param request [
|
55
|
+
# @param request [Hash]
|
42
56
|
# @return [void]
|
43
57
|
def process request
|
44
58
|
@host.process(request)
|
45
59
|
end
|
46
60
|
|
61
|
+
# @return [void]
|
47
62
|
def shutdown
|
48
63
|
Backport.stop unless @host.options['transport'] == 'external'
|
49
64
|
end
|
@@ -16,6 +16,7 @@ module Solargraph
|
|
16
16
|
# client.
|
17
17
|
#
|
18
18
|
# @yieldparam [Hash] The message received from the client
|
19
|
+
# @return [void]
|
19
20
|
def set_message_handler &block
|
20
21
|
@message_handler = block
|
21
22
|
end
|
@@ -26,6 +27,7 @@ module Solargraph
|
|
26
27
|
# will be buffered and subsequent data will be appended to the buffer.
|
27
28
|
#
|
28
29
|
# @param data [String]
|
30
|
+
# @return [void]
|
29
31
|
def receive data
|
30
32
|
data.each_char do |char|
|
31
33
|
@buffer.concat char
|
data/lib/solargraph/library.rb
CHANGED
@@ -159,7 +159,7 @@ module Solargraph
|
|
159
159
|
# @param filename [String] The file to analyze
|
160
160
|
# @param line [Integer] The zero-based line number
|
161
161
|
# @param column [Integer] The zero-based column number
|
162
|
-
# @return [SourceMap::Completion]
|
162
|
+
# @return [SourceMap::Completion, nil]
|
163
163
|
# @todo Take a Location instead of filename/line/column
|
164
164
|
def completions_at filename, line, column
|
165
165
|
position = Position.new(line, column)
|
@@ -175,7 +175,7 @@ module Solargraph
|
|
175
175
|
# @param filename [String] The file to analyze
|
176
176
|
# @param line [Integer] The zero-based line number
|
177
177
|
# @param column [Integer] The zero-based column number
|
178
|
-
# @return [Array<Solargraph::Pin::Base
|
178
|
+
# @return [Array<Solargraph::Pin::Base>, nil]
|
179
179
|
# @todo Take filename/position instead of filename/line/column
|
180
180
|
def definitions_at filename, line, column
|
181
181
|
position = Position.new(line, column)
|
@@ -205,7 +205,7 @@ module Solargraph
|
|
205
205
|
# @param filename [String] The file to analyze
|
206
206
|
# @param line [Integer] The zero-based line number
|
207
207
|
# @param column [Integer] The zero-based column number
|
208
|
-
# @return [Array<Solargraph::Pin::Base
|
208
|
+
# @return [Array<Solargraph::Pin::Base>, nil]
|
209
209
|
# @todo Take filename/position instead of filename/line/column
|
210
210
|
def type_definitions_at filename, line, column
|
211
211
|
position = Position.new(line, column)
|
@@ -251,7 +251,19 @@ module Solargraph
|
|
251
251
|
found = source.references(pin.name)
|
252
252
|
found.select! do |loc|
|
253
253
|
referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character).first
|
254
|
-
referenced
|
254
|
+
referenced&.path == pin.path
|
255
|
+
end
|
256
|
+
if pin.path == 'Class#new'
|
257
|
+
caller = cursor.chain.base.infer(api_map, clip.send(:block), clip.locals).first
|
258
|
+
if caller.defined?
|
259
|
+
found.select! do |loc|
|
260
|
+
clip = api_map.clip_at(loc.filename, loc.range.start)
|
261
|
+
other = clip.send(:cursor).chain.base.infer(api_map, clip.send(:block), clip.locals).first
|
262
|
+
caller == other
|
263
|
+
end
|
264
|
+
else
|
265
|
+
found.clear
|
266
|
+
end
|
255
267
|
end
|
256
268
|
# HACK: for language clients that exclude special characters from the start of variable names
|
257
269
|
if strip && match = cursor.word.match(/^[^a-z0-9_]+/i)
|
@@ -283,6 +295,7 @@ module Solargraph
|
|
283
295
|
return if map.nil?
|
284
296
|
pin = map.requires.select { |p| p.location.range.contain?(location.range.start) }.first
|
285
297
|
return nil if pin.nil?
|
298
|
+
# @param full [String]
|
286
299
|
return_if_match = proc do |full|
|
287
300
|
if source_map_hash.key?(full)
|
288
301
|
return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0))
|
@@ -301,13 +314,13 @@ module Solargraph
|
|
301
314
|
# Get an array of pins that match a path.
|
302
315
|
#
|
303
316
|
# @param path [String]
|
304
|
-
# @return [
|
317
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
305
318
|
def get_path_pins path
|
306
319
|
api_map.get_path_suggestions(path)
|
307
320
|
end
|
308
321
|
|
309
322
|
# @param query [String]
|
310
|
-
# @return [
|
323
|
+
# @return [Enumerable<YARD::CodeObjects::Base>]
|
311
324
|
def document query
|
312
325
|
api_map.document query
|
313
326
|
end
|
@@ -339,11 +352,12 @@ module Solargraph
|
|
339
352
|
end
|
340
353
|
|
341
354
|
# @param path [String]
|
342
|
-
# @return [
|
355
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
343
356
|
def path_pins path
|
344
357
|
api_map.get_path_suggestions(path)
|
345
358
|
end
|
346
359
|
|
360
|
+
# @return [Array<SourceMap>]
|
347
361
|
def source_maps
|
348
362
|
source_map_hash.values
|
349
363
|
end
|
@@ -400,14 +414,19 @@ module Solargraph
|
|
400
414
|
end
|
401
415
|
end
|
402
416
|
|
417
|
+
# @return [void]
|
403
418
|
private def catalog_inlock
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
419
|
+
return if synchronized?
|
420
|
+
|
421
|
+
logger.info "Cataloging #{workspace.directory.empty? ? 'generic workspace' : workspace.directory}"
|
422
|
+
api_map.catalog bench
|
423
|
+
@synchronized = true
|
424
|
+
logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)"
|
425
|
+
logger.info "#{api_map.uncached_gemspecs.length} uncached gemspecs"
|
426
|
+
cache_next_gemspec
|
409
427
|
end
|
410
428
|
|
429
|
+
# @return [Bench]
|
411
430
|
def bench
|
412
431
|
Bench.new(
|
413
432
|
source_maps: source_map_hash.values,
|
@@ -452,6 +471,7 @@ module Solargraph
|
|
452
471
|
result
|
453
472
|
end
|
454
473
|
|
474
|
+
# @return [Hash{String => SourceMap}]
|
455
475
|
def source_map_hash
|
456
476
|
@source_map_hash ||= {}
|
457
477
|
end
|
@@ -460,6 +480,7 @@ module Solargraph
|
|
460
480
|
(workspace.filenames - source_map_hash.keys).empty?
|
461
481
|
end
|
462
482
|
|
483
|
+
# @return [SourceMap, Boolean]
|
463
484
|
def next_map
|
464
485
|
return false if mapped?
|
465
486
|
mutex.synchronize do
|
@@ -476,6 +497,7 @@ module Solargraph
|
|
476
497
|
end
|
477
498
|
end
|
478
499
|
|
500
|
+
# @return [self]
|
479
501
|
def map!
|
480
502
|
workspace.sources.each do |src|
|
481
503
|
source_map_hash[src.filename] = Solargraph::SourceMap.map(src)
|
@@ -484,21 +506,25 @@ module Solargraph
|
|
484
506
|
self
|
485
507
|
end
|
486
508
|
|
509
|
+
# @return [Array<Solargraph::Pin::Base>]
|
487
510
|
def pins
|
488
511
|
@pins ||= []
|
489
512
|
end
|
490
513
|
|
514
|
+
# @return [Set<String>]
|
491
515
|
def external_requires
|
492
516
|
@external_requires ||= source_map_external_require_hash.values.flatten.to_set
|
493
517
|
end
|
494
518
|
|
495
519
|
private
|
496
520
|
|
521
|
+
# @return [Hash{String => Set<String>}]
|
497
522
|
def source_map_external_require_hash
|
498
523
|
@source_map_external_require_hash ||= {}
|
499
524
|
end
|
500
525
|
|
501
526
|
# @param source_map [SourceMap]
|
527
|
+
# @return [void]
|
502
528
|
def find_external_requires source_map
|
503
529
|
new_set = source_map.requires.map(&:name).to_set
|
504
530
|
# return if new_set == source_map_external_require_hash[source_map.filename]
|
@@ -537,6 +563,9 @@ module Solargraph
|
|
537
563
|
workspace.source(filename)
|
538
564
|
end
|
539
565
|
|
566
|
+
# @param filename [String]
|
567
|
+
# @param error [FileNotFoundError]
|
568
|
+
# @return [nil]
|
540
569
|
def handle_file_not_found filename, error
|
541
570
|
if workspace.source(filename)
|
542
571
|
Solargraph.logger.debug "#{filename} is not cataloged in the ApiMap"
|
@@ -546,6 +575,8 @@ module Solargraph
|
|
546
575
|
end
|
547
576
|
end
|
548
577
|
|
578
|
+
# @param source [Source]
|
579
|
+
# @return [void]
|
549
580
|
def maybe_map source
|
550
581
|
return unless source
|
551
582
|
return unless @current == source || workspace.has_file?(source.filename)
|
@@ -570,5 +601,33 @@ module Solargraph
|
|
570
601
|
@synchronized = false
|
571
602
|
end
|
572
603
|
end
|
604
|
+
|
605
|
+
# @return [Set<Gem::Specification>]
|
606
|
+
def cache_errors
|
607
|
+
@cache_errors ||= Set.new
|
608
|
+
end
|
609
|
+
|
610
|
+
# @return [void]
|
611
|
+
def cache_next_gemspec
|
612
|
+
return if @cache_pid
|
613
|
+
spec = api_map.uncached_gemspecs.find { |spec| !cache_errors.include?(spec)}
|
614
|
+
return unless spec
|
615
|
+
|
616
|
+
logger.info "Caching #{spec.name} #{spec.version}"
|
617
|
+
Thread.new do
|
618
|
+
@cache_pid = Process.spawn(workspace.command_path, 'cache', spec.name, spec.version.to_s)
|
619
|
+
Process.wait(@cache_pid)
|
620
|
+
logger.info "Cached #{spec.name} #{spec.version}"
|
621
|
+
@synchronized = false
|
622
|
+
rescue Errno::EINVAL => e
|
623
|
+
logger.info "Cached #{spec.name} #{spec.version} with EINVAL"
|
624
|
+
@synchronized = false
|
625
|
+
rescue StandardError => e
|
626
|
+
cache_errors.add spec
|
627
|
+
Solargraph.logger.warn "Error caching gemspec #{spec.name} #{spec.version}: [#{e.class}] #{e.message}"
|
628
|
+
ensure
|
629
|
+
@cache_pid = nil
|
630
|
+
end
|
631
|
+
end
|
573
632
|
end
|
574
633
|
end
|
data/lib/solargraph/location.rb
CHANGED
data/lib/solargraph/page.rb
CHANGED
@@ -7,6 +7,12 @@ require 'cgi'
|
|
7
7
|
|
8
8
|
module Solargraph
|
9
9
|
class Page
|
10
|
+
# @todo This method directive is necessary because OpenStruct.new confuses
|
11
|
+
# the typechecker.
|
12
|
+
# @!method self.new(locals, render_method)
|
13
|
+
# @param locals[Hash]
|
14
|
+
# @param render_method [Proc]
|
15
|
+
# @return [Binder]
|
10
16
|
class Binder < OpenStruct
|
11
17
|
# @param locals [Hash]
|
12
18
|
# @param render_method [Proc]
|
@@ -3,39 +3,78 @@ module Solargraph
|
|
3
3
|
class NodeMethods
|
4
4
|
module_function
|
5
5
|
|
6
|
+
# @abstract
|
7
|
+
# @param node [Parser::AST::Node]
|
8
|
+
# @return [String]
|
6
9
|
def unpack_name node
|
7
10
|
raise NotImplementedError
|
8
11
|
end
|
9
12
|
|
10
|
-
|
13
|
+
# @abstract
|
14
|
+
# @todo Temporarily here for testing. Move to Solargraph::Parser.
|
15
|
+
# @param node [Parser::AST::Node]
|
16
|
+
# @return [Array<Parser::AST::Node>]
|
17
|
+
def call_nodes_from node
|
11
18
|
raise NotImplementedError
|
12
19
|
end
|
13
20
|
|
14
|
-
|
21
|
+
# Find all the nodes within the provided node that potentially return a
|
22
|
+
# value.
|
23
|
+
#
|
24
|
+
# The node parameter typically represents a method's logic, e.g., the
|
25
|
+
# second child (after the :args node) of a :def node. A simple one-line
|
26
|
+
# method would typically return itself, while a node with conditions
|
27
|
+
# would return the resulting node from each conditional branch. Nodes
|
28
|
+
# that follow a :return node are assumed to be unreachable. Nil values
|
29
|
+
# are converted to nil node types.
|
30
|
+
#
|
31
|
+
# @abstract
|
32
|
+
# @param node [Parser::AST::Node]
|
33
|
+
# @return [Array<Parser::AST::Node>]
|
34
|
+
def returns_from_method_body node
|
15
35
|
raise NotImplementedError
|
16
36
|
end
|
17
37
|
|
18
|
-
|
38
|
+
# @abstract
|
39
|
+
# @param node [Parser::AST::Node]
|
40
|
+
#
|
41
|
+
# @return [Array<Parser::AST::Node>]
|
42
|
+
def const_nodes_from node
|
19
43
|
raise NotImplementedError
|
20
44
|
end
|
21
45
|
|
22
|
-
|
46
|
+
# @abstract
|
47
|
+
# @param cursor [Solargraph::Source::Cursor]
|
48
|
+
# @return [Parser::AST::Node, nil]
|
49
|
+
def find_recipient_node cursor
|
23
50
|
raise NotImplementedError
|
24
51
|
end
|
25
52
|
|
26
|
-
|
53
|
+
# @abstract
|
54
|
+
# @param node [Parser::AST::Node]
|
55
|
+
# @return [Array<AST::Node>] low-level value nodes in
|
56
|
+
# value position. Does not include explicit return
|
57
|
+
# statements
|
58
|
+
def value_position_nodes_only(node)
|
27
59
|
raise NotImplementedError
|
28
60
|
end
|
29
61
|
|
30
|
-
# @
|
31
|
-
|
62
|
+
# @abstract
|
63
|
+
# @param nodes [Enumerable<Parser::AST::Node>]
|
64
|
+
def any_splatted_call?(nodes)
|
32
65
|
raise NotImplementedError
|
33
66
|
end
|
34
67
|
|
35
|
-
|
68
|
+
# @abstract
|
69
|
+
# @param node [Parser::AST::Node]
|
70
|
+
# @return [void]
|
71
|
+
def process node
|
36
72
|
raise NotImplementedError
|
37
73
|
end
|
38
74
|
|
75
|
+
# @abstract
|
76
|
+
# @param node [Parser::AST::Node]
|
77
|
+
# @return [Hash{Parser::AST::Node => Chain}]
|
39
78
|
def convert_hash node
|
40
79
|
raise NotImplementedError
|
41
80
|
end
|
@@ -19,6 +19,7 @@ module Solargraph
|
|
19
19
|
# @param node [Parser::AST::Node]
|
20
20
|
# @param region [Region]
|
21
21
|
# @param pins [Array<Pin::Base>]
|
22
|
+
# @param locals [Array<Pin::LocalVariable>]
|
22
23
|
def initialize node, region, pins, locals
|
23
24
|
@node = node
|
24
25
|
@region = region
|
@@ -54,20 +55,28 @@ module Solargraph
|
|
54
55
|
Location.new(region.filename, range)
|
55
56
|
end
|
56
57
|
|
58
|
+
# @param node [Parser::AST::Node]
|
59
|
+
# @return [String, nil]
|
57
60
|
def comments_for(node)
|
58
61
|
region.source.comments_for(node)
|
59
62
|
end
|
60
63
|
|
64
|
+
# @param position [Solargraph::Position]
|
65
|
+
# @return [Pin::Base, nil]
|
61
66
|
def named_path_pin position
|
62
67
|
pins.select{|pin| pin.is_a?(Pin::Closure) && pin.path && !pin.path.empty? && pin.location.range.contain?(position)}.last
|
63
68
|
end
|
64
69
|
|
65
70
|
# @todo Candidate for deprecation
|
71
|
+
# @param position [Solargraph::Position]
|
72
|
+
# @return [Pin::Closure, nil]
|
66
73
|
def block_pin position
|
67
74
|
pins.select{|pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position)}.last
|
68
75
|
end
|
69
76
|
|
70
77
|
# @todo Candidate for deprecation
|
78
|
+
# @param position [Solargraph::Position]
|
79
|
+
# @return [Pin::Closure, nil]
|
71
80
|
def closure_pin position
|
72
81
|
pins.select{|pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position)}.last
|
73
82
|
end
|
@@ -1,12 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'parser/current'
|
4
|
+
require 'parser/source/buffer'
|
2
5
|
|
3
6
|
module Solargraph
|
4
7
|
module Parser
|
5
|
-
module
|
8
|
+
module ParserGem
|
6
9
|
module ClassMethods
|
7
10
|
# @param code [String]
|
8
11
|
# @param filename [String, nil]
|
9
|
-
# @return [Array(Parser::AST::Node,
|
12
|
+
# @return [Array(Parser::AST::Node, Hash{Integer => String})]
|
10
13
|
def parse_with_comments code, filename = nil
|
11
14
|
buffer = ::Parser::Source::Buffer.new(filename, 0)
|
12
15
|
buffer.source = code
|
@@ -29,7 +32,7 @@ module Solargraph
|
|
29
32
|
raise Parser::SyntaxError, e.message
|
30
33
|
end
|
31
34
|
|
32
|
-
# @return [Parser::Base]
|
35
|
+
# @return [::Parser::Base]
|
33
36
|
def parser
|
34
37
|
# @todo Consider setting an instance variable. We might not need to
|
35
38
|
# recreate the parser every time we use it.
|
@@ -39,19 +42,30 @@ module Solargraph
|
|
39
42
|
parser
|
40
43
|
end
|
41
44
|
|
45
|
+
# @param source [Source]
|
46
|
+
# @return [Array(Array<Pin::Base>, Array<Pin::Base>)]
|
42
47
|
def map source
|
43
48
|
NodeProcessor.process(source.node, Region.new(source: source))
|
44
49
|
end
|
45
50
|
|
51
|
+
# @param node [Parser::AST::Node]
|
52
|
+
# @return [Array<Parser::AST::Node>]
|
46
53
|
def returns_from node
|
47
54
|
NodeMethods.returns_from(node)
|
48
55
|
end
|
49
56
|
|
57
|
+
# @param source [Source]
|
58
|
+
# @param name [String]
|
59
|
+
# @return [Array<Location>]
|
50
60
|
def references source, name
|
51
61
|
if name.end_with?("=")
|
52
62
|
reg = /#{Regexp.escape name[0..-2]}\s*=/
|
63
|
+
# @param code [String]
|
64
|
+
# @param offset [Integer]
|
53
65
|
extract_offset = ->(code, offset) { reg.match(code, offset).offset(0) }
|
54
66
|
else
|
67
|
+
# @param code [String]
|
68
|
+
# @param offset [Integer]
|
55
69
|
extract_offset = ->(code, offset) { [soff = code.index(name, offset), soff + name.length] }
|
56
70
|
end
|
57
71
|
inner_node_references(name, source.node).map do |n|
|
@@ -80,36 +94,48 @@ module Solargraph
|
|
80
94
|
result
|
81
95
|
end
|
82
96
|
|
97
|
+
# @return [Source::Chain]
|
83
98
|
def chain *args
|
84
99
|
NodeChainer.chain *args
|
85
100
|
end
|
86
101
|
|
102
|
+
# @return [Source::Chain]
|
87
103
|
def chain_string *args
|
88
104
|
NodeChainer.load_string *args
|
89
105
|
end
|
90
106
|
|
107
|
+
# @return [Array(Array<Pin::Base>, Array<Pin::Base>)]
|
91
108
|
def process_node *args
|
92
109
|
Solargraph::Parser::NodeProcessor.process *args
|
93
110
|
end
|
94
111
|
|
112
|
+
# @param node [Parser::AST::Node]
|
113
|
+
# @return [String, nil]
|
95
114
|
def infer_literal_node_type node
|
96
115
|
NodeMethods.infer_literal_node_type node
|
97
116
|
end
|
98
117
|
|
118
|
+
# @return [void]
|
99
119
|
def version
|
100
120
|
parser.version
|
101
121
|
end
|
102
122
|
|
123
|
+
# @param node [BasicObject]
|
124
|
+
# @return [Boolean]
|
103
125
|
def is_ast_node? node
|
104
126
|
node.is_a?(::Parser::AST::Node)
|
105
127
|
end
|
106
128
|
|
129
|
+
# @param node [Parser::AST::Node]
|
130
|
+
# @return [Range]
|
107
131
|
def node_range node
|
108
132
|
st = Position.new(node.loc.line, node.loc.column)
|
109
133
|
en = Position.new(node.loc.last_line, node.loc.last_column)
|
110
134
|
Range.new(st, en)
|
111
135
|
end
|
112
136
|
|
137
|
+
# @param node [Parser::AST::Node]
|
138
|
+
# @return [Array<Range>]
|
113
139
|
def string_ranges node
|
114
140
|
return [] unless is_ast_node?(node)
|
115
141
|
result = []
|
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
module Solargraph
|
4
4
|
module Parser
|
5
|
-
module
|
5
|
+
module ParserGem
|
6
6
|
# A custom builder for source parsers that ignores character encoding
|
7
7
|
# issues in literal strings.
|
8
8
|
#
|
9
9
|
class FlawedBuilder < ::Parser::Builders::Default
|
10
|
+
# @param token [::Parser::AST::Node]
|
11
|
+
# @return [String]
|
10
12
|
def string_value(token)
|
11
13
|
value(token)
|
12
14
|
end
|