prism 1.9.0 → 2.0.0.rc2
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 +88 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/LICENSE.md +1 -1
- data/Makefile +41 -12
- data/README.md +35 -97
- data/config.yml +174 -161
- 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/serialization.md +22 -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 +796 -422
- data/ext/prism/extension.h +3 -3
- data/include/prism/arena.h +37 -0
- data/include/prism/ast.h +2727 -610
- data/include/prism/buffer.h +52 -0
- data/include/prism/comments.h +55 -0
- data/include/prism/compiler/accel.h +26 -0
- data/include/prism/compiler/align.h +36 -0
- data/include/prism/compiler/assume.h +25 -0
- data/include/prism/compiler/bswap.h +46 -0
- data/include/prism/compiler/endianness.h +34 -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 -403
- 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 +94 -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 +1004 -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/internal/xxh3.h +16 -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 +356 -867
- 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 +74 -0
- data/include/prism/stringy.h +72 -0
- data/include/prism/version.h +12 -3
- 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 +258 -90
- data/lib/prism/inspect_visitor.rb +357 -325
- data/lib/prism/lex_compat.rb +254 -212
- data/lib/prism/mutation_compiler.rb +313 -305
- data/lib/prism/node.rb +20966 -6992
- 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 +468 -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 +3460 -539
- data/lib/prism/string_query.rb +24 -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/lexer.rb +8 -10
- data/lib/prism/translation/ripper/sexp.rb +2 -10
- data/lib/prism/translation/ripper/shim.rb +2 -0
- data/lib/prism/translation/ripper.rb +967 -209
- 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 -9
- data/prism.gemspec +128 -62
- 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 +14407 -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 +776 -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 +184 -0
- data/rbi/generated/prism/string_query.rbi +43 -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 +20896 -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 +871 -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 +198 -0
- data/sig/generated/prism/string_query.rbs +43 -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} +53 -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 +97 -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 +367 -0
- data/src/prettyprint.c +421 -354
- data/src/prism.c +8402 -7161
- data/src/regexp.c +961 -45
- data/src/serialize.c +460 -424
- data/src/source.c +518 -0
- data/src/static_literals.c +111 -43
- data/src/string_query.c +180 -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
- data/src/xxh3.c +292 -0
- metadata +128 -63
- 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/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 -8750
- 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 -63
- 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 -4042
- 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 -197
- 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 -272
- 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
|
|
@@ -88,7 +77,22 @@ module Prism
|
|
|
88
77
|
# # => ["def", " ", "m", "(", "a", ")", " ", "nil", " ", "end"]
|
|
89
78
|
#
|
|
90
79
|
def self.tokenize(...)
|
|
91
|
-
lex(...).map
|
|
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
|
|
92
96
|
end
|
|
93
97
|
|
|
94
98
|
# This contains a table of all of the parser events and their
|
|
@@ -343,7 +347,7 @@ module Prism
|
|
|
343
347
|
"__ENCODING__",
|
|
344
348
|
"__FILE__",
|
|
345
349
|
"__LINE__"
|
|
346
|
-
]
|
|
350
|
+
].to_set
|
|
347
351
|
|
|
348
352
|
# A list of all of the Ruby binary operators.
|
|
349
353
|
BINARY_OPERATORS = [
|
|
@@ -368,7 +372,7 @@ module Prism
|
|
|
368
372
|
:/,
|
|
369
373
|
:*,
|
|
370
374
|
:**
|
|
371
|
-
]
|
|
375
|
+
].to_set
|
|
372
376
|
|
|
373
377
|
private_constant :KEYWORDS, :BINARY_OPERATORS
|
|
374
378
|
|
|
@@ -442,6 +446,64 @@ module Prism
|
|
|
442
446
|
autoload :SexpBuilder, "prism/translation/ripper/sexp"
|
|
443
447
|
autoload :SexpBuilderPP, "prism/translation/ripper/sexp"
|
|
444
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
|
+
|
|
445
507
|
# :stopdoc:
|
|
446
508
|
# This is not part of the public API but used by some gems.
|
|
447
509
|
|
|
@@ -475,16 +537,17 @@ module Prism
|
|
|
475
537
|
# The current line number of the parser.
|
|
476
538
|
attr_reader :lineno
|
|
477
539
|
|
|
478
|
-
# The current column
|
|
540
|
+
# The current column in bytes of the parser.
|
|
479
541
|
attr_reader :column
|
|
480
542
|
|
|
481
543
|
# Create a new Translation::Ripper object with the given source.
|
|
482
544
|
def initialize(source, filename = "(ripper)", lineno = 1)
|
|
483
|
-
@source = source
|
|
545
|
+
@source = Ripper.coerce_source(source)
|
|
484
546
|
@filename = filename
|
|
485
547
|
@lineno = lineno
|
|
486
548
|
@column = 0
|
|
487
549
|
@result = nil
|
|
550
|
+
@line_and_column_cache = nil
|
|
488
551
|
end
|
|
489
552
|
|
|
490
553
|
##########################################################################
|
|
@@ -503,7 +566,12 @@ module Prism
|
|
|
503
566
|
bounds(location)
|
|
504
567
|
|
|
505
568
|
if comment.is_a?(InlineComment)
|
|
506
|
-
|
|
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
|
|
507
575
|
else
|
|
508
576
|
offset = location.start_offset
|
|
509
577
|
lines = comment.slice.lines
|
|
@@ -580,13 +648,28 @@ module Prism
|
|
|
580
648
|
end
|
|
581
649
|
end
|
|
582
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
|
+
|
|
583
661
|
##########################################################################
|
|
584
662
|
# Visitor methods
|
|
585
663
|
##########################################################################
|
|
586
664
|
|
|
665
|
+
# :stopdoc:
|
|
666
|
+
|
|
587
667
|
# alias foo bar
|
|
588
668
|
# ^^^^^^^^^^^^^
|
|
589
669
|
def visit_alias_method_node(node)
|
|
670
|
+
bounds(node.keyword_loc)
|
|
671
|
+
on_kw("alias")
|
|
672
|
+
|
|
590
673
|
new_name = visit(node.new_name)
|
|
591
674
|
old_name = visit(node.old_name)
|
|
592
675
|
|
|
@@ -597,6 +680,9 @@ module Prism
|
|
|
597
680
|
# alias $foo $bar
|
|
598
681
|
# ^^^^^^^^^^^^^^^
|
|
599
682
|
def visit_alias_global_variable_node(node)
|
|
683
|
+
bounds(node.keyword_loc)
|
|
684
|
+
on_kw("alias")
|
|
685
|
+
|
|
600
686
|
new_name = visit_alias_global_variable_node_value(node.new_name)
|
|
601
687
|
old_name = visit_alias_global_variable_node_value(node.old_name)
|
|
602
688
|
|
|
@@ -622,6 +708,10 @@ module Prism
|
|
|
622
708
|
# ^^^^^^^^^
|
|
623
709
|
def visit_alternation_pattern_node(node)
|
|
624
710
|
left = visit_pattern_node(node.left)
|
|
711
|
+
|
|
712
|
+
bounds(node.operator_loc)
|
|
713
|
+
on_op("|")
|
|
714
|
+
|
|
625
715
|
right = visit_pattern_node(node.right)
|
|
626
716
|
|
|
627
717
|
bounds(node.location)
|
|
@@ -632,7 +722,13 @@ module Prism
|
|
|
632
722
|
# parenthesis node that can be used to wrap patterns.
|
|
633
723
|
private def visit_pattern_node(node)
|
|
634
724
|
if node.is_a?(ParenthesesNode)
|
|
635
|
-
|
|
725
|
+
bounds(node.opening_loc)
|
|
726
|
+
on_lparen("(")
|
|
727
|
+
result = visit(node.body)
|
|
728
|
+
bounds(node.closing_loc)
|
|
729
|
+
on_rparen(")")
|
|
730
|
+
|
|
731
|
+
result
|
|
636
732
|
else
|
|
637
733
|
visit(node)
|
|
638
734
|
end
|
|
@@ -642,6 +738,14 @@ module Prism
|
|
|
642
738
|
# ^^^^^^^
|
|
643
739
|
def visit_and_node(node)
|
|
644
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
|
+
|
|
645
749
|
right = visit(node.right)
|
|
646
750
|
|
|
647
751
|
bounds(node.location)
|
|
@@ -669,6 +773,8 @@ module Prism
|
|
|
669
773
|
previous = element
|
|
670
774
|
end
|
|
671
775
|
|
|
776
|
+
visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
|
|
777
|
+
|
|
672
778
|
bounds(node.closing_loc)
|
|
673
779
|
on_tstring_end(node.closing)
|
|
674
780
|
when /^%i/
|
|
@@ -683,11 +789,13 @@ module Prism
|
|
|
683
789
|
visit_words_sep(opening_loc, previous, element)
|
|
684
790
|
|
|
685
791
|
bounds(element.location)
|
|
686
|
-
elements = on_qsymbols_add(elements, on_tstring_content(element.
|
|
792
|
+
elements = on_qsymbols_add(elements, on_tstring_content(element.content))
|
|
687
793
|
|
|
688
794
|
previous = element
|
|
689
795
|
end
|
|
690
796
|
|
|
797
|
+
visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
|
|
798
|
+
|
|
691
799
|
bounds(node.closing_loc)
|
|
692
800
|
on_tstring_end(node.closing)
|
|
693
801
|
when /^%W/
|
|
@@ -725,6 +833,8 @@ module Prism
|
|
|
725
833
|
previous = element
|
|
726
834
|
end
|
|
727
835
|
|
|
836
|
+
visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
|
|
837
|
+
|
|
728
838
|
bounds(node.closing_loc)
|
|
729
839
|
on_tstring_end(node.closing)
|
|
730
840
|
when /^%I/
|
|
@@ -743,7 +853,7 @@ module Prism
|
|
|
743
853
|
on_symbols_add(
|
|
744
854
|
elements,
|
|
745
855
|
if element.is_a?(SymbolNode)
|
|
746
|
-
on_word_add(on_word_new, on_tstring_content(element.
|
|
856
|
+
on_word_add(on_word_new, on_tstring_content(element.content))
|
|
747
857
|
else
|
|
748
858
|
element.parts.inject(on_word_new) do |word, part|
|
|
749
859
|
word_part =
|
|
@@ -762,6 +872,8 @@ module Prism
|
|
|
762
872
|
previous = element
|
|
763
873
|
end
|
|
764
874
|
|
|
875
|
+
visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
|
|
876
|
+
|
|
765
877
|
bounds(node.closing_loc)
|
|
766
878
|
on_tstring_end(node.closing)
|
|
767
879
|
else
|
|
@@ -778,15 +890,21 @@ module Prism
|
|
|
778
890
|
on_array(elements)
|
|
779
891
|
end
|
|
780
892
|
|
|
781
|
-
# Dispatch
|
|
893
|
+
# Dispatch words_sep events that contains the whitespace between the elements
|
|
782
894
|
# of list literals.
|
|
783
895
|
private def visit_words_sep(opening_loc, previous, current)
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
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
|
|
790
908
|
end
|
|
791
909
|
end
|
|
792
910
|
|
|
@@ -812,9 +930,18 @@ module Prism
|
|
|
812
930
|
# ^^^^^
|
|
813
931
|
def visit_array_pattern_node(node)
|
|
814
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
|
+
|
|
815
939
|
requireds = visit_all(node.requireds) if node.requireds.any?
|
|
816
940
|
rest =
|
|
817
941
|
if (rest_node = node.rest).is_a?(SplatNode)
|
|
942
|
+
bounds(rest_node.operator_loc)
|
|
943
|
+
on_op("*")
|
|
944
|
+
|
|
818
945
|
if rest_node.expression.nil?
|
|
819
946
|
bounds(rest_node.location)
|
|
820
947
|
on_var_field(nil)
|
|
@@ -825,6 +952,10 @@ module Prism
|
|
|
825
952
|
|
|
826
953
|
posts = visit_all(node.posts) if node.posts.any?
|
|
827
954
|
|
|
955
|
+
if node.closing_loc
|
|
956
|
+
bounds(node.closing_loc)
|
|
957
|
+
node.closing == "]" ? on_rbracket("]") : on_rparen(")")
|
|
958
|
+
end
|
|
828
959
|
bounds(node.location)
|
|
829
960
|
on_aryptn(constant, requireds, rest, posts)
|
|
830
961
|
end
|
|
@@ -832,7 +963,7 @@ module Prism
|
|
|
832
963
|
# foo(bar)
|
|
833
964
|
# ^^^
|
|
834
965
|
def visit_arguments_node(node)
|
|
835
|
-
arguments, _
|
|
966
|
+
arguments, _ = visit_call_node_arguments(node, nil, false)
|
|
836
967
|
arguments
|
|
837
968
|
end
|
|
838
969
|
|
|
@@ -840,6 +971,12 @@ module Prism
|
|
|
840
971
|
# ^^^^
|
|
841
972
|
def visit_assoc_node(node)
|
|
842
973
|
key = visit(node.key)
|
|
974
|
+
|
|
975
|
+
if node.operator_loc
|
|
976
|
+
bounds(node.operator_loc)
|
|
977
|
+
on_op("=>")
|
|
978
|
+
end
|
|
979
|
+
|
|
843
980
|
value = visit(node.value)
|
|
844
981
|
|
|
845
982
|
bounds(node.location)
|
|
@@ -852,6 +989,9 @@ module Prism
|
|
|
852
989
|
# { **foo }
|
|
853
990
|
# ^^^^^
|
|
854
991
|
def visit_assoc_splat_node(node)
|
|
992
|
+
bounds(node.operator_loc)
|
|
993
|
+
on_op("**")
|
|
994
|
+
|
|
855
995
|
value = visit(node.value)
|
|
856
996
|
|
|
857
997
|
bounds(node.location)
|
|
@@ -868,8 +1008,18 @@ module Prism
|
|
|
868
1008
|
# begin end
|
|
869
1009
|
# ^^^^^^^^^
|
|
870
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
|
+
|
|
871
1016
|
clauses = visit_begin_node_clauses(node.begin_keyword_loc, node, false)
|
|
872
1017
|
|
|
1018
|
+
if node.end_keyword_loc
|
|
1019
|
+
bounds(node.end_keyword_loc)
|
|
1020
|
+
on_kw("end")
|
|
1021
|
+
end
|
|
1022
|
+
|
|
873
1023
|
bounds(node.location)
|
|
874
1024
|
on_begin(clauses)
|
|
875
1025
|
end
|
|
@@ -881,7 +1031,7 @@ module Prism
|
|
|
881
1031
|
on_stmts_add(on_stmts_new, on_void_stmt)
|
|
882
1032
|
else
|
|
883
1033
|
body = node.statements.body
|
|
884
|
-
body
|
|
1034
|
+
body = [nil, *body] if void_stmt?(location, node.statements.body[0].location, allow_newline)
|
|
885
1035
|
|
|
886
1036
|
bounds(node.statements.location)
|
|
887
1037
|
visit_statements_node_body(body)
|
|
@@ -890,12 +1040,15 @@ module Prism
|
|
|
890
1040
|
rescue_clause = visit(node.rescue_clause)
|
|
891
1041
|
else_clause =
|
|
892
1042
|
unless (else_clause_node = node.else_clause).nil?
|
|
1043
|
+
bounds(else_clause_node.else_keyword_loc)
|
|
1044
|
+
on_kw("else")
|
|
1045
|
+
|
|
893
1046
|
else_statements =
|
|
894
1047
|
if else_clause_node.statements.nil?
|
|
895
1048
|
[nil]
|
|
896
1049
|
else
|
|
897
1050
|
body = else_clause_node.statements.body
|
|
898
|
-
body
|
|
1051
|
+
body = [nil, *body] if void_stmt?(else_clause_node.else_keyword_loc, else_clause_node.statements.body[0].location, allow_newline)
|
|
899
1052
|
body
|
|
900
1053
|
end
|
|
901
1054
|
|
|
@@ -917,7 +1070,7 @@ module Prism
|
|
|
917
1070
|
on_bodystmt(visit_statements_node_body([nil]), nil, nil, nil)
|
|
918
1071
|
when StatementsNode
|
|
919
1072
|
body = [*node.body]
|
|
920
|
-
body
|
|
1073
|
+
body = [nil, *body] if void_stmt?(location, body[0].location, allow_newline)
|
|
921
1074
|
stmts = visit_statements_node_body(body)
|
|
922
1075
|
|
|
923
1076
|
bounds(node.body.first.location)
|
|
@@ -932,6 +1085,8 @@ module Prism
|
|
|
932
1085
|
# foo(&bar)
|
|
933
1086
|
# ^^^^
|
|
934
1087
|
def visit_block_argument_node(node)
|
|
1088
|
+
bounds(node.operator_loc)
|
|
1089
|
+
on_op("&")
|
|
935
1090
|
visit(node.expression)
|
|
936
1091
|
end
|
|
937
1092
|
|
|
@@ -945,6 +1100,13 @@ module Prism
|
|
|
945
1100
|
# Visit a BlockNode.
|
|
946
1101
|
def visit_block_node(node)
|
|
947
1102
|
braces = node.opening == "{"
|
|
1103
|
+
bounds(node.opening_loc)
|
|
1104
|
+
if braces
|
|
1105
|
+
on_lbrace("{")
|
|
1106
|
+
else
|
|
1107
|
+
on_kw("do")
|
|
1108
|
+
end
|
|
1109
|
+
|
|
948
1110
|
parameters = visit(node.parameters)
|
|
949
1111
|
|
|
950
1112
|
body =
|
|
@@ -957,7 +1119,7 @@ module Prism
|
|
|
957
1119
|
braces ? stmts : on_bodystmt(stmts, nil, nil, nil)
|
|
958
1120
|
when StatementsNode
|
|
959
1121
|
stmts = node.body.body
|
|
960
|
-
stmts
|
|
1122
|
+
stmts = [nil, *stmts] if void_stmt?(node.parameters&.location || node.opening_loc, node.body.location, false)
|
|
961
1123
|
stmts = visit_statements_node_body(stmts)
|
|
962
1124
|
|
|
963
1125
|
bounds(node.body.location)
|
|
@@ -968,6 +1130,14 @@ module Prism
|
|
|
968
1130
|
raise
|
|
969
1131
|
end
|
|
970
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
|
+
|
|
971
1141
|
if braces
|
|
972
1142
|
bounds(node.location)
|
|
973
1143
|
on_brace_block(parameters, body)
|
|
@@ -980,12 +1150,15 @@ module Prism
|
|
|
980
1150
|
# def foo(&bar); end
|
|
981
1151
|
# ^^^^
|
|
982
1152
|
def visit_block_parameter_node(node)
|
|
1153
|
+
bounds(node.operator_loc)
|
|
1154
|
+
on_op("&")
|
|
1155
|
+
|
|
983
1156
|
if node.name_loc.nil?
|
|
984
1157
|
bounds(node.location)
|
|
985
1158
|
on_blockarg(nil)
|
|
986
1159
|
else
|
|
987
1160
|
bounds(node.name_loc)
|
|
988
|
-
name =
|
|
1161
|
+
name = on_ident(node.name.to_s)
|
|
989
1162
|
|
|
990
1163
|
bounds(node.location)
|
|
991
1164
|
on_blockarg(name)
|
|
@@ -994,6 +1167,9 @@ module Prism
|
|
|
994
1167
|
|
|
995
1168
|
# A block's parameters.
|
|
996
1169
|
def visit_block_parameters_node(node)
|
|
1170
|
+
bounds(node.opening_loc)
|
|
1171
|
+
on_op("|")
|
|
1172
|
+
|
|
997
1173
|
parameters =
|
|
998
1174
|
if node.parameters.nil?
|
|
999
1175
|
on_params(nil, nil, nil, nil, nil, nil, nil)
|
|
@@ -1008,6 +1184,9 @@ module Prism
|
|
|
1008
1184
|
false
|
|
1009
1185
|
end
|
|
1010
1186
|
|
|
1187
|
+
bounds(node.closing_loc)
|
|
1188
|
+
on_op("|")
|
|
1189
|
+
|
|
1011
1190
|
bounds(node.location)
|
|
1012
1191
|
on_block_var(parameters, locals)
|
|
1013
1192
|
end
|
|
@@ -1018,6 +1197,9 @@ module Prism
|
|
|
1018
1197
|
# break foo
|
|
1019
1198
|
# ^^^^^^^^^
|
|
1020
1199
|
def visit_break_node(node)
|
|
1200
|
+
bounds(node.keyword_loc)
|
|
1201
|
+
on_kw("break")
|
|
1202
|
+
|
|
1021
1203
|
if node.arguments.nil?
|
|
1022
1204
|
bounds(node.location)
|
|
1023
1205
|
on_break(on_args_new)
|
|
@@ -1042,12 +1224,21 @@ module Prism
|
|
|
1042
1224
|
case node.name
|
|
1043
1225
|
when :[]
|
|
1044
1226
|
receiver = visit(node.receiver)
|
|
1045
|
-
|
|
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)
|
|
1046
1237
|
|
|
1047
1238
|
bounds(node.location)
|
|
1048
1239
|
call = on_aref(receiver, arguments)
|
|
1049
1240
|
|
|
1050
|
-
if
|
|
1241
|
+
if block_node
|
|
1051
1242
|
bounds(node.location)
|
|
1052
1243
|
on_method_add_block(call, block)
|
|
1053
1244
|
else
|
|
@@ -1056,6 +1247,9 @@ module Prism
|
|
|
1056
1247
|
when :[]=
|
|
1057
1248
|
receiver = visit(node.receiver)
|
|
1058
1249
|
|
|
1250
|
+
bounds(node.opening_loc)
|
|
1251
|
+
on_lbracket("[")
|
|
1252
|
+
|
|
1059
1253
|
*arguments, last_argument = node.arguments.arguments
|
|
1060
1254
|
arguments << node.block if !node.block.nil?
|
|
1061
1255
|
|
|
@@ -1071,6 +1265,11 @@ module Prism
|
|
|
1071
1265
|
end
|
|
1072
1266
|
end
|
|
1073
1267
|
|
|
1268
|
+
bounds(node.closing_loc)
|
|
1269
|
+
on_rbracket("]")
|
|
1270
|
+
bounds(node.equal_loc)
|
|
1271
|
+
on_op("=")
|
|
1272
|
+
|
|
1074
1273
|
bounds(node.location)
|
|
1075
1274
|
call = on_aref_field(receiver, arguments)
|
|
1076
1275
|
value = visit_write_value(last_argument)
|
|
@@ -1078,27 +1277,54 @@ module Prism
|
|
|
1078
1277
|
bounds(last_argument.location)
|
|
1079
1278
|
on_assign(call, value)
|
|
1080
1279
|
when :-@, :+@, :~
|
|
1081
|
-
|
|
1280
|
+
bounds(node.message_loc)
|
|
1281
|
+
on_op(node.message)
|
|
1082
1282
|
|
|
1283
|
+
receiver = visit(node.receiver)
|
|
1083
1284
|
bounds(node.location)
|
|
1084
1285
|
on_unary(node.name, receiver)
|
|
1085
1286
|
when :!
|
|
1287
|
+
bounds(node.message_loc)
|
|
1086
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
|
+
|
|
1087
1296
|
receiver =
|
|
1088
|
-
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
|
|
1089
1305
|
visit(node.receiver)
|
|
1090
1306
|
end
|
|
1091
1307
|
|
|
1308
|
+
if node.closing_loc
|
|
1309
|
+
bounds(node.closing_loc)
|
|
1310
|
+
on_rparen(")")
|
|
1311
|
+
end
|
|
1092
1312
|
bounds(node.location)
|
|
1093
1313
|
on_unary(:not, receiver)
|
|
1094
1314
|
else
|
|
1315
|
+
on_op("!")
|
|
1316
|
+
|
|
1095
1317
|
receiver = visit(node.receiver)
|
|
1096
1318
|
|
|
1097
1319
|
bounds(node.location)
|
|
1098
1320
|
on_unary(:!, receiver)
|
|
1099
1321
|
end
|
|
1100
|
-
when
|
|
1322
|
+
when BINARY_OPERATORS
|
|
1101
1323
|
receiver = visit(node.receiver)
|
|
1324
|
+
|
|
1325
|
+
bounds(node.message_loc)
|
|
1326
|
+
on_op(node.message)
|
|
1327
|
+
|
|
1102
1328
|
value = visit(node.arguments.arguments.first)
|
|
1103
1329
|
|
|
1104
1330
|
bounds(node.location)
|
|
@@ -1110,7 +1336,19 @@ module Prism
|
|
|
1110
1336
|
if node.variable_call?
|
|
1111
1337
|
on_vcall(message)
|
|
1112
1338
|
else
|
|
1113
|
-
|
|
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)
|
|
1114
1352
|
call =
|
|
1115
1353
|
if node.opening_loc.nil? && get_arguments_and_block(node.arguments, node.block).first.any?
|
|
1116
1354
|
bounds(node.location)
|
|
@@ -1123,7 +1361,7 @@ module Prism
|
|
|
1123
1361
|
on_method_add_arg(on_fcall(message), on_args_new)
|
|
1124
1362
|
end
|
|
1125
1363
|
|
|
1126
|
-
if
|
|
1364
|
+
if block_node
|
|
1127
1365
|
bounds(node.block.location)
|
|
1128
1366
|
on_method_add_block(call, block)
|
|
1129
1367
|
else
|
|
@@ -1135,7 +1373,7 @@ module Prism
|
|
|
1135
1373
|
receiver = visit(node.receiver)
|
|
1136
1374
|
|
|
1137
1375
|
bounds(node.call_operator_loc)
|
|
1138
|
-
call_operator =
|
|
1376
|
+
call_operator = visit_call_operator(node.call_operator)
|
|
1139
1377
|
|
|
1140
1378
|
message =
|
|
1141
1379
|
if node.message_loc.nil?
|
|
@@ -1145,13 +1383,30 @@ module Prism
|
|
|
1145
1383
|
visit_token(node.message, false)
|
|
1146
1384
|
end
|
|
1147
1385
|
|
|
1386
|
+
if node.equal_loc
|
|
1387
|
+
bounds(node.equal_loc)
|
|
1388
|
+
on_op("=")
|
|
1389
|
+
end
|
|
1390
|
+
|
|
1148
1391
|
if node.name.end_with?("=") && !node.message.end_with?("=") && !node.arguments.nil? && node.block.nil?
|
|
1149
1392
|
value = visit_write_value(node.arguments.arguments.first)
|
|
1150
1393
|
|
|
1151
1394
|
bounds(node.location)
|
|
1152
1395
|
on_assign(on_field(receiver, call_operator, message), value)
|
|
1153
1396
|
else
|
|
1154
|
-
|
|
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)
|
|
1155
1410
|
call =
|
|
1156
1411
|
if node.opening_loc.nil?
|
|
1157
1412
|
bounds(node.location)
|
|
@@ -1169,7 +1424,7 @@ module Prism
|
|
|
1169
1424
|
on_method_add_arg(on_call(receiver, call_operator, message), arguments)
|
|
1170
1425
|
end
|
|
1171
1426
|
|
|
1172
|
-
if
|
|
1427
|
+
if block_node
|
|
1173
1428
|
bounds(node.block.location)
|
|
1174
1429
|
on_method_add_block(call, block)
|
|
1175
1430
|
else
|
|
@@ -1211,8 +1466,7 @@ module Prism
|
|
|
1211
1466
|
on_args_add_block(args, false)
|
|
1212
1467
|
end
|
|
1213
1468
|
end,
|
|
1214
|
-
|
|
1215
|
-
block != nil,
|
|
1469
|
+
block,
|
|
1216
1470
|
]
|
|
1217
1471
|
end
|
|
1218
1472
|
|
|
@@ -1230,7 +1484,7 @@ module Prism
|
|
|
1230
1484
|
receiver = visit(node.receiver)
|
|
1231
1485
|
|
|
1232
1486
|
bounds(node.call_operator_loc)
|
|
1233
|
-
call_operator =
|
|
1487
|
+
call_operator = visit_call_operator(node.call_operator)
|
|
1234
1488
|
|
|
1235
1489
|
bounds(node.message_loc)
|
|
1236
1490
|
message = visit_token(node.message)
|
|
@@ -1252,7 +1506,7 @@ module Prism
|
|
|
1252
1506
|
receiver = visit(node.receiver)
|
|
1253
1507
|
|
|
1254
1508
|
bounds(node.call_operator_loc)
|
|
1255
|
-
call_operator =
|
|
1509
|
+
call_operator = visit_call_operator(node.call_operator)
|
|
1256
1510
|
|
|
1257
1511
|
bounds(node.message_loc)
|
|
1258
1512
|
message = visit_token(node.message)
|
|
@@ -1274,7 +1528,7 @@ module Prism
|
|
|
1274
1528
|
receiver = visit(node.receiver)
|
|
1275
1529
|
|
|
1276
1530
|
bounds(node.call_operator_loc)
|
|
1277
|
-
call_operator =
|
|
1531
|
+
call_operator = visit_call_operator(node.call_operator)
|
|
1278
1532
|
|
|
1279
1533
|
bounds(node.message_loc)
|
|
1280
1534
|
message = visit_token(node.message)
|
|
@@ -1296,6 +1550,9 @@ module Prism
|
|
|
1296
1550
|
if node.call_operator == "::"
|
|
1297
1551
|
receiver = visit(node.receiver)
|
|
1298
1552
|
|
|
1553
|
+
bounds(node.call_operator_loc)
|
|
1554
|
+
on_op("::")
|
|
1555
|
+
|
|
1299
1556
|
bounds(node.message_loc)
|
|
1300
1557
|
message = visit_token(node.message)
|
|
1301
1558
|
|
|
@@ -1305,7 +1562,7 @@ module Prism
|
|
|
1305
1562
|
receiver = visit(node.receiver)
|
|
1306
1563
|
|
|
1307
1564
|
bounds(node.call_operator_loc)
|
|
1308
|
-
call_operator =
|
|
1565
|
+
call_operator = visit_call_operator(node.call_operator)
|
|
1309
1566
|
|
|
1310
1567
|
bounds(node.message_loc)
|
|
1311
1568
|
message = visit_token(node.message)
|
|
@@ -1319,6 +1576,10 @@ module Prism
|
|
|
1319
1576
|
# ^^^^^^^^^^
|
|
1320
1577
|
def visit_capture_pattern_node(node)
|
|
1321
1578
|
value = visit(node.value)
|
|
1579
|
+
|
|
1580
|
+
bounds(node.operator_loc)
|
|
1581
|
+
on_op("=>")
|
|
1582
|
+
|
|
1322
1583
|
target = visit(node.target)
|
|
1323
1584
|
|
|
1324
1585
|
bounds(node.location)
|
|
@@ -1328,10 +1589,21 @@ module Prism
|
|
|
1328
1589
|
# case foo; when bar; end
|
|
1329
1590
|
# ^^^^^^^^^^^^^^^^^^^^^^^
|
|
1330
1591
|
def visit_case_node(node)
|
|
1592
|
+
bounds(node.case_keyword_loc)
|
|
1593
|
+
on_kw("case")
|
|
1594
|
+
|
|
1331
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
|
+
|
|
1332
1604
|
clauses =
|
|
1333
|
-
|
|
1334
|
-
on_when(*
|
|
1605
|
+
visited_conditions.reverse_each.inject(visited_else_clause) do |current, condition|
|
|
1606
|
+
on_when(*condition, current)
|
|
1335
1607
|
end
|
|
1336
1608
|
|
|
1337
1609
|
bounds(node.location)
|
|
@@ -1341,10 +1613,23 @@ module Prism
|
|
|
1341
1613
|
# case foo; in bar; end
|
|
1342
1614
|
# ^^^^^^^^^^^^^^^^^^^^^
|
|
1343
1615
|
def visit_case_match_node(node)
|
|
1616
|
+
bounds(node.case_keyword_loc)
|
|
1617
|
+
on_kw("case")
|
|
1618
|
+
|
|
1344
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
|
+
|
|
1345
1630
|
clauses =
|
|
1346
|
-
|
|
1347
|
-
on_in(*
|
|
1631
|
+
visited_conditions.reverse_each.inject(visited_else_clause) do |current, condition|
|
|
1632
|
+
on_in(*condition, current)
|
|
1348
1633
|
end
|
|
1349
1634
|
|
|
1350
1635
|
bounds(node.location)
|
|
@@ -1354,6 +1639,9 @@ module Prism
|
|
|
1354
1639
|
# class Foo; end
|
|
1355
1640
|
# ^^^^^^^^^^^^^^
|
|
1356
1641
|
def visit_class_node(node)
|
|
1642
|
+
bounds(node.class_keyword_loc)
|
|
1643
|
+
on_kw("class")
|
|
1644
|
+
|
|
1357
1645
|
constant_path =
|
|
1358
1646
|
if node.constant_path.is_a?(ConstantReadNode)
|
|
1359
1647
|
bounds(node.constant_path.location)
|
|
@@ -1362,9 +1650,17 @@ module Prism
|
|
|
1362
1650
|
visit(node.constant_path)
|
|
1363
1651
|
end
|
|
1364
1652
|
|
|
1653
|
+
if node.inheritance_operator_loc
|
|
1654
|
+
bounds(node.inheritance_operator_loc)
|
|
1655
|
+
on_op("<")
|
|
1656
|
+
end
|
|
1657
|
+
|
|
1365
1658
|
superclass = visit(node.superclass)
|
|
1366
1659
|
bodystmt = visit_body_node(node.superclass&.location || node.constant_path.location, node.body, node.superclass.nil?)
|
|
1367
1660
|
|
|
1661
|
+
bounds(node.end_keyword_loc)
|
|
1662
|
+
on_kw("end")
|
|
1663
|
+
|
|
1368
1664
|
bounds(node.location)
|
|
1369
1665
|
on_class(constant_path, superclass, bodystmt)
|
|
1370
1666
|
end
|
|
@@ -1378,12 +1674,13 @@ module Prism
|
|
|
1378
1674
|
|
|
1379
1675
|
# @@foo = 1
|
|
1380
1676
|
# ^^^^^^^^^
|
|
1381
|
-
#
|
|
1382
|
-
# @@foo, @@bar = 1
|
|
1383
|
-
# ^^^^^ ^^^^^
|
|
1384
1677
|
def visit_class_variable_write_node(node)
|
|
1385
1678
|
bounds(node.name_loc)
|
|
1386
1679
|
target = on_var_field(on_cvar(node.name.to_s))
|
|
1680
|
+
|
|
1681
|
+
bounds(node.operator_loc)
|
|
1682
|
+
on_op("=")
|
|
1683
|
+
|
|
1387
1684
|
value = visit_write_value(node.value)
|
|
1388
1685
|
|
|
1389
1686
|
bounds(node.location)
|
|
@@ -1448,12 +1745,13 @@ module Prism
|
|
|
1448
1745
|
|
|
1449
1746
|
# Foo = 1
|
|
1450
1747
|
# ^^^^^^^
|
|
1451
|
-
#
|
|
1452
|
-
# Foo, Bar = 1
|
|
1453
|
-
# ^^^ ^^^
|
|
1454
1748
|
def visit_constant_write_node(node)
|
|
1455
1749
|
bounds(node.name_loc)
|
|
1456
1750
|
target = on_var_field(on_const(node.name.to_s))
|
|
1751
|
+
|
|
1752
|
+
bounds(node.operator_loc)
|
|
1753
|
+
on_op("=")
|
|
1754
|
+
|
|
1457
1755
|
value = visit_write_value(node.value)
|
|
1458
1756
|
|
|
1459
1757
|
bounds(node.location)
|
|
@@ -1513,6 +1811,11 @@ module Prism
|
|
|
1513
1811
|
# ^^^^^^^^
|
|
1514
1812
|
def visit_constant_path_node(node)
|
|
1515
1813
|
if node.parent.nil?
|
|
1814
|
+
if node.delimiter_loc
|
|
1815
|
+
bounds(node.delimiter_loc)
|
|
1816
|
+
on_op("::")
|
|
1817
|
+
end
|
|
1818
|
+
|
|
1516
1819
|
bounds(node.name_loc)
|
|
1517
1820
|
child = on_const(node.name.to_s)
|
|
1518
1821
|
|
|
@@ -1521,6 +1824,9 @@ module Prism
|
|
|
1521
1824
|
else
|
|
1522
1825
|
parent = visit(node.parent)
|
|
1523
1826
|
|
|
1827
|
+
bounds(node.delimiter_loc)
|
|
1828
|
+
on_op("::")
|
|
1829
|
+
|
|
1524
1830
|
bounds(node.name_loc)
|
|
1525
1831
|
child = on_const(node.name.to_s)
|
|
1526
1832
|
|
|
@@ -1531,11 +1837,12 @@ module Prism
|
|
|
1531
1837
|
|
|
1532
1838
|
# Foo::Bar = 1
|
|
1533
1839
|
# ^^^^^^^^^^^^
|
|
1534
|
-
#
|
|
1535
|
-
# Foo::Foo, Bar::Bar = 1
|
|
1536
|
-
# ^^^^^^^^ ^^^^^^^^
|
|
1537
1840
|
def visit_constant_path_write_node(node)
|
|
1538
1841
|
target = visit_constant_path_write_node_target(node.target)
|
|
1842
|
+
|
|
1843
|
+
bounds(node.operator_loc)
|
|
1844
|
+
on_op("=")
|
|
1845
|
+
|
|
1539
1846
|
value = visit_write_value(node.value)
|
|
1540
1847
|
|
|
1541
1848
|
bounds(node.location)
|
|
@@ -1545,6 +1852,11 @@ module Prism
|
|
|
1545
1852
|
# Visit a constant path that is part of a write node.
|
|
1546
1853
|
private def visit_constant_path_write_node_target(node)
|
|
1547
1854
|
if node.parent.nil?
|
|
1855
|
+
if node.delimiter_loc
|
|
1856
|
+
bounds(node.delimiter_loc)
|
|
1857
|
+
on_op("::")
|
|
1858
|
+
end
|
|
1859
|
+
|
|
1548
1860
|
bounds(node.name_loc)
|
|
1549
1861
|
child = on_const(node.name.to_s)
|
|
1550
1862
|
|
|
@@ -1553,6 +1865,9 @@ module Prism
|
|
|
1553
1865
|
else
|
|
1554
1866
|
parent = visit(node.parent)
|
|
1555
1867
|
|
|
1868
|
+
bounds(node.delimiter_loc)
|
|
1869
|
+
on_op("::")
|
|
1870
|
+
|
|
1556
1871
|
bounds(node.name_loc)
|
|
1557
1872
|
child = on_const(node.name.to_s)
|
|
1558
1873
|
|
|
@@ -1565,7 +1880,6 @@ module Prism
|
|
|
1565
1880
|
# ^^^^^^^^^^^^^^^
|
|
1566
1881
|
def visit_constant_path_operator_write_node(node)
|
|
1567
1882
|
target = visit_constant_path_write_node_target(node.target)
|
|
1568
|
-
value = visit(node.value)
|
|
1569
1883
|
|
|
1570
1884
|
bounds(node.binary_operator_loc)
|
|
1571
1885
|
operator = on_op("#{node.binary_operator}=")
|
|
@@ -1579,7 +1893,6 @@ module Prism
|
|
|
1579
1893
|
# ^^^^^^^^^^^^^^^^
|
|
1580
1894
|
def visit_constant_path_and_write_node(node)
|
|
1581
1895
|
target = visit_constant_path_write_node_target(node.target)
|
|
1582
|
-
value = visit(node.value)
|
|
1583
1896
|
|
|
1584
1897
|
bounds(node.operator_loc)
|
|
1585
1898
|
operator = on_op("&&=")
|
|
@@ -1593,7 +1906,6 @@ module Prism
|
|
|
1593
1906
|
# ^^^^^^^^^^^^^^^^
|
|
1594
1907
|
def visit_constant_path_or_write_node(node)
|
|
1595
1908
|
target = visit_constant_path_write_node_target(node.target)
|
|
1596
|
-
value = visit(node.value)
|
|
1597
1909
|
|
|
1598
1910
|
bounds(node.operator_loc)
|
|
1599
1911
|
operator = on_op("||=")
|
|
@@ -1615,16 +1927,24 @@ module Prism
|
|
|
1615
1927
|
# def self.foo; end
|
|
1616
1928
|
# ^^^^^^^^^^^^^^^^^
|
|
1617
1929
|
def visit_def_node(node)
|
|
1930
|
+
bounds(node.def_keyword_loc)
|
|
1931
|
+
on_kw("def")
|
|
1932
|
+
|
|
1618
1933
|
receiver = visit(node.receiver)
|
|
1619
1934
|
operator =
|
|
1620
1935
|
if !node.operator_loc.nil?
|
|
1621
1936
|
bounds(node.operator_loc)
|
|
1622
|
-
|
|
1937
|
+
node.operator == "." ? on_period(".") : on_op("::")
|
|
1623
1938
|
end
|
|
1624
1939
|
|
|
1625
1940
|
bounds(node.name_loc)
|
|
1626
1941
|
name = visit_token(node.name_loc.slice)
|
|
1627
1942
|
|
|
1943
|
+
if node.lparen_loc
|
|
1944
|
+
bounds(node.lparen_loc)
|
|
1945
|
+
on_lparen("(")
|
|
1946
|
+
end
|
|
1947
|
+
|
|
1628
1948
|
parameters =
|
|
1629
1949
|
if node.parameters.nil?
|
|
1630
1950
|
bounds(node.location)
|
|
@@ -1634,10 +1954,17 @@ module Prism
|
|
|
1634
1954
|
end
|
|
1635
1955
|
|
|
1636
1956
|
if !node.lparen_loc.nil?
|
|
1957
|
+
bounds(node.rparen_loc)
|
|
1958
|
+
on_rparen(")")
|
|
1637
1959
|
bounds(node.lparen_loc)
|
|
1638
1960
|
parameters = on_paren(parameters)
|
|
1639
1961
|
end
|
|
1640
1962
|
|
|
1963
|
+
if node.equal_loc
|
|
1964
|
+
bounds(node.equal_loc)
|
|
1965
|
+
on_op("=")
|
|
1966
|
+
end
|
|
1967
|
+
|
|
1641
1968
|
bodystmt =
|
|
1642
1969
|
if node.equal_loc.nil?
|
|
1643
1970
|
visit_body_node(node.rparen_loc || node.end_keyword_loc, node.body)
|
|
@@ -1648,6 +1975,11 @@ module Prism
|
|
|
1648
1975
|
on_bodystmt(body, nil, nil, nil)
|
|
1649
1976
|
end
|
|
1650
1977
|
|
|
1978
|
+
if node.end_keyword_loc
|
|
1979
|
+
bounds(node.end_keyword_loc)
|
|
1980
|
+
on_kw("end")
|
|
1981
|
+
end
|
|
1982
|
+
|
|
1651
1983
|
bounds(node.location)
|
|
1652
1984
|
if receiver
|
|
1653
1985
|
on_defs(receiver, operator, name, parameters, bodystmt)
|
|
@@ -1662,8 +1994,21 @@ module Prism
|
|
|
1662
1994
|
# defined?(a)
|
|
1663
1995
|
# ^^^^^^^^^^^
|
|
1664
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
|
+
|
|
1665
2005
|
expression = visit(node.value)
|
|
1666
2006
|
|
|
2007
|
+
if node.rparen_loc
|
|
2008
|
+
bounds(node.rparen_loc)
|
|
2009
|
+
on_rparen(")")
|
|
2010
|
+
end
|
|
2011
|
+
|
|
1667
2012
|
# Very weird circumstances here where something like:
|
|
1668
2013
|
#
|
|
1669
2014
|
# defined?
|
|
@@ -1684,17 +2029,24 @@ module Prism
|
|
|
1684
2029
|
# if foo then bar else baz end
|
|
1685
2030
|
# ^^^^^^^^^^^^
|
|
1686
2031
|
def visit_else_node(node)
|
|
2032
|
+
bounds(node.else_keyword_loc)
|
|
2033
|
+
on_kw("else")
|
|
2034
|
+
|
|
1687
2035
|
statements =
|
|
1688
2036
|
if node.statements.nil?
|
|
1689
2037
|
[nil]
|
|
1690
2038
|
else
|
|
1691
2039
|
body = node.statements.body
|
|
1692
|
-
body
|
|
2040
|
+
body = [nil, *body] if void_stmt?(node.else_keyword_loc, node.statements.body[0].location, false)
|
|
1693
2041
|
body
|
|
1694
2042
|
end
|
|
1695
2043
|
|
|
2044
|
+
else_statements = visit_statements_node_body(statements)
|
|
2045
|
+
|
|
2046
|
+
bounds(node.end_keyword_loc)
|
|
2047
|
+
on_kw("end")
|
|
1696
2048
|
bounds(node.location)
|
|
1697
|
-
on_else(
|
|
2049
|
+
on_else(else_statements)
|
|
1698
2050
|
end
|
|
1699
2051
|
|
|
1700
2052
|
# "foo #{bar}"
|
|
@@ -1732,12 +2084,15 @@ module Prism
|
|
|
1732
2084
|
|
|
1733
2085
|
# Visit an EnsureNode node.
|
|
1734
2086
|
def visit_ensure_node(node)
|
|
2087
|
+
bounds(node.ensure_keyword_loc)
|
|
2088
|
+
on_kw("ensure")
|
|
2089
|
+
|
|
1735
2090
|
statements =
|
|
1736
2091
|
if node.statements.nil?
|
|
1737
2092
|
[nil]
|
|
1738
2093
|
else
|
|
1739
2094
|
body = node.statements.body
|
|
1740
|
-
body
|
|
2095
|
+
body = [nil, *body] if void_stmt?(node.ensure_keyword_loc, body[0].location, false)
|
|
1741
2096
|
body
|
|
1742
2097
|
end
|
|
1743
2098
|
|
|
@@ -1758,6 +2113,14 @@ module Prism
|
|
|
1758
2113
|
# ^^^^^^^^^^^
|
|
1759
2114
|
def visit_find_pattern_node(node)
|
|
1760
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
|
+
|
|
1761
2124
|
left =
|
|
1762
2125
|
if node.left.expression.nil?
|
|
1763
2126
|
bounds(node.left.location)
|
|
@@ -1767,6 +2130,10 @@ module Prism
|
|
|
1767
2130
|
end
|
|
1768
2131
|
|
|
1769
2132
|
requireds = visit_all(node.requireds) if node.requireds.any?
|
|
2133
|
+
|
|
2134
|
+
bounds(node.right.operator_loc)
|
|
2135
|
+
on_op("*")
|
|
2136
|
+
|
|
1770
2137
|
right =
|
|
1771
2138
|
if node.right.expression.nil?
|
|
1772
2139
|
bounds(node.right.location)
|
|
@@ -1775,6 +2142,10 @@ module Prism
|
|
|
1775
2142
|
visit(node.right.expression)
|
|
1776
2143
|
end
|
|
1777
2144
|
|
|
2145
|
+
if node.closing_loc
|
|
2146
|
+
bounds(node.closing_loc)
|
|
2147
|
+
node.closing == "]" ? on_rbracket("]") : on_rparen(")")
|
|
2148
|
+
end
|
|
1778
2149
|
bounds(node.location)
|
|
1779
2150
|
on_fndptn(constant, left, requireds, right)
|
|
1780
2151
|
end
|
|
@@ -1783,6 +2154,10 @@ module Prism
|
|
|
1783
2154
|
# ^^^^^^^^^^
|
|
1784
2155
|
def visit_flip_flop_node(node)
|
|
1785
2156
|
left = visit(node.left)
|
|
2157
|
+
|
|
2158
|
+
bounds(node.operator_loc)
|
|
2159
|
+
on_op(node.operator)
|
|
2160
|
+
|
|
1786
2161
|
right = visit(node.right)
|
|
1787
2162
|
|
|
1788
2163
|
bounds(node.location)
|
|
@@ -1802,8 +2177,18 @@ module Prism
|
|
|
1802
2177
|
# for foo in bar do end
|
|
1803
2178
|
# ^^^^^^^^^^^^^^^^^^^^^
|
|
1804
2179
|
def visit_for_node(node)
|
|
2180
|
+
bounds(node.for_keyword_loc)
|
|
2181
|
+
on_kw("for")
|
|
2182
|
+
|
|
1805
2183
|
index = visit(node.index)
|
|
2184
|
+
bounds(node.in_keyword_loc)
|
|
2185
|
+
on_kw("in")
|
|
2186
|
+
|
|
1806
2187
|
collection = visit(node.collection)
|
|
2188
|
+
if node.do_keyword_loc
|
|
2189
|
+
bounds(node.do_keyword_loc)
|
|
2190
|
+
on_kw("do")
|
|
2191
|
+
end
|
|
1807
2192
|
statements =
|
|
1808
2193
|
if node.statements.nil?
|
|
1809
2194
|
bounds(node.location)
|
|
@@ -1812,6 +2197,9 @@ module Prism
|
|
|
1812
2197
|
visit(node.statements)
|
|
1813
2198
|
end
|
|
1814
2199
|
|
|
2200
|
+
bounds(node.end_keyword_loc)
|
|
2201
|
+
on_kw("end")
|
|
2202
|
+
|
|
1815
2203
|
bounds(node.location)
|
|
1816
2204
|
on_for(index, collection, statements)
|
|
1817
2205
|
end
|
|
@@ -1820,6 +2208,7 @@ module Prism
|
|
|
1820
2208
|
# ^^^
|
|
1821
2209
|
def visit_forwarding_arguments_node(node)
|
|
1822
2210
|
bounds(node.location)
|
|
2211
|
+
on_op("...")
|
|
1823
2212
|
on_args_forward
|
|
1824
2213
|
end
|
|
1825
2214
|
|
|
@@ -1827,6 +2216,7 @@ module Prism
|
|
|
1827
2216
|
# ^^^
|
|
1828
2217
|
def visit_forwarding_parameter_node(node)
|
|
1829
2218
|
bounds(node.location)
|
|
2219
|
+
on_op("...")
|
|
1830
2220
|
on_args_forward
|
|
1831
2221
|
end
|
|
1832
2222
|
|
|
@@ -1836,6 +2226,9 @@ module Prism
|
|
|
1836
2226
|
# super {}
|
|
1837
2227
|
# ^^^^^^^^
|
|
1838
2228
|
def visit_forwarding_super_node(node)
|
|
2229
|
+
bounds(node.keyword_loc)
|
|
2230
|
+
on_kw("super")
|
|
2231
|
+
|
|
1839
2232
|
if node.block.nil?
|
|
1840
2233
|
bounds(node.location)
|
|
1841
2234
|
on_zsuper
|
|
@@ -1856,12 +2249,13 @@ module Prism
|
|
|
1856
2249
|
|
|
1857
2250
|
# $foo = 1
|
|
1858
2251
|
# ^^^^^^^^
|
|
1859
|
-
#
|
|
1860
|
-
# $foo, $bar = 1
|
|
1861
|
-
# ^^^^ ^^^^
|
|
1862
2252
|
def visit_global_variable_write_node(node)
|
|
1863
2253
|
bounds(node.name_loc)
|
|
1864
2254
|
target = on_var_field(on_gvar(node.name.to_s))
|
|
2255
|
+
|
|
2256
|
+
bounds(node.operator_loc)
|
|
2257
|
+
on_op("=")
|
|
2258
|
+
|
|
1865
2259
|
value = visit_write_value(node.value)
|
|
1866
2260
|
|
|
1867
2261
|
bounds(node.location)
|
|
@@ -1920,6 +2314,9 @@ module Prism
|
|
|
1920
2314
|
# {}
|
|
1921
2315
|
# ^^
|
|
1922
2316
|
def visit_hash_node(node)
|
|
2317
|
+
bounds(node.opening_loc)
|
|
2318
|
+
on_lbrace("{")
|
|
2319
|
+
|
|
1923
2320
|
elements =
|
|
1924
2321
|
if node.elements.any?
|
|
1925
2322
|
args = visit_all(node.elements)
|
|
@@ -1928,6 +2325,8 @@ module Prism
|
|
|
1928
2325
|
on_assoclist_from_args(args)
|
|
1929
2326
|
end
|
|
1930
2327
|
|
|
2328
|
+
bounds(node.closing_loc)
|
|
2329
|
+
on_rbrace("}")
|
|
1931
2330
|
bounds(node.location)
|
|
1932
2331
|
on_hash(elements)
|
|
1933
2332
|
end
|
|
@@ -1936,6 +2335,15 @@ module Prism
|
|
|
1936
2335
|
# ^^
|
|
1937
2336
|
def visit_hash_pattern_node(node)
|
|
1938
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
|
+
|
|
1939
2347
|
elements =
|
|
1940
2348
|
if node.elements.any? || !node.rest.nil?
|
|
1941
2349
|
node.elements.map do |element|
|
|
@@ -1943,8 +2351,8 @@ module Prism
|
|
|
1943
2351
|
if (key = element.key).opening_loc.nil?
|
|
1944
2352
|
visit(key)
|
|
1945
2353
|
else
|
|
1946
|
-
bounds(key.
|
|
1947
|
-
if (value = key.
|
|
2354
|
+
bounds(key.content_loc)
|
|
2355
|
+
if (value = key.content).empty?
|
|
1948
2356
|
on_string_content
|
|
1949
2357
|
else
|
|
1950
2358
|
on_string_add(on_string_content, on_tstring_content(value))
|
|
@@ -1958,12 +2366,21 @@ module Prism
|
|
|
1958
2366
|
rest =
|
|
1959
2367
|
case node.rest
|
|
1960
2368
|
when AssocSplatNode
|
|
2369
|
+
bounds(node.rest.operator_loc)
|
|
2370
|
+
on_op("**")
|
|
1961
2371
|
visit(node.rest.value)
|
|
1962
2372
|
when NoKeywordsParameterNode
|
|
1963
2373
|
bounds(node.rest.location)
|
|
1964
2374
|
on_var_field(visit(node.rest))
|
|
1965
2375
|
end
|
|
1966
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
|
|
1967
2384
|
bounds(node.location)
|
|
1968
2385
|
on_hshptn(constant, elements, rest)
|
|
1969
2386
|
end
|
|
@@ -1979,13 +2396,27 @@ module Prism
|
|
|
1979
2396
|
def visit_if_node(node)
|
|
1980
2397
|
if node.then_keyword == "?"
|
|
1981
2398
|
predicate = visit(node.predicate)
|
|
2399
|
+
|
|
2400
|
+
bounds(node.then_keyword_loc)
|
|
2401
|
+
on_op("?")
|
|
2402
|
+
|
|
1982
2403
|
truthy = visit(node.statements.body.first)
|
|
2404
|
+
|
|
2405
|
+
bounds(node.subsequent.else_keyword_loc)
|
|
2406
|
+
on_op(":")
|
|
2407
|
+
|
|
1983
2408
|
falsy = visit(node.subsequent.statements.body.first)
|
|
1984
2409
|
|
|
1985
2410
|
bounds(node.location)
|
|
1986
2411
|
on_ifop(predicate, truthy, falsy)
|
|
1987
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)
|
|
1988
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
|
|
1989
2420
|
statements =
|
|
1990
2421
|
if node.statements.nil?
|
|
1991
2422
|
bounds(node.location)
|
|
@@ -1995,6 +2426,11 @@ module Prism
|
|
|
1995
2426
|
end
|
|
1996
2427
|
subsequent = visit(node.subsequent)
|
|
1997
2428
|
|
|
2429
|
+
if node.end_keyword_loc && !node.subsequent
|
|
2430
|
+
bounds(node.end_keyword_loc)
|
|
2431
|
+
on_kw("end")
|
|
2432
|
+
end
|
|
2433
|
+
|
|
1998
2434
|
bounds(node.location)
|
|
1999
2435
|
if node.if_keyword == "if"
|
|
2000
2436
|
on_if(predicate, statements, subsequent)
|
|
@@ -2003,6 +2439,8 @@ module Prism
|
|
|
2003
2439
|
end
|
|
2004
2440
|
else
|
|
2005
2441
|
statements = visit(node.statements.body.first)
|
|
2442
|
+
bounds(node.if_keyword_loc)
|
|
2443
|
+
on_kw(node.if_keyword)
|
|
2006
2444
|
predicate = visit(node.predicate)
|
|
2007
2445
|
|
|
2008
2446
|
bounds(node.location)
|
|
@@ -2034,7 +2472,14 @@ module Prism
|
|
|
2034
2472
|
# This is a special case where we're not going to call on_in directly
|
|
2035
2473
|
# because we don't have access to the subsequent. Instead, we'll return
|
|
2036
2474
|
# the component parts and let the parent node handle it.
|
|
2475
|
+
bounds(node.in_keyword_loc)
|
|
2476
|
+
on_kw("in")
|
|
2477
|
+
|
|
2037
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
|
|
2038
2483
|
statements =
|
|
2039
2484
|
if node.statements.nil?
|
|
2040
2485
|
bounds(node.location)
|
|
@@ -2050,7 +2495,14 @@ module Prism
|
|
|
2050
2495
|
# ^^^^^^^^^^^^^^^
|
|
2051
2496
|
def visit_index_operator_write_node(node)
|
|
2052
2497
|
receiver = visit(node.receiver)
|
|
2053
|
-
|
|
2498
|
+
|
|
2499
|
+
bounds(node.opening_loc)
|
|
2500
|
+
on_lbracket("[")
|
|
2501
|
+
|
|
2502
|
+
arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))
|
|
2503
|
+
|
|
2504
|
+
bounds(node.closing_loc)
|
|
2505
|
+
on_rbracket("]")
|
|
2054
2506
|
|
|
2055
2507
|
bounds(node.location)
|
|
2056
2508
|
target = on_aref_field(receiver, arguments)
|
|
@@ -2067,7 +2519,14 @@ module Prism
|
|
|
2067
2519
|
# ^^^^^^^^^^^^^^^^
|
|
2068
2520
|
def visit_index_and_write_node(node)
|
|
2069
2521
|
receiver = visit(node.receiver)
|
|
2070
|
-
|
|
2522
|
+
|
|
2523
|
+
bounds(node.opening_loc)
|
|
2524
|
+
on_lbracket("[")
|
|
2525
|
+
|
|
2526
|
+
arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))
|
|
2527
|
+
|
|
2528
|
+
bounds(node.closing_loc)
|
|
2529
|
+
on_rbracket("]")
|
|
2071
2530
|
|
|
2072
2531
|
bounds(node.location)
|
|
2073
2532
|
target = on_aref_field(receiver, arguments)
|
|
@@ -2084,7 +2543,14 @@ module Prism
|
|
|
2084
2543
|
# ^^^^^^^^^^^^^^^^
|
|
2085
2544
|
def visit_index_or_write_node(node)
|
|
2086
2545
|
receiver = visit(node.receiver)
|
|
2087
|
-
|
|
2546
|
+
|
|
2547
|
+
bounds(node.opening_loc)
|
|
2548
|
+
on_lbracket("[")
|
|
2549
|
+
|
|
2550
|
+
arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))
|
|
2551
|
+
|
|
2552
|
+
bounds(node.closing_loc)
|
|
2553
|
+
on_rbracket("]")
|
|
2088
2554
|
|
|
2089
2555
|
bounds(node.location)
|
|
2090
2556
|
target = on_aref_field(receiver, arguments)
|
|
@@ -2101,7 +2567,14 @@ module Prism
|
|
|
2101
2567
|
# ^^^^^^^^
|
|
2102
2568
|
def visit_index_target_node(node)
|
|
2103
2569
|
receiver = visit(node.receiver)
|
|
2104
|
-
|
|
2570
|
+
|
|
2571
|
+
bounds(node.opening_loc)
|
|
2572
|
+
on_lbracket("[")
|
|
2573
|
+
|
|
2574
|
+
arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))
|
|
2575
|
+
|
|
2576
|
+
bounds(node.closing_loc)
|
|
2577
|
+
on_rbracket("]")
|
|
2105
2578
|
|
|
2106
2579
|
bounds(node.location)
|
|
2107
2580
|
on_aref_field(receiver, arguments)
|
|
@@ -2119,6 +2592,10 @@ module Prism
|
|
|
2119
2592
|
def visit_instance_variable_write_node(node)
|
|
2120
2593
|
bounds(node.name_loc)
|
|
2121
2594
|
target = on_var_field(on_ivar(node.name.to_s))
|
|
2595
|
+
|
|
2596
|
+
bounds(node.operator_loc)
|
|
2597
|
+
on_op("=")
|
|
2598
|
+
|
|
2122
2599
|
value = visit_write_value(node.value)
|
|
2123
2600
|
|
|
2124
2601
|
bounds(node.location)
|
|
@@ -2221,20 +2698,37 @@ module Prism
|
|
|
2221
2698
|
# "foo #{bar}"
|
|
2222
2699
|
# ^^^^^^^^^^^^
|
|
2223
2700
|
def visit_interpolated_string_node(node)
|
|
2224
|
-
|
|
2225
|
-
|
|
2701
|
+
with_string_bounds(node) do
|
|
2702
|
+
if node.opening&.start_with?("<<~")
|
|
2703
|
+
heredoc = visit_heredoc_string_node(node)
|
|
2226
2704
|
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
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
|
|
2233
2721
|
|
|
2234
|
-
bounds(
|
|
2235
|
-
|
|
2722
|
+
bounds(node.location)
|
|
2723
|
+
on_string_literal(parts)
|
|
2236
2724
|
end
|
|
2237
|
-
|
|
2725
|
+
end
|
|
2726
|
+
end
|
|
2727
|
+
|
|
2728
|
+
# :"foo #{bar}"
|
|
2729
|
+
# ^^^^^^^^^^^^^
|
|
2730
|
+
def visit_interpolated_symbol_node(node)
|
|
2731
|
+
with_string_bounds(node) do
|
|
2238
2732
|
bounds(node.parts.first.location)
|
|
2239
2733
|
parts =
|
|
2240
2734
|
node.parts.inject(on_string_content) do |content, part|
|
|
@@ -2242,40 +2736,29 @@ module Prism
|
|
|
2242
2736
|
end
|
|
2243
2737
|
|
|
2244
2738
|
bounds(node.location)
|
|
2245
|
-
|
|
2739
|
+
on_dyna_symbol(parts)
|
|
2246
2740
|
end
|
|
2247
2741
|
end
|
|
2248
2742
|
|
|
2249
|
-
# :"foo #{bar}"
|
|
2250
|
-
# ^^^^^^^^^^^^^
|
|
2251
|
-
def visit_interpolated_symbol_node(node)
|
|
2252
|
-
bounds(node.parts.first.location)
|
|
2253
|
-
parts =
|
|
2254
|
-
node.parts.inject(on_string_content) do |content, part|
|
|
2255
|
-
on_string_add(content, visit_string_content(part))
|
|
2256
|
-
end
|
|
2257
|
-
|
|
2258
|
-
bounds(node.location)
|
|
2259
|
-
on_dyna_symbol(parts)
|
|
2260
|
-
end
|
|
2261
|
-
|
|
2262
2743
|
# `foo #{bar}`
|
|
2263
2744
|
# ^^^^^^^^^^^^
|
|
2264
2745
|
def visit_interpolated_x_string_node(node)
|
|
2265
|
-
|
|
2266
|
-
|
|
2746
|
+
with_string_bounds(node) do
|
|
2747
|
+
if node.opening.start_with?("<<~")
|
|
2748
|
+
heredoc = visit_heredoc_x_string_node(node)
|
|
2267
2749
|
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
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
|
|
2276
2758
|
|
|
2277
|
-
|
|
2278
|
-
|
|
2759
|
+
bounds(node.location)
|
|
2760
|
+
on_xstring_literal(parts)
|
|
2761
|
+
end
|
|
2279
2762
|
end
|
|
2280
2763
|
end
|
|
2281
2764
|
|
|
@@ -2316,6 +2799,9 @@ module Prism
|
|
|
2316
2799
|
# def foo(**); end
|
|
2317
2800
|
# ^^
|
|
2318
2801
|
def visit_keyword_rest_parameter_node(node)
|
|
2802
|
+
bounds(node.operator_loc)
|
|
2803
|
+
on_op("**")
|
|
2804
|
+
|
|
2319
2805
|
if node.name_loc.nil?
|
|
2320
2806
|
bounds(node.location)
|
|
2321
2807
|
on_kwrest_param(nil)
|
|
@@ -2335,6 +2821,11 @@ module Prism
|
|
|
2335
2821
|
|
|
2336
2822
|
parameters =
|
|
2337
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
|
+
|
|
2338
2829
|
# Ripper does not track block-locals within lambdas, so we skip
|
|
2339
2830
|
# directly to the parameters here.
|
|
2340
2831
|
params =
|
|
@@ -2345,6 +2836,13 @@ module Prism
|
|
|
2345
2836
|
visit(node.parameters.parameters)
|
|
2346
2837
|
end
|
|
2347
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
|
+
|
|
2348
2846
|
if node.parameters.opening_loc.nil?
|
|
2349
2847
|
params
|
|
2350
2848
|
else
|
|
@@ -2357,9 +2855,11 @@ module Prism
|
|
|
2357
2855
|
end
|
|
2358
2856
|
|
|
2359
2857
|
braces = node.opening == "{"
|
|
2858
|
+
bounds(node.opening_loc)
|
|
2360
2859
|
if braces
|
|
2361
|
-
bounds(node.opening_loc)
|
|
2362
2860
|
on_tlambeg(node.opening)
|
|
2861
|
+
else
|
|
2862
|
+
on_kw("do")
|
|
2363
2863
|
end
|
|
2364
2864
|
|
|
2365
2865
|
body =
|
|
@@ -2372,7 +2872,7 @@ module Prism
|
|
|
2372
2872
|
braces ? stmts : on_bodystmt(stmts, nil, nil, nil)
|
|
2373
2873
|
when StatementsNode
|
|
2374
2874
|
stmts = node.body.body
|
|
2375
|
-
stmts
|
|
2875
|
+
stmts = [nil, *stmts] if void_stmt?(node.parameters&.location || node.opening_loc, node.body.location, false)
|
|
2376
2876
|
stmts = visit_statements_node_body(stmts)
|
|
2377
2877
|
|
|
2378
2878
|
bounds(node.body.location)
|
|
@@ -2383,6 +2883,13 @@ module Prism
|
|
|
2383
2883
|
raise
|
|
2384
2884
|
end
|
|
2385
2885
|
|
|
2886
|
+
bounds(node.closing_loc)
|
|
2887
|
+
if braces
|
|
2888
|
+
on_rbrace("}")
|
|
2889
|
+
else
|
|
2890
|
+
on_kw("end")
|
|
2891
|
+
end
|
|
2892
|
+
|
|
2386
2893
|
bounds(node.location)
|
|
2387
2894
|
on_lambda(parameters, body)
|
|
2388
2895
|
end
|
|
@@ -2399,6 +2906,10 @@ module Prism
|
|
|
2399
2906
|
def visit_local_variable_write_node(node)
|
|
2400
2907
|
bounds(node.name_loc)
|
|
2401
2908
|
target = on_var_field(on_ident(node.name_loc.slice))
|
|
2909
|
+
|
|
2910
|
+
bounds(node.operator_loc)
|
|
2911
|
+
on_op("=")
|
|
2912
|
+
|
|
2402
2913
|
value = visit_write_value(node.value)
|
|
2403
2914
|
|
|
2404
2915
|
bounds(node.location)
|
|
@@ -2473,6 +2984,8 @@ module Prism
|
|
|
2473
2984
|
# ^^^^^^^^^^
|
|
2474
2985
|
def visit_match_predicate_node(node)
|
|
2475
2986
|
value = visit(node.value)
|
|
2987
|
+
bounds(node.keyword_loc)
|
|
2988
|
+
on_kw("in")
|
|
2476
2989
|
pattern = on_in(visit_pattern_node(node.pattern), nil, nil)
|
|
2477
2990
|
|
|
2478
2991
|
on_case(value, pattern)
|
|
@@ -2482,6 +2995,10 @@ module Prism
|
|
|
2482
2995
|
# ^^^^^^^^^^
|
|
2483
2996
|
def visit_match_required_node(node)
|
|
2484
2997
|
value = visit(node.value)
|
|
2998
|
+
|
|
2999
|
+
bounds(node.operator_loc)
|
|
3000
|
+
on_op("=>")
|
|
3001
|
+
|
|
2485
3002
|
pattern = on_in(visit_pattern_node(node.pattern), nil, nil)
|
|
2486
3003
|
|
|
2487
3004
|
on_case(value, pattern)
|
|
@@ -2495,13 +3012,16 @@ module Prism
|
|
|
2495
3012
|
|
|
2496
3013
|
# A node that is missing from the syntax tree. This is only used in the
|
|
2497
3014
|
# case of a syntax error.
|
|
2498
|
-
def
|
|
2499
|
-
raise "Cannot visit
|
|
3015
|
+
def visit_error_recovery_node(node)
|
|
3016
|
+
raise "Cannot visit error recovery nodes directly."
|
|
2500
3017
|
end
|
|
2501
3018
|
|
|
2502
3019
|
# module Foo; end
|
|
2503
3020
|
# ^^^^^^^^^^^^^^^
|
|
2504
3021
|
def visit_module_node(node)
|
|
3022
|
+
bounds(node.module_keyword_loc)
|
|
3023
|
+
on_kw("module")
|
|
3024
|
+
|
|
2505
3025
|
constant_path =
|
|
2506
3026
|
if node.constant_path.is_a?(ConstantReadNode)
|
|
2507
3027
|
bounds(node.constant_path.location)
|
|
@@ -2512,6 +3032,9 @@ module Prism
|
|
|
2512
3032
|
|
|
2513
3033
|
bodystmt = visit_body_node(node.constant_path.location, node.body, true)
|
|
2514
3034
|
|
|
3035
|
+
bounds(node.end_keyword_loc)
|
|
3036
|
+
on_kw("end")
|
|
3037
|
+
|
|
2515
3038
|
bounds(node.location)
|
|
2516
3039
|
on_module(constant_path, bodystmt)
|
|
2517
3040
|
end
|
|
@@ -2519,9 +3042,19 @@ module Prism
|
|
|
2519
3042
|
# (foo, bar), bar = qux
|
|
2520
3043
|
# ^^^^^^^^^^
|
|
2521
3044
|
def visit_multi_target_node(node)
|
|
3045
|
+
if node.lparen_loc
|
|
3046
|
+
bounds(node.lparen_loc)
|
|
3047
|
+
on_lparen("(")
|
|
3048
|
+
end
|
|
3049
|
+
|
|
2522
3050
|
bounds(node.location)
|
|
2523
3051
|
targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, true)
|
|
2524
3052
|
|
|
3053
|
+
if node.rparen_loc
|
|
3054
|
+
bounds(node.rparen_loc)
|
|
3055
|
+
on_rparen(")")
|
|
3056
|
+
end
|
|
3057
|
+
|
|
2525
3058
|
if node.lparen_loc.nil?
|
|
2526
3059
|
targets
|
|
2527
3060
|
else
|
|
@@ -2573,9 +3106,22 @@ module Prism
|
|
|
2573
3106
|
# foo, bar = baz
|
|
2574
3107
|
# ^^^^^^^^^^^^^^
|
|
2575
3108
|
def visit_multi_write_node(node)
|
|
3109
|
+
if node.lparen_loc
|
|
3110
|
+
bounds(node.lparen_loc)
|
|
3111
|
+
on_lparen("(")
|
|
3112
|
+
end
|
|
3113
|
+
|
|
2576
3114
|
bounds(node.location)
|
|
2577
3115
|
targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, true)
|
|
2578
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
|
+
|
|
2579
3125
|
unless node.lparen_loc.nil?
|
|
2580
3126
|
bounds(node.lparen_loc)
|
|
2581
3127
|
targets = on_mlhs_paren(targets)
|
|
@@ -2593,6 +3139,9 @@ module Prism
|
|
|
2593
3139
|
# next foo
|
|
2594
3140
|
# ^^^^^^^^
|
|
2595
3141
|
def visit_next_node(node)
|
|
3142
|
+
bounds(node.keyword_loc)
|
|
3143
|
+
on_kw("next")
|
|
3144
|
+
|
|
2596
3145
|
if node.arguments.nil?
|
|
2597
3146
|
bounds(node.location)
|
|
2598
3147
|
on_next(on_args_new)
|
|
@@ -2611,9 +3160,24 @@ module Prism
|
|
|
2611
3160
|
on_var_ref(on_kw("nil"))
|
|
2612
3161
|
end
|
|
2613
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
|
+
|
|
2614
3174
|
# def foo(**nil); end
|
|
2615
3175
|
# ^^^^^
|
|
2616
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")
|
|
2617
3181
|
bounds(node.location)
|
|
2618
3182
|
on_nokw_param(nil)
|
|
2619
3183
|
|
|
@@ -2646,7 +3210,11 @@ module Prism
|
|
|
2646
3210
|
# ^^^^^^^
|
|
2647
3211
|
def visit_optional_parameter_node(node)
|
|
2648
3212
|
bounds(node.name_loc)
|
|
2649
|
-
name =
|
|
3213
|
+
name = on_ident(node.name.to_s)
|
|
3214
|
+
|
|
3215
|
+
bounds(node.operator_loc)
|
|
3216
|
+
on_op("=")
|
|
3217
|
+
|
|
2650
3218
|
value = visit(node.value)
|
|
2651
3219
|
|
|
2652
3220
|
[name, value]
|
|
@@ -2656,6 +3224,14 @@ module Prism
|
|
|
2656
3224
|
# ^^^^^^
|
|
2657
3225
|
def visit_or_node(node)
|
|
2658
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
|
+
|
|
2659
3235
|
right = visit(node.right)
|
|
2660
3236
|
|
|
2661
3237
|
bounds(node.location)
|
|
@@ -2679,9 +3255,19 @@ module Prism
|
|
|
2679
3255
|
|
|
2680
3256
|
# Visit a destructured positional parameter node.
|
|
2681
3257
|
private def visit_destructured_parameter_node(node)
|
|
3258
|
+
if node.lparen_loc
|
|
3259
|
+
bounds(node.lparen_loc)
|
|
3260
|
+
on_lparen("(")
|
|
3261
|
+
end
|
|
3262
|
+
|
|
2682
3263
|
bounds(node.location)
|
|
2683
3264
|
targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, false)
|
|
2684
3265
|
|
|
3266
|
+
if node.rparen_loc
|
|
3267
|
+
bounds(node.rparen_loc)
|
|
3268
|
+
on_rparen(")")
|
|
3269
|
+
end
|
|
3270
|
+
|
|
2685
3271
|
bounds(node.lparen_loc)
|
|
2686
3272
|
on_mlhs_paren(targets)
|
|
2687
3273
|
end
|
|
@@ -2692,6 +3278,9 @@ module Prism
|
|
|
2692
3278
|
# (1)
|
|
2693
3279
|
# ^^^
|
|
2694
3280
|
def visit_parentheses_node(node)
|
|
3281
|
+
bounds(node.opening_loc)
|
|
3282
|
+
on_lparen("(")
|
|
3283
|
+
|
|
2695
3284
|
body =
|
|
2696
3285
|
if node.body.nil?
|
|
2697
3286
|
on_stmts_add(on_stmts_new, on_void_stmt)
|
|
@@ -2699,6 +3288,8 @@ module Prism
|
|
|
2699
3288
|
visit(node.body)
|
|
2700
3289
|
end
|
|
2701
3290
|
|
|
3291
|
+
bounds(node.closing_loc)
|
|
3292
|
+
on_rparen(")")
|
|
2702
3293
|
bounds(node.location)
|
|
2703
3294
|
on_paren(body)
|
|
2704
3295
|
end
|
|
@@ -2706,8 +3297,15 @@ module Prism
|
|
|
2706
3297
|
# foo => ^(bar)
|
|
2707
3298
|
# ^^^^^^
|
|
2708
3299
|
def visit_pinned_expression_node(node)
|
|
3300
|
+
bounds(node.operator_loc)
|
|
3301
|
+
on_op("^")
|
|
3302
|
+
bounds(node.lparen_loc)
|
|
3303
|
+
on_lparen("(")
|
|
3304
|
+
|
|
2709
3305
|
expression = visit(node.expression)
|
|
2710
3306
|
|
|
3307
|
+
bounds(node.rparen_loc)
|
|
3308
|
+
on_rparen(")")
|
|
2711
3309
|
bounds(node.location)
|
|
2712
3310
|
on_begin(expression)
|
|
2713
3311
|
end
|
|
@@ -2715,12 +3313,20 @@ module Prism
|
|
|
2715
3313
|
# foo = 1 and bar => ^foo
|
|
2716
3314
|
# ^^^^
|
|
2717
3315
|
def visit_pinned_variable_node(node)
|
|
3316
|
+
bounds(node.operator_loc)
|
|
3317
|
+
on_op("^")
|
|
3318
|
+
|
|
2718
3319
|
visit(node.variable)
|
|
2719
3320
|
end
|
|
2720
3321
|
|
|
2721
3322
|
# END {}
|
|
2722
3323
|
# ^^^^^^
|
|
2723
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
|
+
|
|
2724
3330
|
statements =
|
|
2725
3331
|
if node.statements.nil?
|
|
2726
3332
|
bounds(node.location)
|
|
@@ -2729,6 +3335,8 @@ module Prism
|
|
|
2729
3335
|
visit(node.statements)
|
|
2730
3336
|
end
|
|
2731
3337
|
|
|
3338
|
+
bounds(node.closing_loc)
|
|
3339
|
+
on_rbrace("}")
|
|
2732
3340
|
bounds(node.location)
|
|
2733
3341
|
on_END(statements)
|
|
2734
3342
|
end
|
|
@@ -2736,6 +3344,11 @@ module Prism
|
|
|
2736
3344
|
# BEGIN {}
|
|
2737
3345
|
# ^^^^^^^^
|
|
2738
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
|
+
|
|
2739
3352
|
statements =
|
|
2740
3353
|
if node.statements.nil?
|
|
2741
3354
|
bounds(node.location)
|
|
@@ -2744,6 +3357,8 @@ module Prism
|
|
|
2744
3357
|
visit(node.statements)
|
|
2745
3358
|
end
|
|
2746
3359
|
|
|
3360
|
+
bounds(node.closing_loc)
|
|
3361
|
+
on_rbrace("}")
|
|
2747
3362
|
bounds(node.location)
|
|
2748
3363
|
on_BEGIN(statements)
|
|
2749
3364
|
end
|
|
@@ -2751,7 +3366,7 @@ module Prism
|
|
|
2751
3366
|
# The top-level program node.
|
|
2752
3367
|
def visit_program_node(node)
|
|
2753
3368
|
body = node.statements.body
|
|
2754
|
-
body
|
|
3369
|
+
body = [nil] if body.empty?
|
|
2755
3370
|
statements = visit_statements_node_body(body)
|
|
2756
3371
|
|
|
2757
3372
|
bounds(node.location)
|
|
@@ -2762,6 +3377,10 @@ module Prism
|
|
|
2762
3377
|
# ^^^^
|
|
2763
3378
|
def visit_range_node(node)
|
|
2764
3379
|
left = visit(node.left)
|
|
3380
|
+
|
|
3381
|
+
bounds(node.operator_loc)
|
|
3382
|
+
on_op(node.operator)
|
|
3383
|
+
|
|
2765
3384
|
right = visit(node.right)
|
|
2766
3385
|
|
|
2767
3386
|
bounds(node.location)
|
|
@@ -2782,6 +3401,7 @@ module Prism
|
|
|
2782
3401
|
# ^^^^
|
|
2783
3402
|
def visit_redo_node(node)
|
|
2784
3403
|
bounds(node.location)
|
|
3404
|
+
on_kw("redo")
|
|
2785
3405
|
on_redo
|
|
2786
3406
|
end
|
|
2787
3407
|
|
|
@@ -2824,6 +3444,9 @@ module Prism
|
|
|
2824
3444
|
# foo rescue bar
|
|
2825
3445
|
# ^^^^^^^^^^^^^^
|
|
2826
3446
|
def visit_rescue_modifier_node(node)
|
|
3447
|
+
bounds(node.keyword_loc)
|
|
3448
|
+
on_kw("rescue")
|
|
3449
|
+
|
|
2827
3450
|
expression = visit_write_value(node.expression)
|
|
2828
3451
|
rescue_expression = visit(node.rescue_expression)
|
|
2829
3452
|
|
|
@@ -2834,6 +3457,9 @@ module Prism
|
|
|
2834
3457
|
# begin; rescue; end
|
|
2835
3458
|
# ^^^^^^^
|
|
2836
3459
|
def visit_rescue_node(node)
|
|
3460
|
+
bounds(node.keyword_loc)
|
|
3461
|
+
on_kw("rescue")
|
|
3462
|
+
|
|
2837
3463
|
exceptions =
|
|
2838
3464
|
case node.exceptions.length
|
|
2839
3465
|
when 0
|
|
@@ -2871,6 +3497,11 @@ module Prism
|
|
|
2871
3497
|
end
|
|
2872
3498
|
end
|
|
2873
3499
|
|
|
3500
|
+
if node.operator_loc
|
|
3501
|
+
bounds(node.operator_loc)
|
|
3502
|
+
on_op("=>")
|
|
3503
|
+
end
|
|
3504
|
+
|
|
2874
3505
|
reference = visit(node.reference)
|
|
2875
3506
|
statements =
|
|
2876
3507
|
if node.statements.nil?
|
|
@@ -2892,12 +3523,15 @@ module Prism
|
|
|
2892
3523
|
# def foo(*); end
|
|
2893
3524
|
# ^
|
|
2894
3525
|
def visit_rest_parameter_node(node)
|
|
3526
|
+
bounds(node.operator_loc)
|
|
3527
|
+
on_op("*")
|
|
3528
|
+
|
|
2895
3529
|
if node.name_loc.nil?
|
|
2896
3530
|
bounds(node.location)
|
|
2897
3531
|
on_rest_param(nil)
|
|
2898
3532
|
else
|
|
2899
3533
|
bounds(node.name_loc)
|
|
2900
|
-
on_rest_param(
|
|
3534
|
+
on_rest_param(on_ident(node.name.to_s))
|
|
2901
3535
|
end
|
|
2902
3536
|
end
|
|
2903
3537
|
|
|
@@ -2905,6 +3539,7 @@ module Prism
|
|
|
2905
3539
|
# ^^^^^
|
|
2906
3540
|
def visit_retry_node(node)
|
|
2907
3541
|
bounds(node.location)
|
|
3542
|
+
on_kw("retry")
|
|
2908
3543
|
on_retry
|
|
2909
3544
|
end
|
|
2910
3545
|
|
|
@@ -2914,6 +3549,9 @@ module Prism
|
|
|
2914
3549
|
# return 1
|
|
2915
3550
|
# ^^^^^^^^
|
|
2916
3551
|
def visit_return_node(node)
|
|
3552
|
+
bounds(node.keyword_loc)
|
|
3553
|
+
on_kw("return")
|
|
3554
|
+
|
|
2917
3555
|
if node.arguments.nil?
|
|
2918
3556
|
bounds(node.location)
|
|
2919
3557
|
on_return0
|
|
@@ -2940,9 +3578,17 @@ module Prism
|
|
|
2940
3578
|
# class << self; end
|
|
2941
3579
|
# ^^^^^^^^^^^^^^^^^^
|
|
2942
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
|
+
|
|
2943
3586
|
expression = visit(node.expression)
|
|
2944
3587
|
bodystmt = visit_body_node(node.body&.location || node.end_keyword_loc, node.body)
|
|
2945
3588
|
|
|
3589
|
+
bounds(node.end_keyword_loc)
|
|
3590
|
+
on_kw("end")
|
|
3591
|
+
|
|
2946
3592
|
bounds(node.location)
|
|
2947
3593
|
on_sclass(expression, bodystmt)
|
|
2948
3594
|
end
|
|
@@ -2977,6 +3623,8 @@ module Prism
|
|
|
2977
3623
|
# def foo(*); bar(*); end
|
|
2978
3624
|
# ^
|
|
2979
3625
|
def visit_splat_node(node)
|
|
3626
|
+
bounds(node.operator_loc)
|
|
3627
|
+
on_op("*")
|
|
2980
3628
|
visit(node.expression)
|
|
2981
3629
|
end
|
|
2982
3630
|
|
|
@@ -2999,24 +3647,66 @@ module Prism
|
|
|
2999
3647
|
# "foo"
|
|
3000
3648
|
# ^^^^^
|
|
3001
3649
|
def visit_string_node(node)
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
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)
|
|
3010
3659
|
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3660
|
+
bounds(node.location)
|
|
3661
|
+
on_string_literal(heredoc)
|
|
3662
|
+
else
|
|
3663
|
+
bounds(node.content_loc)
|
|
3664
|
+
tstring_content = on_tstring_content(content)
|
|
3016
3665
|
|
|
3017
|
-
|
|
3018
|
-
|
|
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
|
|
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)
|
|
3019
3707
|
end
|
|
3708
|
+
|
|
3709
|
+
result
|
|
3020
3710
|
end
|
|
3021
3711
|
|
|
3022
3712
|
# Ripper gives back the escaped string content but strips out the common
|
|
@@ -3096,42 +3786,39 @@ module Prism
|
|
|
3096
3786
|
|
|
3097
3787
|
# Visit a heredoc node that is representing a string.
|
|
3098
3788
|
private def visit_heredoc_string_node(node)
|
|
3099
|
-
bounds(node.opening_loc)
|
|
3100
|
-
on_heredoc_beg(node.opening)
|
|
3101
|
-
|
|
3102
3789
|
bounds(node.location)
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
end
|
|
3107
|
-
|
|
3108
|
-
bounds(node.closing_loc)
|
|
3109
|
-
on_heredoc_end(node.closing)
|
|
3110
|
-
|
|
3111
|
-
result
|
|
3790
|
+
visit_heredoc_node(node.parts, on_string_content) do |parts, part|
|
|
3791
|
+
on_string_add(parts, part)
|
|
3792
|
+
end
|
|
3112
3793
|
end
|
|
3113
3794
|
|
|
3114
3795
|
# Visit a heredoc node that is representing an xstring.
|
|
3115
3796
|
private def visit_heredoc_x_string_node(node)
|
|
3116
|
-
bounds(node.opening_loc)
|
|
3117
|
-
on_heredoc_beg(node.opening)
|
|
3118
|
-
|
|
3119
3797
|
bounds(node.location)
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
end
|
|
3124
|
-
|
|
3125
|
-
bounds(node.closing_loc)
|
|
3126
|
-
on_heredoc_end(node.closing)
|
|
3127
|
-
|
|
3128
|
-
result
|
|
3798
|
+
visit_heredoc_node(node.parts, on_xstring_new) do |parts, part|
|
|
3799
|
+
on_xstring_add(parts, part)
|
|
3800
|
+
end
|
|
3129
3801
|
end
|
|
3130
3802
|
|
|
3131
3803
|
# super(foo)
|
|
3132
3804
|
# ^^^^^^^^^^
|
|
3133
3805
|
def visit_super_node(node)
|
|
3134
|
-
|
|
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)
|
|
3135
3822
|
|
|
3136
3823
|
if !node.lparen_loc.nil?
|
|
3137
3824
|
bounds(node.lparen_loc)
|
|
@@ -3141,7 +3828,7 @@ module Prism
|
|
|
3141
3828
|
bounds(node.location)
|
|
3142
3829
|
call = on_super(arguments)
|
|
3143
3830
|
|
|
3144
|
-
if
|
|
3831
|
+
if block_node
|
|
3145
3832
|
bounds(node.block.location)
|
|
3146
3833
|
on_method_add_block(call, block)
|
|
3147
3834
|
else
|
|
@@ -3152,24 +3839,27 @@ module Prism
|
|
|
3152
3839
|
# :foo
|
|
3153
3840
|
# ^^^^
|
|
3154
3841
|
def visit_symbol_node(node)
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3842
|
+
with_string_bounds(node) do
|
|
3843
|
+
if (opening = node.opening)&.match?(/^%s|['"]:?$/)
|
|
3844
|
+
bounds(node.content_loc)
|
|
3845
|
+
content = on_string_content
|
|
3158
3846
|
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3847
|
+
if !(value = node.content).empty?
|
|
3848
|
+
content = on_string_add(content, on_tstring_content(value))
|
|
3849
|
+
end
|
|
3162
3850
|
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
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
|
|
3173
3863
|
end
|
|
3174
3864
|
end
|
|
3175
3865
|
|
|
@@ -3183,6 +3873,9 @@ module Prism
|
|
|
3183
3873
|
# undef foo
|
|
3184
3874
|
# ^^^^^^^^^
|
|
3185
3875
|
def visit_undef_node(node)
|
|
3876
|
+
bounds(node.keyword_loc)
|
|
3877
|
+
on_kw("undef")
|
|
3878
|
+
|
|
3186
3879
|
names = visit_all(node.names)
|
|
3187
3880
|
|
|
3188
3881
|
bounds(node.location)
|
|
@@ -3196,7 +3889,13 @@ module Prism
|
|
|
3196
3889
|
# ^^^^^^^^^^^^^^
|
|
3197
3890
|
def visit_unless_node(node)
|
|
3198
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")
|
|
3199
3894
|
predicate = visit(node.predicate)
|
|
3895
|
+
if node.then_keyword_loc
|
|
3896
|
+
bounds(node.then_keyword_loc)
|
|
3897
|
+
on_kw("then")
|
|
3898
|
+
end
|
|
3200
3899
|
statements =
|
|
3201
3900
|
if node.statements.nil?
|
|
3202
3901
|
bounds(node.location)
|
|
@@ -3206,10 +3905,17 @@ module Prism
|
|
|
3206
3905
|
end
|
|
3207
3906
|
else_clause = visit(node.else_clause)
|
|
3208
3907
|
|
|
3908
|
+
if node.end_keyword_loc && !node.else_clause
|
|
3909
|
+
bounds(node.end_keyword_loc)
|
|
3910
|
+
on_kw("end")
|
|
3911
|
+
end
|
|
3912
|
+
|
|
3209
3913
|
bounds(node.location)
|
|
3210
3914
|
on_unless(predicate, statements, else_clause)
|
|
3211
3915
|
else
|
|
3212
3916
|
statements = visit(node.statements.body.first)
|
|
3917
|
+
bounds(node.unless_keyword_loc)
|
|
3918
|
+
on_kw("unless")
|
|
3213
3919
|
predicate = visit(node.predicate)
|
|
3214
3920
|
|
|
3215
3921
|
bounds(node.location)
|
|
@@ -3223,7 +3929,14 @@ module Prism
|
|
|
3223
3929
|
# bar until foo
|
|
3224
3930
|
# ^^^^^^^^^^^^^
|
|
3225
3931
|
def visit_until_node(node)
|
|
3932
|
+
bounds(node.until_keyword_loc)
|
|
3933
|
+
on_kw("until")
|
|
3934
|
+
|
|
3226
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
|
|
3227
3940
|
predicate = visit(node.predicate)
|
|
3228
3941
|
statements =
|
|
3229
3942
|
if node.statements.nil?
|
|
@@ -3233,6 +3946,11 @@ module Prism
|
|
|
3233
3946
|
visit(node.statements)
|
|
3234
3947
|
end
|
|
3235
3948
|
|
|
3949
|
+
if node.end_keyword_loc
|
|
3950
|
+
bounds(node.end_keyword_loc)
|
|
3951
|
+
on_kw("end")
|
|
3952
|
+
end
|
|
3953
|
+
|
|
3236
3954
|
bounds(node.location)
|
|
3237
3955
|
on_until(predicate, statements)
|
|
3238
3956
|
else
|
|
@@ -3250,7 +3968,14 @@ module Prism
|
|
|
3250
3968
|
# This is a special case where we're not going to call on_when directly
|
|
3251
3969
|
# because we don't have access to the subsequent. Instead, we'll return
|
|
3252
3970
|
# the component parts and let the parent node handle it.
|
|
3971
|
+
bounds(node.when_keyword_loc)
|
|
3972
|
+
on_kw("when")
|
|
3973
|
+
|
|
3253
3974
|
conditions = visit_arguments(node.conditions)
|
|
3975
|
+
if node.then_keyword_loc
|
|
3976
|
+
bounds(node.then_keyword_loc)
|
|
3977
|
+
on_kw("then")
|
|
3978
|
+
end
|
|
3254
3979
|
statements =
|
|
3255
3980
|
if node.statements.nil?
|
|
3256
3981
|
bounds(node.location)
|
|
@@ -3269,7 +3994,17 @@ module Prism
|
|
|
3269
3994
|
# ^^^^^^^^^^^^^
|
|
3270
3995
|
def visit_while_node(node)
|
|
3271
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
|
|
3272
4003
|
predicate = visit(node.predicate)
|
|
4004
|
+
if node.end_keyword_loc
|
|
4005
|
+
bounds(node.end_keyword_loc)
|
|
4006
|
+
on_kw("end")
|
|
4007
|
+
end
|
|
3273
4008
|
statements =
|
|
3274
4009
|
if node.statements.nil?
|
|
3275
4010
|
bounds(node.location)
|
|
@@ -3282,6 +4017,8 @@ module Prism
|
|
|
3282
4017
|
on_while(predicate, statements)
|
|
3283
4018
|
else
|
|
3284
4019
|
statements = visit(node.statements.body.first)
|
|
4020
|
+
bounds(node.while_keyword_loc)
|
|
4021
|
+
on_kw("while")
|
|
3285
4022
|
predicate = visit(node.predicate)
|
|
3286
4023
|
|
|
3287
4024
|
bounds(node.location)
|
|
@@ -3292,20 +4029,22 @@ module Prism
|
|
|
3292
4029
|
# `foo`
|
|
3293
4030
|
# ^^^^^
|
|
3294
4031
|
def visit_x_string_node(node)
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
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)
|
|
3300
4038
|
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
4039
|
+
bounds(node.location)
|
|
4040
|
+
on_xstring_literal(heredoc)
|
|
4041
|
+
else
|
|
4042
|
+
bounds(node.content_loc)
|
|
4043
|
+
content = on_tstring_content(node.content)
|
|
3306
4044
|
|
|
3307
|
-
|
|
3308
|
-
|
|
4045
|
+
bounds(node.location)
|
|
4046
|
+
on_xstring_literal(on_xstring_add(on_xstring_new, content))
|
|
4047
|
+
end
|
|
3309
4048
|
end
|
|
3310
4049
|
end
|
|
3311
4050
|
|
|
@@ -3315,10 +4054,18 @@ module Prism
|
|
|
3315
4054
|
# yield 1
|
|
3316
4055
|
# ^^^^^^^
|
|
3317
4056
|
def visit_yield_node(node)
|
|
4057
|
+
bounds(node.keyword_loc)
|
|
4058
|
+
on_kw("yield")
|
|
4059
|
+
|
|
3318
4060
|
if node.arguments.nil? && node.lparen_loc.nil?
|
|
3319
4061
|
bounds(node.location)
|
|
3320
4062
|
on_yield0
|
|
3321
4063
|
else
|
|
4064
|
+
if node.lparen_loc
|
|
4065
|
+
bounds(node.lparen_loc)
|
|
4066
|
+
on_lparen("(")
|
|
4067
|
+
end
|
|
4068
|
+
|
|
3322
4069
|
arguments =
|
|
3323
4070
|
if node.arguments.nil?
|
|
3324
4071
|
bounds(node.location)
|
|
@@ -3328,6 +4075,8 @@ module Prism
|
|
|
3328
4075
|
end
|
|
3329
4076
|
|
|
3330
4077
|
unless node.lparen_loc.nil?
|
|
4078
|
+
bounds(node.rparen_loc)
|
|
4079
|
+
on_rparen(")")
|
|
3331
4080
|
bounds(node.lparen_loc)
|
|
3332
4081
|
arguments = on_paren(arguments)
|
|
3333
4082
|
end
|
|
@@ -3341,7 +4090,11 @@ module Prism
|
|
|
3341
4090
|
|
|
3342
4091
|
# Lazily initialize the parse result.
|
|
3343
4092
|
def result
|
|
3344
|
-
@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)
|
|
3345
4098
|
end
|
|
3346
4099
|
|
|
3347
4100
|
##########################################################################
|
|
@@ -3362,30 +4115,34 @@ module Prism
|
|
|
3362
4115
|
# Visit the string content of a particular node. This method is used to
|
|
3363
4116
|
# split into the various token types.
|
|
3364
4117
|
def visit_token(token, allow_keywords = true)
|
|
3365
|
-
|
|
3366
|
-
when "."
|
|
4118
|
+
if token == "."
|
|
3367
4119
|
on_period(token)
|
|
3368
|
-
|
|
4120
|
+
elsif token == "`"
|
|
3369
4121
|
on_backtick(token)
|
|
3370
|
-
|
|
4122
|
+
elsif allow_keywords && KEYWORDS.include?(token)
|
|
3371
4123
|
on_kw(token)
|
|
3372
|
-
|
|
4124
|
+
elsif token.start_with?("_")
|
|
3373
4125
|
on_ident(token)
|
|
3374
|
-
|
|
4126
|
+
elsif token.match?(/^[[:upper:]]\w*$/)
|
|
3375
4127
|
on_const(token)
|
|
3376
|
-
|
|
4128
|
+
elsif token.start_with?("@@")
|
|
3377
4129
|
on_cvar(token)
|
|
3378
|
-
|
|
4130
|
+
elsif token.start_with?("@")
|
|
3379
4131
|
on_ivar(token)
|
|
3380
|
-
|
|
4132
|
+
elsif token.start_with?("$")
|
|
3381
4133
|
on_gvar(token)
|
|
3382
|
-
|
|
4134
|
+
elsif token.match?(/^[[:punct:]]/)
|
|
3383
4135
|
on_op(token)
|
|
3384
4136
|
else
|
|
3385
4137
|
on_ident(token)
|
|
3386
4138
|
end
|
|
3387
4139
|
end
|
|
3388
4140
|
|
|
4141
|
+
# Visit either `.`, `&.`, or `::`.
|
|
4142
|
+
def visit_call_operator(token)
|
|
4143
|
+
token == "." ? on_period(token) : on_op(token)
|
|
4144
|
+
end
|
|
4145
|
+
|
|
3389
4146
|
# Visit a node that represents a number. We need to explicitly handle the
|
|
3390
4147
|
# unary - operator.
|
|
3391
4148
|
def visit_number_node(node)
|
|
@@ -3393,6 +4150,9 @@ module Prism
|
|
|
3393
4150
|
location = node.location
|
|
3394
4151
|
|
|
3395
4152
|
if slice[0] == "-"
|
|
4153
|
+
bounds(location.copy(length: 1))
|
|
4154
|
+
on_op("-")
|
|
4155
|
+
|
|
3396
4156
|
bounds(location.copy(start_offset: location.start_offset + 1))
|
|
3397
4157
|
value = yield slice[1..-1]
|
|
3398
4158
|
|
|
@@ -3441,14 +4201,12 @@ module Prism
|
|
|
3441
4201
|
|
|
3442
4202
|
# This method is responsible for updating lineno and column information
|
|
3443
4203
|
# to reflect the current node.
|
|
3444
|
-
#
|
|
3445
|
-
# This method could be drastically improved with some caching on the start
|
|
3446
|
-
# of every line, but for now it's good enough.
|
|
3447
4204
|
def bounds(location)
|
|
3448
|
-
@lineno = location.
|
|
3449
|
-
@column = location.start_column
|
|
4205
|
+
@lineno, @column = line_and_column_cache.line_and_column(location.start_offset)
|
|
3450
4206
|
end
|
|
3451
4207
|
|
|
4208
|
+
# :startdoc:
|
|
4209
|
+
|
|
3452
4210
|
##########################################################################
|
|
3453
4211
|
# Ripper interface
|
|
3454
4212
|
##########################################################################
|