summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2023-10-17 11:45:49 -0400
committergit <svn-admin@ruby-lang.org>2023-10-18 16:09:16 +0000
commit8210cc4218b639b699c73ac273b62422d5718e10 (patch)
tree921cdeb6a614fb703e7cc3187ce8546b698ba9b1
parentc82b10bbc3a3293ba9464c27ac5e778c70d2fe9b (diff)
[ruby/prism] Fix lex compat when dedent should be 0
https://github.com/ruby/prism/commit/41c0e0e06e
-rw-r--r--lib/prism/lex_compat.rb9
-rw-r--r--test/prism/fixtures/tilde_heredocs.txt6
-rw-r--r--test/prism/heredoc_dedent_test.rb5
-rw-r--r--test/prism/snapshots/tilde_heredocs.txt350
4 files changed, 209 insertions, 161 deletions
diff --git a/lib/prism/lex_compat.rb b/lib/prism/lex_compat.rb
index a17d4eaadd..4801fe364b 100644
--- a/lib/prism/lex_compat.rb
+++ b/lib/prism/lex_compat.rb
@@ -357,6 +357,7 @@ module Prism
@dedent_next = true
@dedent = nil
@embexpr_balance = 0
+ @ended_on_newline = false
end
# As tokens are coming in, we track the minimum amount of common leading
@@ -366,13 +367,14 @@ module Prism
case token.event
when :on_embexpr_beg, :on_heredoc_beg
@embexpr_balance += 1
+ @dedent = 0 if @dedent_next && @ended_on_newline
when :on_embexpr_end, :on_heredoc_end
@embexpr_balance -= 1
when :on_tstring_content
if embexpr_balance == 0
line = token.value
- if !(line.strip.empty? && line.end_with?("\n")) && dedent_next
+ if dedent_next && !(line.strip.empty? && line.end_with?("\n"))
leading = line[/\A(\s*)\n?/, 1]
next_dedent = 0
@@ -385,11 +387,16 @@ module Prism
end
@dedent = [dedent, next_dedent].compact.min
+ @dedent_next = true
+ @ended_on_newline = line.end_with?("\n")
+ tokens << token
+ return
end
end
end
@dedent_next = token.event == :on_tstring_content && embexpr_balance == 0
+ @ended_on_newline = false
tokens << token
end
diff --git a/test/prism/fixtures/tilde_heredocs.txt b/test/prism/fixtures/tilde_heredocs.txt
index 415d4d42c8..cca47ef00b 100644
--- a/test/prism/fixtures/tilde_heredocs.txt
+++ b/test/prism/fixtures/tilde_heredocs.txt
@@ -1,5 +1,11 @@
<<~EOF
a
+#{1}
+ a
+EOF
+
+<<~EOF
+ a
EOF
<<~EOF
diff --git a/test/prism/heredoc_dedent_test.rb b/test/prism/heredoc_dedent_test.rb
index 1943235731..9fbc4d936a 100644
--- a/test/prism/heredoc_dedent_test.rb
+++ b/test/prism/heredoc_dedent_test.rb
@@ -7,8 +7,13 @@ module Prism
filepath = File.expand_path("fixtures/tilde_heredocs.txt", __dir__)
File.read(filepath).split(/(?=\n)\n(?=<)/).each_with_index do |heredoc, index|
+ # The first example in this file has incorrect dedent calculated by
+ # TruffleRuby so we skip it.
+ next if index == 0 && RUBY_ENGINE == "truffleruby"
+
define_method "test_heredoc_#{index}" do
node = Prism.parse(heredoc).value.statements.body.first
+
if node.is_a?(StringNode)
actual = node.unescaped
else
diff --git a/test/prism/snapshots/tilde_heredocs.txt b/test/prism/snapshots/tilde_heredocs.txt
index 3d3335776d..3f9ca04707 100644
--- a/test/prism/snapshots/tilde_heredocs.txt
+++ b/test/prism/snapshots/tilde_heredocs.txt
@@ -1,247 +1,255 @@
-@ ProgramNode (location: (1,0)-(88,6))
+@ ProgramNode (location: (1,0)-(94,6))
├── locals: []
└── statements:
- @ StatementsNode (location: (1,0)-(88,6))
- └── body: (length: 18)
- ├── @ StringNode (location: (1,0)-(1,6))
- │ ├── flags: ∅
+ @ StatementsNode (location: (1,0)-(94,6))
+ └── body: (length: 19)
+ ├── @ InterpolatedStringNode (location: (1,0)-(1,6))
│ ├── opening_loc: (1,0)-(1,6) = "<<~EOF"
- │ ├── content_loc: (2,0)-(2,0) = " a\n"
- │ ├── closing_loc: (3,0)-(3,0) = "EOF\n"
+ │ ├── parts: (length: 4)
+ │ │ ├── @ StringNode (location: (2,0)-(2,0))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(2,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (3,0)-(3,4))
+ │ │ │ ├── opening_loc: (3,0)-(3,2) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (3,2)-(3,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (3,2)-(3,3))
+ │ │ │ │ └── flags: decimal
+ │ │ │ └── closing_loc: (3,3)-(3,4) = "}"
+ │ │ ├── @ StringNode (location: (3,4)-(3,0))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,4)-(3,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── @ StringNode (location: (4,0)-(4,0))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (4,0)-(4,0) = " a\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " a\n"
+ │ └── closing_loc: (5,0)-(5,0) = "EOF\n"
+ ├── @ StringNode (location: (7,0)-(7,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (7,0)-(7,6) = "<<~EOF"
+ │ ├── content_loc: (8,0)-(8,0) = " a\n"
+ │ ├── closing_loc: (9,0)-(9,0) = "EOF\n"
│ └── unescaped: "a\n"
- ├── @ InterpolatedStringNode (location: (5,0)-(5,6))
- │ ├── opening_loc: (5,0)-(5,6) = "<<~EOF"
+ ├── @ InterpolatedStringNode (location: (11,0)-(11,6))
+ │ ├── opening_loc: (11,0)-(11,6) = "<<~EOF"
│ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (6,0)-(6,0))
+ │ │ ├── @ StringNode (location: (12,0)-(12,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (6,0)-(6,0) = "\ta\n"
+ │ │ │ ├── content_loc: (12,0)-(12,0) = "\ta\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "\ta\n"
- │ │ ├── @ StringNode (location: (7,0)-(7,0))
+ │ │ ├── @ StringNode (location: (13,0)-(13,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (7,0)-(7,0) = " b\n"
+ │ │ │ ├── content_loc: (13,0)-(13,0) = " b\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "b\n"
- │ │ └── @ StringNode (location: (8,0)-(8,0))
+ │ │ └── @ StringNode (location: (14,0)-(14,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (8,0)-(8,0) = "\t\tc\n"
+ │ │ ├── content_loc: (14,0)-(14,0) = "\t\tc\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "\t\tc\n"
- │ └── closing_loc: (9,0)-(9,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (11,0)-(11,6))
- │ ├── opening_loc: (11,0)-(11,6) = "<<~EOF"
+ │ └── closing_loc: (15,0)-(15,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (17,0)-(17,6))
+ │ ├── opening_loc: (17,0)-(17,6) = "<<~EOF"
│ ├── parts: (length: 2)
- │ │ ├── @ EmbeddedStatementsNode (location: (12,2)-(12,6))
- │ │ │ ├── opening_loc: (12,2)-(12,4) = "\#{"
+ │ │ ├── @ EmbeddedStatementsNode (location: (18,2)-(18,6))
+ │ │ │ ├── opening_loc: (18,2)-(18,4) = "\#{"
│ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (12,4)-(12,5))
+ │ │ │ │ @ StatementsNode (location: (18,4)-(18,5))
│ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (12,4)-(12,5))
+ │ │ │ │ └── @ IntegerNode (location: (18,4)-(18,5))
│ │ │ │ └── flags: decimal
- │ │ │ └── closing_loc: (12,5)-(12,6) = "}"
- │ │ └── @ StringNode (location: (12,6)-(12,0))
+ │ │ │ └── closing_loc: (18,5)-(18,6) = "}"
+ │ │ └── @ StringNode (location: (18,6)-(18,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (12,6)-(12,0) = " a\n"
+ │ │ ├── content_loc: (18,6)-(18,0) = " a\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: " a\n"
- │ └── closing_loc: (13,0)-(13,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (15,0)-(15,6))
- │ ├── opening_loc: (15,0)-(15,6) = "<<~EOF"
+ │ └── closing_loc: (19,0)-(19,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (21,0)-(21,6))
+ │ ├── opening_loc: (21,0)-(21,6) = "<<~EOF"
│ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (16,0)-(16,4))
+ │ │ ├── @ StringNode (location: (22,0)-(22,4))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (16,0)-(16,4) = " a "
+ │ │ │ ├── content_loc: (22,0)-(22,4) = " a "
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "a "
- │ │ ├── @ EmbeddedStatementsNode (location: (16,4)-(16,8))
- │ │ │ ├── opening_loc: (16,4)-(16,6) = "\#{"
+ │ │ ├── @ EmbeddedStatementsNode (location: (22,4)-(22,8))
+ │ │ │ ├── opening_loc: (22,4)-(22,6) = "\#{"
│ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (16,6)-(16,7))
+ │ │ │ │ @ StatementsNode (location: (22,6)-(22,7))
│ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (16,6)-(16,7))
+ │ │ │ │ └── @ IntegerNode (location: (22,6)-(22,7))
│ │ │ │ └── flags: decimal
- │ │ │ └── closing_loc: (16,7)-(16,8) = "}"
- │ │ └── @ StringNode (location: (16,8)-(16,0))
+ │ │ │ └── closing_loc: (22,7)-(22,8) = "}"
+ │ │ └── @ StringNode (location: (22,8)-(22,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (16,8)-(16,0) = "\n"
+ │ │ ├── content_loc: (22,8)-(22,0) = "\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "\n"
- │ └── closing_loc: (17,0)-(17,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (19,0)-(19,6))
- │ ├── opening_loc: (19,0)-(19,6) = "<<~EOF"
+ │ └── closing_loc: (23,0)-(23,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (25,0)-(25,6))
+ │ ├── opening_loc: (25,0)-(25,6) = "<<~EOF"
│ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (20,0)-(20,0))
+ │ │ ├── @ StringNode (location: (26,0)-(26,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (20,0)-(20,0) = " a\n"
+ │ │ │ ├── content_loc: (26,0)-(26,0) = " a\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: " a\n"
- │ │ ├── @ EmbeddedStatementsNode (location: (21,1)-(21,5))
- │ │ │ ├── opening_loc: (21,1)-(21,3) = "\#{"
+ │ │ ├── @ EmbeddedStatementsNode (location: (27,1)-(27,5))
+ │ │ │ ├── opening_loc: (27,1)-(27,3) = "\#{"
│ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (21,3)-(21,4))
+ │ │ │ │ @ StatementsNode (location: (27,3)-(27,4))
│ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (21,3)-(21,4))
+ │ │ │ │ └── @ IntegerNode (location: (27,3)-(27,4))
│ │ │ │ └── flags: decimal
- │ │ │ └── closing_loc: (21,4)-(21,5) = "}"
- │ │ └── @ StringNode (location: (21,5)-(21,0))
+ │ │ │ └── closing_loc: (27,4)-(27,5) = "}"
+ │ │ └── @ StringNode (location: (27,5)-(27,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (21,5)-(21,0) = "\n"
+ │ │ ├── content_loc: (27,5)-(27,0) = "\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "\n"
- │ └── closing_loc: (22,0)-(22,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (24,0)-(24,6))
- │ ├── opening_loc: (24,0)-(24,6) = "<<~EOF"
+ │ └── closing_loc: (28,0)-(28,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (30,0)-(30,6))
+ │ ├── opening_loc: (30,0)-(30,6) = "<<~EOF"
│ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (25,0)-(25,0))
+ │ │ ├── @ StringNode (location: (31,0)-(31,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (25,0)-(25,0) = " a\n"
+ │ │ │ ├── content_loc: (31,0)-(31,0) = " a\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "a\n"
- │ │ ├── @ EmbeddedStatementsNode (location: (26,2)-(26,6))
- │ │ │ ├── opening_loc: (26,2)-(26,4) = "\#{"
+ │ │ ├── @ EmbeddedStatementsNode (location: (32,2)-(32,6))
+ │ │ │ ├── opening_loc: (32,2)-(32,4) = "\#{"
│ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (26,4)-(26,5))
+ │ │ │ │ @ StatementsNode (location: (32,4)-(32,5))
│ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (26,4)-(26,5))
+ │ │ │ │ └── @ IntegerNode (location: (32,4)-(32,5))
│ │ │ │ └── flags: decimal
- │ │ │ └── closing_loc: (26,5)-(26,6) = "}"
- │ │ └── @ StringNode (location: (26,6)-(26,0))
+ │ │ │ └── closing_loc: (32,5)-(32,6) = "}"
+ │ │ └── @ StringNode (location: (32,6)-(32,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (26,6)-(26,0) = "\n"
+ │ │ ├── content_loc: (32,6)-(32,0) = "\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "\n"
- │ └── closing_loc: (27,0)-(27,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (29,0)-(29,6))
- │ ├── opening_loc: (29,0)-(29,6) = "<<~EOF"
+ │ └── closing_loc: (33,0)-(33,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (35,0)-(35,6))
+ │ ├── opening_loc: (35,0)-(35,6) = "<<~EOF"
│ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (30,0)-(30,0))
+ │ │ ├── @ StringNode (location: (36,0)-(36,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (30,0)-(30,0) = " a\n"
+ │ │ │ ├── content_loc: (36,0)-(36,0) = " a\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (31,0)-(31,0))
+ │ │ └── @ StringNode (location: (37,0)-(37,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (31,0)-(31,0) = " b\n"
+ │ │ ├── content_loc: (37,0)-(37,0) = " b\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "b\n"
- │ └── closing_loc: (32,0)-(32,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (34,0)-(34,6))
- │ ├── opening_loc: (34,0)-(34,6) = "<<~EOF"
+ │ └── closing_loc: (38,0)-(38,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (40,0)-(40,6))
+ │ ├── opening_loc: (40,0)-(40,6) = "<<~EOF"
│ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (35,0)-(35,0))
+ │ │ ├── @ StringNode (location: (41,0)-(41,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (35,0)-(35,0) = " a\n"
+ │ │ │ ├── content_loc: (41,0)-(41,0) = " a\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (36,0)-(36,0))
+ │ │ └── @ StringNode (location: (42,0)-(42,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (36,0)-(36,0) = " b\n"
+ │ │ ├── content_loc: (42,0)-(42,0) = " b\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: " b\n"
- │ └── closing_loc: (37,0)-(37,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (39,0)-(39,6))
- │ ├── opening_loc: (39,0)-(39,6) = "<<~EOF"
+ │ └── closing_loc: (43,0)-(43,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (45,0)-(45,6))
+ │ ├── opening_loc: (45,0)-(45,6) = "<<~EOF"
│ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (40,0)-(40,0))
+ │ │ ├── @ StringNode (location: (46,0)-(46,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (40,0)-(40,0) = "\t\t\ta\n"
+ │ │ │ ├── content_loc: (46,0)-(46,0) = "\t\t\ta\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "\ta\n"
- │ │ └── @ StringNode (location: (41,0)-(41,0))
+ │ │ └── @ StringNode (location: (47,0)-(47,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (41,0)-(41,0) = "\t\tb\n"
+ │ │ ├── content_loc: (47,0)-(47,0) = "\t\tb\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "b\n"
- │ └── closing_loc: (42,0)-(42,0) = "EOF\n"
- ├── @ StringNode (location: (44,0)-(44,8))
+ │ └── closing_loc: (48,0)-(48,0) = "EOF\n"
+ ├── @ StringNode (location: (50,0)-(50,8))
│ ├── flags: ∅
- │ ├── opening_loc: (44,0)-(44,8) = "<<~'EOF'"
- │ ├── content_loc: (45,0)-(45,0) = " a \#{1}\n"
- │ ├── closing_loc: (46,0)-(46,0) = "EOF\n"
+ │ ├── opening_loc: (50,0)-(50,8) = "<<~'EOF'"
+ │ ├── content_loc: (51,0)-(51,0) = " a \#{1}\n"
+ │ ├── closing_loc: (52,0)-(52,0) = "EOF\n"
│ └── unescaped: "a \#{1}\n"
- ├── @ InterpolatedStringNode (location: (48,0)-(48,6))
- │ ├── opening_loc: (48,0)-(48,6) = "<<~EOF"
+ ├── @ InterpolatedStringNode (location: (54,0)-(54,6))
+ │ ├── opening_loc: (54,0)-(54,6) = "<<~EOF"
│ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (49,0)-(49,0))
+ │ │ ├── @ StringNode (location: (55,0)-(55,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (49,0)-(49,0) = "\ta\n"
+ │ │ │ ├── content_loc: (55,0)-(55,0) = "\ta\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (50,0)-(50,0))
+ │ │ └── @ StringNode (location: (56,0)-(56,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (50,0)-(50,0) = "\t b\n"
+ │ │ ├── content_loc: (56,0)-(56,0) = "\t b\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: " b\n"
- │ └── closing_loc: (51,0)-(51,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (53,0)-(53,6))
- │ ├── opening_loc: (53,0)-(53,6) = "<<~EOF"
+ │ └── closing_loc: (57,0)-(57,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (59,0)-(59,6))
+ │ ├── opening_loc: (59,0)-(59,6) = "<<~EOF"
│ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (54,0)-(54,0))
+ │ │ ├── @ StringNode (location: (60,0)-(60,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (54,0)-(54,0) = "\t a\n"
+ │ │ │ ├── content_loc: (60,0)-(60,0) = "\t a\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: " a\n"
- │ │ └── @ StringNode (location: (55,0)-(55,0))
+ │ │ └── @ StringNode (location: (61,0)-(61,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (55,0)-(55,0) = "\tb\n"
+ │ │ ├── content_loc: (61,0)-(61,0) = "\tb\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "b\n"
- │ └── closing_loc: (56,0)-(56,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (58,0)-(58,6))
- │ ├── opening_loc: (58,0)-(58,6) = "<<~EOF"
+ │ └── closing_loc: (62,0)-(62,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (64,0)-(64,6))
+ │ ├── opening_loc: (64,0)-(64,6) = "<<~EOF"
│ ├── parts: (length: 2)
- │ │ ├── @ StringNode (location: (59,0)-(59,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (59,0)-(59,0) = " \ta\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
- │ │ └── @ StringNode (location: (60,0)-(60,0))
- │ │ ├── flags: ∅
- │ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (60,0)-(60,0) = " b\n"
- │ │ ├── closing_loc: ∅
- │ │ └── unescaped: "b\n"
- │ └── closing_loc: (61,0)-(61,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (63,0)-(63,6))
- │ ├── opening_loc: (63,0)-(63,6) = "<<~EOF"
- │ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (64,0)-(64,0))
- │ │ │ ├── flags: ∅
- │ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (64,0)-(64,0) = " a\n"
- │ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "a\n"
│ │ ├── @ StringNode (location: (65,0)-(65,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (65,0)-(65,0) = "\n"
+ │ │ │ ├── content_loc: (65,0)-(65,0) = " \ta\n"
│ │ │ ├── closing_loc: ∅
- │ │ │ └── unescaped: "\n"
+ │ │ │ └── unescaped: "a\n"
│ │ └── @ StringNode (location: (66,0)-(66,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (66,0)-(66,0) = " b\n"
+ │ │ ├── content_loc: (66,0)-(66,0) = " b\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "b\n"
│ └── closing_loc: (67,0)-(67,0) = "EOF\n"
@@ -269,7 +277,7 @@
│ └── closing_loc: (73,0)-(73,0) = "EOF\n"
├── @ InterpolatedStringNode (location: (75,0)-(75,6))
│ ├── opening_loc: (75,0)-(75,6) = "<<~EOF"
- │ ├── parts: (length: 5)
+ │ ├── parts: (length: 3)
│ │ ├── @ StringNode (location: (76,0)-(76,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
@@ -282,70 +290,92 @@
│ │ │ ├── content_loc: (77,0)-(77,0) = "\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "\n"
- │ │ ├── @ StringNode (location: (78,0)-(78,0))
+ │ │ └── @ StringNode (location: (78,0)-(78,0))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (78,0)-(78,0) = " b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n"
+ │ └── closing_loc: (79,0)-(79,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (81,0)-(81,6))
+ │ ├── opening_loc: (81,0)-(81,6) = "<<~EOF"
+ │ ├── parts: (length: 5)
+ │ │ ├── @ StringNode (location: (82,0)-(82,0))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (82,0)-(82,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── @ StringNode (location: (83,0)-(83,0))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (83,0)-(83,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ ├── @ StringNode (location: (84,0)-(84,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (78,0)-(78,0) = "\n"
+ │ │ │ ├── content_loc: (84,0)-(84,0) = "\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "\n"
- │ │ ├── @ StringNode (location: (79,0)-(79,0))
+ │ │ ├── @ StringNode (location: (85,0)-(85,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (79,0)-(79,0) = "\n"
+ │ │ │ ├── content_loc: (85,0)-(85,0) = "\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "\n"
- │ │ └── @ StringNode (location: (80,0)-(80,0))
+ │ │ └── @ StringNode (location: (86,0)-(86,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (80,0)-(80,0) = " b\n"
+ │ │ ├── content_loc: (86,0)-(86,0) = " b\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "b\n"
- │ └── closing_loc: (81,0)-(81,0) = "EOF\n"
- ├── @ InterpolatedStringNode (location: (83,0)-(83,6))
- │ ├── opening_loc: (83,0)-(83,6) = "<<~EOF"
+ │ └── closing_loc: (87,0)-(87,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (89,0)-(89,6))
+ │ ├── opening_loc: (89,0)-(89,6) = "<<~EOF"
│ ├── parts: (length: 3)
- │ │ ├── @ StringNode (location: (84,0)-(84,0))
+ │ │ ├── @ StringNode (location: (90,0)-(90,0))
│ │ │ ├── flags: ∅
│ │ │ ├── opening_loc: ∅
- │ │ │ ├── content_loc: (84,0)-(84,0) = "\n"
+ │ │ │ ├── content_loc: (90,0)-(90,0) = "\n"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "\n"
- │ │ ├── @ EmbeddedStatementsNode (location: (85,2)-(85,6))
- │ │ │ ├── opening_loc: (85,2)-(85,4) = "\#{"
+ │ │ ├── @ EmbeddedStatementsNode (location: (91,2)-(91,6))
+ │ │ │ ├── opening_loc: (91,2)-(91,4) = "\#{"
│ │ │ ├── statements:
- │ │ │ │ @ StatementsNode (location: (85,4)-(85,5))
+ │ │ │ │ @ StatementsNode (location: (91,4)-(91,5))
│ │ │ │ └── body: (length: 1)
- │ │ │ │ └── @ IntegerNode (location: (85,4)-(85,5))
+ │ │ │ │ └── @ IntegerNode (location: (91,4)-(91,5))
│ │ │ │ └── flags: decimal
- │ │ │ └── closing_loc: (85,5)-(85,6) = "}"
- │ │ └── @ StringNode (location: (85,6)-(85,0))
+ │ │ │ └── closing_loc: (91,5)-(91,6) = "}"
+ │ │ └── @ StringNode (location: (91,6)-(91,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (85,6)-(85,0) = "a\n"
+ │ │ ├── content_loc: (91,6)-(91,0) = "a\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "a\n"
- │ └── closing_loc: (86,0)-(86,0) = " EOF\n"
- └── @ InterpolatedStringNode (location: (88,0)-(88,6))
- ├── opening_loc: (88,0)-(88,6) = "<<~EOT"
+ │ └── closing_loc: (92,0)-(92,0) = " EOF\n"
+ └── @ InterpolatedStringNode (location: (94,0)-(94,6))
+ ├── opening_loc: (94,0)-(94,6) = "<<~EOT"
├── parts: (length: 3)
- │ ├── @ EmbeddedStatementsNode (location: (89,2)-(89,6))
- │ │ ├── opening_loc: (89,2)-(89,4) = "\#{"
+ │ ├── @ EmbeddedStatementsNode (location: (95,2)-(95,6))
+ │ │ ├── opening_loc: (95,2)-(95,4) = "\#{"
│ │ ├── statements:
- │ │ │ @ StatementsNode (location: (89,4)-(89,5))
+ │ │ │ @ StatementsNode (location: (95,4)-(95,5))
│ │ │ └── body: (length: 1)
- │ │ │ └── @ IntegerNode (location: (89,4)-(89,5))
+ │ │ │ └── @ IntegerNode (location: (95,4)-(95,5))
│ │ │ └── flags: decimal
- │ │ └── closing_loc: (89,5)-(89,6) = "}"
- │ ├── @ StringNode (location: (89,6)-(89,0))
+ │ │ └── closing_loc: (95,5)-(95,6) = "}"
+ │ ├── @ StringNode (location: (95,6)-(95,0))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
- │ │ ├── content_loc: (89,6)-(89,0) = "\n"
+ │ │ ├── content_loc: (95,6)-(95,0) = "\n"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "\n"
- │ └── @ StringNode (location: (90,0)-(90,0))
+ │ └── @ StringNode (location: (96,0)-(96,0))
│ ├── flags: ∅
│ ├── opening_loc: ∅
- │ ├── content_loc: (90,0)-(90,0) = "\tb\n"
+ │ ├── content_loc: (96,0)-(96,0) = "\tb\n"
│ ├── closing_loc: ∅
│ └── unescaped: "\tb\n"
- └── closing_loc: (91,0)-(91,0) = "EOT\n"
+ └── closing_loc: (97,0)-(97,0) = "EOT\n"