prism 1.8.1 → 2.0.0.rc1
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 +90 -2
- data/Makefile +41 -12
- data/README.md +35 -97
- data/config.yml +174 -163
- data/docs/build_system.md +2 -2
- data/docs/configuration.md +5 -4
- data/docs/encoding.md +2 -2
- data/docs/fuzzing.md +4 -11
- data/docs/javascript.md +19 -4
- data/docs/mapping.md +1 -1
- data/docs/releasing.md +77 -5
- data/docs/relocation.md +2 -4
- data/docs/ripper_translation.md +8 -17
- data/docs/serialization.md +21 -24
- data/docs/testing.md +46 -29
- data/ext/prism/api_node.c +1461 -1401
- data/ext/prism/extconf.rb +3 -4
- data/ext/prism/extension.c +778 -422
- data/ext/prism/extension.h +3 -3
- data/include/prism/arena.h +37 -0
- data/include/prism/ast.h +2729 -612
- data/include/prism/buffer.h +52 -0
- data/include/prism/comments.h +55 -0
- data/include/prism/compiler/accel.h +24 -0
- data/include/prism/compiler/align.h +36 -0
- data/include/prism/compiler/assume.h +25 -0
- data/include/prism/compiler/exported.h +24 -0
- data/include/prism/compiler/fallthrough.h +22 -0
- data/include/prism/compiler/filesystem.h +32 -0
- data/include/prism/compiler/flex_array.h +19 -0
- data/include/prism/compiler/force_inline.h +21 -0
- data/include/prism/compiler/format.h +25 -0
- data/include/prism/compiler/inline.h +17 -0
- data/include/prism/compiler/nodiscard.h +22 -0
- data/include/prism/compiler/nonnull.h +18 -0
- data/include/prism/compiler/unused.h +18 -0
- data/include/prism/constant_pool.h +81 -0
- data/include/prism/diagnostic.h +38 -405
- data/include/prism/errors_format.h +53 -0
- data/include/prism/excludes.h +29 -0
- data/include/prism/integer.h +41 -0
- data/include/prism/internal/allocator.h +68 -0
- data/include/prism/internal/allocator_debug.h +88 -0
- data/include/prism/internal/arena.h +108 -0
- data/include/prism/internal/bit.h +42 -0
- data/include/prism/internal/buffer.h +91 -0
- data/include/prism/internal/char.h +145 -0
- data/include/prism/internal/comments.h +53 -0
- data/include/prism/internal/constant_pool.h +152 -0
- data/include/prism/internal/diagnostic.h +389 -0
- data/include/prism/{encoding.h → internal/encoding.h} +27 -68
- data/include/prism/internal/integer.h +68 -0
- data/include/prism/internal/isinf.h +16 -0
- data/include/prism/internal/line_offset_list.h +34 -0
- data/include/prism/{util/pm_list.h → internal/list.h} +11 -52
- data/include/prism/internal/magic_comments.h +23 -0
- data/include/prism/internal/memchr.h +15 -0
- data/include/prism/internal/node.h +38 -0
- data/include/prism/internal/options.h +232 -0
- data/include/prism/internal/parser.h +984 -0
- data/include/prism/internal/regexp.h +26 -0
- data/include/prism/internal/serialize.h +39 -0
- data/include/prism/internal/source.h +72 -0
- data/include/prism/{static_literals.h → internal/static_literals.h} +26 -47
- data/include/prism/internal/stringy.h +35 -0
- data/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
- data/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
- data/include/prism/internal/tokens.h +11 -0
- data/include/prism/json.h +32 -0
- data/include/prism/line_offset_list.h +61 -0
- data/include/prism/magic_comments.h +35 -0
- data/include/prism/node.h +18 -53
- data/include/prism/options.h +146 -280
- data/include/prism/parser.h +336 -868
- data/include/prism/prettyprint.h +6 -9
- data/include/prism/serialize.h +115 -0
- data/include/prism/source.h +155 -0
- data/include/prism/stream.h +28 -0
- data/include/prism/string_query.h +63 -0
- data/include/prism/stringy.h +72 -0
- data/include/prism/version.h +13 -4
- data/include/prism.h +43 -320
- data/lib/prism/compiler.rb +319 -305
- data/lib/prism/desugar_compiler.rb +105 -34
- data/lib/prism/dispatcher.rb +646 -473
- data/lib/prism/dot_visitor.rb +592 -511
- data/lib/prism/dsl.rb +391 -25
- data/lib/prism/ffi.rb +252 -90
- data/lib/prism/inspect_visitor.rb +357 -325
- data/lib/prism/lex_compat.rb +311 -228
- data/lib/prism/mutation_compiler.rb +313 -305
- data/lib/prism/node.rb +20284 -7038
- data/lib/prism/node_ext.rb +180 -187
- data/lib/prism/node_find.rb +215 -0
- data/lib/prism/parse_result/errors.rb +7 -1
- data/lib/prism/parse_result/newlines.rb +276 -8
- data/lib/prism/parse_result.rb +462 -139
- data/lib/prism/pattern.rb +65 -20
- data/lib/prism/reflection.rb +23 -12
- data/lib/prism/relocation.rb +149 -87
- data/lib/prism/serialize.rb +3442 -536
- data/lib/prism/string_query.rb +16 -1
- data/lib/prism/translation/parser/builder.rb +10 -2
- data/lib/prism/translation/parser/compiler.rb +44 -52
- data/lib/prism/translation/parser/lexer.rb +41 -92
- data/lib/prism/translation/parser.rb +1 -1
- data/lib/prism/translation/parser_current.rb +1 -1
- data/lib/prism/translation/ripper/filter.rb +53 -0
- data/lib/prism/translation/ripper/lexer.rb +92 -5
- data/lib/prism/translation/ripper/sexp.rb +2 -10
- data/lib/prism/translation/ripper/shim.rb +2 -0
- data/lib/prism/translation/ripper.rb +1005 -224
- data/lib/prism/translation/ruby_parser.rb +73 -316
- data/lib/prism/translation.rb +2 -0
- data/lib/prism/visitor.rb +632 -5
- data/lib/prism.rb +79 -22
- data/prism.gemspec +123 -61
- data/rbi/generated/prism/compiler.rbi +489 -0
- data/rbi/generated/prism/desugar_compiler.rbi +306 -0
- data/rbi/generated/prism/dispatcher.rbi +1138 -0
- data/rbi/generated/prism/dot_visitor.rbi +618 -0
- data/rbi/generated/prism/dsl.rbi +751 -0
- data/rbi/generated/prism/inspect_visitor.rbi +503 -0
- data/rbi/generated/prism/lex_compat.rbi +162 -0
- data/rbi/generated/prism/mutation_compiler.rbi +464 -0
- data/rbi/generated/prism/node.rbi +13681 -0
- data/rbi/generated/prism/node_ext.rbi +259 -0
- data/rbi/generated/prism/node_find.rbi +79 -0
- data/rbi/generated/prism/parse_result/errors.rbi +21 -0
- data/rbi/generated/prism/parse_result/newlines.rbi +208 -0
- data/rbi/generated/prism/parse_result.rbi +764 -0
- data/rbi/generated/prism/pattern.rbi +134 -0
- data/rbi/generated/prism/reflection.rbi +89 -0
- data/rbi/generated/prism/relocation.rbi +329 -0
- data/rbi/generated/prism/serialize.rbi +181 -0
- data/rbi/generated/prism/string_query.rbi +36 -0
- data/rbi/generated/prism/translation.rbi +7 -0
- data/rbi/generated/prism/visitor.rbi +650 -0
- data/rbi/generated/prism.rbi +86 -0
- data/rbi/prism/translation/parser_versions.rbi +5 -0
- data/rbi/rubyvm/node_find.rbi +14 -0
- data/sig/generated/prism/compiler.rbs +492 -0
- data/sig/generated/prism/desugar_compiler.rbs +305 -0
- data/sig/generated/prism/dispatcher.rbs +1292 -0
- data/sig/generated/prism/dot_visitor.rbs +635 -0
- data/sig/generated/prism/dsl.rbs +928 -0
- data/sig/generated/prism/inspect_visitor.rbs +509 -0
- data/sig/generated/prism/lex_compat.rbs +166 -0
- data/sig/{prism → generated/prism}/mutation_compiler.rbs +309 -4
- data/sig/generated/prism/node.rbs +20160 -0
- data/sig/generated/prism/node_ext.rbs +290 -0
- data/sig/generated/prism/node_find.rbs +90 -0
- data/sig/generated/prism/parse_result/errors.rbs +22 -0
- data/sig/generated/prism/parse_result/newlines.rbs +223 -0
- data/sig/generated/prism/parse_result.rbs +859 -0
- data/sig/generated/prism/pattern.rbs +156 -0
- data/sig/generated/prism/reflection.rbs +101 -0
- data/sig/generated/prism/relocation.rbs +428 -0
- data/sig/generated/prism/serialize.rbs +195 -0
- data/sig/generated/prism/string_query.rbs +36 -0
- data/sig/generated/prism/translation.rbs +8 -0
- data/sig/generated/prism/visitor.rbs +1111 -0
- data/sig/generated/prism.rbs +84 -0
- data/sig/manifest.yaml +2 -0
- data/src/arena.c +117 -0
- data/src/{util/pm_buffer.c → buffer.c} +44 -21
- data/src/{util/pm_char.c → char.c} +28 -57
- data/src/comments.c +454 -0
- data/src/constant_pool.c +406 -0
- data/src/diagnostic.c +93 -65
- data/src/encoding.c +8 -3
- data/src/errors_format.c +519 -0
- data/src/{util/pm_integer.c → integer.c} +33 -22
- data/src/json.c +5733 -0
- data/src/line_offset_list.c +100 -0
- data/src/list.c +24 -0
- data/src/{util/pm_memchr.c → memchr.c} +8 -6
- data/src/node.c +3504 -7674
- data/src/options.c +162 -49
- data/src/parser.c +349 -0
- data/src/prettyprint.c +421 -354
- data/src/prism.c +8035 -7019
- data/src/regexp.c +961 -45
- data/src/serialize.c +459 -424
- data/src/source.c +518 -0
- data/src/static_literals.c +111 -43
- data/src/string_query.c +166 -0
- data/src/stringy.c +91 -0
- data/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
- data/src/strpbrk.c +447 -0
- data/src/{token_type.c → tokens.c} +39 -18
- metadata +123 -62
- data/ext/prism/api_pack.c +0 -276
- data/include/prism/defines.h +0 -260
- data/include/prism/pack.h +0 -163
- data/include/prism/regexp.h +0 -43
- data/include/prism/util/pm_buffer.h +0 -236
- data/include/prism/util/pm_char.h +0 -204
- data/include/prism/util/pm_constant_pool.h +0 -218
- data/include/prism/util/pm_integer.h +0 -130
- data/include/prism/util/pm_memchr.h +0 -29
- data/include/prism/util/pm_newline_list.h +0 -113
- data/include/prism/util/pm_string.h +0 -200
- data/lib/prism/lex_ripper.rb +0 -64
- data/lib/prism/pack.rb +0 -230
- data/lib/prism/parse_result/comments.rb +0 -188
- data/rbi/prism/compiler.rbi +0 -12
- data/rbi/prism/dsl.rbi +0 -524
- data/rbi/prism/inspect_visitor.rbi +0 -12
- data/rbi/prism/node.rbi +0 -8747
- data/rbi/prism/node_ext.rbi +0 -107
- data/rbi/prism/parse_result.rbi +0 -404
- data/rbi/prism/reflection.rbi +0 -58
- data/rbi/prism/string_query.rbi +0 -12
- data/rbi/prism/visitor.rbi +0 -473
- data/rbi/prism.rbi +0 -66
- data/sig/prism/compiler.rbs +0 -9
- data/sig/prism/dispatcher.rbs +0 -19
- data/sig/prism/dot_visitor.rbs +0 -6
- data/sig/prism/dsl.rbs +0 -351
- data/sig/prism/inspect_visitor.rbs +0 -22
- data/sig/prism/lex_compat.rbs +0 -10
- data/sig/prism/node.rbs +0 -4039
- data/sig/prism/node_ext.rbs +0 -149
- data/sig/prism/pack.rbs +0 -43
- data/sig/prism/parse_result/comments.rbs +0 -38
- data/sig/prism/parse_result.rbs +0 -196
- data/sig/prism/pattern.rbs +0 -13
- data/sig/prism/reflection.rbs +0 -50
- data/sig/prism/relocation.rbs +0 -185
- data/sig/prism/serialize.rbs +0 -8
- data/sig/prism/string_query.rbs +0 -11
- data/sig/prism/visitor.rbs +0 -169
- data/sig/prism.rbs +0 -258
- data/src/pack.c +0 -509
- data/src/util/pm_constant_pool.c +0 -342
- data/src/util/pm_list.c +0 -49
- data/src/util/pm_newline_list.c +0 -125
- data/src/util/pm_string.c +0 -381
- data/src/util/pm_strpbrk.c +0 -206
|
@@ -22,22 +22,10 @@ module Prism
|
|
|
22
22
|
# - on_comma
|
|
23
23
|
# - on_ignored_nl
|
|
24
24
|
# - on_ignored_sp
|
|
25
|
-
# - on_kw
|
|
26
|
-
# - on_label_end
|
|
27
|
-
# - on_lbrace
|
|
28
|
-
# - on_lbracket
|
|
29
|
-
# - on_lparen
|
|
30
25
|
# - on_nl
|
|
31
|
-
# - on_op
|
|
32
26
|
# - on_operator_ambiguous
|
|
33
|
-
# - on_rbrace
|
|
34
|
-
# - on_rbracket
|
|
35
|
-
# - on_rparen
|
|
36
27
|
# - on_semicolon
|
|
37
28
|
# - on_sp
|
|
38
|
-
# - on_symbeg
|
|
39
|
-
# - on_tstring_beg
|
|
40
|
-
# - on_tstring_end
|
|
41
29
|
#
|
|
42
30
|
class Ripper < Compiler
|
|
43
31
|
# Parses the given Ruby program read from +src+.
|
|
@@ -69,7 +57,8 @@ module Prism
|
|
|
69
57
|
# [[1, 13], :on_kw, "end", END ]]
|
|
70
58
|
#
|
|
71
59
|
def self.lex(src, filename = "-", lineno = 1, raise_errors: false)
|
|
72
|
-
|
|
60
|
+
coerced = coerce_source(src)
|
|
61
|
+
result = Prism.lex_compat(coerced, filepath: filename, line: lineno, version: "current", encoding: coerced.encoding)
|
|
73
62
|
|
|
74
63
|
if result.failure? && raise_errors
|
|
75
64
|
raise SyntaxError, result.errors.first.message
|
|
@@ -78,6 +67,34 @@ module Prism
|
|
|
78
67
|
end
|
|
79
68
|
end
|
|
80
69
|
|
|
70
|
+
# Tokenizes the Ruby program and returns an array of strings.
|
|
71
|
+
# The +filename+ and +lineno+ arguments are mostly ignored, since the
|
|
72
|
+
# return value is just the tokenized input.
|
|
73
|
+
# By default, this method does not handle syntax errors in +src+,
|
|
74
|
+
# use the +raise_errors+ keyword to raise a SyntaxError for an error in +src+.
|
|
75
|
+
#
|
|
76
|
+
# p Ripper.tokenize("def m(a) nil end")
|
|
77
|
+
# # => ["def", " ", "m", "(", "a", ")", " ", "nil", " ", "end"]
|
|
78
|
+
#
|
|
79
|
+
def self.tokenize(...)
|
|
80
|
+
lex(...).map { |token| token[2] }
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Mirros the various lex_types that ripper supports
|
|
84
|
+
def self.coerce_source(source) # :nodoc:
|
|
85
|
+
if source.is_a?(IO)
|
|
86
|
+
source.read
|
|
87
|
+
elsif source.respond_to?(:gets)
|
|
88
|
+
src = +""
|
|
89
|
+
while line = source.gets
|
|
90
|
+
src << line
|
|
91
|
+
end
|
|
92
|
+
src
|
|
93
|
+
else
|
|
94
|
+
source.to_str
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
81
98
|
# This contains a table of all of the parser events and their
|
|
82
99
|
# corresponding arity.
|
|
83
100
|
PARSER_EVENT_TABLE = {
|
|
@@ -330,7 +347,7 @@ module Prism
|
|
|
330
347
|
"__ENCODING__",
|
|
331
348
|
"__FILE__",
|
|
332
349
|
"__LINE__"
|
|
333
|
-
]
|
|
350
|
+
].to_set
|
|
334
351
|
|
|
335
352
|
# A list of all of the Ruby binary operators.
|
|
336
353
|
BINARY_OPERATORS = [
|
|
@@ -355,7 +372,7 @@ module Prism
|
|
|
355
372
|
:/,
|
|
356
373
|
:*,
|
|
357
374
|
:**
|
|
358
|
-
]
|
|
375
|
+
].to_set
|
|
359
376
|
|
|
360
377
|
private_constant :KEYWORDS, :BINARY_OPERATORS
|
|
361
378
|
|
|
@@ -424,10 +441,69 @@ module Prism
|
|
|
424
441
|
end
|
|
425
442
|
end
|
|
426
443
|
|
|
444
|
+
autoload :Filter, "prism/translation/ripper/filter"
|
|
427
445
|
autoload :Lexer, "prism/translation/ripper/lexer"
|
|
428
446
|
autoload :SexpBuilder, "prism/translation/ripper/sexp"
|
|
429
447
|
autoload :SexpBuilderPP, "prism/translation/ripper/sexp"
|
|
430
448
|
|
|
449
|
+
# Provides optimized access to line and column information.
|
|
450
|
+
# Ripper bounds are mostly accessed in a linear fashion, so
|
|
451
|
+
# we can try a linear scan first and fall back to binary search.
|
|
452
|
+
class LineAndColumnCache # :nodoc:
|
|
453
|
+
# How many should it look ahead/behind before falling back to binary searching.
|
|
454
|
+
WINDOW = 8
|
|
455
|
+
private_constant :WINDOW
|
|
456
|
+
|
|
457
|
+
#: (Source source) -> void
|
|
458
|
+
def initialize(source)
|
|
459
|
+
@source = source
|
|
460
|
+
@offsets = source.offsets
|
|
461
|
+
@hint = 0
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
#: (Integer byte_offset) -> [Integer, Integer]
|
|
465
|
+
def line_and_column(byte_offset)
|
|
466
|
+
@hint = new_hint(byte_offset) || @source.find_line(byte_offset)
|
|
467
|
+
return [@hint + @source.start_line, byte_offset - @offsets[@hint]]
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
private
|
|
471
|
+
|
|
472
|
+
def new_hint(byte_offset)
|
|
473
|
+
if @offsets[@hint] <= byte_offset
|
|
474
|
+
# Same line?
|
|
475
|
+
if (@hint + 1 >= @offsets.size || @offsets[@hint + 1] > byte_offset)
|
|
476
|
+
return @hint
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
# Scan forwards
|
|
480
|
+
limit = [@hint + WINDOW + 1, @offsets.size].min
|
|
481
|
+
idx = @hint + 1
|
|
482
|
+
while idx < limit
|
|
483
|
+
if @offsets[idx] > byte_offset
|
|
484
|
+
return idx - 1
|
|
485
|
+
end
|
|
486
|
+
if @offsets[idx] == byte_offset
|
|
487
|
+
return idx
|
|
488
|
+
end
|
|
489
|
+
idx += 1
|
|
490
|
+
end
|
|
491
|
+
else
|
|
492
|
+
# Scan backwards
|
|
493
|
+
limit = @hint > WINDOW ? @hint - WINDOW : 0
|
|
494
|
+
idx = @hint
|
|
495
|
+
while idx >= limit + 1
|
|
496
|
+
if @offsets[idx - 1] <= byte_offset
|
|
497
|
+
return idx - 1
|
|
498
|
+
end
|
|
499
|
+
idx -= 1
|
|
500
|
+
end
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
nil
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
|
|
431
507
|
# :stopdoc:
|
|
432
508
|
# This is not part of the public API but used by some gems.
|
|
433
509
|
|
|
@@ -461,16 +537,17 @@ module Prism
|
|
|
461
537
|
# The current line number of the parser.
|
|
462
538
|
attr_reader :lineno
|
|
463
539
|
|
|
464
|
-
# The current column
|
|
540
|
+
# The current column in bytes of the parser.
|
|
465
541
|
attr_reader :column
|
|
466
542
|
|
|
467
543
|
# Create a new Translation::Ripper object with the given source.
|
|
468
544
|
def initialize(source, filename = "(ripper)", lineno = 1)
|
|
469
|
-
@source = source
|
|
545
|
+
@source = Ripper.coerce_source(source)
|
|
470
546
|
@filename = filename
|
|
471
547
|
@lineno = lineno
|
|
472
548
|
@column = 0
|
|
473
549
|
@result = nil
|
|
550
|
+
@line_and_column_cache = nil
|
|
474
551
|
end
|
|
475
552
|
|
|
476
553
|
##########################################################################
|
|
@@ -489,7 +566,12 @@ module Prism
|
|
|
489
566
|
bounds(location)
|
|
490
567
|
|
|
491
568
|
if comment.is_a?(InlineComment)
|
|
492
|
-
|
|
569
|
+
# Inline comments always contain a newline if the line itself contains it
|
|
570
|
+
if result.source.source.bytesize > comment.location.end_offset
|
|
571
|
+
on_comment("#{comment.slice}\n")
|
|
572
|
+
else
|
|
573
|
+
on_comment(comment.slice)
|
|
574
|
+
end
|
|
493
575
|
else
|
|
494
576
|
offset = location.start_offset
|
|
495
577
|
lines = comment.slice.lines
|
|
@@ -566,13 +648,28 @@ module Prism
|
|
|
566
648
|
end
|
|
567
649
|
end
|
|
568
650
|
|
|
651
|
+
# Return encoding of the source.
|
|
652
|
+
def encoding
|
|
653
|
+
result.source.encoding
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
# Return true if parsed source ended by `__END__`.
|
|
657
|
+
def end_seen?
|
|
658
|
+
!!result.data_loc
|
|
659
|
+
end
|
|
660
|
+
|
|
569
661
|
##########################################################################
|
|
570
662
|
# Visitor methods
|
|
571
663
|
##########################################################################
|
|
572
664
|
|
|
665
|
+
# :stopdoc:
|
|
666
|
+
|
|
573
667
|
# alias foo bar
|
|
574
668
|
# ^^^^^^^^^^^^^
|
|
575
669
|
def visit_alias_method_node(node)
|
|
670
|
+
bounds(node.keyword_loc)
|
|
671
|
+
on_kw("alias")
|
|
672
|
+
|
|
576
673
|
new_name = visit(node.new_name)
|
|
577
674
|
old_name = visit(node.old_name)
|
|
578
675
|
|
|
@@ -583,6 +680,9 @@ module Prism
|
|
|
583
680
|
# alias $foo $bar
|
|
584
681
|
# ^^^^^^^^^^^^^^^
|
|
585
682
|
def visit_alias_global_variable_node(node)
|
|
683
|
+
bounds(node.keyword_loc)
|
|
684
|
+
on_kw("alias")
|
|
685
|
+
|
|
586
686
|
new_name = visit_alias_global_variable_node_value(node.new_name)
|
|
587
687
|
old_name = visit_alias_global_variable_node_value(node.old_name)
|
|
588
688
|
|
|
@@ -608,6 +708,10 @@ module Prism
|
|
|
608
708
|
# ^^^^^^^^^
|
|
609
709
|
def visit_alternation_pattern_node(node)
|
|
610
710
|
left = visit_pattern_node(node.left)
|
|
711
|
+
|
|
712
|
+
bounds(node.operator_loc)
|
|
713
|
+
on_op("|")
|
|
714
|
+
|
|
611
715
|
right = visit_pattern_node(node.right)
|
|
612
716
|
|
|
613
717
|
bounds(node.location)
|
|
@@ -618,7 +722,13 @@ module Prism
|
|
|
618
722
|
# parenthesis node that can be used to wrap patterns.
|
|
619
723
|
private def visit_pattern_node(node)
|
|
620
724
|
if node.is_a?(ParenthesesNode)
|
|
621
|
-
|
|
725
|
+
bounds(node.opening_loc)
|
|
726
|
+
on_lparen("(")
|
|
727
|
+
result = visit(node.body)
|
|
728
|
+
bounds(node.closing_loc)
|
|
729
|
+
on_rparen(")")
|
|
730
|
+
|
|
731
|
+
result
|
|
622
732
|
else
|
|
623
733
|
visit(node)
|
|
624
734
|
end
|
|
@@ -628,6 +738,14 @@ module Prism
|
|
|
628
738
|
# ^^^^^^^
|
|
629
739
|
def visit_and_node(node)
|
|
630
740
|
left = visit(node.left)
|
|
741
|
+
|
|
742
|
+
bounds(node.operator_loc)
|
|
743
|
+
if node.operator == "and"
|
|
744
|
+
on_kw("and")
|
|
745
|
+
else
|
|
746
|
+
on_op("&&")
|
|
747
|
+
end
|
|
748
|
+
|
|
631
749
|
right = visit(node.right)
|
|
632
750
|
|
|
633
751
|
bounds(node.location)
|
|
@@ -655,6 +773,8 @@ module Prism
|
|
|
655
773
|
previous = element
|
|
656
774
|
end
|
|
657
775
|
|
|
776
|
+
visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
|
|
777
|
+
|
|
658
778
|
bounds(node.closing_loc)
|
|
659
779
|
on_tstring_end(node.closing)
|
|
660
780
|
when /^%i/
|
|
@@ -669,11 +789,13 @@ module Prism
|
|
|
669
789
|
visit_words_sep(opening_loc, previous, element)
|
|
670
790
|
|
|
671
791
|
bounds(element.location)
|
|
672
|
-
elements = on_qsymbols_add(elements, on_tstring_content(element.
|
|
792
|
+
elements = on_qsymbols_add(elements, on_tstring_content(element.content))
|
|
673
793
|
|
|
674
794
|
previous = element
|
|
675
795
|
end
|
|
676
796
|
|
|
797
|
+
visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
|
|
798
|
+
|
|
677
799
|
bounds(node.closing_loc)
|
|
678
800
|
on_tstring_end(node.closing)
|
|
679
801
|
when /^%W/
|
|
@@ -711,6 +833,8 @@ module Prism
|
|
|
711
833
|
previous = element
|
|
712
834
|
end
|
|
713
835
|
|
|
836
|
+
visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
|
|
837
|
+
|
|
714
838
|
bounds(node.closing_loc)
|
|
715
839
|
on_tstring_end(node.closing)
|
|
716
840
|
when /^%I/
|
|
@@ -729,7 +853,7 @@ module Prism
|
|
|
729
853
|
on_symbols_add(
|
|
730
854
|
elements,
|
|
731
855
|
if element.is_a?(SymbolNode)
|
|
732
|
-
on_word_add(on_word_new, on_tstring_content(element.
|
|
856
|
+
on_word_add(on_word_new, on_tstring_content(element.content))
|
|
733
857
|
else
|
|
734
858
|
element.parts.inject(on_word_new) do |word, part|
|
|
735
859
|
word_part =
|
|
@@ -748,6 +872,8 @@ module Prism
|
|
|
748
872
|
previous = element
|
|
749
873
|
end
|
|
750
874
|
|
|
875
|
+
visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
|
|
876
|
+
|
|
751
877
|
bounds(node.closing_loc)
|
|
752
878
|
on_tstring_end(node.closing)
|
|
753
879
|
else
|
|
@@ -764,15 +890,21 @@ module Prism
|
|
|
764
890
|
on_array(elements)
|
|
765
891
|
end
|
|
766
892
|
|
|
767
|
-
# Dispatch
|
|
893
|
+
# Dispatch words_sep events that contains the whitespace between the elements
|
|
768
894
|
# of list literals.
|
|
769
895
|
private def visit_words_sep(opening_loc, previous, current)
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
896
|
+
start_offset = (previous.nil? ? opening_loc : previous.location).end_offset
|
|
897
|
+
end_offset = current.start_offset
|
|
898
|
+
length = end_offset - start_offset
|
|
899
|
+
|
|
900
|
+
if length > 0
|
|
901
|
+
whitespace = source.byteslice(start_offset, length)
|
|
902
|
+
current_offset = start_offset
|
|
903
|
+
whitespace.each_line do |part|
|
|
904
|
+
bounds(opening_loc.copy(start_offset: current_offset, length: part.bytesize))
|
|
905
|
+
on_words_sep(part)
|
|
906
|
+
current_offset += part.bytesize
|
|
907
|
+
end
|
|
776
908
|
end
|
|
777
909
|
end
|
|
778
910
|
|
|
@@ -798,9 +930,18 @@ module Prism
|
|
|
798
930
|
# ^^^^^
|
|
799
931
|
def visit_array_pattern_node(node)
|
|
800
932
|
constant = visit(node.constant)
|
|
933
|
+
|
|
934
|
+
if node.opening_loc
|
|
935
|
+
bounds(node.opening_loc)
|
|
936
|
+
node.opening == "[" ? on_lbracket("[") : on_lparen("(")
|
|
937
|
+
end
|
|
938
|
+
|
|
801
939
|
requireds = visit_all(node.requireds) if node.requireds.any?
|
|
802
940
|
rest =
|
|
803
941
|
if (rest_node = node.rest).is_a?(SplatNode)
|
|
942
|
+
bounds(rest_node.operator_loc)
|
|
943
|
+
on_op("*")
|
|
944
|
+
|
|
804
945
|
if rest_node.expression.nil?
|
|
805
946
|
bounds(rest_node.location)
|
|
806
947
|
on_var_field(nil)
|
|
@@ -811,6 +952,10 @@ module Prism
|
|
|
811
952
|
|
|
812
953
|
posts = visit_all(node.posts) if node.posts.any?
|
|
813
954
|
|
|
955
|
+
if node.closing_loc
|
|
956
|
+
bounds(node.closing_loc)
|
|
957
|
+
node.closing == "]" ? on_rbracket("]") : on_rparen(")")
|
|
958
|
+
end
|
|
814
959
|
bounds(node.location)
|
|
815
960
|
on_aryptn(constant, requireds, rest, posts)
|
|
816
961
|
end
|
|
@@ -826,6 +971,12 @@ module Prism
|
|
|
826
971
|
# ^^^^
|
|
827
972
|
def visit_assoc_node(node)
|
|
828
973
|
key = visit(node.key)
|
|
974
|
+
|
|
975
|
+
if node.operator_loc
|
|
976
|
+
bounds(node.operator_loc)
|
|
977
|
+
on_op("=>")
|
|
978
|
+
end
|
|
979
|
+
|
|
829
980
|
value = visit(node.value)
|
|
830
981
|
|
|
831
982
|
bounds(node.location)
|
|
@@ -838,6 +989,9 @@ module Prism
|
|
|
838
989
|
# { **foo }
|
|
839
990
|
# ^^^^^
|
|
840
991
|
def visit_assoc_splat_node(node)
|
|
992
|
+
bounds(node.operator_loc)
|
|
993
|
+
on_op("**")
|
|
994
|
+
|
|
841
995
|
value = visit(node.value)
|
|
842
996
|
|
|
843
997
|
bounds(node.location)
|
|
@@ -854,8 +1008,18 @@ module Prism
|
|
|
854
1008
|
# begin end
|
|
855
1009
|
# ^^^^^^^^^
|
|
856
1010
|
def visit_begin_node(node)
|
|
1011
|
+
if node.begin_keyword_loc
|
|
1012
|
+
bounds(node.begin_keyword_loc)
|
|
1013
|
+
on_kw("begin")
|
|
1014
|
+
end
|
|
1015
|
+
|
|
857
1016
|
clauses = visit_begin_node_clauses(node.begin_keyword_loc, node, false)
|
|
858
1017
|
|
|
1018
|
+
if node.end_keyword_loc
|
|
1019
|
+
bounds(node.end_keyword_loc)
|
|
1020
|
+
on_kw("end")
|
|
1021
|
+
end
|
|
1022
|
+
|
|
859
1023
|
bounds(node.location)
|
|
860
1024
|
on_begin(clauses)
|
|
861
1025
|
end
|
|
@@ -867,7 +1031,7 @@ module Prism
|
|
|
867
1031
|
on_stmts_add(on_stmts_new, on_void_stmt)
|
|
868
1032
|
else
|
|
869
1033
|
body = node.statements.body
|
|
870
|
-
body
|
|
1034
|
+
body = [nil, *body] if void_stmt?(location, node.statements.body[0].location, allow_newline)
|
|
871
1035
|
|
|
872
1036
|
bounds(node.statements.location)
|
|
873
1037
|
visit_statements_node_body(body)
|
|
@@ -876,12 +1040,15 @@ module Prism
|
|
|
876
1040
|
rescue_clause = visit(node.rescue_clause)
|
|
877
1041
|
else_clause =
|
|
878
1042
|
unless (else_clause_node = node.else_clause).nil?
|
|
1043
|
+
bounds(else_clause_node.else_keyword_loc)
|
|
1044
|
+
on_kw("else")
|
|
1045
|
+
|
|
879
1046
|
else_statements =
|
|
880
1047
|
if else_clause_node.statements.nil?
|
|
881
1048
|
[nil]
|
|
882
1049
|
else
|
|
883
1050
|
body = else_clause_node.statements.body
|
|
884
|
-
body
|
|
1051
|
+
body = [nil, *body] if void_stmt?(else_clause_node.else_keyword_loc, else_clause_node.statements.body[0].location, allow_newline)
|
|
885
1052
|
body
|
|
886
1053
|
end
|
|
887
1054
|
|
|
@@ -903,7 +1070,7 @@ module Prism
|
|
|
903
1070
|
on_bodystmt(visit_statements_node_body([nil]), nil, nil, nil)
|
|
904
1071
|
when StatementsNode
|
|
905
1072
|
body = [*node.body]
|
|
906
|
-
body
|
|
1073
|
+
body = [nil, *body] if void_stmt?(location, body[0].location, allow_newline)
|
|
907
1074
|
stmts = visit_statements_node_body(body)
|
|
908
1075
|
|
|
909
1076
|
bounds(node.body.first.location)
|
|
@@ -918,6 +1085,8 @@ module Prism
|
|
|
918
1085
|
# foo(&bar)
|
|
919
1086
|
# ^^^^
|
|
920
1087
|
def visit_block_argument_node(node)
|
|
1088
|
+
bounds(node.operator_loc)
|
|
1089
|
+
on_op("&")
|
|
921
1090
|
visit(node.expression)
|
|
922
1091
|
end
|
|
923
1092
|
|
|
@@ -931,6 +1100,13 @@ module Prism
|
|
|
931
1100
|
# Visit a BlockNode.
|
|
932
1101
|
def visit_block_node(node)
|
|
933
1102
|
braces = node.opening == "{"
|
|
1103
|
+
bounds(node.opening_loc)
|
|
1104
|
+
if braces
|
|
1105
|
+
on_lbrace("{")
|
|
1106
|
+
else
|
|
1107
|
+
on_kw("do")
|
|
1108
|
+
end
|
|
1109
|
+
|
|
934
1110
|
parameters = visit(node.parameters)
|
|
935
1111
|
|
|
936
1112
|
body =
|
|
@@ -943,7 +1119,7 @@ module Prism
|
|
|
943
1119
|
braces ? stmts : on_bodystmt(stmts, nil, nil, nil)
|
|
944
1120
|
when StatementsNode
|
|
945
1121
|
stmts = node.body.body
|
|
946
|
-
stmts
|
|
1122
|
+
stmts = [nil, *stmts] if void_stmt?(node.parameters&.location || node.opening_loc, node.body.location, false)
|
|
947
1123
|
stmts = visit_statements_node_body(stmts)
|
|
948
1124
|
|
|
949
1125
|
bounds(node.body.location)
|
|
@@ -954,6 +1130,14 @@ module Prism
|
|
|
954
1130
|
raise
|
|
955
1131
|
end
|
|
956
1132
|
|
|
1133
|
+
if braces
|
|
1134
|
+
bounds(node.closing_loc)
|
|
1135
|
+
on_rbrace("}")
|
|
1136
|
+
else
|
|
1137
|
+
bounds(node.closing_loc)
|
|
1138
|
+
on_kw("end")
|
|
1139
|
+
end
|
|
1140
|
+
|
|
957
1141
|
if braces
|
|
958
1142
|
bounds(node.location)
|
|
959
1143
|
on_brace_block(parameters, body)
|
|
@@ -966,12 +1150,15 @@ module Prism
|
|
|
966
1150
|
# def foo(&bar); end
|
|
967
1151
|
# ^^^^
|
|
968
1152
|
def visit_block_parameter_node(node)
|
|
1153
|
+
bounds(node.operator_loc)
|
|
1154
|
+
on_op("&")
|
|
1155
|
+
|
|
969
1156
|
if node.name_loc.nil?
|
|
970
1157
|
bounds(node.location)
|
|
971
1158
|
on_blockarg(nil)
|
|
972
1159
|
else
|
|
973
1160
|
bounds(node.name_loc)
|
|
974
|
-
name =
|
|
1161
|
+
name = on_ident(node.name.to_s)
|
|
975
1162
|
|
|
976
1163
|
bounds(node.location)
|
|
977
1164
|
on_blockarg(name)
|
|
@@ -980,6 +1167,9 @@ module Prism
|
|
|
980
1167
|
|
|
981
1168
|
# A block's parameters.
|
|
982
1169
|
def visit_block_parameters_node(node)
|
|
1170
|
+
bounds(node.opening_loc)
|
|
1171
|
+
on_op("|")
|
|
1172
|
+
|
|
983
1173
|
parameters =
|
|
984
1174
|
if node.parameters.nil?
|
|
985
1175
|
on_params(nil, nil, nil, nil, nil, nil, nil)
|
|
@@ -994,6 +1184,9 @@ module Prism
|
|
|
994
1184
|
false
|
|
995
1185
|
end
|
|
996
1186
|
|
|
1187
|
+
bounds(node.closing_loc)
|
|
1188
|
+
on_op("|")
|
|
1189
|
+
|
|
997
1190
|
bounds(node.location)
|
|
998
1191
|
on_block_var(parameters, locals)
|
|
999
1192
|
end
|
|
@@ -1004,6 +1197,9 @@ module Prism
|
|
|
1004
1197
|
# break foo
|
|
1005
1198
|
# ^^^^^^^^^
|
|
1006
1199
|
def visit_break_node(node)
|
|
1200
|
+
bounds(node.keyword_loc)
|
|
1201
|
+
on_kw("break")
|
|
1202
|
+
|
|
1007
1203
|
if node.arguments.nil?
|
|
1008
1204
|
bounds(node.location)
|
|
1009
1205
|
on_break(on_args_new)
|
|
@@ -1028,20 +1224,32 @@ module Prism
|
|
|
1028
1224
|
case node.name
|
|
1029
1225
|
when :[]
|
|
1030
1226
|
receiver = visit(node.receiver)
|
|
1031
|
-
|
|
1227
|
+
|
|
1228
|
+
bounds(node.opening_loc)
|
|
1229
|
+
on_lbracket("[")
|
|
1230
|
+
|
|
1231
|
+
arguments, block_node = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))
|
|
1232
|
+
|
|
1233
|
+
bounds(node.closing_loc)
|
|
1234
|
+
on_rbracket("]")
|
|
1235
|
+
|
|
1236
|
+
block = visit(block_node)
|
|
1032
1237
|
|
|
1033
1238
|
bounds(node.location)
|
|
1034
1239
|
call = on_aref(receiver, arguments)
|
|
1035
1240
|
|
|
1036
|
-
if
|
|
1037
|
-
call
|
|
1038
|
-
else
|
|
1241
|
+
if block_node
|
|
1039
1242
|
bounds(node.location)
|
|
1040
1243
|
on_method_add_block(call, block)
|
|
1244
|
+
else
|
|
1245
|
+
call
|
|
1041
1246
|
end
|
|
1042
1247
|
when :[]=
|
|
1043
1248
|
receiver = visit(node.receiver)
|
|
1044
1249
|
|
|
1250
|
+
bounds(node.opening_loc)
|
|
1251
|
+
on_lbracket("[")
|
|
1252
|
+
|
|
1045
1253
|
*arguments, last_argument = node.arguments.arguments
|
|
1046
1254
|
arguments << node.block if !node.block.nil?
|
|
1047
1255
|
|
|
@@ -1057,6 +1265,11 @@ module Prism
|
|
|
1057
1265
|
end
|
|
1058
1266
|
end
|
|
1059
1267
|
|
|
1268
|
+
bounds(node.closing_loc)
|
|
1269
|
+
on_rbracket("]")
|
|
1270
|
+
bounds(node.equal_loc)
|
|
1271
|
+
on_op("=")
|
|
1272
|
+
|
|
1060
1273
|
bounds(node.location)
|
|
1061
1274
|
call = on_aref_field(receiver, arguments)
|
|
1062
1275
|
value = visit_write_value(last_argument)
|
|
@@ -1064,27 +1277,54 @@ module Prism
|
|
|
1064
1277
|
bounds(last_argument.location)
|
|
1065
1278
|
on_assign(call, value)
|
|
1066
1279
|
when :-@, :+@, :~
|
|
1067
|
-
|
|
1280
|
+
bounds(node.message_loc)
|
|
1281
|
+
on_op(node.message)
|
|
1068
1282
|
|
|
1283
|
+
receiver = visit(node.receiver)
|
|
1069
1284
|
bounds(node.location)
|
|
1070
1285
|
on_unary(node.name, receiver)
|
|
1071
1286
|
when :!
|
|
1287
|
+
bounds(node.message_loc)
|
|
1072
1288
|
if node.message == "not"
|
|
1289
|
+
on_kw("not")
|
|
1290
|
+
|
|
1291
|
+
if node.opening_loc
|
|
1292
|
+
bounds(node.opening_loc)
|
|
1293
|
+
on_lparen("(")
|
|
1294
|
+
end
|
|
1295
|
+
|
|
1073
1296
|
receiver =
|
|
1074
|
-
if
|
|
1297
|
+
if node.receiver.is_a?(ParenthesesNode) && node.receiver.body.nil?
|
|
1298
|
+
# The parens in `not()` just emit parens and nothing else.
|
|
1299
|
+
bounds(node.receiver.opening_loc)
|
|
1300
|
+
on_lparen("(")
|
|
1301
|
+
bounds(node.receiver.closing_loc)
|
|
1302
|
+
on_rparen(")")
|
|
1303
|
+
nil
|
|
1304
|
+
else
|
|
1075
1305
|
visit(node.receiver)
|
|
1076
1306
|
end
|
|
1077
1307
|
|
|
1308
|
+
if node.closing_loc
|
|
1309
|
+
bounds(node.closing_loc)
|
|
1310
|
+
on_rparen(")")
|
|
1311
|
+
end
|
|
1078
1312
|
bounds(node.location)
|
|
1079
1313
|
on_unary(:not, receiver)
|
|
1080
1314
|
else
|
|
1315
|
+
on_op("!")
|
|
1316
|
+
|
|
1081
1317
|
receiver = visit(node.receiver)
|
|
1082
1318
|
|
|
1083
1319
|
bounds(node.location)
|
|
1084
1320
|
on_unary(:!, receiver)
|
|
1085
1321
|
end
|
|
1086
|
-
when
|
|
1322
|
+
when BINARY_OPERATORS
|
|
1087
1323
|
receiver = visit(node.receiver)
|
|
1324
|
+
|
|
1325
|
+
bounds(node.message_loc)
|
|
1326
|
+
on_op(node.message)
|
|
1327
|
+
|
|
1088
1328
|
value = visit(node.arguments.arguments.first)
|
|
1089
1329
|
|
|
1090
1330
|
bounds(node.location)
|
|
@@ -1096,9 +1336,21 @@ module Prism
|
|
|
1096
1336
|
if node.variable_call?
|
|
1097
1337
|
on_vcall(message)
|
|
1098
1338
|
else
|
|
1099
|
-
|
|
1339
|
+
if node.opening_loc
|
|
1340
|
+
bounds(node.opening_loc)
|
|
1341
|
+
on_lparen("(")
|
|
1342
|
+
end
|
|
1343
|
+
|
|
1344
|
+
arguments, block_node = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc || node.location))
|
|
1345
|
+
|
|
1346
|
+
if node.closing_loc
|
|
1347
|
+
bounds(node.closing_loc)
|
|
1348
|
+
on_rparen(")")
|
|
1349
|
+
end
|
|
1350
|
+
|
|
1351
|
+
block = visit(block_node)
|
|
1100
1352
|
call =
|
|
1101
|
-
if node.opening_loc.nil? && arguments
|
|
1353
|
+
if node.opening_loc.nil? && get_arguments_and_block(node.arguments, node.block).first.any?
|
|
1102
1354
|
bounds(node.location)
|
|
1103
1355
|
on_command(message, arguments)
|
|
1104
1356
|
elsif !node.opening_loc.nil?
|
|
@@ -1109,11 +1361,11 @@ module Prism
|
|
|
1109
1361
|
on_method_add_arg(on_fcall(message), on_args_new)
|
|
1110
1362
|
end
|
|
1111
1363
|
|
|
1112
|
-
if
|
|
1113
|
-
call
|
|
1114
|
-
else
|
|
1364
|
+
if block_node
|
|
1115
1365
|
bounds(node.block.location)
|
|
1116
1366
|
on_method_add_block(call, block)
|
|
1367
|
+
else
|
|
1368
|
+
call
|
|
1117
1369
|
end
|
|
1118
1370
|
end
|
|
1119
1371
|
end
|
|
@@ -1121,7 +1373,7 @@ module Prism
|
|
|
1121
1373
|
receiver = visit(node.receiver)
|
|
1122
1374
|
|
|
1123
1375
|
bounds(node.call_operator_loc)
|
|
1124
|
-
call_operator =
|
|
1376
|
+
call_operator = visit_call_operator(node.call_operator)
|
|
1125
1377
|
|
|
1126
1378
|
message =
|
|
1127
1379
|
if node.message_loc.nil?
|
|
@@ -1131,13 +1383,30 @@ module Prism
|
|
|
1131
1383
|
visit_token(node.message, false)
|
|
1132
1384
|
end
|
|
1133
1385
|
|
|
1386
|
+
if node.equal_loc
|
|
1387
|
+
bounds(node.equal_loc)
|
|
1388
|
+
on_op("=")
|
|
1389
|
+
end
|
|
1390
|
+
|
|
1134
1391
|
if node.name.end_with?("=") && !node.message.end_with?("=") && !node.arguments.nil? && node.block.nil?
|
|
1135
1392
|
value = visit_write_value(node.arguments.arguments.first)
|
|
1136
1393
|
|
|
1137
1394
|
bounds(node.location)
|
|
1138
1395
|
on_assign(on_field(receiver, call_operator, message), value)
|
|
1139
1396
|
else
|
|
1140
|
-
|
|
1397
|
+
if node.opening_loc
|
|
1398
|
+
bounds(node.opening_loc)
|
|
1399
|
+
on_lparen("(")
|
|
1400
|
+
end
|
|
1401
|
+
|
|
1402
|
+
arguments, block_node = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc || node.location))
|
|
1403
|
+
|
|
1404
|
+
if node.closing_loc
|
|
1405
|
+
bounds(node.closing_loc)
|
|
1406
|
+
on_rparen(")")
|
|
1407
|
+
end
|
|
1408
|
+
|
|
1409
|
+
block = visit(block_node)
|
|
1141
1410
|
call =
|
|
1142
1411
|
if node.opening_loc.nil?
|
|
1143
1412
|
bounds(node.location)
|
|
@@ -1155,27 +1424,35 @@ module Prism
|
|
|
1155
1424
|
on_method_add_arg(on_call(receiver, call_operator, message), arguments)
|
|
1156
1425
|
end
|
|
1157
1426
|
|
|
1158
|
-
if
|
|
1159
|
-
call
|
|
1160
|
-
else
|
|
1427
|
+
if block_node
|
|
1161
1428
|
bounds(node.block.location)
|
|
1162
1429
|
on_method_add_block(call, block)
|
|
1430
|
+
else
|
|
1431
|
+
call
|
|
1163
1432
|
end
|
|
1164
1433
|
end
|
|
1165
1434
|
end
|
|
1166
1435
|
end
|
|
1167
1436
|
|
|
1168
|
-
#
|
|
1169
|
-
#
|
|
1170
|
-
private def
|
|
1437
|
+
# Extract the arguments and block Ripper-style, which means if the block
|
|
1438
|
+
# is like `&b` then it's moved to arguments.
|
|
1439
|
+
private def get_arguments_and_block(arguments_node, block_node)
|
|
1171
1440
|
arguments = arguments_node&.arguments || []
|
|
1172
1441
|
block = block_node
|
|
1173
1442
|
|
|
1174
1443
|
if block.is_a?(BlockArgumentNode)
|
|
1175
|
-
arguments
|
|
1444
|
+
arguments += [block]
|
|
1176
1445
|
block = nil
|
|
1177
1446
|
end
|
|
1178
1447
|
|
|
1448
|
+
[arguments, block]
|
|
1449
|
+
end
|
|
1450
|
+
|
|
1451
|
+
# Visit the arguments and block of a call node and return the arguments
|
|
1452
|
+
# and block as they should be used.
|
|
1453
|
+
private def visit_call_node_arguments(arguments_node, block_node, trailing_comma)
|
|
1454
|
+
arguments, block = get_arguments_and_block(arguments_node, block_node)
|
|
1455
|
+
|
|
1179
1456
|
[
|
|
1180
1457
|
if arguments.length == 1 && arguments.first.is_a?(ForwardingArgumentsNode)
|
|
1181
1458
|
visit(arguments.first)
|
|
@@ -1189,7 +1466,7 @@ module Prism
|
|
|
1189
1466
|
on_args_add_block(args, false)
|
|
1190
1467
|
end
|
|
1191
1468
|
end,
|
|
1192
|
-
|
|
1469
|
+
block,
|
|
1193
1470
|
]
|
|
1194
1471
|
end
|
|
1195
1472
|
|
|
@@ -1207,7 +1484,7 @@ module Prism
|
|
|
1207
1484
|
receiver = visit(node.receiver)
|
|
1208
1485
|
|
|
1209
1486
|
bounds(node.call_operator_loc)
|
|
1210
|
-
call_operator =
|
|
1487
|
+
call_operator = visit_call_operator(node.call_operator)
|
|
1211
1488
|
|
|
1212
1489
|
bounds(node.message_loc)
|
|
1213
1490
|
message = visit_token(node.message)
|
|
@@ -1229,7 +1506,7 @@ module Prism
|
|
|
1229
1506
|
receiver = visit(node.receiver)
|
|
1230
1507
|
|
|
1231
1508
|
bounds(node.call_operator_loc)
|
|
1232
|
-
call_operator =
|
|
1509
|
+
call_operator = visit_call_operator(node.call_operator)
|
|
1233
1510
|
|
|
1234
1511
|
bounds(node.message_loc)
|
|
1235
1512
|
message = visit_token(node.message)
|
|
@@ -1251,7 +1528,7 @@ module Prism
|
|
|
1251
1528
|
receiver = visit(node.receiver)
|
|
1252
1529
|
|
|
1253
1530
|
bounds(node.call_operator_loc)
|
|
1254
|
-
call_operator =
|
|
1531
|
+
call_operator = visit_call_operator(node.call_operator)
|
|
1255
1532
|
|
|
1256
1533
|
bounds(node.message_loc)
|
|
1257
1534
|
message = visit_token(node.message)
|
|
@@ -1273,6 +1550,9 @@ module Prism
|
|
|
1273
1550
|
if node.call_operator == "::"
|
|
1274
1551
|
receiver = visit(node.receiver)
|
|
1275
1552
|
|
|
1553
|
+
bounds(node.call_operator_loc)
|
|
1554
|
+
on_op("::")
|
|
1555
|
+
|
|
1276
1556
|
bounds(node.message_loc)
|
|
1277
1557
|
message = visit_token(node.message)
|
|
1278
1558
|
|
|
@@ -1282,7 +1562,7 @@ module Prism
|
|
|
1282
1562
|
receiver = visit(node.receiver)
|
|
1283
1563
|
|
|
1284
1564
|
bounds(node.call_operator_loc)
|
|
1285
|
-
call_operator =
|
|
1565
|
+
call_operator = visit_call_operator(node.call_operator)
|
|
1286
1566
|
|
|
1287
1567
|
bounds(node.message_loc)
|
|
1288
1568
|
message = visit_token(node.message)
|
|
@@ -1296,6 +1576,10 @@ module Prism
|
|
|
1296
1576
|
# ^^^^^^^^^^
|
|
1297
1577
|
def visit_capture_pattern_node(node)
|
|
1298
1578
|
value = visit(node.value)
|
|
1579
|
+
|
|
1580
|
+
bounds(node.operator_loc)
|
|
1581
|
+
on_op("=>")
|
|
1582
|
+
|
|
1299
1583
|
target = visit(node.target)
|
|
1300
1584
|
|
|
1301
1585
|
bounds(node.location)
|
|
@@ -1305,10 +1589,21 @@ module Prism
|
|
|
1305
1589
|
# case foo; when bar; end
|
|
1306
1590
|
# ^^^^^^^^^^^^^^^^^^^^^^^
|
|
1307
1591
|
def visit_case_node(node)
|
|
1592
|
+
bounds(node.case_keyword_loc)
|
|
1593
|
+
on_kw("case")
|
|
1594
|
+
|
|
1308
1595
|
predicate = visit(node.predicate)
|
|
1596
|
+
visited_conditions = node.conditions.map { |condition| visit(condition) }
|
|
1597
|
+
visited_else_clause = visit(node.else_clause)
|
|
1598
|
+
|
|
1599
|
+
if !node.else_clause
|
|
1600
|
+
bounds(node.end_keyword_loc)
|
|
1601
|
+
on_kw("end")
|
|
1602
|
+
end
|
|
1603
|
+
|
|
1309
1604
|
clauses =
|
|
1310
|
-
|
|
1311
|
-
on_when(*
|
|
1605
|
+
visited_conditions.reverse_each.inject(visited_else_clause) do |current, condition|
|
|
1606
|
+
on_when(*condition, current)
|
|
1312
1607
|
end
|
|
1313
1608
|
|
|
1314
1609
|
bounds(node.location)
|
|
@@ -1318,10 +1613,23 @@ module Prism
|
|
|
1318
1613
|
# case foo; in bar; end
|
|
1319
1614
|
# ^^^^^^^^^^^^^^^^^^^^^
|
|
1320
1615
|
def visit_case_match_node(node)
|
|
1616
|
+
bounds(node.case_keyword_loc)
|
|
1617
|
+
on_kw("case")
|
|
1618
|
+
|
|
1321
1619
|
predicate = visit(node.predicate)
|
|
1620
|
+
visited_conditions = node.conditions.map do | condition|
|
|
1621
|
+
visit(condition)
|
|
1622
|
+
end
|
|
1623
|
+
visited_else_clause = visit(node.else_clause)
|
|
1624
|
+
|
|
1625
|
+
if !node.else_clause
|
|
1626
|
+
bounds(node.end_keyword_loc)
|
|
1627
|
+
on_kw("end")
|
|
1628
|
+
end
|
|
1629
|
+
|
|
1322
1630
|
clauses =
|
|
1323
|
-
|
|
1324
|
-
on_in(*
|
|
1631
|
+
visited_conditions.reverse_each.inject(visited_else_clause) do |current, condition|
|
|
1632
|
+
on_in(*condition, current)
|
|
1325
1633
|
end
|
|
1326
1634
|
|
|
1327
1635
|
bounds(node.location)
|
|
@@ -1331,6 +1639,9 @@ module Prism
|
|
|
1331
1639
|
# class Foo; end
|
|
1332
1640
|
# ^^^^^^^^^^^^^^
|
|
1333
1641
|
def visit_class_node(node)
|
|
1642
|
+
bounds(node.class_keyword_loc)
|
|
1643
|
+
on_kw("class")
|
|
1644
|
+
|
|
1334
1645
|
constant_path =
|
|
1335
1646
|
if node.constant_path.is_a?(ConstantReadNode)
|
|
1336
1647
|
bounds(node.constant_path.location)
|
|
@@ -1339,9 +1650,17 @@ module Prism
|
|
|
1339
1650
|
visit(node.constant_path)
|
|
1340
1651
|
end
|
|
1341
1652
|
|
|
1653
|
+
if node.inheritance_operator_loc
|
|
1654
|
+
bounds(node.inheritance_operator_loc)
|
|
1655
|
+
on_op("<")
|
|
1656
|
+
end
|
|
1657
|
+
|
|
1342
1658
|
superclass = visit(node.superclass)
|
|
1343
1659
|
bodystmt = visit_body_node(node.superclass&.location || node.constant_path.location, node.body, node.superclass.nil?)
|
|
1344
1660
|
|
|
1661
|
+
bounds(node.end_keyword_loc)
|
|
1662
|
+
on_kw("end")
|
|
1663
|
+
|
|
1345
1664
|
bounds(node.location)
|
|
1346
1665
|
on_class(constant_path, superclass, bodystmt)
|
|
1347
1666
|
end
|
|
@@ -1355,12 +1674,13 @@ module Prism
|
|
|
1355
1674
|
|
|
1356
1675
|
# @@foo = 1
|
|
1357
1676
|
# ^^^^^^^^^
|
|
1358
|
-
#
|
|
1359
|
-
# @@foo, @@bar = 1
|
|
1360
|
-
# ^^^^^ ^^^^^
|
|
1361
1677
|
def visit_class_variable_write_node(node)
|
|
1362
1678
|
bounds(node.name_loc)
|
|
1363
1679
|
target = on_var_field(on_cvar(node.name.to_s))
|
|
1680
|
+
|
|
1681
|
+
bounds(node.operator_loc)
|
|
1682
|
+
on_op("=")
|
|
1683
|
+
|
|
1364
1684
|
value = visit_write_value(node.value)
|
|
1365
1685
|
|
|
1366
1686
|
bounds(node.location)
|
|
@@ -1425,12 +1745,13 @@ module Prism
|
|
|
1425
1745
|
|
|
1426
1746
|
# Foo = 1
|
|
1427
1747
|
# ^^^^^^^
|
|
1428
|
-
#
|
|
1429
|
-
# Foo, Bar = 1
|
|
1430
|
-
# ^^^ ^^^
|
|
1431
1748
|
def visit_constant_write_node(node)
|
|
1432
1749
|
bounds(node.name_loc)
|
|
1433
1750
|
target = on_var_field(on_const(node.name.to_s))
|
|
1751
|
+
|
|
1752
|
+
bounds(node.operator_loc)
|
|
1753
|
+
on_op("=")
|
|
1754
|
+
|
|
1434
1755
|
value = visit_write_value(node.value)
|
|
1435
1756
|
|
|
1436
1757
|
bounds(node.location)
|
|
@@ -1490,6 +1811,11 @@ module Prism
|
|
|
1490
1811
|
# ^^^^^^^^
|
|
1491
1812
|
def visit_constant_path_node(node)
|
|
1492
1813
|
if node.parent.nil?
|
|
1814
|
+
if node.delimiter_loc
|
|
1815
|
+
bounds(node.delimiter_loc)
|
|
1816
|
+
on_op("::")
|
|
1817
|
+
end
|
|
1818
|
+
|
|
1493
1819
|
bounds(node.name_loc)
|
|
1494
1820
|
child = on_const(node.name.to_s)
|
|
1495
1821
|
|
|
@@ -1498,6 +1824,9 @@ module Prism
|
|
|
1498
1824
|
else
|
|
1499
1825
|
parent = visit(node.parent)
|
|
1500
1826
|
|
|
1827
|
+
bounds(node.delimiter_loc)
|
|
1828
|
+
on_op("::")
|
|
1829
|
+
|
|
1501
1830
|
bounds(node.name_loc)
|
|
1502
1831
|
child = on_const(node.name.to_s)
|
|
1503
1832
|
|
|
@@ -1508,11 +1837,12 @@ module Prism
|
|
|
1508
1837
|
|
|
1509
1838
|
# Foo::Bar = 1
|
|
1510
1839
|
# ^^^^^^^^^^^^
|
|
1511
|
-
#
|
|
1512
|
-
# Foo::Foo, Bar::Bar = 1
|
|
1513
|
-
# ^^^^^^^^ ^^^^^^^^
|
|
1514
1840
|
def visit_constant_path_write_node(node)
|
|
1515
1841
|
target = visit_constant_path_write_node_target(node.target)
|
|
1842
|
+
|
|
1843
|
+
bounds(node.operator_loc)
|
|
1844
|
+
on_op("=")
|
|
1845
|
+
|
|
1516
1846
|
value = visit_write_value(node.value)
|
|
1517
1847
|
|
|
1518
1848
|
bounds(node.location)
|
|
@@ -1522,6 +1852,11 @@ module Prism
|
|
|
1522
1852
|
# Visit a constant path that is part of a write node.
|
|
1523
1853
|
private def visit_constant_path_write_node_target(node)
|
|
1524
1854
|
if node.parent.nil?
|
|
1855
|
+
if node.delimiter_loc
|
|
1856
|
+
bounds(node.delimiter_loc)
|
|
1857
|
+
on_op("::")
|
|
1858
|
+
end
|
|
1859
|
+
|
|
1525
1860
|
bounds(node.name_loc)
|
|
1526
1861
|
child = on_const(node.name.to_s)
|
|
1527
1862
|
|
|
@@ -1530,6 +1865,9 @@ module Prism
|
|
|
1530
1865
|
else
|
|
1531
1866
|
parent = visit(node.parent)
|
|
1532
1867
|
|
|
1868
|
+
bounds(node.delimiter_loc)
|
|
1869
|
+
on_op("::")
|
|
1870
|
+
|
|
1533
1871
|
bounds(node.name_loc)
|
|
1534
1872
|
child = on_const(node.name.to_s)
|
|
1535
1873
|
|
|
@@ -1542,7 +1880,6 @@ module Prism
|
|
|
1542
1880
|
# ^^^^^^^^^^^^^^^
|
|
1543
1881
|
def visit_constant_path_operator_write_node(node)
|
|
1544
1882
|
target = visit_constant_path_write_node_target(node.target)
|
|
1545
|
-
value = visit(node.value)
|
|
1546
1883
|
|
|
1547
1884
|
bounds(node.binary_operator_loc)
|
|
1548
1885
|
operator = on_op("#{node.binary_operator}=")
|
|
@@ -1556,7 +1893,6 @@ module Prism
|
|
|
1556
1893
|
# ^^^^^^^^^^^^^^^^
|
|
1557
1894
|
def visit_constant_path_and_write_node(node)
|
|
1558
1895
|
target = visit_constant_path_write_node_target(node.target)
|
|
1559
|
-
value = visit(node.value)
|
|
1560
1896
|
|
|
1561
1897
|
bounds(node.operator_loc)
|
|
1562
1898
|
operator = on_op("&&=")
|
|
@@ -1570,7 +1906,6 @@ module Prism
|
|
|
1570
1906
|
# ^^^^^^^^^^^^^^^^
|
|
1571
1907
|
def visit_constant_path_or_write_node(node)
|
|
1572
1908
|
target = visit_constant_path_write_node_target(node.target)
|
|
1573
|
-
value = visit(node.value)
|
|
1574
1909
|
|
|
1575
1910
|
bounds(node.operator_loc)
|
|
1576
1911
|
operator = on_op("||=")
|
|
@@ -1592,16 +1927,24 @@ module Prism
|
|
|
1592
1927
|
# def self.foo; end
|
|
1593
1928
|
# ^^^^^^^^^^^^^^^^^
|
|
1594
1929
|
def visit_def_node(node)
|
|
1930
|
+
bounds(node.def_keyword_loc)
|
|
1931
|
+
on_kw("def")
|
|
1932
|
+
|
|
1595
1933
|
receiver = visit(node.receiver)
|
|
1596
1934
|
operator =
|
|
1597
1935
|
if !node.operator_loc.nil?
|
|
1598
1936
|
bounds(node.operator_loc)
|
|
1599
|
-
|
|
1937
|
+
node.operator == "." ? on_period(".") : on_op("::")
|
|
1600
1938
|
end
|
|
1601
1939
|
|
|
1602
1940
|
bounds(node.name_loc)
|
|
1603
1941
|
name = visit_token(node.name_loc.slice)
|
|
1604
1942
|
|
|
1943
|
+
if node.lparen_loc
|
|
1944
|
+
bounds(node.lparen_loc)
|
|
1945
|
+
on_lparen("(")
|
|
1946
|
+
end
|
|
1947
|
+
|
|
1605
1948
|
parameters =
|
|
1606
1949
|
if node.parameters.nil?
|
|
1607
1950
|
bounds(node.location)
|
|
@@ -1611,10 +1954,17 @@ module Prism
|
|
|
1611
1954
|
end
|
|
1612
1955
|
|
|
1613
1956
|
if !node.lparen_loc.nil?
|
|
1957
|
+
bounds(node.rparen_loc)
|
|
1958
|
+
on_rparen(")")
|
|
1614
1959
|
bounds(node.lparen_loc)
|
|
1615
1960
|
parameters = on_paren(parameters)
|
|
1616
1961
|
end
|
|
1617
1962
|
|
|
1963
|
+
if node.equal_loc
|
|
1964
|
+
bounds(node.equal_loc)
|
|
1965
|
+
on_op("=")
|
|
1966
|
+
end
|
|
1967
|
+
|
|
1618
1968
|
bodystmt =
|
|
1619
1969
|
if node.equal_loc.nil?
|
|
1620
1970
|
visit_body_node(node.rparen_loc || node.end_keyword_loc, node.body)
|
|
@@ -1625,11 +1975,16 @@ module Prism
|
|
|
1625
1975
|
on_bodystmt(body, nil, nil, nil)
|
|
1626
1976
|
end
|
|
1627
1977
|
|
|
1978
|
+
if node.end_keyword_loc
|
|
1979
|
+
bounds(node.end_keyword_loc)
|
|
1980
|
+
on_kw("end")
|
|
1981
|
+
end
|
|
1982
|
+
|
|
1628
1983
|
bounds(node.location)
|
|
1629
|
-
if receiver
|
|
1630
|
-
on_def(name, parameters, bodystmt)
|
|
1631
|
-
else
|
|
1984
|
+
if receiver
|
|
1632
1985
|
on_defs(receiver, operator, name, parameters, bodystmt)
|
|
1986
|
+
else
|
|
1987
|
+
on_def(name, parameters, bodystmt)
|
|
1633
1988
|
end
|
|
1634
1989
|
end
|
|
1635
1990
|
|
|
@@ -1639,8 +1994,21 @@ module Prism
|
|
|
1639
1994
|
# defined?(a)
|
|
1640
1995
|
# ^^^^^^^^^^^
|
|
1641
1996
|
def visit_defined_node(node)
|
|
1997
|
+
bounds(node.keyword_loc)
|
|
1998
|
+
on_kw("defined?")
|
|
1999
|
+
|
|
2000
|
+
if node.lparen_loc
|
|
2001
|
+
bounds(node.lparen_loc)
|
|
2002
|
+
on_lparen("(")
|
|
2003
|
+
end
|
|
2004
|
+
|
|
1642
2005
|
expression = visit(node.value)
|
|
1643
2006
|
|
|
2007
|
+
if node.rparen_loc
|
|
2008
|
+
bounds(node.rparen_loc)
|
|
2009
|
+
on_rparen(")")
|
|
2010
|
+
end
|
|
2011
|
+
|
|
1644
2012
|
# Very weird circumstances here where something like:
|
|
1645
2013
|
#
|
|
1646
2014
|
# defined?
|
|
@@ -1661,17 +2029,24 @@ module Prism
|
|
|
1661
2029
|
# if foo then bar else baz end
|
|
1662
2030
|
# ^^^^^^^^^^^^
|
|
1663
2031
|
def visit_else_node(node)
|
|
2032
|
+
bounds(node.else_keyword_loc)
|
|
2033
|
+
on_kw("else")
|
|
2034
|
+
|
|
1664
2035
|
statements =
|
|
1665
2036
|
if node.statements.nil?
|
|
1666
2037
|
[nil]
|
|
1667
2038
|
else
|
|
1668
2039
|
body = node.statements.body
|
|
1669
|
-
body
|
|
2040
|
+
body = [nil, *body] if void_stmt?(node.else_keyword_loc, node.statements.body[0].location, false)
|
|
1670
2041
|
body
|
|
1671
2042
|
end
|
|
1672
2043
|
|
|
2044
|
+
else_statements = visit_statements_node_body(statements)
|
|
2045
|
+
|
|
2046
|
+
bounds(node.end_keyword_loc)
|
|
2047
|
+
on_kw("end")
|
|
1673
2048
|
bounds(node.location)
|
|
1674
|
-
on_else(
|
|
2049
|
+
on_else(else_statements)
|
|
1675
2050
|
end
|
|
1676
2051
|
|
|
1677
2052
|
# "foo #{bar}"
|
|
@@ -1709,12 +2084,15 @@ module Prism
|
|
|
1709
2084
|
|
|
1710
2085
|
# Visit an EnsureNode node.
|
|
1711
2086
|
def visit_ensure_node(node)
|
|
2087
|
+
bounds(node.ensure_keyword_loc)
|
|
2088
|
+
on_kw("ensure")
|
|
2089
|
+
|
|
1712
2090
|
statements =
|
|
1713
2091
|
if node.statements.nil?
|
|
1714
2092
|
[nil]
|
|
1715
2093
|
else
|
|
1716
2094
|
body = node.statements.body
|
|
1717
|
-
body
|
|
2095
|
+
body = [nil, *body] if void_stmt?(node.ensure_keyword_loc, body[0].location, false)
|
|
1718
2096
|
body
|
|
1719
2097
|
end
|
|
1720
2098
|
|
|
@@ -1735,6 +2113,14 @@ module Prism
|
|
|
1735
2113
|
# ^^^^^^^^^^^
|
|
1736
2114
|
def visit_find_pattern_node(node)
|
|
1737
2115
|
constant = visit(node.constant)
|
|
2116
|
+
|
|
2117
|
+
if node.opening_loc
|
|
2118
|
+
bounds(node.opening_loc)
|
|
2119
|
+
node.opening == "[" ? on_lbracket("[") : on_lparen("(")
|
|
2120
|
+
end
|
|
2121
|
+
bounds(node.left.operator_loc)
|
|
2122
|
+
on_op("*")
|
|
2123
|
+
|
|
1738
2124
|
left =
|
|
1739
2125
|
if node.left.expression.nil?
|
|
1740
2126
|
bounds(node.left.location)
|
|
@@ -1744,6 +2130,10 @@ module Prism
|
|
|
1744
2130
|
end
|
|
1745
2131
|
|
|
1746
2132
|
requireds = visit_all(node.requireds) if node.requireds.any?
|
|
2133
|
+
|
|
2134
|
+
bounds(node.right.operator_loc)
|
|
2135
|
+
on_op("*")
|
|
2136
|
+
|
|
1747
2137
|
right =
|
|
1748
2138
|
if node.right.expression.nil?
|
|
1749
2139
|
bounds(node.right.location)
|
|
@@ -1752,6 +2142,10 @@ module Prism
|
|
|
1752
2142
|
visit(node.right.expression)
|
|
1753
2143
|
end
|
|
1754
2144
|
|
|
2145
|
+
if node.closing_loc
|
|
2146
|
+
bounds(node.closing_loc)
|
|
2147
|
+
node.closing == "]" ? on_rbracket("]") : on_rparen(")")
|
|
2148
|
+
end
|
|
1755
2149
|
bounds(node.location)
|
|
1756
2150
|
on_fndptn(constant, left, requireds, right)
|
|
1757
2151
|
end
|
|
@@ -1760,6 +2154,10 @@ module Prism
|
|
|
1760
2154
|
# ^^^^^^^^^^
|
|
1761
2155
|
def visit_flip_flop_node(node)
|
|
1762
2156
|
left = visit(node.left)
|
|
2157
|
+
|
|
2158
|
+
bounds(node.operator_loc)
|
|
2159
|
+
on_op(node.operator)
|
|
2160
|
+
|
|
1763
2161
|
right = visit(node.right)
|
|
1764
2162
|
|
|
1765
2163
|
bounds(node.location)
|
|
@@ -1779,8 +2177,18 @@ module Prism
|
|
|
1779
2177
|
# for foo in bar do end
|
|
1780
2178
|
# ^^^^^^^^^^^^^^^^^^^^^
|
|
1781
2179
|
def visit_for_node(node)
|
|
2180
|
+
bounds(node.for_keyword_loc)
|
|
2181
|
+
on_kw("for")
|
|
2182
|
+
|
|
1782
2183
|
index = visit(node.index)
|
|
2184
|
+
bounds(node.in_keyword_loc)
|
|
2185
|
+
on_kw("in")
|
|
2186
|
+
|
|
1783
2187
|
collection = visit(node.collection)
|
|
2188
|
+
if node.do_keyword_loc
|
|
2189
|
+
bounds(node.do_keyword_loc)
|
|
2190
|
+
on_kw("do")
|
|
2191
|
+
end
|
|
1784
2192
|
statements =
|
|
1785
2193
|
if node.statements.nil?
|
|
1786
2194
|
bounds(node.location)
|
|
@@ -1789,6 +2197,9 @@ module Prism
|
|
|
1789
2197
|
visit(node.statements)
|
|
1790
2198
|
end
|
|
1791
2199
|
|
|
2200
|
+
bounds(node.end_keyword_loc)
|
|
2201
|
+
on_kw("end")
|
|
2202
|
+
|
|
1792
2203
|
bounds(node.location)
|
|
1793
2204
|
on_for(index, collection, statements)
|
|
1794
2205
|
end
|
|
@@ -1797,6 +2208,7 @@ module Prism
|
|
|
1797
2208
|
# ^^^
|
|
1798
2209
|
def visit_forwarding_arguments_node(node)
|
|
1799
2210
|
bounds(node.location)
|
|
2211
|
+
on_op("...")
|
|
1800
2212
|
on_args_forward
|
|
1801
2213
|
end
|
|
1802
2214
|
|
|
@@ -1804,6 +2216,7 @@ module Prism
|
|
|
1804
2216
|
# ^^^
|
|
1805
2217
|
def visit_forwarding_parameter_node(node)
|
|
1806
2218
|
bounds(node.location)
|
|
2219
|
+
on_op("...")
|
|
1807
2220
|
on_args_forward
|
|
1808
2221
|
end
|
|
1809
2222
|
|
|
@@ -1813,6 +2226,9 @@ module Prism
|
|
|
1813
2226
|
# super {}
|
|
1814
2227
|
# ^^^^^^^^
|
|
1815
2228
|
def visit_forwarding_super_node(node)
|
|
2229
|
+
bounds(node.keyword_loc)
|
|
2230
|
+
on_kw("super")
|
|
2231
|
+
|
|
1816
2232
|
if node.block.nil?
|
|
1817
2233
|
bounds(node.location)
|
|
1818
2234
|
on_zsuper
|
|
@@ -1833,12 +2249,13 @@ module Prism
|
|
|
1833
2249
|
|
|
1834
2250
|
# $foo = 1
|
|
1835
2251
|
# ^^^^^^^^
|
|
1836
|
-
#
|
|
1837
|
-
# $foo, $bar = 1
|
|
1838
|
-
# ^^^^ ^^^^
|
|
1839
2252
|
def visit_global_variable_write_node(node)
|
|
1840
2253
|
bounds(node.name_loc)
|
|
1841
2254
|
target = on_var_field(on_gvar(node.name.to_s))
|
|
2255
|
+
|
|
2256
|
+
bounds(node.operator_loc)
|
|
2257
|
+
on_op("=")
|
|
2258
|
+
|
|
1842
2259
|
value = visit_write_value(node.value)
|
|
1843
2260
|
|
|
1844
2261
|
bounds(node.location)
|
|
@@ -1897,6 +2314,9 @@ module Prism
|
|
|
1897
2314
|
# {}
|
|
1898
2315
|
# ^^
|
|
1899
2316
|
def visit_hash_node(node)
|
|
2317
|
+
bounds(node.opening_loc)
|
|
2318
|
+
on_lbrace("{")
|
|
2319
|
+
|
|
1900
2320
|
elements =
|
|
1901
2321
|
if node.elements.any?
|
|
1902
2322
|
args = visit_all(node.elements)
|
|
@@ -1905,6 +2325,8 @@ module Prism
|
|
|
1905
2325
|
on_assoclist_from_args(args)
|
|
1906
2326
|
end
|
|
1907
2327
|
|
|
2328
|
+
bounds(node.closing_loc)
|
|
2329
|
+
on_rbrace("}")
|
|
1908
2330
|
bounds(node.location)
|
|
1909
2331
|
on_hash(elements)
|
|
1910
2332
|
end
|
|
@@ -1913,6 +2335,15 @@ module Prism
|
|
|
1913
2335
|
# ^^
|
|
1914
2336
|
def visit_hash_pattern_node(node)
|
|
1915
2337
|
constant = visit(node.constant)
|
|
2338
|
+
|
|
2339
|
+
if node.constant
|
|
2340
|
+
bounds(node.opening_loc)
|
|
2341
|
+
node.opening == "[" ? on_lbracket("[") : on_lparen("(")
|
|
2342
|
+
elsif node.opening_loc
|
|
2343
|
+
bounds(node.opening_loc)
|
|
2344
|
+
on_lbrace("{")
|
|
2345
|
+
end
|
|
2346
|
+
|
|
1916
2347
|
elements =
|
|
1917
2348
|
if node.elements.any? || !node.rest.nil?
|
|
1918
2349
|
node.elements.map do |element|
|
|
@@ -1920,8 +2351,8 @@ module Prism
|
|
|
1920
2351
|
if (key = element.key).opening_loc.nil?
|
|
1921
2352
|
visit(key)
|
|
1922
2353
|
else
|
|
1923
|
-
bounds(key.
|
|
1924
|
-
if (value = key.
|
|
2354
|
+
bounds(key.content_loc)
|
|
2355
|
+
if (value = key.content).empty?
|
|
1925
2356
|
on_string_content
|
|
1926
2357
|
else
|
|
1927
2358
|
on_string_add(on_string_content, on_tstring_content(value))
|
|
@@ -1935,12 +2366,21 @@ module Prism
|
|
|
1935
2366
|
rest =
|
|
1936
2367
|
case node.rest
|
|
1937
2368
|
when AssocSplatNode
|
|
2369
|
+
bounds(node.rest.operator_loc)
|
|
2370
|
+
on_op("**")
|
|
1938
2371
|
visit(node.rest.value)
|
|
1939
2372
|
when NoKeywordsParameterNode
|
|
1940
2373
|
bounds(node.rest.location)
|
|
1941
2374
|
on_var_field(visit(node.rest))
|
|
1942
2375
|
end
|
|
1943
2376
|
|
|
2377
|
+
if node.constant
|
|
2378
|
+
bounds(node.closing_loc)
|
|
2379
|
+
node.closing == "]" ? on_rbracket("]") : on_rparen(")")
|
|
2380
|
+
elsif node.closing_loc
|
|
2381
|
+
bounds(node.closing_loc)
|
|
2382
|
+
on_rbrace("}")
|
|
2383
|
+
end
|
|
1944
2384
|
bounds(node.location)
|
|
1945
2385
|
on_hshptn(constant, elements, rest)
|
|
1946
2386
|
end
|
|
@@ -1956,13 +2396,27 @@ module Prism
|
|
|
1956
2396
|
def visit_if_node(node)
|
|
1957
2397
|
if node.then_keyword == "?"
|
|
1958
2398
|
predicate = visit(node.predicate)
|
|
2399
|
+
|
|
2400
|
+
bounds(node.then_keyword_loc)
|
|
2401
|
+
on_op("?")
|
|
2402
|
+
|
|
1959
2403
|
truthy = visit(node.statements.body.first)
|
|
2404
|
+
|
|
2405
|
+
bounds(node.subsequent.else_keyword_loc)
|
|
2406
|
+
on_op(":")
|
|
2407
|
+
|
|
1960
2408
|
falsy = visit(node.subsequent.statements.body.first)
|
|
1961
2409
|
|
|
1962
2410
|
bounds(node.location)
|
|
1963
2411
|
on_ifop(predicate, truthy, falsy)
|
|
1964
2412
|
elsif node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset)
|
|
2413
|
+
bounds(node.if_keyword_loc)
|
|
2414
|
+
on_kw(node.if_keyword)
|
|
1965
2415
|
predicate = visit(node.predicate)
|
|
2416
|
+
if node.then_keyword_loc && node.then_keyword != "?"
|
|
2417
|
+
bounds(node.then_keyword_loc)
|
|
2418
|
+
on_kw("then")
|
|
2419
|
+
end
|
|
1966
2420
|
statements =
|
|
1967
2421
|
if node.statements.nil?
|
|
1968
2422
|
bounds(node.location)
|
|
@@ -1972,6 +2426,11 @@ module Prism
|
|
|
1972
2426
|
end
|
|
1973
2427
|
subsequent = visit(node.subsequent)
|
|
1974
2428
|
|
|
2429
|
+
if node.end_keyword_loc && !node.subsequent
|
|
2430
|
+
bounds(node.end_keyword_loc)
|
|
2431
|
+
on_kw("end")
|
|
2432
|
+
end
|
|
2433
|
+
|
|
1975
2434
|
bounds(node.location)
|
|
1976
2435
|
if node.if_keyword == "if"
|
|
1977
2436
|
on_if(predicate, statements, subsequent)
|
|
@@ -1980,6 +2439,8 @@ module Prism
|
|
|
1980
2439
|
end
|
|
1981
2440
|
else
|
|
1982
2441
|
statements = visit(node.statements.body.first)
|
|
2442
|
+
bounds(node.if_keyword_loc)
|
|
2443
|
+
on_kw(node.if_keyword)
|
|
1983
2444
|
predicate = visit(node.predicate)
|
|
1984
2445
|
|
|
1985
2446
|
bounds(node.location)
|
|
@@ -2011,7 +2472,14 @@ module Prism
|
|
|
2011
2472
|
# This is a special case where we're not going to call on_in directly
|
|
2012
2473
|
# because we don't have access to the subsequent. Instead, we'll return
|
|
2013
2474
|
# the component parts and let the parent node handle it.
|
|
2475
|
+
bounds(node.in_keyword_loc)
|
|
2476
|
+
on_kw("in")
|
|
2477
|
+
|
|
2014
2478
|
pattern = visit_pattern_node(node.pattern)
|
|
2479
|
+
if node.then_keyword_loc
|
|
2480
|
+
bounds(node.then_keyword_loc)
|
|
2481
|
+
on_kw("then")
|
|
2482
|
+
end
|
|
2015
2483
|
statements =
|
|
2016
2484
|
if node.statements.nil?
|
|
2017
2485
|
bounds(node.location)
|
|
@@ -2027,8 +2495,15 @@ module Prism
|
|
|
2027
2495
|
# ^^^^^^^^^^^^^^^
|
|
2028
2496
|
def visit_index_operator_write_node(node)
|
|
2029
2497
|
receiver = visit(node.receiver)
|
|
2498
|
+
|
|
2499
|
+
bounds(node.opening_loc)
|
|
2500
|
+
on_lbracket("[")
|
|
2501
|
+
|
|
2030
2502
|
arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))
|
|
2031
2503
|
|
|
2504
|
+
bounds(node.closing_loc)
|
|
2505
|
+
on_rbracket("]")
|
|
2506
|
+
|
|
2032
2507
|
bounds(node.location)
|
|
2033
2508
|
target = on_aref_field(receiver, arguments)
|
|
2034
2509
|
|
|
@@ -2044,8 +2519,15 @@ module Prism
|
|
|
2044
2519
|
# ^^^^^^^^^^^^^^^^
|
|
2045
2520
|
def visit_index_and_write_node(node)
|
|
2046
2521
|
receiver = visit(node.receiver)
|
|
2522
|
+
|
|
2523
|
+
bounds(node.opening_loc)
|
|
2524
|
+
on_lbracket("[")
|
|
2525
|
+
|
|
2047
2526
|
arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))
|
|
2048
2527
|
|
|
2528
|
+
bounds(node.closing_loc)
|
|
2529
|
+
on_rbracket("]")
|
|
2530
|
+
|
|
2049
2531
|
bounds(node.location)
|
|
2050
2532
|
target = on_aref_field(receiver, arguments)
|
|
2051
2533
|
|
|
@@ -2061,8 +2543,15 @@ module Prism
|
|
|
2061
2543
|
# ^^^^^^^^^^^^^^^^
|
|
2062
2544
|
def visit_index_or_write_node(node)
|
|
2063
2545
|
receiver = visit(node.receiver)
|
|
2546
|
+
|
|
2547
|
+
bounds(node.opening_loc)
|
|
2548
|
+
on_lbracket("[")
|
|
2549
|
+
|
|
2064
2550
|
arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))
|
|
2065
2551
|
|
|
2552
|
+
bounds(node.closing_loc)
|
|
2553
|
+
on_rbracket("]")
|
|
2554
|
+
|
|
2066
2555
|
bounds(node.location)
|
|
2067
2556
|
target = on_aref_field(receiver, arguments)
|
|
2068
2557
|
|
|
@@ -2078,8 +2567,15 @@ module Prism
|
|
|
2078
2567
|
# ^^^^^^^^
|
|
2079
2568
|
def visit_index_target_node(node)
|
|
2080
2569
|
receiver = visit(node.receiver)
|
|
2570
|
+
|
|
2571
|
+
bounds(node.opening_loc)
|
|
2572
|
+
on_lbracket("[")
|
|
2573
|
+
|
|
2081
2574
|
arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))
|
|
2082
2575
|
|
|
2576
|
+
bounds(node.closing_loc)
|
|
2577
|
+
on_rbracket("]")
|
|
2578
|
+
|
|
2083
2579
|
bounds(node.location)
|
|
2084
2580
|
on_aref_field(receiver, arguments)
|
|
2085
2581
|
end
|
|
@@ -2096,6 +2592,10 @@ module Prism
|
|
|
2096
2592
|
def visit_instance_variable_write_node(node)
|
|
2097
2593
|
bounds(node.name_loc)
|
|
2098
2594
|
target = on_var_field(on_ivar(node.name.to_s))
|
|
2595
|
+
|
|
2596
|
+
bounds(node.operator_loc)
|
|
2597
|
+
on_op("=")
|
|
2598
|
+
|
|
2099
2599
|
value = visit_write_value(node.value)
|
|
2100
2600
|
|
|
2101
2601
|
bounds(node.location)
|
|
@@ -2198,20 +2698,37 @@ module Prism
|
|
|
2198
2698
|
# "foo #{bar}"
|
|
2199
2699
|
# ^^^^^^^^^^^^
|
|
2200
2700
|
def visit_interpolated_string_node(node)
|
|
2201
|
-
|
|
2202
|
-
|
|
2701
|
+
with_string_bounds(node) do
|
|
2702
|
+
if node.opening&.start_with?("<<~")
|
|
2703
|
+
heredoc = visit_heredoc_string_node(node)
|
|
2203
2704
|
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2705
|
+
bounds(node.location)
|
|
2706
|
+
on_string_literal(heredoc)
|
|
2707
|
+
elsif !node.heredoc? && node.parts.length > 1 && node.parts.any? { |part| (part.is_a?(StringNode) || part.is_a?(InterpolatedStringNode)) && !part.opening_loc.nil? }
|
|
2708
|
+
first, *rest = node.parts
|
|
2709
|
+
rest.inject(visit(first)) do |content, part|
|
|
2710
|
+
concat = visit(part)
|
|
2711
|
+
|
|
2712
|
+
bounds(part.location)
|
|
2713
|
+
on_string_concat(content, concat)
|
|
2714
|
+
end
|
|
2715
|
+
else
|
|
2716
|
+
bounds(node.parts.first.location)
|
|
2717
|
+
parts =
|
|
2718
|
+
node.parts.inject(on_string_content) do |content, part|
|
|
2719
|
+
on_string_add(content, visit_string_content(part))
|
|
2720
|
+
end
|
|
2210
2721
|
|
|
2211
|
-
bounds(
|
|
2212
|
-
|
|
2722
|
+
bounds(node.location)
|
|
2723
|
+
on_string_literal(parts)
|
|
2213
2724
|
end
|
|
2214
|
-
|
|
2725
|
+
end
|
|
2726
|
+
end
|
|
2727
|
+
|
|
2728
|
+
# :"foo #{bar}"
|
|
2729
|
+
# ^^^^^^^^^^^^^
|
|
2730
|
+
def visit_interpolated_symbol_node(node)
|
|
2731
|
+
with_string_bounds(node) do
|
|
2215
2732
|
bounds(node.parts.first.location)
|
|
2216
2733
|
parts =
|
|
2217
2734
|
node.parts.inject(on_string_content) do |content, part|
|
|
@@ -2219,40 +2736,29 @@ module Prism
|
|
|
2219
2736
|
end
|
|
2220
2737
|
|
|
2221
2738
|
bounds(node.location)
|
|
2222
|
-
|
|
2739
|
+
on_dyna_symbol(parts)
|
|
2223
2740
|
end
|
|
2224
2741
|
end
|
|
2225
2742
|
|
|
2226
|
-
# :"foo #{bar}"
|
|
2227
|
-
# ^^^^^^^^^^^^^
|
|
2228
|
-
def visit_interpolated_symbol_node(node)
|
|
2229
|
-
bounds(node.parts.first.location)
|
|
2230
|
-
parts =
|
|
2231
|
-
node.parts.inject(on_string_content) do |content, part|
|
|
2232
|
-
on_string_add(content, visit_string_content(part))
|
|
2233
|
-
end
|
|
2234
|
-
|
|
2235
|
-
bounds(node.location)
|
|
2236
|
-
on_dyna_symbol(parts)
|
|
2237
|
-
end
|
|
2238
|
-
|
|
2239
2743
|
# `foo #{bar}`
|
|
2240
2744
|
# ^^^^^^^^^^^^
|
|
2241
2745
|
def visit_interpolated_x_string_node(node)
|
|
2242
|
-
|
|
2243
|
-
|
|
2746
|
+
with_string_bounds(node) do
|
|
2747
|
+
if node.opening.start_with?("<<~")
|
|
2748
|
+
heredoc = visit_heredoc_x_string_node(node)
|
|
2244
2749
|
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2750
|
+
bounds(node.location)
|
|
2751
|
+
on_xstring_literal(heredoc)
|
|
2752
|
+
else
|
|
2753
|
+
bounds(node.parts.first.location)
|
|
2754
|
+
parts =
|
|
2755
|
+
node.parts.inject(on_xstring_new) do |content, part|
|
|
2756
|
+
on_xstring_add(content, visit_string_content(part))
|
|
2757
|
+
end
|
|
2253
2758
|
|
|
2254
|
-
|
|
2255
|
-
|
|
2759
|
+
bounds(node.location)
|
|
2760
|
+
on_xstring_literal(parts)
|
|
2761
|
+
end
|
|
2256
2762
|
end
|
|
2257
2763
|
end
|
|
2258
2764
|
|
|
@@ -2293,6 +2799,9 @@ module Prism
|
|
|
2293
2799
|
# def foo(**); end
|
|
2294
2800
|
# ^^
|
|
2295
2801
|
def visit_keyword_rest_parameter_node(node)
|
|
2802
|
+
bounds(node.operator_loc)
|
|
2803
|
+
on_op("**")
|
|
2804
|
+
|
|
2296
2805
|
if node.name_loc.nil?
|
|
2297
2806
|
bounds(node.location)
|
|
2298
2807
|
on_kwrest_param(nil)
|
|
@@ -2312,6 +2821,11 @@ module Prism
|
|
|
2312
2821
|
|
|
2313
2822
|
parameters =
|
|
2314
2823
|
if node.parameters.is_a?(BlockParametersNode)
|
|
2824
|
+
if node.parameters.opening_loc
|
|
2825
|
+
bounds(node.parameters.opening_loc)
|
|
2826
|
+
on_lparen("(")
|
|
2827
|
+
end
|
|
2828
|
+
|
|
2315
2829
|
# Ripper does not track block-locals within lambdas, so we skip
|
|
2316
2830
|
# directly to the parameters here.
|
|
2317
2831
|
params =
|
|
@@ -2322,6 +2836,13 @@ module Prism
|
|
|
2322
2836
|
visit(node.parameters.parameters)
|
|
2323
2837
|
end
|
|
2324
2838
|
|
|
2839
|
+
visit_all(node.parameters.locals)
|
|
2840
|
+
|
|
2841
|
+
if node.parameters.closing_loc
|
|
2842
|
+
bounds(node.parameters.closing_loc)
|
|
2843
|
+
on_rparen(")")
|
|
2844
|
+
end
|
|
2845
|
+
|
|
2325
2846
|
if node.parameters.opening_loc.nil?
|
|
2326
2847
|
params
|
|
2327
2848
|
else
|
|
@@ -2334,9 +2855,11 @@ module Prism
|
|
|
2334
2855
|
end
|
|
2335
2856
|
|
|
2336
2857
|
braces = node.opening == "{"
|
|
2858
|
+
bounds(node.opening_loc)
|
|
2337
2859
|
if braces
|
|
2338
|
-
bounds(node.opening_loc)
|
|
2339
2860
|
on_tlambeg(node.opening)
|
|
2861
|
+
else
|
|
2862
|
+
on_kw("do")
|
|
2340
2863
|
end
|
|
2341
2864
|
|
|
2342
2865
|
body =
|
|
@@ -2349,7 +2872,7 @@ module Prism
|
|
|
2349
2872
|
braces ? stmts : on_bodystmt(stmts, nil, nil, nil)
|
|
2350
2873
|
when StatementsNode
|
|
2351
2874
|
stmts = node.body.body
|
|
2352
|
-
stmts
|
|
2875
|
+
stmts = [nil, *stmts] if void_stmt?(node.parameters&.location || node.opening_loc, node.body.location, false)
|
|
2353
2876
|
stmts = visit_statements_node_body(stmts)
|
|
2354
2877
|
|
|
2355
2878
|
bounds(node.body.location)
|
|
@@ -2360,6 +2883,13 @@ module Prism
|
|
|
2360
2883
|
raise
|
|
2361
2884
|
end
|
|
2362
2885
|
|
|
2886
|
+
bounds(node.closing_loc)
|
|
2887
|
+
if braces
|
|
2888
|
+
on_rbrace("}")
|
|
2889
|
+
else
|
|
2890
|
+
on_kw("end")
|
|
2891
|
+
end
|
|
2892
|
+
|
|
2363
2893
|
bounds(node.location)
|
|
2364
2894
|
on_lambda(parameters, body)
|
|
2365
2895
|
end
|
|
@@ -2376,6 +2906,10 @@ module Prism
|
|
|
2376
2906
|
def visit_local_variable_write_node(node)
|
|
2377
2907
|
bounds(node.name_loc)
|
|
2378
2908
|
target = on_var_field(on_ident(node.name_loc.slice))
|
|
2909
|
+
|
|
2910
|
+
bounds(node.operator_loc)
|
|
2911
|
+
on_op("=")
|
|
2912
|
+
|
|
2379
2913
|
value = visit_write_value(node.value)
|
|
2380
2914
|
|
|
2381
2915
|
bounds(node.location)
|
|
@@ -2450,6 +2984,8 @@ module Prism
|
|
|
2450
2984
|
# ^^^^^^^^^^
|
|
2451
2985
|
def visit_match_predicate_node(node)
|
|
2452
2986
|
value = visit(node.value)
|
|
2987
|
+
bounds(node.keyword_loc)
|
|
2988
|
+
on_kw("in")
|
|
2453
2989
|
pattern = on_in(visit_pattern_node(node.pattern), nil, nil)
|
|
2454
2990
|
|
|
2455
2991
|
on_case(value, pattern)
|
|
@@ -2459,6 +2995,10 @@ module Prism
|
|
|
2459
2995
|
# ^^^^^^^^^^
|
|
2460
2996
|
def visit_match_required_node(node)
|
|
2461
2997
|
value = visit(node.value)
|
|
2998
|
+
|
|
2999
|
+
bounds(node.operator_loc)
|
|
3000
|
+
on_op("=>")
|
|
3001
|
+
|
|
2462
3002
|
pattern = on_in(visit_pattern_node(node.pattern), nil, nil)
|
|
2463
3003
|
|
|
2464
3004
|
on_case(value, pattern)
|
|
@@ -2472,13 +3012,16 @@ module Prism
|
|
|
2472
3012
|
|
|
2473
3013
|
# A node that is missing from the syntax tree. This is only used in the
|
|
2474
3014
|
# case of a syntax error.
|
|
2475
|
-
def
|
|
2476
|
-
raise "Cannot visit
|
|
3015
|
+
def visit_error_recovery_node(node)
|
|
3016
|
+
raise "Cannot visit error recovery nodes directly."
|
|
2477
3017
|
end
|
|
2478
3018
|
|
|
2479
3019
|
# module Foo; end
|
|
2480
3020
|
# ^^^^^^^^^^^^^^^
|
|
2481
3021
|
def visit_module_node(node)
|
|
3022
|
+
bounds(node.module_keyword_loc)
|
|
3023
|
+
on_kw("module")
|
|
3024
|
+
|
|
2482
3025
|
constant_path =
|
|
2483
3026
|
if node.constant_path.is_a?(ConstantReadNode)
|
|
2484
3027
|
bounds(node.constant_path.location)
|
|
@@ -2489,6 +3032,9 @@ module Prism
|
|
|
2489
3032
|
|
|
2490
3033
|
bodystmt = visit_body_node(node.constant_path.location, node.body, true)
|
|
2491
3034
|
|
|
3035
|
+
bounds(node.end_keyword_loc)
|
|
3036
|
+
on_kw("end")
|
|
3037
|
+
|
|
2492
3038
|
bounds(node.location)
|
|
2493
3039
|
on_module(constant_path, bodystmt)
|
|
2494
3040
|
end
|
|
@@ -2496,9 +3042,19 @@ module Prism
|
|
|
2496
3042
|
# (foo, bar), bar = qux
|
|
2497
3043
|
# ^^^^^^^^^^
|
|
2498
3044
|
def visit_multi_target_node(node)
|
|
3045
|
+
if node.lparen_loc
|
|
3046
|
+
bounds(node.lparen_loc)
|
|
3047
|
+
on_lparen("(")
|
|
3048
|
+
end
|
|
3049
|
+
|
|
2499
3050
|
bounds(node.location)
|
|
2500
3051
|
targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, true)
|
|
2501
3052
|
|
|
3053
|
+
if node.rparen_loc
|
|
3054
|
+
bounds(node.rparen_loc)
|
|
3055
|
+
on_rparen(")")
|
|
3056
|
+
end
|
|
3057
|
+
|
|
2502
3058
|
if node.lparen_loc.nil?
|
|
2503
3059
|
targets
|
|
2504
3060
|
else
|
|
@@ -2550,9 +3106,22 @@ module Prism
|
|
|
2550
3106
|
# foo, bar = baz
|
|
2551
3107
|
# ^^^^^^^^^^^^^^
|
|
2552
3108
|
def visit_multi_write_node(node)
|
|
3109
|
+
if node.lparen_loc
|
|
3110
|
+
bounds(node.lparen_loc)
|
|
3111
|
+
on_lparen("(")
|
|
3112
|
+
end
|
|
3113
|
+
|
|
2553
3114
|
bounds(node.location)
|
|
2554
3115
|
targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, true)
|
|
2555
3116
|
|
|
3117
|
+
if node.rparen_loc
|
|
3118
|
+
bounds(node.rparen_loc)
|
|
3119
|
+
on_rparen(")")
|
|
3120
|
+
end
|
|
3121
|
+
|
|
3122
|
+
bounds(node.operator_loc)
|
|
3123
|
+
on_op("=")
|
|
3124
|
+
|
|
2556
3125
|
unless node.lparen_loc.nil?
|
|
2557
3126
|
bounds(node.lparen_loc)
|
|
2558
3127
|
targets = on_mlhs_paren(targets)
|
|
@@ -2570,6 +3139,9 @@ module Prism
|
|
|
2570
3139
|
# next foo
|
|
2571
3140
|
# ^^^^^^^^
|
|
2572
3141
|
def visit_next_node(node)
|
|
3142
|
+
bounds(node.keyword_loc)
|
|
3143
|
+
on_kw("next")
|
|
3144
|
+
|
|
2573
3145
|
if node.arguments.nil?
|
|
2574
3146
|
bounds(node.location)
|
|
2575
3147
|
on_next(on_args_new)
|
|
@@ -2588,9 +3160,24 @@ module Prism
|
|
|
2588
3160
|
on_var_ref(on_kw("nil"))
|
|
2589
3161
|
end
|
|
2590
3162
|
|
|
3163
|
+
# def foo(&nil); end
|
|
3164
|
+
# ^^^^
|
|
3165
|
+
def visit_no_block_parameter_node(node)
|
|
3166
|
+
bounds(node.operator_loc)
|
|
3167
|
+
on_op("&")
|
|
3168
|
+
bounds(node.keyword_loc)
|
|
3169
|
+
on_kw("nil")
|
|
3170
|
+
bounds(node.location)
|
|
3171
|
+
on_blockarg(:nil)
|
|
3172
|
+
end
|
|
3173
|
+
|
|
2591
3174
|
# def foo(**nil); end
|
|
2592
3175
|
# ^^^^^
|
|
2593
3176
|
def visit_no_keywords_parameter_node(node)
|
|
3177
|
+
bounds(node.operator_loc)
|
|
3178
|
+
on_op("**")
|
|
3179
|
+
bounds(node.keyword_loc)
|
|
3180
|
+
on_kw("nil")
|
|
2594
3181
|
bounds(node.location)
|
|
2595
3182
|
on_nokw_param(nil)
|
|
2596
3183
|
|
|
@@ -2623,7 +3210,11 @@ module Prism
|
|
|
2623
3210
|
# ^^^^^^^
|
|
2624
3211
|
def visit_optional_parameter_node(node)
|
|
2625
3212
|
bounds(node.name_loc)
|
|
2626
|
-
name =
|
|
3213
|
+
name = on_ident(node.name.to_s)
|
|
3214
|
+
|
|
3215
|
+
bounds(node.operator_loc)
|
|
3216
|
+
on_op("=")
|
|
3217
|
+
|
|
2627
3218
|
value = visit(node.value)
|
|
2628
3219
|
|
|
2629
3220
|
[name, value]
|
|
@@ -2633,6 +3224,14 @@ module Prism
|
|
|
2633
3224
|
# ^^^^^^
|
|
2634
3225
|
def visit_or_node(node)
|
|
2635
3226
|
left = visit(node.left)
|
|
3227
|
+
|
|
3228
|
+
bounds(node.operator_loc)
|
|
3229
|
+
if node.operator == "or"
|
|
3230
|
+
on_kw("or")
|
|
3231
|
+
else
|
|
3232
|
+
on_op("||")
|
|
3233
|
+
end
|
|
3234
|
+
|
|
2636
3235
|
right = visit(node.right)
|
|
2637
3236
|
|
|
2638
3237
|
bounds(node.location)
|
|
@@ -2656,9 +3255,19 @@ module Prism
|
|
|
2656
3255
|
|
|
2657
3256
|
# Visit a destructured positional parameter node.
|
|
2658
3257
|
private def visit_destructured_parameter_node(node)
|
|
3258
|
+
if node.lparen_loc
|
|
3259
|
+
bounds(node.lparen_loc)
|
|
3260
|
+
on_lparen("(")
|
|
3261
|
+
end
|
|
3262
|
+
|
|
2659
3263
|
bounds(node.location)
|
|
2660
3264
|
targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, false)
|
|
2661
3265
|
|
|
3266
|
+
if node.rparen_loc
|
|
3267
|
+
bounds(node.rparen_loc)
|
|
3268
|
+
on_rparen(")")
|
|
3269
|
+
end
|
|
3270
|
+
|
|
2662
3271
|
bounds(node.lparen_loc)
|
|
2663
3272
|
on_mlhs_paren(targets)
|
|
2664
3273
|
end
|
|
@@ -2669,6 +3278,9 @@ module Prism
|
|
|
2669
3278
|
# (1)
|
|
2670
3279
|
# ^^^
|
|
2671
3280
|
def visit_parentheses_node(node)
|
|
3281
|
+
bounds(node.opening_loc)
|
|
3282
|
+
on_lparen("(")
|
|
3283
|
+
|
|
2672
3284
|
body =
|
|
2673
3285
|
if node.body.nil?
|
|
2674
3286
|
on_stmts_add(on_stmts_new, on_void_stmt)
|
|
@@ -2676,6 +3288,8 @@ module Prism
|
|
|
2676
3288
|
visit(node.body)
|
|
2677
3289
|
end
|
|
2678
3290
|
|
|
3291
|
+
bounds(node.closing_loc)
|
|
3292
|
+
on_rparen(")")
|
|
2679
3293
|
bounds(node.location)
|
|
2680
3294
|
on_paren(body)
|
|
2681
3295
|
end
|
|
@@ -2683,8 +3297,15 @@ module Prism
|
|
|
2683
3297
|
# foo => ^(bar)
|
|
2684
3298
|
# ^^^^^^
|
|
2685
3299
|
def visit_pinned_expression_node(node)
|
|
3300
|
+
bounds(node.operator_loc)
|
|
3301
|
+
on_op("^")
|
|
3302
|
+
bounds(node.lparen_loc)
|
|
3303
|
+
on_lparen("(")
|
|
3304
|
+
|
|
2686
3305
|
expression = visit(node.expression)
|
|
2687
3306
|
|
|
3307
|
+
bounds(node.rparen_loc)
|
|
3308
|
+
on_rparen(")")
|
|
2688
3309
|
bounds(node.location)
|
|
2689
3310
|
on_begin(expression)
|
|
2690
3311
|
end
|
|
@@ -2692,12 +3313,20 @@ module Prism
|
|
|
2692
3313
|
# foo = 1 and bar => ^foo
|
|
2693
3314
|
# ^^^^
|
|
2694
3315
|
def visit_pinned_variable_node(node)
|
|
3316
|
+
bounds(node.operator_loc)
|
|
3317
|
+
on_op("^")
|
|
3318
|
+
|
|
2695
3319
|
visit(node.variable)
|
|
2696
3320
|
end
|
|
2697
3321
|
|
|
2698
3322
|
# END {}
|
|
2699
3323
|
# ^^^^^^
|
|
2700
3324
|
def visit_post_execution_node(node)
|
|
3325
|
+
bounds(node.keyword_loc)
|
|
3326
|
+
on_kw("END")
|
|
3327
|
+
bounds(node.opening_loc)
|
|
3328
|
+
on_lbrace("{")
|
|
3329
|
+
|
|
2701
3330
|
statements =
|
|
2702
3331
|
if node.statements.nil?
|
|
2703
3332
|
bounds(node.location)
|
|
@@ -2706,6 +3335,8 @@ module Prism
|
|
|
2706
3335
|
visit(node.statements)
|
|
2707
3336
|
end
|
|
2708
3337
|
|
|
3338
|
+
bounds(node.closing_loc)
|
|
3339
|
+
on_rbrace("}")
|
|
2709
3340
|
bounds(node.location)
|
|
2710
3341
|
on_END(statements)
|
|
2711
3342
|
end
|
|
@@ -2713,6 +3344,11 @@ module Prism
|
|
|
2713
3344
|
# BEGIN {}
|
|
2714
3345
|
# ^^^^^^^^
|
|
2715
3346
|
def visit_pre_execution_node(node)
|
|
3347
|
+
bounds(node.keyword_loc)
|
|
3348
|
+
on_kw("BEGIN")
|
|
3349
|
+
bounds(node.opening_loc)
|
|
3350
|
+
on_lbrace("{")
|
|
3351
|
+
|
|
2716
3352
|
statements =
|
|
2717
3353
|
if node.statements.nil?
|
|
2718
3354
|
bounds(node.location)
|
|
@@ -2721,6 +3357,8 @@ module Prism
|
|
|
2721
3357
|
visit(node.statements)
|
|
2722
3358
|
end
|
|
2723
3359
|
|
|
3360
|
+
bounds(node.closing_loc)
|
|
3361
|
+
on_rbrace("}")
|
|
2724
3362
|
bounds(node.location)
|
|
2725
3363
|
on_BEGIN(statements)
|
|
2726
3364
|
end
|
|
@@ -2728,7 +3366,7 @@ module Prism
|
|
|
2728
3366
|
# The top-level program node.
|
|
2729
3367
|
def visit_program_node(node)
|
|
2730
3368
|
body = node.statements.body
|
|
2731
|
-
body
|
|
3369
|
+
body = [nil] if body.empty?
|
|
2732
3370
|
statements = visit_statements_node_body(body)
|
|
2733
3371
|
|
|
2734
3372
|
bounds(node.location)
|
|
@@ -2739,6 +3377,10 @@ module Prism
|
|
|
2739
3377
|
# ^^^^
|
|
2740
3378
|
def visit_range_node(node)
|
|
2741
3379
|
left = visit(node.left)
|
|
3380
|
+
|
|
3381
|
+
bounds(node.operator_loc)
|
|
3382
|
+
on_op(node.operator)
|
|
3383
|
+
|
|
2742
3384
|
right = visit(node.right)
|
|
2743
3385
|
|
|
2744
3386
|
bounds(node.location)
|
|
@@ -2759,6 +3401,7 @@ module Prism
|
|
|
2759
3401
|
# ^^^^
|
|
2760
3402
|
def visit_redo_node(node)
|
|
2761
3403
|
bounds(node.location)
|
|
3404
|
+
on_kw("redo")
|
|
2762
3405
|
on_redo
|
|
2763
3406
|
end
|
|
2764
3407
|
|
|
@@ -2801,6 +3444,9 @@ module Prism
|
|
|
2801
3444
|
# foo rescue bar
|
|
2802
3445
|
# ^^^^^^^^^^^^^^
|
|
2803
3446
|
def visit_rescue_modifier_node(node)
|
|
3447
|
+
bounds(node.keyword_loc)
|
|
3448
|
+
on_kw("rescue")
|
|
3449
|
+
|
|
2804
3450
|
expression = visit_write_value(node.expression)
|
|
2805
3451
|
rescue_expression = visit(node.rescue_expression)
|
|
2806
3452
|
|
|
@@ -2811,6 +3457,9 @@ module Prism
|
|
|
2811
3457
|
# begin; rescue; end
|
|
2812
3458
|
# ^^^^^^^
|
|
2813
3459
|
def visit_rescue_node(node)
|
|
3460
|
+
bounds(node.keyword_loc)
|
|
3461
|
+
on_kw("rescue")
|
|
3462
|
+
|
|
2814
3463
|
exceptions =
|
|
2815
3464
|
case node.exceptions.length
|
|
2816
3465
|
when 0
|
|
@@ -2848,6 +3497,11 @@ module Prism
|
|
|
2848
3497
|
end
|
|
2849
3498
|
end
|
|
2850
3499
|
|
|
3500
|
+
if node.operator_loc
|
|
3501
|
+
bounds(node.operator_loc)
|
|
3502
|
+
on_op("=>")
|
|
3503
|
+
end
|
|
3504
|
+
|
|
2851
3505
|
reference = visit(node.reference)
|
|
2852
3506
|
statements =
|
|
2853
3507
|
if node.statements.nil?
|
|
@@ -2869,12 +3523,15 @@ module Prism
|
|
|
2869
3523
|
# def foo(*); end
|
|
2870
3524
|
# ^
|
|
2871
3525
|
def visit_rest_parameter_node(node)
|
|
3526
|
+
bounds(node.operator_loc)
|
|
3527
|
+
on_op("*")
|
|
3528
|
+
|
|
2872
3529
|
if node.name_loc.nil?
|
|
2873
3530
|
bounds(node.location)
|
|
2874
3531
|
on_rest_param(nil)
|
|
2875
3532
|
else
|
|
2876
3533
|
bounds(node.name_loc)
|
|
2877
|
-
on_rest_param(
|
|
3534
|
+
on_rest_param(on_ident(node.name.to_s))
|
|
2878
3535
|
end
|
|
2879
3536
|
end
|
|
2880
3537
|
|
|
@@ -2882,6 +3539,7 @@ module Prism
|
|
|
2882
3539
|
# ^^^^^
|
|
2883
3540
|
def visit_retry_node(node)
|
|
2884
3541
|
bounds(node.location)
|
|
3542
|
+
on_kw("retry")
|
|
2885
3543
|
on_retry
|
|
2886
3544
|
end
|
|
2887
3545
|
|
|
@@ -2891,6 +3549,9 @@ module Prism
|
|
|
2891
3549
|
# return 1
|
|
2892
3550
|
# ^^^^^^^^
|
|
2893
3551
|
def visit_return_node(node)
|
|
3552
|
+
bounds(node.keyword_loc)
|
|
3553
|
+
on_kw("return")
|
|
3554
|
+
|
|
2894
3555
|
if node.arguments.nil?
|
|
2895
3556
|
bounds(node.location)
|
|
2896
3557
|
on_return0
|
|
@@ -2917,9 +3578,17 @@ module Prism
|
|
|
2917
3578
|
# class << self; end
|
|
2918
3579
|
# ^^^^^^^^^^^^^^^^^^
|
|
2919
3580
|
def visit_singleton_class_node(node)
|
|
3581
|
+
bounds(node.class_keyword_loc)
|
|
3582
|
+
on_kw("class")
|
|
3583
|
+
bounds(node.operator_loc)
|
|
3584
|
+
on_op("<<")
|
|
3585
|
+
|
|
2920
3586
|
expression = visit(node.expression)
|
|
2921
3587
|
bodystmt = visit_body_node(node.body&.location || node.end_keyword_loc, node.body)
|
|
2922
3588
|
|
|
3589
|
+
bounds(node.end_keyword_loc)
|
|
3590
|
+
on_kw("end")
|
|
3591
|
+
|
|
2923
3592
|
bounds(node.location)
|
|
2924
3593
|
on_sclass(expression, bodystmt)
|
|
2925
3594
|
end
|
|
@@ -2954,6 +3623,8 @@ module Prism
|
|
|
2954
3623
|
# def foo(*); bar(*); end
|
|
2955
3624
|
# ^
|
|
2956
3625
|
def visit_splat_node(node)
|
|
3626
|
+
bounds(node.operator_loc)
|
|
3627
|
+
on_op("*")
|
|
2957
3628
|
visit(node.expression)
|
|
2958
3629
|
end
|
|
2959
3630
|
|
|
@@ -2976,24 +3647,66 @@ module Prism
|
|
|
2976
3647
|
# "foo"
|
|
2977
3648
|
# ^^^^^
|
|
2978
3649
|
def visit_string_node(node)
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
3650
|
+
with_string_bounds(node) do
|
|
3651
|
+
if (content = node.content).empty?
|
|
3652
|
+
bounds(node.location)
|
|
3653
|
+
on_string_literal(on_string_content)
|
|
3654
|
+
elsif (opening = node.opening) == "?"
|
|
3655
|
+
bounds(node.location)
|
|
3656
|
+
on_CHAR("?#{node.content}")
|
|
3657
|
+
elsif opening.start_with?("<<~")
|
|
3658
|
+
heredoc = visit_heredoc_string_node(node.to_interpolated)
|
|
2987
3659
|
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
3660
|
+
bounds(node.location)
|
|
3661
|
+
on_string_literal(heredoc)
|
|
3662
|
+
else
|
|
3663
|
+
bounds(node.content_loc)
|
|
3664
|
+
tstring_content = on_tstring_content(content)
|
|
2993
3665
|
|
|
2994
|
-
|
|
2995
|
-
|
|
3666
|
+
bounds(node.location)
|
|
3667
|
+
on_string_literal(on_string_add(on_string_content, tstring_content))
|
|
3668
|
+
end
|
|
3669
|
+
end
|
|
3670
|
+
end
|
|
3671
|
+
|
|
3672
|
+
# Responsible for emitting the various string-like begin/end events
|
|
3673
|
+
private def with_string_bounds(node)
|
|
3674
|
+
# `foo "bar": baz` doesn't emit the closing location
|
|
3675
|
+
assoc = !(opening = node.opening)&.include?(":") && node.closing&.end_with?(":")
|
|
3676
|
+
|
|
3677
|
+
is_heredoc = opening&.start_with?("<<")
|
|
3678
|
+
if is_heredoc
|
|
3679
|
+
bounds(node.opening_loc)
|
|
3680
|
+
on_heredoc_beg(node.opening)
|
|
3681
|
+
elsif opening&.start_with?(":", "%s")
|
|
3682
|
+
bounds(node.opening_loc)
|
|
3683
|
+
on_symbeg(node.opening)
|
|
3684
|
+
elsif opening&.start_with?("`", "%x")
|
|
3685
|
+
bounds(node.opening_loc)
|
|
3686
|
+
on_backtick(node.opening)
|
|
3687
|
+
elsif opening && !opening.start_with?("?")
|
|
3688
|
+
bounds(node.opening_loc)
|
|
3689
|
+
on_tstring_beg(opening)
|
|
3690
|
+
end
|
|
3691
|
+
|
|
3692
|
+
result = yield
|
|
3693
|
+
if assoc
|
|
3694
|
+
if node.closing != ":"
|
|
3695
|
+
bounds(node.closing_loc)
|
|
3696
|
+
on_label_end(node.closing)
|
|
3697
|
+
end
|
|
3698
|
+
return result
|
|
2996
3699
|
end
|
|
3700
|
+
|
|
3701
|
+
if is_heredoc
|
|
3702
|
+
bounds(node.closing_loc)
|
|
3703
|
+
on_heredoc_end(node.closing)
|
|
3704
|
+
elsif node.closing_loc
|
|
3705
|
+
bounds(node.closing_loc)
|
|
3706
|
+
on_tstring_end(node.closing)
|
|
3707
|
+
end
|
|
3708
|
+
|
|
3709
|
+
result
|
|
2997
3710
|
end
|
|
2998
3711
|
|
|
2999
3712
|
# Ripper gives back the escaped string content but strips out the common
|
|
@@ -3073,42 +3786,39 @@ module Prism
|
|
|
3073
3786
|
|
|
3074
3787
|
# Visit a heredoc node that is representing a string.
|
|
3075
3788
|
private def visit_heredoc_string_node(node)
|
|
3076
|
-
bounds(node.opening_loc)
|
|
3077
|
-
on_heredoc_beg(node.opening)
|
|
3078
|
-
|
|
3079
3789
|
bounds(node.location)
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
end
|
|
3084
|
-
|
|
3085
|
-
bounds(node.closing_loc)
|
|
3086
|
-
on_heredoc_end(node.closing)
|
|
3087
|
-
|
|
3088
|
-
result
|
|
3790
|
+
visit_heredoc_node(node.parts, on_string_content) do |parts, part|
|
|
3791
|
+
on_string_add(parts, part)
|
|
3792
|
+
end
|
|
3089
3793
|
end
|
|
3090
3794
|
|
|
3091
3795
|
# Visit a heredoc node that is representing an xstring.
|
|
3092
3796
|
private def visit_heredoc_x_string_node(node)
|
|
3093
|
-
bounds(node.opening_loc)
|
|
3094
|
-
on_heredoc_beg(node.opening)
|
|
3095
|
-
|
|
3096
3797
|
bounds(node.location)
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
end
|
|
3101
|
-
|
|
3102
|
-
bounds(node.closing_loc)
|
|
3103
|
-
on_heredoc_end(node.closing)
|
|
3104
|
-
|
|
3105
|
-
result
|
|
3798
|
+
visit_heredoc_node(node.parts, on_xstring_new) do |parts, part|
|
|
3799
|
+
on_xstring_add(parts, part)
|
|
3800
|
+
end
|
|
3106
3801
|
end
|
|
3107
3802
|
|
|
3108
3803
|
# super(foo)
|
|
3109
3804
|
# ^^^^^^^^^^
|
|
3110
3805
|
def visit_super_node(node)
|
|
3111
|
-
|
|
3806
|
+
bounds(node.keyword_loc)
|
|
3807
|
+
on_kw("super")
|
|
3808
|
+
|
|
3809
|
+
if node.lparen_loc
|
|
3810
|
+
bounds(node.lparen_loc)
|
|
3811
|
+
on_lparen("(")
|
|
3812
|
+
end
|
|
3813
|
+
|
|
3814
|
+
arguments, block_node = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.rparen_loc || node.location))
|
|
3815
|
+
|
|
3816
|
+
if node.rparen_loc
|
|
3817
|
+
bounds(node.rparen_loc)
|
|
3818
|
+
on_rparen(")")
|
|
3819
|
+
end
|
|
3820
|
+
|
|
3821
|
+
block = visit(block_node)
|
|
3112
3822
|
|
|
3113
3823
|
if !node.lparen_loc.nil?
|
|
3114
3824
|
bounds(node.lparen_loc)
|
|
@@ -3118,35 +3828,38 @@ module Prism
|
|
|
3118
3828
|
bounds(node.location)
|
|
3119
3829
|
call = on_super(arguments)
|
|
3120
3830
|
|
|
3121
|
-
if
|
|
3122
|
-
call
|
|
3123
|
-
else
|
|
3831
|
+
if block_node
|
|
3124
3832
|
bounds(node.block.location)
|
|
3125
3833
|
on_method_add_block(call, block)
|
|
3834
|
+
else
|
|
3835
|
+
call
|
|
3126
3836
|
end
|
|
3127
3837
|
end
|
|
3128
3838
|
|
|
3129
3839
|
# :foo
|
|
3130
3840
|
# ^^^^
|
|
3131
3841
|
def visit_symbol_node(node)
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3842
|
+
with_string_bounds(node) do
|
|
3843
|
+
if (opening = node.opening)&.match?(/^%s|['"]:?$/)
|
|
3844
|
+
bounds(node.content_loc)
|
|
3845
|
+
content = on_string_content
|
|
3135
3846
|
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3847
|
+
if !(value = node.content).empty?
|
|
3848
|
+
content = on_string_add(content, on_tstring_content(value))
|
|
3849
|
+
end
|
|
3139
3850
|
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3851
|
+
bounds(node.location)
|
|
3852
|
+
on_dyna_symbol(content)
|
|
3853
|
+
elsif (closing = node.closing) == ":"
|
|
3854
|
+
bounds(node.location)
|
|
3855
|
+
on_label("#{node.content}:")
|
|
3856
|
+
elsif opening.nil? && node.closing_loc.nil?
|
|
3857
|
+
bounds(node.content_loc)
|
|
3858
|
+
on_symbol_literal(visit_token(node.content))
|
|
3859
|
+
else
|
|
3860
|
+
bounds(node.content_loc)
|
|
3861
|
+
on_symbol_literal(on_symbol(visit_token(node.content)))
|
|
3862
|
+
end
|
|
3150
3863
|
end
|
|
3151
3864
|
end
|
|
3152
3865
|
|
|
@@ -3160,6 +3873,9 @@ module Prism
|
|
|
3160
3873
|
# undef foo
|
|
3161
3874
|
# ^^^^^^^^^
|
|
3162
3875
|
def visit_undef_node(node)
|
|
3876
|
+
bounds(node.keyword_loc)
|
|
3877
|
+
on_kw("undef")
|
|
3878
|
+
|
|
3163
3879
|
names = visit_all(node.names)
|
|
3164
3880
|
|
|
3165
3881
|
bounds(node.location)
|
|
@@ -3173,7 +3889,13 @@ module Prism
|
|
|
3173
3889
|
# ^^^^^^^^^^^^^^
|
|
3174
3890
|
def visit_unless_node(node)
|
|
3175
3891
|
if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset)
|
|
3892
|
+
bounds(node.unless_keyword_loc)
|
|
3893
|
+
on_kw("unless")
|
|
3176
3894
|
predicate = visit(node.predicate)
|
|
3895
|
+
if node.then_keyword_loc
|
|
3896
|
+
bounds(node.then_keyword_loc)
|
|
3897
|
+
on_kw("then")
|
|
3898
|
+
end
|
|
3177
3899
|
statements =
|
|
3178
3900
|
if node.statements.nil?
|
|
3179
3901
|
bounds(node.location)
|
|
@@ -3183,10 +3905,17 @@ module Prism
|
|
|
3183
3905
|
end
|
|
3184
3906
|
else_clause = visit(node.else_clause)
|
|
3185
3907
|
|
|
3908
|
+
if node.end_keyword_loc && !node.else_clause
|
|
3909
|
+
bounds(node.end_keyword_loc)
|
|
3910
|
+
on_kw("end")
|
|
3911
|
+
end
|
|
3912
|
+
|
|
3186
3913
|
bounds(node.location)
|
|
3187
3914
|
on_unless(predicate, statements, else_clause)
|
|
3188
3915
|
else
|
|
3189
3916
|
statements = visit(node.statements.body.first)
|
|
3917
|
+
bounds(node.unless_keyword_loc)
|
|
3918
|
+
on_kw("unless")
|
|
3190
3919
|
predicate = visit(node.predicate)
|
|
3191
3920
|
|
|
3192
3921
|
bounds(node.location)
|
|
@@ -3200,7 +3929,14 @@ module Prism
|
|
|
3200
3929
|
# bar until foo
|
|
3201
3930
|
# ^^^^^^^^^^^^^
|
|
3202
3931
|
def visit_until_node(node)
|
|
3932
|
+
bounds(node.until_keyword_loc)
|
|
3933
|
+
on_kw("until")
|
|
3934
|
+
|
|
3203
3935
|
if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset)
|
|
3936
|
+
if node.do_keyword_loc
|
|
3937
|
+
bounds(node.do_keyword_loc)
|
|
3938
|
+
on_kw("do")
|
|
3939
|
+
end
|
|
3204
3940
|
predicate = visit(node.predicate)
|
|
3205
3941
|
statements =
|
|
3206
3942
|
if node.statements.nil?
|
|
@@ -3210,6 +3946,11 @@ module Prism
|
|
|
3210
3946
|
visit(node.statements)
|
|
3211
3947
|
end
|
|
3212
3948
|
|
|
3949
|
+
if node.end_keyword_loc
|
|
3950
|
+
bounds(node.end_keyword_loc)
|
|
3951
|
+
on_kw("end")
|
|
3952
|
+
end
|
|
3953
|
+
|
|
3213
3954
|
bounds(node.location)
|
|
3214
3955
|
on_until(predicate, statements)
|
|
3215
3956
|
else
|
|
@@ -3227,7 +3968,14 @@ module Prism
|
|
|
3227
3968
|
# This is a special case where we're not going to call on_when directly
|
|
3228
3969
|
# because we don't have access to the subsequent. Instead, we'll return
|
|
3229
3970
|
# the component parts and let the parent node handle it.
|
|
3971
|
+
bounds(node.when_keyword_loc)
|
|
3972
|
+
on_kw("when")
|
|
3973
|
+
|
|
3230
3974
|
conditions = visit_arguments(node.conditions)
|
|
3975
|
+
if node.then_keyword_loc
|
|
3976
|
+
bounds(node.then_keyword_loc)
|
|
3977
|
+
on_kw("then")
|
|
3978
|
+
end
|
|
3231
3979
|
statements =
|
|
3232
3980
|
if node.statements.nil?
|
|
3233
3981
|
bounds(node.location)
|
|
@@ -3246,7 +3994,17 @@ module Prism
|
|
|
3246
3994
|
# ^^^^^^^^^^^^^
|
|
3247
3995
|
def visit_while_node(node)
|
|
3248
3996
|
if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset)
|
|
3997
|
+
bounds(node.while_keyword_loc)
|
|
3998
|
+
on_kw("while")
|
|
3999
|
+
if node.do_keyword_loc
|
|
4000
|
+
bounds(node.do_keyword_loc)
|
|
4001
|
+
on_kw("do")
|
|
4002
|
+
end
|
|
3249
4003
|
predicate = visit(node.predicate)
|
|
4004
|
+
if node.end_keyword_loc
|
|
4005
|
+
bounds(node.end_keyword_loc)
|
|
4006
|
+
on_kw("end")
|
|
4007
|
+
end
|
|
3250
4008
|
statements =
|
|
3251
4009
|
if node.statements.nil?
|
|
3252
4010
|
bounds(node.location)
|
|
@@ -3259,6 +4017,8 @@ module Prism
|
|
|
3259
4017
|
on_while(predicate, statements)
|
|
3260
4018
|
else
|
|
3261
4019
|
statements = visit(node.statements.body.first)
|
|
4020
|
+
bounds(node.while_keyword_loc)
|
|
4021
|
+
on_kw("while")
|
|
3262
4022
|
predicate = visit(node.predicate)
|
|
3263
4023
|
|
|
3264
4024
|
bounds(node.location)
|
|
@@ -3269,20 +4029,22 @@ module Prism
|
|
|
3269
4029
|
# `foo`
|
|
3270
4030
|
# ^^^^^
|
|
3271
4031
|
def visit_x_string_node(node)
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
4032
|
+
with_string_bounds(node) do
|
|
4033
|
+
if node.unescaped.empty?
|
|
4034
|
+
bounds(node.location)
|
|
4035
|
+
on_xstring_literal(on_xstring_new)
|
|
4036
|
+
elsif node.opening.start_with?("<<~")
|
|
4037
|
+
heredoc = visit_heredoc_x_string_node(node.to_interpolated)
|
|
3277
4038
|
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
4039
|
+
bounds(node.location)
|
|
4040
|
+
on_xstring_literal(heredoc)
|
|
4041
|
+
else
|
|
4042
|
+
bounds(node.content_loc)
|
|
4043
|
+
content = on_tstring_content(node.content)
|
|
3283
4044
|
|
|
3284
|
-
|
|
3285
|
-
|
|
4045
|
+
bounds(node.location)
|
|
4046
|
+
on_xstring_literal(on_xstring_add(on_xstring_new, content))
|
|
4047
|
+
end
|
|
3286
4048
|
end
|
|
3287
4049
|
end
|
|
3288
4050
|
|
|
@@ -3292,10 +4054,18 @@ module Prism
|
|
|
3292
4054
|
# yield 1
|
|
3293
4055
|
# ^^^^^^^
|
|
3294
4056
|
def visit_yield_node(node)
|
|
4057
|
+
bounds(node.keyword_loc)
|
|
4058
|
+
on_kw("yield")
|
|
4059
|
+
|
|
3295
4060
|
if node.arguments.nil? && node.lparen_loc.nil?
|
|
3296
4061
|
bounds(node.location)
|
|
3297
4062
|
on_yield0
|
|
3298
4063
|
else
|
|
4064
|
+
if node.lparen_loc
|
|
4065
|
+
bounds(node.lparen_loc)
|
|
4066
|
+
on_lparen("(")
|
|
4067
|
+
end
|
|
4068
|
+
|
|
3299
4069
|
arguments =
|
|
3300
4070
|
if node.arguments.nil?
|
|
3301
4071
|
bounds(node.location)
|
|
@@ -3305,6 +4075,8 @@ module Prism
|
|
|
3305
4075
|
end
|
|
3306
4076
|
|
|
3307
4077
|
unless node.lparen_loc.nil?
|
|
4078
|
+
bounds(node.rparen_loc)
|
|
4079
|
+
on_rparen(")")
|
|
3308
4080
|
bounds(node.lparen_loc)
|
|
3309
4081
|
arguments = on_paren(arguments)
|
|
3310
4082
|
end
|
|
@@ -3318,7 +4090,11 @@ module Prism
|
|
|
3318
4090
|
|
|
3319
4091
|
# Lazily initialize the parse result.
|
|
3320
4092
|
def result
|
|
3321
|
-
@result ||= Prism.parse(source, partial_script: true, version: "current")
|
|
4093
|
+
@result ||= Prism.parse(source, partial_script: true, version: "current", freeze: true, encoding: source.encoding)
|
|
4094
|
+
end
|
|
4095
|
+
|
|
4096
|
+
def line_and_column_cache
|
|
4097
|
+
@line_and_column_cache ||= LineAndColumnCache.new(result.source)
|
|
3322
4098
|
end
|
|
3323
4099
|
|
|
3324
4100
|
##########################################################################
|
|
@@ -3339,30 +4115,34 @@ module Prism
|
|
|
3339
4115
|
# Visit the string content of a particular node. This method is used to
|
|
3340
4116
|
# split into the various token types.
|
|
3341
4117
|
def visit_token(token, allow_keywords = true)
|
|
3342
|
-
|
|
3343
|
-
when "."
|
|
4118
|
+
if token == "."
|
|
3344
4119
|
on_period(token)
|
|
3345
|
-
|
|
4120
|
+
elsif token == "`"
|
|
3346
4121
|
on_backtick(token)
|
|
3347
|
-
|
|
4122
|
+
elsif allow_keywords && KEYWORDS.include?(token)
|
|
3348
4123
|
on_kw(token)
|
|
3349
|
-
|
|
4124
|
+
elsif token.start_with?("_")
|
|
3350
4125
|
on_ident(token)
|
|
3351
|
-
|
|
4126
|
+
elsif token.match?(/^[[:upper:]]\w*$/)
|
|
3352
4127
|
on_const(token)
|
|
3353
|
-
|
|
4128
|
+
elsif token.start_with?("@@")
|
|
3354
4129
|
on_cvar(token)
|
|
3355
|
-
|
|
4130
|
+
elsif token.start_with?("@")
|
|
3356
4131
|
on_ivar(token)
|
|
3357
|
-
|
|
4132
|
+
elsif token.start_with?("$")
|
|
3358
4133
|
on_gvar(token)
|
|
3359
|
-
|
|
4134
|
+
elsif token.match?(/^[[:punct:]]/)
|
|
3360
4135
|
on_op(token)
|
|
3361
4136
|
else
|
|
3362
4137
|
on_ident(token)
|
|
3363
4138
|
end
|
|
3364
4139
|
end
|
|
3365
4140
|
|
|
4141
|
+
# Visit either `.`, `&.`, or `::`.
|
|
4142
|
+
def visit_call_operator(token)
|
|
4143
|
+
token == "." ? on_period(token) : on_op(token)
|
|
4144
|
+
end
|
|
4145
|
+
|
|
3366
4146
|
# Visit a node that represents a number. We need to explicitly handle the
|
|
3367
4147
|
# unary - operator.
|
|
3368
4148
|
def visit_number_node(node)
|
|
@@ -3370,6 +4150,9 @@ module Prism
|
|
|
3370
4150
|
location = node.location
|
|
3371
4151
|
|
|
3372
4152
|
if slice[0] == "-"
|
|
4153
|
+
bounds(location.copy(length: 1))
|
|
4154
|
+
on_op("-")
|
|
4155
|
+
|
|
3373
4156
|
bounds(location.copy(start_offset: location.start_offset + 1))
|
|
3374
4157
|
value = yield slice[1..-1]
|
|
3375
4158
|
|
|
@@ -3418,26 +4201,24 @@ module Prism
|
|
|
3418
4201
|
|
|
3419
4202
|
# This method is responsible for updating lineno and column information
|
|
3420
4203
|
# to reflect the current node.
|
|
3421
|
-
#
|
|
3422
|
-
# This method could be drastically improved with some caching on the start
|
|
3423
|
-
# of every line, but for now it's good enough.
|
|
3424
4204
|
def bounds(location)
|
|
3425
|
-
@lineno = location.
|
|
3426
|
-
@column = location.start_column
|
|
4205
|
+
@lineno, @column = line_and_column_cache.line_and_column(location.start_offset)
|
|
3427
4206
|
end
|
|
3428
4207
|
|
|
4208
|
+
# :startdoc:
|
|
4209
|
+
|
|
3429
4210
|
##########################################################################
|
|
3430
4211
|
# Ripper interface
|
|
3431
4212
|
##########################################################################
|
|
3432
4213
|
|
|
3433
4214
|
# :stopdoc:
|
|
3434
4215
|
def _dispatch_0; end
|
|
3435
|
-
def _dispatch_1(
|
|
3436
|
-
def _dispatch_2(
|
|
3437
|
-
def _dispatch_3(
|
|
3438
|
-
def _dispatch_4(
|
|
3439
|
-
def _dispatch_5(
|
|
3440
|
-
def _dispatch_7(
|
|
4216
|
+
def _dispatch_1(arg); arg end
|
|
4217
|
+
def _dispatch_2(arg, _); arg end
|
|
4218
|
+
def _dispatch_3(arg, _, _); arg end
|
|
4219
|
+
def _dispatch_4(arg, _, _, _); arg end
|
|
4220
|
+
def _dispatch_5(arg, _, _, _, _); arg end
|
|
4221
|
+
def _dispatch_7(arg, _, _, _, _, _, _); arg end
|
|
3441
4222
|
# :startdoc:
|
|
3442
4223
|
|
|
3443
4224
|
#
|