From 26370079291a420c6b2b7be5cdbd5c609da62f21 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Wed, 8 Jan 2025 21:17:21 +0100 Subject: [PATCH] Better handle all kinds of multiline strings in the parser translator This is a followup to #3373, where the implementation was extracted --- lib/prism/translation/parser/compiler.rb | 105 ++---- test/prism/fixtures/dstring.txt | 6 + test/prism/fixtures/strings.txt | 5 + test/prism/fixtures/symbols.txt | 11 + test/prism/fixtures/xstring.txt | 5 + test/prism/snapshots/dstring.txt | 36 +- test/prism/snapshots/strings.txt | 402 +++++++++++----------- test/prism/snapshots/symbols.txt | 420 ++++++++++++----------- test/prism/snapshots/xstring.txt | 20 +- 9 files changed, 532 insertions(+), 478 deletions(-) diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb index 27af56e03e..e6ffa39d9d 100644 --- a/lib/prism/translation/parser/compiler.rb +++ b/lib/prism/translation/parser/compiler.rb @@ -1085,21 +1085,13 @@ def visit_interpolated_string_node(node) return visit_heredoc(node) { |children, closing| builder.string_compose(token(node.opening_loc), children, closing) } end - parts = node.parts.flat_map do |node| + parts = node.parts.flat_map do |part| # When the content of a string node is split across multiple lines, the # parser gem creates individual string nodes for each line the content is part of. - if node.type == :string_node && node.content.include?("\n") && node.opening_loc.nil? - start_offset = node.content_loc.start_offset - - node.unescaped.lines.map do |line| - end_offset = start_offset + line.bytesize - offsets = srange_offsets(start_offset, end_offset) - start_offset = end_offset - - builder.string_internal([line, offsets]) - end + if part.type == :string_node && part.content.include?("\n") && part.opening_loc.nil? + string_nodes_from_line_continuations(part.unescaped, part.content, part.content_loc.start_offset, node.opening) else - visit(node) + visit(part) end end @@ -1513,7 +1505,7 @@ def visit_regular_expression_node(node) if node.content == "" [] elsif node.content.include?("\n") - string_nodes_from_line_continuations(node, node.content_loc.start_offset, node.opening) + string_nodes_from_line_continuations(node.unescaped, node.content, node.content_loc.start_offset, node.opening) else [builder.string_internal(token(node.content_loc))] end @@ -1672,28 +1664,11 @@ def visit_string_node(node) elsif node.opening&.start_with?("%") && node.unescaped.empty? builder.string_compose(token(node.opening_loc), [], token(node.closing_loc)) else - content_lines = node.content.lines - unescaped_lines = node.unescaped.lines - parts = - if content_lines.length <= 1 || unescaped_lines.length <= 1 - [builder.string_internal([node.unescaped, srange(node.content_loc)])] - elsif content_lines.length != unescaped_lines.length - # This occurs when we have line continuations in the string. We - # need to come back and fix this, but for now this stops the - # code from breaking when we encounter it because of trying to - # transpose arrays of different lengths. - [builder.string_internal([node.unescaped, srange(node.content_loc)])] + if node.content.include?("\n") + string_nodes_from_line_continuations(node.unescaped, node.content, node.content_loc.start_offset, node.opening) else - start_offset = node.content_loc.start_offset - - [content_lines, unescaped_lines].transpose.map do |content_line, unescaped_line| - end_offset = start_offset + content_line.bytesize - offsets = srange_offsets(start_offset, end_offset) - start_offset = end_offset - - builder.string_internal([unescaped_line, offsets]) - end + [builder.string_internal([node.unescaped, srange(node.content_loc)])] end builder.string_compose( @@ -1737,19 +1712,14 @@ def visit_symbol_node(node) builder.symbol([node.unescaped, srange(node.location)]) end else - parts = if node.value.lines.one? - [builder.string_internal([node.unescaped, srange(node.value_loc)])] - else - start_offset = node.value_loc.start_offset - - node.value.lines.map do |line| - end_offset = start_offset + line.bytesize - offsets = srange_offsets(start_offset, end_offset) - start_offset = end_offset - - builder.string_internal([line, offsets]) + parts = + if node.value == "" + [] + elsif node.value.include?("\n") + string_nodes_from_line_continuations(node.unescaped, node.value, node.value_loc.start_offset, node.opening) + else + [builder.string_internal([node.unescaped, srange(node.value_loc)])] end - end builder.symbol_compose( token(node.opening_loc), @@ -1878,28 +1848,23 @@ def visit_while_node(node) # ^^^^^ def visit_x_string_node(node) if node.heredoc? - visit_heredoc(node.to_interpolated) { |children, closing| builder.xstring_compose(token(node.opening_loc), children, closing) } - else - parts = if node.unescaped.lines.one? - [builder.string_internal([node.unescaped, srange(node.content_loc)])] - else - start_offset = node.content_loc.start_offset - - node.unescaped.lines.map do |line| - end_offset = start_offset + line.bytesize - offsets = srange_offsets(start_offset, end_offset) - start_offset = end_offset + return visit_heredoc(node.to_interpolated) { |children, closing| builder.xstring_compose(token(node.opening_loc), children, closing) } + end - builder.string_internal([line, offsets]) - end + parts = + if node.content == "" + [] + elsif node.content.include?("\n") + string_nodes_from_line_continuations(node.unescaped, node.content, node.content_loc.start_offset, node.opening) + else + [builder.string_internal([node.unescaped, srange(node.content_loc)])] end - builder.xstring_compose( - token(node.opening_loc), - parts, - token(node.closing_loc) - ) - end + builder.xstring_compose( + token(node.opening_loc), + parts, + token(node.closing_loc) + ) end # yield @@ -2069,8 +2034,8 @@ def visit_heredoc(node) node.parts.each do |part| pushing = - if part.is_a?(StringNode) && part.unescaped.include?("\n") - string_nodes_from_line_continuations(part, part.location.start_offset, node.opening) + if part.is_a?(StringNode) && part.content.include?("\n") + string_nodes_from_line_continuations(part.unescaped, part.content, part.location.start_offset, node.opening) else [visit(part)] end @@ -2123,9 +2088,9 @@ def within_pattern # Create parser string nodes from a single prism node. The parser gem # "glues" strings together when a line continuation is encountered. - def string_nodes_from_line_continuations(node, start_offset, opening) - unescaped = node.unescaped.lines - escaped = node.content.lines + def string_nodes_from_line_continuations(unescaped, escaped, start_offset, opening) + unescaped = unescaped.lines + escaped = escaped.lines escaped_lengths = [] normalized_lengths = [] @@ -2135,7 +2100,7 @@ def string_nodes_from_line_continuations(node, start_offset, opening) # line continuations don't start a new node as well. do_next_tokens = [] - if opening.end_with?("'") + if opening&.end_with?("'") escaped.each do |line| escaped_lengths << line.bytesize normalized_lengths << chomped_bytesize(line) diff --git a/test/prism/fixtures/dstring.txt b/test/prism/fixtures/dstring.txt index 69019662c1..99f6c0dfac 100644 --- a/test/prism/fixtures/dstring.txt +++ b/test/prism/fixtures/dstring.txt @@ -28,5 +28,11 @@ foo\\\\ foo\\\\\ " +" +foo\ +b\nar +#{} +" + " ’" diff --git a/test/prism/fixtures/strings.txt b/test/prism/fixtures/strings.txt index 6963d75b2d..a8861be687 100644 --- a/test/prism/fixtures/strings.txt +++ b/test/prism/fixtures/strings.txt @@ -40,6 +40,11 @@ # "bar" +" +foo\ +b\nar +" + %q{abc} %s[abc] diff --git a/test/prism/fixtures/symbols.txt b/test/prism/fixtures/symbols.txt index 7563eb874f..edee418bca 100644 --- a/test/prism/fixtures/symbols.txt +++ b/test/prism/fixtures/symbols.txt @@ -4,6 +4,17 @@ :"abc#{1}" +" +foo\ +b\nar +" + +" +foo\ +b\nar +#{} +" + [:Υ, :ά, :ŗ, :ρ] :-@ diff --git a/test/prism/fixtures/xstring.txt b/test/prism/fixtures/xstring.txt index bb3d1c6ee1..465a14e84b 100644 --- a/test/prism/fixtures/xstring.txt +++ b/test/prism/fixtures/xstring.txt @@ -12,5 +12,10 @@ %x{} +` +foo\ +b\nar +` + ` ’` diff --git a/test/prism/snapshots/dstring.txt b/test/prism/snapshots/dstring.txt index 7c9692fc18..6bcdd8fab3 100644 --- a/test/prism/snapshots/dstring.txt +++ b/test/prism/snapshots/dstring.txt @@ -1,10 +1,10 @@ -@ ProgramNode (location: (1,0)-(32,4)) +@ ProgramNode (location: (1,0)-(38,4)) ├── flags: ∅ ├── locals: [] └── statements: - @ StatementsNode (location: (1,0)-(32,4)) + @ StatementsNode (location: (1,0)-(38,4)) ├── flags: ∅ - └── body: (length: 9) + └── body: (length: 10) ├── @ StringNode (location: (1,0)-(2,6)) │ ├── flags: newline │ ├── opening_loc: (1,0)-(1,1) = "\"" @@ -87,9 +87,31 @@ │ ├── content_loc: (27,1)-(29,0) = "\nfoo\\\\\\\\\\\n" │ ├── closing_loc: (29,0)-(29,1) = "\"" │ └── unescaped: "\nfoo\\\\" - └── @ StringNode (location: (31,0)-(32,4)) + ├── @ InterpolatedStringNode (location: (31,0)-(35,1)) + │ ├── flags: newline + │ ├── opening_loc: (31,0)-(31,1) = "\"" + │ ├── parts: (length: 3) + │ │ ├── @ StringNode (location: (31,1)-(34,0)) + │ │ │ ├── flags: static_literal, frozen + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (31,1)-(34,0) = "\nfoo\\\nb\\nar\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\nfoob\nar\n" + │ │ ├── @ EmbeddedStatementsNode (location: (34,0)-(34,3)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (34,0)-(34,2) = "\#{" + │ │ │ ├── statements: ∅ + │ │ │ └── closing_loc: (34,2)-(34,3) = "}" + │ │ └── @ StringNode (location: (34,3)-(35,0)) + │ │ ├── flags: static_literal, frozen + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (34,3)-(35,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (35,0)-(35,1) = "\"" + └── @ StringNode (location: (37,0)-(38,4)) ├── flags: newline - ├── opening_loc: (31,0)-(31,1) = "\"" - ├── content_loc: (31,1)-(32,3) = "\n’" - ├── closing_loc: (32,3)-(32,4) = "\"" + ├── opening_loc: (37,0)-(37,1) = "\"" + ├── content_loc: (37,1)-(38,3) = "\n’" + ├── closing_loc: (38,3)-(38,4) = "\"" └── unescaped: "\n’" diff --git a/test/prism/snapshots/strings.txt b/test/prism/snapshots/strings.txt index 05b3a27bd5..8f13c79b00 100644 --- a/test/prism/snapshots/strings.txt +++ b/test/prism/snapshots/strings.txt @@ -1,10 +1,10 @@ -@ ProgramNode (location: (1,0)-(107,15)) +@ ProgramNode (location: (1,0)-(112,15)) ├── flags: ∅ ├── locals: [] └── statements: - @ StatementsNode (location: (1,0)-(107,15)) + @ StatementsNode (location: (1,0)-(112,15)) ├── flags: ∅ - └── body: (length: 51) + └── body: (length: 52) ├── @ StringNode (location: (1,0)-(1,6)) │ ├── flags: newline │ ├── opening_loc: (1,0)-(1,2) = "%%" @@ -178,412 +178,418 @@ │ │ └── unescaped: "bar" │ ├── closing_loc: ∅ │ └── block: ∅ - ├── @ StringNode (location: (43,0)-(43,7)) + ├── @ StringNode (location: (43,0)-(46,1)) │ ├── flags: newline - │ ├── opening_loc: (43,0)-(43,3) = "%q{" - │ ├── content_loc: (43,3)-(43,6) = "abc" - │ ├── closing_loc: (43,6)-(43,7) = "}" + │ ├── opening_loc: (43,0)-(43,1) = "\"" + │ ├── content_loc: (43,1)-(46,0) = "\nfoo\\\nb\\nar\n" + │ ├── closing_loc: (46,0)-(46,1) = "\"" + │ └── unescaped: "\nfoob\nar\n" + ├── @ StringNode (location: (48,0)-(48,7)) + │ ├── flags: newline + │ ├── opening_loc: (48,0)-(48,3) = "%q{" + │ ├── content_loc: (48,3)-(48,6) = "abc" + │ ├── closing_loc: (48,6)-(48,7) = "}" │ └── unescaped: "abc" - ├── @ SymbolNode (location: (45,0)-(45,7)) + ├── @ SymbolNode (location: (50,0)-(50,7)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (45,0)-(45,3) = "%s[" - │ ├── value_loc: (45,3)-(45,6) = "abc" - │ ├── closing_loc: (45,6)-(45,7) = "]" + │ ├── opening_loc: (50,0)-(50,3) = "%s[" + │ ├── value_loc: (50,3)-(50,6) = "abc" + │ ├── closing_loc: (50,6)-(50,7) = "]" │ └── unescaped: "abc" - ├── @ StringNode (location: (47,0)-(47,6)) + ├── @ StringNode (location: (52,0)-(52,6)) │ ├── flags: newline - │ ├── opening_loc: (47,0)-(47,2) = "%{" - │ ├── content_loc: (47,2)-(47,5) = "abc" - │ ├── closing_loc: (47,5)-(47,6) = "}" + │ ├── opening_loc: (52,0)-(52,2) = "%{" + │ ├── content_loc: (52,2)-(52,5) = "abc" + │ ├── closing_loc: (52,5)-(52,6) = "}" │ └── unescaped: "abc" - ├── @ StringNode (location: (49,0)-(49,2)) + ├── @ StringNode (location: (54,0)-(54,2)) │ ├── flags: newline - │ ├── opening_loc: (49,0)-(49,1) = "'" - │ ├── content_loc: (49,1)-(49,1) = "" - │ ├── closing_loc: (49,1)-(49,2) = "'" + │ ├── opening_loc: (54,0)-(54,1) = "'" + │ ├── content_loc: (54,1)-(54,1) = "" + │ ├── closing_loc: (54,1)-(54,2) = "'" │ └── unescaped: "" - ├── @ StringNode (location: (51,0)-(51,5)) + ├── @ StringNode (location: (56,0)-(56,5)) │ ├── flags: newline - │ ├── opening_loc: (51,0)-(51,1) = "\"" - │ ├── content_loc: (51,1)-(51,4) = "abc" - │ ├── closing_loc: (51,4)-(51,5) = "\"" + │ ├── opening_loc: (56,0)-(56,1) = "\"" + │ ├── content_loc: (56,1)-(56,4) = "abc" + │ ├── closing_loc: (56,4)-(56,5) = "\"" │ └── unescaped: "abc" - ├── @ StringNode (location: (53,0)-(53,7)) + ├── @ StringNode (location: (58,0)-(58,7)) │ ├── flags: newline - │ ├── opening_loc: (53,0)-(53,1) = "\"" - │ ├── content_loc: (53,1)-(53,6) = "\#@---" - │ ├── closing_loc: (53,6)-(53,7) = "\"" + │ ├── opening_loc: (58,0)-(58,1) = "\"" + │ ├── content_loc: (58,1)-(58,6) = "\#@---" + │ ├── closing_loc: (58,6)-(58,7) = "\"" │ └── unescaped: "\#@---" - ├── @ InterpolatedStringNode (location: (55,0)-(55,16)) + ├── @ InterpolatedStringNode (location: (60,0)-(60,16)) │ ├── flags: newline - │ ├── opening_loc: (55,0)-(55,1) = "\"" + │ ├── opening_loc: (60,0)-(60,1) = "\"" │ ├── parts: (length: 3) - │ │ ├── @ StringNode (location: (55,1)-(55,5)) + │ │ ├── @ StringNode (location: (60,1)-(60,5)) │ │ │ ├── flags: static_literal, frozen │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (55,1)-(55,5) = "aaa " + │ │ │ ├── content_loc: (60,1)-(60,5) = "aaa " │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "aaa " - │ │ ├── @ EmbeddedStatementsNode (location: (55,5)-(55,11)) + │ │ ├── @ EmbeddedStatementsNode (location: (60,5)-(60,11)) │ │ │ ├── flags: ∅ - │ │ │ ├── opening_loc: (55,5)-(55,7) = "\#{" + │ │ │ ├── opening_loc: (60,5)-(60,7) = "\#{" │ │ │ ├── statements: - │ │ │ │ @ StatementsNode (location: (55,7)-(55,10)) + │ │ │ │ @ StatementsNode (location: (60,7)-(60,10)) │ │ │ │ ├── flags: ∅ │ │ │ │ └── body: (length: 1) - │ │ │ │ └── @ CallNode (location: (55,7)-(55,10)) + │ │ │ │ └── @ CallNode (location: (60,7)-(60,10)) │ │ │ │ ├── flags: variable_call, ignore_visibility │ │ │ │ ├── receiver: ∅ │ │ │ │ ├── call_operator_loc: ∅ │ │ │ │ ├── name: :bbb - │ │ │ │ ├── message_loc: (55,7)-(55,10) = "bbb" + │ │ │ │ ├── message_loc: (60,7)-(60,10) = "bbb" │ │ │ │ ├── opening_loc: ∅ │ │ │ │ ├── arguments: ∅ │ │ │ │ ├── closing_loc: ∅ │ │ │ │ └── block: ∅ - │ │ │ └── closing_loc: (55,10)-(55,11) = "}" - │ │ └── @ StringNode (location: (55,11)-(55,15)) + │ │ │ └── closing_loc: (60,10)-(60,11) = "}" + │ │ └── @ StringNode (location: (60,11)-(60,15)) │ │ ├── flags: static_literal, frozen │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (55,11)-(55,15) = " ccc" + │ │ ├── content_loc: (60,11)-(60,15) = " ccc" │ │ ├── closing_loc: ∅ │ │ └── unescaped: " ccc" - │ └── closing_loc: (55,15)-(55,16) = "\"" - ├── @ StringNode (location: (57,0)-(57,5)) + │ └── closing_loc: (60,15)-(60,16) = "\"" + ├── @ StringNode (location: (62,0)-(62,5)) │ ├── flags: newline - │ ├── opening_loc: (57,0)-(57,1) = "'" - │ ├── content_loc: (57,1)-(57,4) = "abc" - │ ├── closing_loc: (57,4)-(57,5) = "'" + │ ├── opening_loc: (62,0)-(62,1) = "'" + │ ├── content_loc: (62,1)-(62,4) = "abc" + │ ├── closing_loc: (62,4)-(62,5) = "'" │ └── unescaped: "abc" - ├── @ ArrayNode (location: (59,0)-(59,9)) + ├── @ ArrayNode (location: (64,0)-(64,9)) │ ├── flags: newline │ ├── elements: (length: 3) - │ │ ├── @ StringNode (location: (59,3)-(59,4)) + │ │ ├── @ StringNode (location: (64,3)-(64,4)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (59,3)-(59,4) = "a" + │ │ │ ├── content_loc: (64,3)-(64,4) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ ├── @ StringNode (location: (59,5)-(59,6)) + │ │ ├── @ StringNode (location: (64,5)-(64,6)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (59,5)-(59,6) = "b" + │ │ │ ├── content_loc: (64,5)-(64,6) = "b" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "b" - │ │ └── @ StringNode (location: (59,7)-(59,8)) + │ │ └── @ StringNode (location: (64,7)-(64,8)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (59,7)-(59,8) = "c" + │ │ ├── content_loc: (64,7)-(64,8) = "c" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "c" - │ ├── opening_loc: (59,0)-(59,3) = "%w[" - │ └── closing_loc: (59,8)-(59,9) = "]" - ├── @ ArrayNode (location: (61,0)-(61,17)) + │ ├── opening_loc: (64,0)-(64,3) = "%w[" + │ └── closing_loc: (64,8)-(64,9) = "]" + ├── @ ArrayNode (location: (66,0)-(66,17)) │ ├── flags: newline │ ├── elements: (length: 3) - │ │ ├── @ StringNode (location: (61,3)-(61,6)) + │ │ ├── @ StringNode (location: (66,3)-(66,6)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (61,3)-(61,6) = "a[]" + │ │ │ ├── content_loc: (66,3)-(66,6) = "a[]" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a[]" - │ │ ├── @ StringNode (location: (61,7)-(61,12)) + │ │ ├── @ StringNode (location: (66,7)-(66,12)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (61,7)-(61,12) = "b[[]]" + │ │ │ ├── content_loc: (66,7)-(66,12) = "b[[]]" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "b[[]]" - │ │ └── @ StringNode (location: (61,13)-(61,16)) + │ │ └── @ StringNode (location: (66,13)-(66,16)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (61,13)-(61,16) = "c[]" + │ │ ├── content_loc: (66,13)-(66,16) = "c[]" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "c[]" - │ ├── opening_loc: (61,0)-(61,3) = "%w[" - │ └── closing_loc: (61,16)-(61,17) = "]" - ├── @ ArrayNode (location: (63,0)-(63,18)) + │ ├── opening_loc: (66,0)-(66,3) = "%w[" + │ └── closing_loc: (66,16)-(66,17) = "]" + ├── @ ArrayNode (location: (68,0)-(68,18)) │ ├── flags: newline │ ├── elements: (length: 2) - │ │ ├── @ StringNode (location: (63,3)-(63,11)) + │ │ ├── @ StringNode (location: (68,3)-(68,11)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (63,3)-(63,11) = "foo\\ bar" + │ │ │ ├── content_loc: (68,3)-(68,11) = "foo\\ bar" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "foo bar" - │ │ └── @ StringNode (location: (63,12)-(63,17)) + │ │ └── @ StringNode (location: (68,12)-(68,17)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (63,12)-(63,17) = "\\\#{1}" + │ │ ├── content_loc: (68,12)-(68,17) = "\\\#{1}" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "\\\#{1}" - │ ├── opening_loc: (63,0)-(63,3) = "%w[" - │ └── closing_loc: (63,17)-(63,18) = "]" - ├── @ ArrayNode (location: (65,0)-(65,16)) + │ ├── opening_loc: (68,0)-(68,3) = "%w[" + │ └── closing_loc: (68,17)-(68,18) = "]" + ├── @ ArrayNode (location: (70,0)-(70,16)) │ ├── flags: newline │ ├── elements: (length: 2) - │ │ ├── @ StringNode (location: (65,3)-(65,11)) + │ │ ├── @ StringNode (location: (70,3)-(70,11)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (65,3)-(65,11) = "foo\\ bar" + │ │ │ ├── content_loc: (70,3)-(70,11) = "foo\\ bar" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "foo bar" - │ │ └── @ StringNode (location: (65,12)-(65,15)) + │ │ └── @ StringNode (location: (70,12)-(70,15)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (65,12)-(65,15) = "baz" + │ │ ├── content_loc: (70,12)-(70,15) = "baz" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "baz" - │ ├── opening_loc: (65,0)-(65,3) = "%w[" - │ └── closing_loc: (65,15)-(65,16) = "]" - ├── @ ArrayNode (location: (67,0)-(67,14)) + │ ├── opening_loc: (70,0)-(70,3) = "%w[" + │ └── closing_loc: (70,15)-(70,16) = "]" + ├── @ ArrayNode (location: (72,0)-(72,14)) │ ├── flags: newline │ ├── elements: (length: 3) - │ │ ├── @ StringNode (location: (67,3)-(67,4)) + │ │ ├── @ StringNode (location: (72,3)-(72,4)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (67,3)-(67,4) = "a" + │ │ │ ├── content_loc: (72,3)-(72,4) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ ├── @ InterpolatedStringNode (location: (67,5)-(67,11)) + │ │ ├── @ InterpolatedStringNode (location: (72,5)-(72,11)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ │ │ │ ├── parts: (length: 3) - │ │ │ │ ├── @ StringNode (location: (67,5)-(67,6)) + │ │ │ │ ├── @ StringNode (location: (72,5)-(72,6)) │ │ │ │ │ ├── flags: static_literal, frozen │ │ │ │ │ ├── opening_loc: ∅ - │ │ │ │ │ ├── content_loc: (67,5)-(67,6) = "b" + │ │ │ │ │ ├── content_loc: (72,5)-(72,6) = "b" │ │ │ │ │ ├── closing_loc: ∅ │ │ │ │ │ └── unescaped: "b" - │ │ │ │ ├── @ EmbeddedStatementsNode (location: (67,6)-(67,10)) + │ │ │ │ ├── @ EmbeddedStatementsNode (location: (72,6)-(72,10)) │ │ │ │ │ ├── flags: ∅ - │ │ │ │ │ ├── opening_loc: (67,6)-(67,8) = "\#{" + │ │ │ │ │ ├── opening_loc: (72,6)-(72,8) = "\#{" │ │ │ │ │ ├── statements: - │ │ │ │ │ │ @ StatementsNode (location: (67,8)-(67,9)) + │ │ │ │ │ │ @ StatementsNode (location: (72,8)-(72,9)) │ │ │ │ │ │ ├── flags: ∅ │ │ │ │ │ │ └── body: (length: 1) - │ │ │ │ │ │ └── @ CallNode (location: (67,8)-(67,9)) + │ │ │ │ │ │ └── @ CallNode (location: (72,8)-(72,9)) │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility │ │ │ │ │ │ ├── receiver: ∅ │ │ │ │ │ │ ├── call_operator_loc: ∅ │ │ │ │ │ │ ├── name: :c - │ │ │ │ │ │ ├── message_loc: (67,8)-(67,9) = "c" + │ │ │ │ │ │ ├── message_loc: (72,8)-(72,9) = "c" │ │ │ │ │ │ ├── opening_loc: ∅ │ │ │ │ │ │ ├── arguments: ∅ │ │ │ │ │ │ ├── closing_loc: ∅ │ │ │ │ │ │ └── block: ∅ - │ │ │ │ │ └── closing_loc: (67,9)-(67,10) = "}" - │ │ │ │ └── @ StringNode (location: (67,10)-(67,11)) + │ │ │ │ │ └── closing_loc: (72,9)-(72,10) = "}" + │ │ │ │ └── @ StringNode (location: (72,10)-(72,11)) │ │ │ │ ├── flags: static_literal, frozen │ │ │ │ ├── opening_loc: ∅ - │ │ │ │ ├── content_loc: (67,10)-(67,11) = "d" + │ │ │ │ ├── content_loc: (72,10)-(72,11) = "d" │ │ │ │ ├── closing_loc: ∅ │ │ │ │ └── unescaped: "d" │ │ │ └── closing_loc: ∅ - │ │ └── @ StringNode (location: (67,12)-(67,13)) + │ │ └── @ StringNode (location: (72,12)-(72,13)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (67,12)-(67,13) = "e" + │ │ ├── content_loc: (72,12)-(72,13) = "e" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "e" - │ ├── opening_loc: (67,0)-(67,3) = "%W[" - │ └── closing_loc: (67,13)-(67,14) = "]" - ├── @ ArrayNode (location: (69,0)-(69,9)) + │ ├── opening_loc: (72,0)-(72,3) = "%W[" + │ └── closing_loc: (72,13)-(72,14) = "]" + ├── @ ArrayNode (location: (74,0)-(74,9)) │ ├── flags: newline │ ├── elements: (length: 3) - │ │ ├── @ StringNode (location: (69,3)-(69,4)) + │ │ ├── @ StringNode (location: (74,3)-(74,4)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (69,3)-(69,4) = "a" + │ │ │ ├── content_loc: (74,3)-(74,4) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ ├── @ StringNode (location: (69,5)-(69,6)) + │ │ ├── @ StringNode (location: (74,5)-(74,6)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (69,5)-(69,6) = "b" + │ │ │ ├── content_loc: (74,5)-(74,6) = "b" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "b" - │ │ └── @ StringNode (location: (69,7)-(69,8)) + │ │ └── @ StringNode (location: (74,7)-(74,8)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (69,7)-(69,8) = "c" + │ │ ├── content_loc: (74,7)-(74,8) = "c" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "c" - │ ├── opening_loc: (69,0)-(69,3) = "%W[" - │ └── closing_loc: (69,8)-(69,9) = "]" - ├── @ ArrayNode (location: (71,0)-(75,1)) + │ ├── opening_loc: (74,0)-(74,3) = "%W[" + │ └── closing_loc: (74,8)-(74,9) = "]" + ├── @ ArrayNode (location: (76,0)-(80,1)) │ ├── flags: newline │ ├── elements: (length: 3) - │ │ ├── @ StringNode (location: (72,2)-(72,3)) + │ │ ├── @ StringNode (location: (77,2)-(77,3)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (72,2)-(72,3) = "a" + │ │ │ ├── content_loc: (77,2)-(77,3) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ ├── @ StringNode (location: (73,2)-(73,3)) + │ │ ├── @ StringNode (location: (78,2)-(78,3)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (73,2)-(73,3) = "b" + │ │ │ ├── content_loc: (78,2)-(78,3) = "b" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "b" - │ │ └── @ StringNode (location: (74,2)-(74,3)) + │ │ └── @ StringNode (location: (79,2)-(79,3)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (74,2)-(74,3) = "c" + │ │ ├── content_loc: (79,2)-(79,3) = "c" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "c" - │ ├── opening_loc: (71,0)-(71,3) = "%w[" - │ └── closing_loc: (75,0)-(75,1) = "]" - ├── @ StringNode (location: (77,0)-(77,15)) + │ ├── opening_loc: (76,0)-(76,3) = "%w[" + │ └── closing_loc: (80,0)-(80,1) = "]" + ├── @ StringNode (location: (82,0)-(82,15)) │ ├── flags: newline - │ ├── opening_loc: (77,0)-(77,1) = "'" - │ ├── content_loc: (77,1)-(77,14) = "\\' foo \\' bar" - │ ├── closing_loc: (77,14)-(77,15) = "'" + │ ├── opening_loc: (82,0)-(82,1) = "'" + │ ├── content_loc: (82,1)-(82,14) = "\\' foo \\' bar" + │ ├── closing_loc: (82,14)-(82,15) = "'" │ └── unescaped: "' foo ' bar" - ├── @ StringNode (location: (79,0)-(79,15)) + ├── @ StringNode (location: (84,0)-(84,15)) │ ├── flags: newline - │ ├── opening_loc: (79,0)-(79,1) = "'" - │ ├── content_loc: (79,1)-(79,14) = "\\\\ foo \\\\ bar" - │ ├── closing_loc: (79,14)-(79,15) = "'" + │ ├── opening_loc: (84,0)-(84,1) = "'" + │ ├── content_loc: (84,1)-(84,14) = "\\\\ foo \\\\ bar" + │ ├── closing_loc: (84,14)-(84,15) = "'" │ └── unescaped: "\\ foo \\ bar" - ├── @ InterpolatedStringNode (location: (81,0)-(81,7)) + ├── @ InterpolatedStringNode (location: (86,0)-(86,7)) │ ├── flags: newline - │ ├── opening_loc: (81,0)-(81,1) = "\"" + │ ├── opening_loc: (86,0)-(86,1) = "\"" │ ├── parts: (length: 1) - │ │ └── @ EmbeddedVariableNode (location: (81,1)-(81,6)) + │ │ └── @ EmbeddedVariableNode (location: (86,1)-(86,6)) │ │ ├── flags: ∅ - │ │ ├── operator_loc: (81,1)-(81,2) = "#" + │ │ ├── operator_loc: (86,1)-(86,2) = "#" │ │ └── variable: - │ │ @ GlobalVariableReadNode (location: (81,2)-(81,6)) + │ │ @ GlobalVariableReadNode (location: (86,2)-(86,6)) │ │ ├── flags: ∅ │ │ └── name: :$foo - │ └── closing_loc: (81,6)-(81,7) = "\"" - ├── @ InterpolatedStringNode (location: (83,0)-(83,7)) + │ └── closing_loc: (86,6)-(86,7) = "\"" + ├── @ InterpolatedStringNode (location: (88,0)-(88,7)) │ ├── flags: newline - │ ├── opening_loc: (83,0)-(83,1) = "\"" + │ ├── opening_loc: (88,0)-(88,1) = "\"" │ ├── parts: (length: 1) - │ │ └── @ EmbeddedVariableNode (location: (83,1)-(83,6)) + │ │ └── @ EmbeddedVariableNode (location: (88,1)-(88,6)) │ │ ├── flags: ∅ - │ │ ├── operator_loc: (83,1)-(83,2) = "#" + │ │ ├── operator_loc: (88,1)-(88,2) = "#" │ │ └── variable: - │ │ @ InstanceVariableReadNode (location: (83,2)-(83,6)) + │ │ @ InstanceVariableReadNode (location: (88,2)-(88,6)) │ │ ├── flags: ∅ │ │ └── name: :@foo - │ └── closing_loc: (83,6)-(83,7) = "\"" - ├── @ StringNode (location: (85,0)-(85,15)) + │ └── closing_loc: (88,6)-(88,7) = "\"" + ├── @ StringNode (location: (90,0)-(90,15)) │ ├── flags: newline - │ ├── opening_loc: (85,0)-(85,1) = "\"" - │ ├── content_loc: (85,1)-(85,14) = "\\x7 \\x23 \\x61" - │ ├── closing_loc: (85,14)-(85,15) = "\"" + │ ├── opening_loc: (90,0)-(90,1) = "\"" + │ ├── content_loc: (90,1)-(90,14) = "\\x7 \\x23 \\x61" + │ ├── closing_loc: (90,14)-(90,15) = "\"" │ └── unescaped: "\a # a" - ├── @ StringNode (location: (87,0)-(87,13)) + ├── @ StringNode (location: (92,0)-(92,13)) │ ├── flags: newline - │ ├── opening_loc: (87,0)-(87,1) = "\"" - │ ├── content_loc: (87,1)-(87,12) = "\\7 \\43 \\141" - │ ├── closing_loc: (87,12)-(87,13) = "\"" + │ ├── opening_loc: (92,0)-(92,1) = "\"" + │ ├── content_loc: (92,1)-(92,12) = "\\7 \\43 \\141" + │ ├── closing_loc: (92,12)-(92,13) = "\"" │ └── unescaped: "\a # a" - ├── @ StringNode (location: (89,0)-(89,6)) + ├── @ StringNode (location: (94,0)-(94,6)) │ ├── flags: newline - │ ├── opening_loc: (89,0)-(89,2) = "%[" - │ ├── content_loc: (89,2)-(89,5) = "abc" - │ ├── closing_loc: (89,5)-(89,6) = "]" + │ ├── opening_loc: (94,0)-(94,2) = "%[" + │ ├── content_loc: (94,2)-(94,5) = "abc" + │ ├── closing_loc: (94,5)-(94,6) = "]" │ └── unescaped: "abc" - ├── @ StringNode (location: (91,0)-(91,6)) + ├── @ StringNode (location: (96,0)-(96,6)) │ ├── flags: newline - │ ├── opening_loc: (91,0)-(91,2) = "%(" - │ ├── content_loc: (91,2)-(91,5) = "abc" - │ ├── closing_loc: (91,5)-(91,6) = ")" + │ ├── opening_loc: (96,0)-(96,2) = "%(" + │ ├── content_loc: (96,2)-(96,5) = "abc" + │ ├── closing_loc: (96,5)-(96,6) = ")" │ └── unescaped: "abc" - ├── @ StringNode (location: (93,0)-(93,6)) + ├── @ StringNode (location: (98,0)-(98,6)) │ ├── flags: newline - │ ├── opening_loc: (93,0)-(93,2) = "%@" - │ ├── content_loc: (93,2)-(93,5) = "abc" - │ ├── closing_loc: (93,5)-(93,6) = "@" + │ ├── opening_loc: (98,0)-(98,2) = "%@" + │ ├── content_loc: (98,2)-(98,5) = "abc" + │ ├── closing_loc: (98,5)-(98,6) = "@" │ └── unescaped: "abc" - ├── @ StringNode (location: (95,0)-(95,6)) + ├── @ StringNode (location: (100,0)-(100,6)) │ ├── flags: newline - │ ├── opening_loc: (95,0)-(95,2) = "%$" - │ ├── content_loc: (95,2)-(95,5) = "abc" - │ ├── closing_loc: (95,5)-(95,6) = "$" + │ ├── opening_loc: (100,0)-(100,2) = "%$" + │ ├── content_loc: (100,2)-(100,5) = "abc" + │ ├── closing_loc: (100,5)-(100,6) = "$" │ └── unescaped: "abc" - ├── @ StringNode (location: (97,0)-(97,2)) + ├── @ StringNode (location: (102,0)-(102,2)) │ ├── flags: newline - │ ├── opening_loc: (97,0)-(97,1) = "?" - │ ├── content_loc: (97,1)-(97,2) = "a" + │ ├── opening_loc: (102,0)-(102,1) = "?" + │ ├── content_loc: (102,1)-(102,2) = "a" │ ├── closing_loc: ∅ │ └── unescaped: "a" - ├── @ InterpolatedStringNode (location: (99,0)-(99,6)) + ├── @ InterpolatedStringNode (location: (104,0)-(104,6)) │ ├── flags: newline, static_literal │ ├── opening_loc: ∅ │ ├── parts: (length: 2) - │ │ ├── @ StringNode (location: (99,0)-(99,2)) + │ │ ├── @ StringNode (location: (104,0)-(104,2)) │ │ │ ├── flags: static_literal, frozen - │ │ │ ├── opening_loc: (99,0)-(99,1) = "?" - │ │ │ ├── content_loc: (99,1)-(99,2) = "a" + │ │ │ ├── opening_loc: (104,0)-(104,1) = "?" + │ │ │ ├── content_loc: (104,1)-(104,2) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ └── @ StringNode (location: (99,3)-(99,6)) + │ │ └── @ StringNode (location: (104,3)-(104,6)) │ │ ├── flags: static_literal, frozen - │ │ ├── opening_loc: (99,3)-(99,4) = "\"" - │ │ ├── content_loc: (99,4)-(99,5) = "a" - │ │ ├── closing_loc: (99,5)-(99,6) = "\"" + │ │ ├── opening_loc: (104,3)-(104,4) = "\"" + │ │ ├── content_loc: (104,4)-(104,5) = "a" + │ │ ├── closing_loc: (104,5)-(104,6) = "\"" │ │ └── unescaped: "a" │ └── closing_loc: ∅ - ├── @ StringNode (location: (101,0)-(101,7)) + ├── @ StringNode (location: (106,0)-(106,7)) │ ├── flags: newline - │ ├── opening_loc: (101,0)-(101,3) = "%Q{" - │ ├── content_loc: (101,3)-(101,6) = "abc" - │ ├── closing_loc: (101,6)-(101,7) = "}" + │ ├── opening_loc: (106,0)-(106,3) = "%Q{" + │ ├── content_loc: (106,3)-(106,6) = "abc" + │ ├── closing_loc: (106,6)-(106,7) = "}" │ └── unescaped: "abc" - ├── @ StringNode (location: (103,0)-(103,5)) + ├── @ StringNode (location: (108,0)-(108,5)) │ ├── flags: newline - │ ├── opening_loc: (103,0)-(103,2) = "%^" - │ ├── content_loc: (103,2)-(103,4) = "\#$" - │ ├── closing_loc: (103,4)-(103,5) = "^" + │ ├── opening_loc: (108,0)-(108,2) = "%^" + │ ├── content_loc: (108,2)-(108,4) = "\#$" + │ ├── closing_loc: (108,4)-(108,5) = "^" │ └── unescaped: "\#$" - ├── @ StringNode (location: (105,0)-(105,4)) + ├── @ StringNode (location: (110,0)-(110,4)) │ ├── flags: newline - │ ├── opening_loc: (105,0)-(105,2) = "%@" - │ ├── content_loc: (105,2)-(105,3) = "#" - │ ├── closing_loc: (105,3)-(105,4) = "@" + │ ├── opening_loc: (110,0)-(110,2) = "%@" + │ ├── content_loc: (110,2)-(110,3) = "#" + │ ├── closing_loc: (110,3)-(110,4) = "@" │ └── unescaped: "#" - └── @ InterpolatedStringNode (location: (107,0)-(107,15)) + └── @ InterpolatedStringNode (location: (112,0)-(112,15)) ├── flags: newline - ├── opening_loc: (107,0)-(107,1) = "\"" + ├── opening_loc: (112,0)-(112,1) = "\"" ├── parts: (length: 2) - │ ├── @ EmbeddedStatementsNode (location: (107,1)-(107,12)) + │ ├── @ EmbeddedStatementsNode (location: (112,1)-(112,12)) │ │ ├── flags: ∅ - │ │ ├── opening_loc: (107,1)-(107,3) = "\#{" + │ │ ├── opening_loc: (112,1)-(112,3) = "\#{" │ │ ├── statements: - │ │ │ @ StatementsNode (location: (107,3)-(107,11)) + │ │ │ @ StatementsNode (location: (112,3)-(112,11)) │ │ │ ├── flags: ∅ │ │ │ └── body: (length: 1) - │ │ │ └── @ InterpolatedStringNode (location: (107,3)-(107,11)) + │ │ │ └── @ InterpolatedStringNode (location: (112,3)-(112,11)) │ │ │ ├── flags: ∅ - │ │ │ ├── opening_loc: (107,3)-(107,4) = "\"" + │ │ │ ├── opening_loc: (112,3)-(112,4) = "\"" │ │ │ ├── parts: (length: 2) - │ │ │ │ ├── @ EmbeddedStatementsNode (location: (107,4)-(107,8)) + │ │ │ │ ├── @ EmbeddedStatementsNode (location: (112,4)-(112,8)) │ │ │ │ │ ├── flags: ∅ - │ │ │ │ │ ├── opening_loc: (107,4)-(107,6) = "\#{" + │ │ │ │ │ ├── opening_loc: (112,4)-(112,6) = "\#{" │ │ │ │ │ ├── statements: - │ │ │ │ │ │ @ StatementsNode (location: (107,6)-(107,7)) + │ │ │ │ │ │ @ StatementsNode (location: (112,6)-(112,7)) │ │ │ │ │ │ ├── flags: ∅ │ │ │ │ │ │ └── body: (length: 1) - │ │ │ │ │ │ └── @ ConstantReadNode (location: (107,6)-(107,7)) + │ │ │ │ │ │ └── @ ConstantReadNode (location: (112,6)-(112,7)) │ │ │ │ │ │ ├── flags: ∅ │ │ │ │ │ │ └── name: :B - │ │ │ │ │ └── closing_loc: (107,7)-(107,8) = "}" - │ │ │ │ └── @ StringNode (location: (107,8)-(107,10)) + │ │ │ │ │ └── closing_loc: (112,7)-(112,8) = "}" + │ │ │ │ └── @ StringNode (location: (112,8)-(112,10)) │ │ │ │ ├── flags: static_literal, frozen │ │ │ │ ├── opening_loc: ∅ - │ │ │ │ ├── content_loc: (107,8)-(107,10) = " C" + │ │ │ │ ├── content_loc: (112,8)-(112,10) = " C" │ │ │ │ ├── closing_loc: ∅ │ │ │ │ └── unescaped: " C" - │ │ │ └── closing_loc: (107,10)-(107,11) = "\"" - │ │ └── closing_loc: (107,11)-(107,12) = "}" - │ └── @ StringNode (location: (107,12)-(107,14)) + │ │ │ └── closing_loc: (112,10)-(112,11) = "\"" + │ │ └── closing_loc: (112,11)-(112,12) = "}" + │ └── @ StringNode (location: (112,12)-(112,14)) │ ├── flags: static_literal, frozen │ ├── opening_loc: ∅ - │ ├── content_loc: (107,12)-(107,14) = " D" + │ ├── content_loc: (112,12)-(112,14) = " D" │ ├── closing_loc: ∅ │ └── unescaped: " D" - └── closing_loc: (107,14)-(107,15) = "\"" + └── closing_loc: (112,14)-(112,15) = "\"" diff --git a/test/prism/snapshots/symbols.txt b/test/prism/snapshots/symbols.txt index 7cbe80c821..d273876437 100644 --- a/test/prism/snapshots/symbols.txt +++ b/test/prism/snapshots/symbols.txt @@ -1,10 +1,10 @@ -@ ProgramNode (location: (1,0)-(93,13)) +@ ProgramNode (location: (1,0)-(104,13)) ├── flags: ∅ ├── locals: [] └── statements: - @ StatementsNode (location: (1,0)-(93,13)) + @ StatementsNode (location: (1,0)-(104,13)) ├── flags: ∅ - └── body: (length: 47) + └── body: (length: 49) ├── @ SymbolNode (location: (1,0)-(1,6)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding │ ├── opening_loc: (1,0)-(1,2) = ":'" @@ -56,427 +56,455 @@ │ │ │ └── value: 1 │ │ └── closing_loc: (5,8)-(5,9) = "}" │ └── closing_loc: (5,9)-(5,10) = "\"" - ├── @ ArrayNode (location: (7,0)-(7,20)) + ├── @ StringNode (location: (7,0)-(10,1)) + │ ├── flags: newline + │ ├── opening_loc: (7,0)-(7,1) = "\"" + │ ├── content_loc: (7,1)-(10,0) = "\nfoo\\\nb\\nar\n" + │ ├── closing_loc: (10,0)-(10,1) = "\"" + │ └── unescaped: "\nfoob\nar\n" + ├── @ InterpolatedStringNode (location: (12,0)-(16,1)) + │ ├── flags: newline + │ ├── opening_loc: (12,0)-(12,1) = "\"" + │ ├── parts: (length: 3) + │ │ ├── @ StringNode (location: (12,1)-(15,0)) + │ │ │ ├── flags: static_literal, frozen + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (12,1)-(15,0) = "\nfoo\\\nb\\nar\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\nfoob\nar\n" + │ │ ├── @ EmbeddedStatementsNode (location: (15,0)-(15,3)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (15,0)-(15,2) = "\#{" + │ │ │ ├── statements: ∅ + │ │ │ └── closing_loc: (15,2)-(15,3) = "}" + │ │ └── @ StringNode (location: (15,3)-(16,0)) + │ │ ├── flags: static_literal, frozen + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (15,3)-(16,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (16,0)-(16,1) = "\"" + ├── @ ArrayNode (location: (18,0)-(18,20)) │ ├── flags: newline, static_literal │ ├── elements: (length: 4) - │ │ ├── @ SymbolNode (location: (7,1)-(7,4)) + │ │ ├── @ SymbolNode (location: (18,1)-(18,4)) │ │ │ ├── flags: static_literal - │ │ │ ├── opening_loc: (7,1)-(7,2) = ":" - │ │ │ ├── value_loc: (7,2)-(7,4) = "Υ" + │ │ │ ├── opening_loc: (18,1)-(18,2) = ":" + │ │ │ ├── value_loc: (18,2)-(18,4) = "Υ" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "Υ" - │ │ ├── @ SymbolNode (location: (7,6)-(7,9)) + │ │ ├── @ SymbolNode (location: (18,6)-(18,9)) │ │ │ ├── flags: static_literal - │ │ │ ├── opening_loc: (7,6)-(7,7) = ":" - │ │ │ ├── value_loc: (7,7)-(7,9) = "ά" + │ │ │ ├── opening_loc: (18,6)-(18,7) = ":" + │ │ │ ├── value_loc: (18,7)-(18,9) = "ά" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "ά" - │ │ ├── @ SymbolNode (location: (7,11)-(7,14)) + │ │ ├── @ SymbolNode (location: (18,11)-(18,14)) │ │ │ ├── flags: static_literal - │ │ │ ├── opening_loc: (7,11)-(7,12) = ":" - │ │ │ ├── value_loc: (7,12)-(7,14) = "ŗ" + │ │ │ ├── opening_loc: (18,11)-(18,12) = ":" + │ │ │ ├── value_loc: (18,12)-(18,14) = "ŗ" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "ŗ" - │ │ └── @ SymbolNode (location: (7,16)-(7,19)) + │ │ └── @ SymbolNode (location: (18,16)-(18,19)) │ │ ├── flags: static_literal - │ │ ├── opening_loc: (7,16)-(7,17) = ":" - │ │ ├── value_loc: (7,17)-(7,19) = "ρ" + │ │ ├── opening_loc: (18,16)-(18,17) = ":" + │ │ ├── value_loc: (18,17)-(18,19) = "ρ" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "ρ" - │ ├── opening_loc: (7,0)-(7,1) = "[" - │ └── closing_loc: (7,19)-(7,20) = "]" - ├── @ SymbolNode (location: (9,0)-(9,3)) + │ ├── opening_loc: (18,0)-(18,1) = "[" + │ └── closing_loc: (18,19)-(18,20) = "]" + ├── @ SymbolNode (location: (20,0)-(20,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (9,0)-(9,1) = ":" - │ ├── value_loc: (9,1)-(9,3) = "-@" + │ ├── opening_loc: (20,0)-(20,1) = ":" + │ ├── value_loc: (20,1)-(20,3) = "-@" │ ├── closing_loc: ∅ │ └── unescaped: "-@" - ├── @ SymbolNode (location: (11,0)-(11,2)) + ├── @ SymbolNode (location: (22,0)-(22,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (11,0)-(11,1) = ":" - │ ├── value_loc: (11,1)-(11,2) = "-" + │ ├── opening_loc: (22,0)-(22,1) = ":" + │ ├── value_loc: (22,1)-(22,2) = "-" │ ├── closing_loc: ∅ │ └── unescaped: "-" - ├── @ SymbolNode (location: (13,0)-(13,2)) + ├── @ SymbolNode (location: (24,0)-(24,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (13,0)-(13,1) = ":" - │ ├── value_loc: (13,1)-(13,2) = "%" + │ ├── opening_loc: (24,0)-(24,1) = ":" + │ ├── value_loc: (24,1)-(24,2) = "%" │ ├── closing_loc: ∅ │ └── unescaped: "%" - ├── @ SymbolNode (location: (15,0)-(15,2)) + ├── @ SymbolNode (location: (26,0)-(26,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (15,0)-(15,1) = ":" - │ ├── value_loc: (15,1)-(15,2) = "|" + │ ├── opening_loc: (26,0)-(26,1) = ":" + │ ├── value_loc: (26,1)-(26,2) = "|" │ ├── closing_loc: ∅ │ └── unescaped: "|" - ├── @ SymbolNode (location: (17,0)-(17,3)) + ├── @ SymbolNode (location: (28,0)-(28,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (17,0)-(17,1) = ":" - │ ├── value_loc: (17,1)-(17,3) = "+@" + │ ├── opening_loc: (28,0)-(28,1) = ":" + │ ├── value_loc: (28,1)-(28,3) = "+@" │ ├── closing_loc: ∅ │ └── unescaped: "+@" - ├── @ SymbolNode (location: (19,0)-(19,2)) + ├── @ SymbolNode (location: (30,0)-(30,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (19,0)-(19,1) = ":" - │ ├── value_loc: (19,1)-(19,2) = "+" + │ ├── opening_loc: (30,0)-(30,1) = ":" + │ ├── value_loc: (30,1)-(30,2) = "+" │ ├── closing_loc: ∅ │ └── unescaped: "+" - ├── @ SymbolNode (location: (21,0)-(21,2)) + ├── @ SymbolNode (location: (32,0)-(32,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (21,0)-(21,1) = ":" - │ ├── value_loc: (21,1)-(21,2) = "/" + │ ├── opening_loc: (32,0)-(32,1) = ":" + │ ├── value_loc: (32,1)-(32,2) = "/" │ ├── closing_loc: ∅ │ └── unescaped: "/" - ├── @ SymbolNode (location: (23,0)-(23,3)) + ├── @ SymbolNode (location: (34,0)-(34,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (23,0)-(23,1) = ":" - │ ├── value_loc: (23,1)-(23,3) = "**" + │ ├── opening_loc: (34,0)-(34,1) = ":" + │ ├── value_loc: (34,1)-(34,3) = "**" │ ├── closing_loc: ∅ │ └── unescaped: "**" - ├── @ SymbolNode (location: (25,0)-(25,2)) + ├── @ SymbolNode (location: (36,0)-(36,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (25,0)-(25,1) = ":" - │ ├── value_loc: (25,1)-(25,2) = "*" + │ ├── opening_loc: (36,0)-(36,1) = ":" + │ ├── value_loc: (36,1)-(36,2) = "*" │ ├── closing_loc: ∅ │ └── unescaped: "*" - ├── @ SymbolNode (location: (27,0)-(27,3)) + ├── @ SymbolNode (location: (38,0)-(38,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (27,0)-(27,1) = ":" - │ ├── value_loc: (27,1)-(27,3) = "~@" + │ ├── opening_loc: (38,0)-(38,1) = ":" + │ ├── value_loc: (38,1)-(38,3) = "~@" │ ├── closing_loc: ∅ │ └── unescaped: "~" - ├── @ ArrayNode (location: (29,0)-(29,16)) + ├── @ ArrayNode (location: (40,0)-(40,16)) │ ├── flags: newline, static_literal │ ├── elements: (length: 4) - │ │ ├── @ IntegerNode (location: (29,1)-(29,2)) + │ │ ├── @ IntegerNode (location: (40,1)-(40,2)) │ │ │ ├── flags: static_literal, decimal │ │ │ └── value: 1 - │ │ ├── @ FloatNode (location: (29,4)-(29,7)) + │ │ ├── @ FloatNode (location: (40,4)-(40,7)) │ │ │ ├── flags: static_literal │ │ │ └── value: 1.0 - │ │ ├── @ RationalNode (location: (29,9)-(29,11)) + │ │ ├── @ RationalNode (location: (40,9)-(40,11)) │ │ │ ├── flags: static_literal, decimal │ │ │ ├── numerator: 1 │ │ │ └── denominator: 1 - │ │ └── @ ImaginaryNode (location: (29,13)-(29,15)) + │ │ └── @ ImaginaryNode (location: (40,13)-(40,15)) │ │ ├── flags: static_literal │ │ └── numeric: - │ │ @ IntegerNode (location: (29,13)-(29,14)) + │ │ @ IntegerNode (location: (40,13)-(40,14)) │ │ ├── flags: static_literal, decimal │ │ └── value: 1 - │ ├── opening_loc: (29,0)-(29,1) = "[" - │ └── closing_loc: (29,15)-(29,16) = "]" - ├── @ SymbolNode (location: (31,0)-(31,2)) + │ ├── opening_loc: (40,0)-(40,1) = "[" + │ └── closing_loc: (40,15)-(40,16) = "]" + ├── @ SymbolNode (location: (42,0)-(42,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (31,0)-(31,1) = ":" - │ ├── value_loc: (31,1)-(31,2) = "~" + │ ├── opening_loc: (42,0)-(42,1) = ":" + │ ├── value_loc: (42,1)-(42,2) = "~" │ ├── closing_loc: ∅ │ └── unescaped: "~" - ├── @ SymbolNode (location: (33,0)-(33,2)) + ├── @ SymbolNode (location: (44,0)-(44,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (33,0)-(33,1) = ":" - │ ├── value_loc: (33,1)-(33,2) = "a" + │ ├── opening_loc: (44,0)-(44,1) = ":" + │ ├── value_loc: (44,1)-(44,2) = "a" │ ├── closing_loc: ∅ │ └── unescaped: "a" - ├── @ ArrayNode (location: (35,0)-(35,9)) + ├── @ ArrayNode (location: (46,0)-(46,9)) │ ├── flags: newline, static_literal │ ├── elements: (length: 3) - │ │ ├── @ SymbolNode (location: (35,3)-(35,4)) + │ │ ├── @ SymbolNode (location: (46,3)-(46,4)) │ │ │ ├── flags: static_literal, forced_us_ascii_encoding │ │ │ ├── opening_loc: ∅ - │ │ │ ├── value_loc: (35,3)-(35,4) = "a" + │ │ │ ├── value_loc: (46,3)-(46,4) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ ├── @ SymbolNode (location: (35,5)-(35,6)) + │ │ ├── @ SymbolNode (location: (46,5)-(46,6)) │ │ │ ├── flags: static_literal, forced_us_ascii_encoding │ │ │ ├── opening_loc: ∅ - │ │ │ ├── value_loc: (35,5)-(35,6) = "b" + │ │ │ ├── value_loc: (46,5)-(46,6) = "b" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "b" - │ │ └── @ SymbolNode (location: (35,7)-(35,8)) + │ │ └── @ SymbolNode (location: (46,7)-(46,8)) │ │ ├── flags: static_literal, forced_us_ascii_encoding │ │ ├── opening_loc: ∅ - │ │ ├── value_loc: (35,7)-(35,8) = "c" + │ │ ├── value_loc: (46,7)-(46,8) = "c" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "c" - │ ├── opening_loc: (35,0)-(35,3) = "%i[" - │ └── closing_loc: (35,8)-(35,9) = "]" - ├── @ ArrayNode (location: (37,0)-(37,24)) + │ ├── opening_loc: (46,0)-(46,3) = "%i[" + │ └── closing_loc: (46,8)-(46,9) = "]" + ├── @ ArrayNode (location: (48,0)-(48,24)) │ ├── flags: newline, static_literal │ ├── elements: (length: 4) - │ │ ├── @ SymbolNode (location: (37,3)-(37,4)) + │ │ ├── @ SymbolNode (location: (48,3)-(48,4)) │ │ │ ├── flags: static_literal, forced_us_ascii_encoding │ │ │ ├── opening_loc: ∅ - │ │ │ ├── value_loc: (37,3)-(37,4) = "a" + │ │ │ ├── value_loc: (48,3)-(48,4) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ ├── @ SymbolNode (location: (37,5)-(37,10)) + │ │ ├── @ SymbolNode (location: (48,5)-(48,10)) │ │ │ ├── flags: static_literal, forced_us_ascii_encoding │ │ │ ├── opening_loc: ∅ - │ │ │ ├── value_loc: (37,5)-(37,10) = "b\#{1}" + │ │ │ ├── value_loc: (48,5)-(48,10) = "b\#{1}" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "b\#{1}" - │ │ ├── @ SymbolNode (location: (37,11)-(37,16)) + │ │ ├── @ SymbolNode (location: (48,11)-(48,16)) │ │ │ ├── flags: static_literal, forced_us_ascii_encoding │ │ │ ├── opening_loc: ∅ - │ │ │ ├── value_loc: (37,11)-(37,16) = "\#{2}c" + │ │ │ ├── value_loc: (48,11)-(48,16) = "\#{2}c" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "\#{2}c" - │ │ └── @ SymbolNode (location: (37,17)-(37,23)) + │ │ └── @ SymbolNode (location: (48,17)-(48,23)) │ │ ├── flags: static_literal, forced_us_ascii_encoding │ │ ├── opening_loc: ∅ - │ │ ├── value_loc: (37,17)-(37,23) = "d\#{3}f" + │ │ ├── value_loc: (48,17)-(48,23) = "d\#{3}f" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "d\#{3}f" - │ ├── opening_loc: (37,0)-(37,3) = "%i[" - │ └── closing_loc: (37,23)-(37,24) = "]" - ├── @ ArrayNode (location: (39,0)-(39,24)) + │ ├── opening_loc: (48,0)-(48,3) = "%i[" + │ └── closing_loc: (48,23)-(48,24) = "]" + ├── @ ArrayNode (location: (50,0)-(50,24)) │ ├── flags: newline │ ├── elements: (length: 4) - │ │ ├── @ SymbolNode (location: (39,3)-(39,4)) + │ │ ├── @ SymbolNode (location: (50,3)-(50,4)) │ │ │ ├── flags: static_literal, forced_us_ascii_encoding │ │ │ ├── opening_loc: ∅ - │ │ │ ├── value_loc: (39,3)-(39,4) = "a" + │ │ │ ├── value_loc: (50,3)-(50,4) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ ├── @ InterpolatedSymbolNode (location: (39,5)-(39,10)) + │ │ ├── @ InterpolatedSymbolNode (location: (50,5)-(50,10)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ │ │ │ ├── parts: (length: 2) - │ │ │ │ ├── @ StringNode (location: (39,5)-(39,6)) + │ │ │ │ ├── @ StringNode (location: (50,5)-(50,6)) │ │ │ │ │ ├── flags: static_literal, frozen │ │ │ │ │ ├── opening_loc: ∅ - │ │ │ │ │ ├── content_loc: (39,5)-(39,6) = "b" + │ │ │ │ │ ├── content_loc: (50,5)-(50,6) = "b" │ │ │ │ │ ├── closing_loc: ∅ │ │ │ │ │ └── unescaped: "b" - │ │ │ │ └── @ EmbeddedStatementsNode (location: (39,6)-(39,10)) + │ │ │ │ └── @ EmbeddedStatementsNode (location: (50,6)-(50,10)) │ │ │ │ ├── flags: ∅ - │ │ │ │ ├── opening_loc: (39,6)-(39,8) = "\#{" + │ │ │ │ ├── opening_loc: (50,6)-(50,8) = "\#{" │ │ │ │ ├── statements: - │ │ │ │ │ @ StatementsNode (location: (39,8)-(39,9)) + │ │ │ │ │ @ StatementsNode (location: (50,8)-(50,9)) │ │ │ │ │ ├── flags: ∅ │ │ │ │ │ └── body: (length: 1) - │ │ │ │ │ └── @ IntegerNode (location: (39,8)-(39,9)) + │ │ │ │ │ └── @ IntegerNode (location: (50,8)-(50,9)) │ │ │ │ │ ├── flags: static_literal, decimal │ │ │ │ │ └── value: 1 - │ │ │ │ └── closing_loc: (39,9)-(39,10) = "}" + │ │ │ │ └── closing_loc: (50,9)-(50,10) = "}" │ │ │ └── closing_loc: ∅ - │ │ ├── @ InterpolatedSymbolNode (location: (39,11)-(39,16)) + │ │ ├── @ InterpolatedSymbolNode (location: (50,11)-(50,16)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ │ │ │ ├── parts: (length: 2) - │ │ │ │ ├── @ EmbeddedStatementsNode (location: (39,11)-(39,15)) + │ │ │ │ ├── @ EmbeddedStatementsNode (location: (50,11)-(50,15)) │ │ │ │ │ ├── flags: ∅ - │ │ │ │ │ ├── opening_loc: (39,11)-(39,13) = "\#{" + │ │ │ │ │ ├── opening_loc: (50,11)-(50,13) = "\#{" │ │ │ │ │ ├── statements: - │ │ │ │ │ │ @ StatementsNode (location: (39,13)-(39,14)) + │ │ │ │ │ │ @ StatementsNode (location: (50,13)-(50,14)) │ │ │ │ │ │ ├── flags: ∅ │ │ │ │ │ │ └── body: (length: 1) - │ │ │ │ │ │ └── @ IntegerNode (location: (39,13)-(39,14)) + │ │ │ │ │ │ └── @ IntegerNode (location: (50,13)-(50,14)) │ │ │ │ │ │ ├── flags: static_literal, decimal │ │ │ │ │ │ └── value: 2 - │ │ │ │ │ └── closing_loc: (39,14)-(39,15) = "}" - │ │ │ │ └── @ StringNode (location: (39,15)-(39,16)) + │ │ │ │ │ └── closing_loc: (50,14)-(50,15) = "}" + │ │ │ │ └── @ StringNode (location: (50,15)-(50,16)) │ │ │ │ ├── flags: static_literal, frozen │ │ │ │ ├── opening_loc: ∅ - │ │ │ │ ├── content_loc: (39,15)-(39,16) = "c" + │ │ │ │ ├── content_loc: (50,15)-(50,16) = "c" │ │ │ │ ├── closing_loc: ∅ │ │ │ │ └── unescaped: "c" │ │ │ └── closing_loc: ∅ - │ │ └── @ InterpolatedSymbolNode (location: (39,17)-(39,23)) + │ │ └── @ InterpolatedSymbolNode (location: (50,17)-(50,23)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ │ │ ├── parts: (length: 3) - │ │ │ ├── @ StringNode (location: (39,17)-(39,18)) + │ │ │ ├── @ StringNode (location: (50,17)-(50,18)) │ │ │ │ ├── flags: static_literal, frozen │ │ │ │ ├── opening_loc: ∅ - │ │ │ │ ├── content_loc: (39,17)-(39,18) = "d" + │ │ │ │ ├── content_loc: (50,17)-(50,18) = "d" │ │ │ │ ├── closing_loc: ∅ │ │ │ │ └── unescaped: "d" - │ │ │ ├── @ EmbeddedStatementsNode (location: (39,18)-(39,22)) + │ │ │ ├── @ EmbeddedStatementsNode (location: (50,18)-(50,22)) │ │ │ │ ├── flags: ∅ - │ │ │ │ ├── opening_loc: (39,18)-(39,20) = "\#{" + │ │ │ │ ├── opening_loc: (50,18)-(50,20) = "\#{" │ │ │ │ ├── statements: - │ │ │ │ │ @ StatementsNode (location: (39,20)-(39,21)) + │ │ │ │ │ @ StatementsNode (location: (50,20)-(50,21)) │ │ │ │ │ ├── flags: ∅ │ │ │ │ │ └── body: (length: 1) - │ │ │ │ │ └── @ IntegerNode (location: (39,20)-(39,21)) + │ │ │ │ │ └── @ IntegerNode (location: (50,20)-(50,21)) │ │ │ │ │ ├── flags: static_literal, decimal │ │ │ │ │ └── value: 3 - │ │ │ │ └── closing_loc: (39,21)-(39,22) = "}" - │ │ │ └── @ StringNode (location: (39,22)-(39,23)) + │ │ │ │ └── closing_loc: (50,21)-(50,22) = "}" + │ │ │ └── @ StringNode (location: (50,22)-(50,23)) │ │ │ ├── flags: static_literal, frozen │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (39,22)-(39,23) = "f" + │ │ │ ├── content_loc: (50,22)-(50,23) = "f" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "f" │ │ └── closing_loc: ∅ - │ ├── opening_loc: (39,0)-(39,3) = "%I[" - │ └── closing_loc: (39,23)-(39,24) = "]" - ├── @ SymbolNode (location: (41,0)-(41,4)) + │ ├── opening_loc: (50,0)-(50,3) = "%I[" + │ └── closing_loc: (50,23)-(50,24) = "]" + ├── @ SymbolNode (location: (52,0)-(52,4)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (41,0)-(41,1) = ":" - │ ├── value_loc: (41,1)-(41,4) = "@@a" + │ ├── opening_loc: (52,0)-(52,1) = ":" + │ ├── value_loc: (52,1)-(52,4) = "@@a" │ ├── closing_loc: ∅ │ └── unescaped: "@@a" - ├── @ SymbolNode (location: (43,0)-(43,5)) + ├── @ SymbolNode (location: (54,0)-(54,5)) │ ├── flags: newline, static_literal - │ ├── opening_loc: (43,0)-(43,1) = ":" - │ ├── value_loc: (43,1)-(43,5) = "👍" + │ ├── opening_loc: (54,0)-(54,1) = ":" + │ ├── value_loc: (54,1)-(54,5) = "👍" │ ├── closing_loc: ∅ │ └── unescaped: "👍" - ├── @ ArrayNode (location: (45,0)-(45,7)) + ├── @ ArrayNode (location: (56,0)-(56,7)) │ ├── flags: newline, static_literal │ ├── elements: (length: 1) - │ │ └── @ SymbolNode (location: (45,3)-(45,6)) + │ │ └── @ SymbolNode (location: (56,3)-(56,6)) │ │ ├── flags: static_literal, forced_us_ascii_encoding │ │ ├── opening_loc: ∅ - │ │ ├── value_loc: (45,3)-(45,6) = "a\\b" + │ │ ├── value_loc: (56,3)-(56,6) = "a\\b" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "a\\b" - │ ├── opening_loc: (45,0)-(45,3) = "%i[" - │ └── closing_loc: (45,6)-(45,7) = "]" - ├── @ SymbolNode (location: (47,0)-(47,3)) + │ ├── opening_loc: (56,0)-(56,3) = "%i[" + │ └── closing_loc: (56,6)-(56,7) = "]" + ├── @ SymbolNode (location: (58,0)-(58,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (47,0)-(47,1) = ":" - │ ├── value_loc: (47,1)-(47,3) = "$a" + │ ├── opening_loc: (58,0)-(58,1) = ":" + │ ├── value_loc: (58,1)-(58,3) = "$a" │ ├── closing_loc: ∅ │ └── unescaped: "$a" - ├── @ SymbolNode (location: (49,0)-(49,3)) + ├── @ SymbolNode (location: (60,0)-(60,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (49,0)-(49,1) = ":" - │ ├── value_loc: (49,1)-(49,3) = "@a" + │ ├── opening_loc: (60,0)-(60,1) = ":" + │ ├── value_loc: (60,1)-(60,3) = "@a" │ ├── closing_loc: ∅ │ └── unescaped: "@a" - ├── @ SymbolNode (location: (51,0)-(51,3)) + ├── @ SymbolNode (location: (62,0)-(62,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (51,0)-(51,1) = ":" - │ ├── value_loc: (51,1)-(51,3) = "do" + │ ├── opening_loc: (62,0)-(62,1) = ":" + │ ├── value_loc: (62,1)-(62,3) = "do" │ ├── closing_loc: ∅ │ └── unescaped: "do" - ├── @ SymbolNode (location: (53,0)-(53,2)) + ├── @ SymbolNode (location: (64,0)-(64,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (53,0)-(53,1) = ":" - │ ├── value_loc: (53,1)-(53,2) = "&" + │ ├── opening_loc: (64,0)-(64,1) = ":" + │ ├── value_loc: (64,1)-(64,2) = "&" │ ├── closing_loc: ∅ │ └── unescaped: "&" - ├── @ SymbolNode (location: (55,0)-(55,2)) + ├── @ SymbolNode (location: (66,0)-(66,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (55,0)-(55,1) = ":" - │ ├── value_loc: (55,1)-(55,2) = "`" + │ ├── opening_loc: (66,0)-(66,1) = ":" + │ ├── value_loc: (66,1)-(66,2) = "`" │ ├── closing_loc: ∅ │ └── unescaped: "`" - ├── @ SymbolNode (location: (57,0)-(57,3)) + ├── @ SymbolNode (location: (68,0)-(68,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (57,0)-(57,1) = ":" - │ ├── value_loc: (57,1)-(57,3) = "!@" + │ ├── opening_loc: (68,0)-(68,1) = ":" + │ ├── value_loc: (68,1)-(68,3) = "!@" │ ├── closing_loc: ∅ │ └── unescaped: "!" - ├── @ SymbolNode (location: (59,0)-(59,3)) + ├── @ SymbolNode (location: (70,0)-(70,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (59,0)-(59,1) = ":" - │ ├── value_loc: (59,1)-(59,3) = "!~" + │ ├── opening_loc: (70,0)-(70,1) = ":" + │ ├── value_loc: (70,1)-(70,3) = "!~" │ ├── closing_loc: ∅ │ └── unescaped: "!~" - ├── @ SymbolNode (location: (61,0)-(61,2)) + ├── @ SymbolNode (location: (72,0)-(72,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (61,0)-(61,1) = ":" - │ ├── value_loc: (61,1)-(61,2) = "!" + │ ├── opening_loc: (72,0)-(72,1) = ":" + │ ├── value_loc: (72,1)-(72,2) = "!" │ ├── closing_loc: ∅ │ └── unescaped: "!" - ├── @ SymbolNode (location: (63,0)-(63,3)) + ├── @ SymbolNode (location: (74,0)-(74,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (63,0)-(63,1) = ":" - │ ├── value_loc: (63,1)-(63,3) = "[]" + │ ├── opening_loc: (74,0)-(74,1) = ":" + │ ├── value_loc: (74,1)-(74,3) = "[]" │ ├── closing_loc: ∅ │ └── unescaped: "[]" - ├── @ SymbolNode (location: (65,0)-(65,4)) + ├── @ SymbolNode (location: (76,0)-(76,4)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (65,0)-(65,1) = ":" - │ ├── value_loc: (65,1)-(65,4) = "[]=" + │ ├── opening_loc: (76,0)-(76,1) = ":" + │ ├── value_loc: (76,1)-(76,4) = "[]=" │ ├── closing_loc: ∅ │ └── unescaped: "[]=" - ├── @ SymbolNode (location: (67,0)-(67,2)) + ├── @ SymbolNode (location: (78,0)-(78,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (67,0)-(67,1) = ":" - │ ├── value_loc: (67,1)-(67,2) = "^" + │ ├── opening_loc: (78,0)-(78,1) = ":" + │ ├── value_loc: (78,1)-(78,2) = "^" │ ├── closing_loc: ∅ │ └── unescaped: "^" - ├── @ SymbolNode (location: (69,0)-(69,3)) + ├── @ SymbolNode (location: (80,0)-(80,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (69,0)-(69,1) = ":" - │ ├── value_loc: (69,1)-(69,3) = "==" + │ ├── opening_loc: (80,0)-(80,1) = ":" + │ ├── value_loc: (80,1)-(80,3) = "==" │ ├── closing_loc: ∅ │ └── unescaped: "==" - ├── @ SymbolNode (location: (71,0)-(71,4)) + ├── @ SymbolNode (location: (82,0)-(82,4)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (71,0)-(71,1) = ":" - │ ├── value_loc: (71,1)-(71,4) = "===" + │ ├── opening_loc: (82,0)-(82,1) = ":" + │ ├── value_loc: (82,1)-(82,4) = "===" │ ├── closing_loc: ∅ │ └── unescaped: "===" - ├── @ SymbolNode (location: (73,0)-(73,3)) + ├── @ SymbolNode (location: (84,0)-(84,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (73,0)-(73,1) = ":" - │ ├── value_loc: (73,1)-(73,3) = "=~" + │ ├── opening_loc: (84,0)-(84,1) = ":" + │ ├── value_loc: (84,1)-(84,3) = "=~" │ ├── closing_loc: ∅ │ └── unescaped: "=~" - ├── @ SymbolNode (location: (75,0)-(75,3)) + ├── @ SymbolNode (location: (86,0)-(86,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (75,0)-(75,1) = ":" - │ ├── value_loc: (75,1)-(75,3) = ">=" + │ ├── opening_loc: (86,0)-(86,1) = ":" + │ ├── value_loc: (86,1)-(86,3) = ">=" │ ├── closing_loc: ∅ │ └── unescaped: ">=" - ├── @ SymbolNode (location: (77,0)-(77,3)) + ├── @ SymbolNode (location: (88,0)-(88,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (77,0)-(77,1) = ":" - │ ├── value_loc: (77,1)-(77,3) = ">>" + │ ├── opening_loc: (88,0)-(88,1) = ":" + │ ├── value_loc: (88,1)-(88,3) = ">>" │ ├── closing_loc: ∅ │ └── unescaped: ">>" - ├── @ SymbolNode (location: (79,0)-(79,2)) + ├── @ SymbolNode (location: (90,0)-(90,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (79,0)-(79,1) = ":" - │ ├── value_loc: (79,1)-(79,2) = ">" + │ ├── opening_loc: (90,0)-(90,1) = ":" + │ ├── value_loc: (90,1)-(90,2) = ">" │ ├── closing_loc: ∅ │ └── unescaped: ">" - ├── @ SymbolNode (location: (81,0)-(81,4)) + ├── @ SymbolNode (location: (92,0)-(92,4)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (81,0)-(81,1) = ":" - │ ├── value_loc: (81,1)-(81,4) = "<=>" + │ ├── opening_loc: (92,0)-(92,1) = ":" + │ ├── value_loc: (92,1)-(92,4) = "<=>" │ ├── closing_loc: ∅ │ └── unescaped: "<=>" - ├── @ SymbolNode (location: (83,0)-(83,3)) + ├── @ SymbolNode (location: (94,0)-(94,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (83,0)-(83,1) = ":" - │ ├── value_loc: (83,1)-(83,3) = "<=" + │ ├── opening_loc: (94,0)-(94,1) = ":" + │ ├── value_loc: (94,1)-(94,3) = "<=" │ ├── closing_loc: ∅ │ └── unescaped: "<=" - ├── @ SymbolNode (location: (85,0)-(85,3)) + ├── @ SymbolNode (location: (96,0)-(96,3)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (85,0)-(85,1) = ":" - │ ├── value_loc: (85,1)-(85,3) = "<<" + │ ├── opening_loc: (96,0)-(96,1) = ":" + │ ├── value_loc: (96,1)-(96,3) = "<<" │ ├── closing_loc: ∅ │ └── unescaped: "<<" - ├── @ SymbolNode (location: (87,0)-(87,2)) + ├── @ SymbolNode (location: (98,0)-(98,2)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (87,0)-(87,1) = ":" - │ ├── value_loc: (87,1)-(87,2) = "<" + │ ├── opening_loc: (98,0)-(98,1) = ":" + │ ├── value_loc: (98,1)-(98,2) = "<" │ ├── closing_loc: ∅ │ └── unescaped: "<" - ├── @ SymbolNode (location: (89,0)-(89,9)) + ├── @ SymbolNode (location: (100,0)-(100,9)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (89,0)-(89,1) = ":" - │ ├── value_loc: (89,1)-(89,9) = "__LINE__" + │ ├── opening_loc: (100,0)-(100,1) = ":" + │ ├── value_loc: (100,1)-(100,9) = "__LINE__" │ ├── closing_loc: ∅ │ └── unescaped: "__LINE__" - ├── @ SymbolNode (location: (91,0)-(91,9)) + ├── @ SymbolNode (location: (102,0)-(102,9)) │ ├── flags: newline, static_literal, forced_us_ascii_encoding - │ ├── opening_loc: (91,0)-(91,1) = ":" - │ ├── value_loc: (91,1)-(91,9) = "__FILE__" + │ ├── opening_loc: (102,0)-(102,1) = ":" + │ ├── value_loc: (102,1)-(102,9) = "__FILE__" │ ├── closing_loc: ∅ │ └── unescaped: "__FILE__" - └── @ SymbolNode (location: (93,0)-(93,13)) + └── @ SymbolNode (location: (104,0)-(104,13)) ├── flags: newline, static_literal, forced_us_ascii_encoding - ├── opening_loc: (93,0)-(93,1) = ":" - ├── value_loc: (93,1)-(93,13) = "__ENCODING__" + ├── opening_loc: (104,0)-(104,1) = ":" + ├── value_loc: (104,1)-(104,13) = "__ENCODING__" ├── closing_loc: ∅ └── unescaped: "__ENCODING__" diff --git a/test/prism/snapshots/xstring.txt b/test/prism/snapshots/xstring.txt index b3a3cb801b..530066fd45 100644 --- a/test/prism/snapshots/xstring.txt +++ b/test/prism/snapshots/xstring.txt @@ -1,10 +1,10 @@ -@ ProgramNode (location: (1,0)-(16,4)) +@ ProgramNode (location: (1,0)-(21,4)) ├── flags: ∅ ├── locals: [] └── statements: - @ StatementsNode (location: (1,0)-(16,4)) + @ StatementsNode (location: (1,0)-(21,4)) ├── flags: ∅ - └── body: (length: 7) + └── body: (length: 8) ├── @ XStringNode (location: (1,0)-(1,7)) │ ├── flags: newline │ ├── opening_loc: (1,0)-(1,3) = "%x[" @@ -70,9 +70,15 @@ │ ├── content_loc: (13,3)-(13,3) = "" │ ├── closing_loc: (13,3)-(13,4) = "}" │ └── unescaped: "" - └── @ XStringNode (location: (15,0)-(16,4)) + ├── @ XStringNode (location: (15,0)-(18,1)) + │ ├── flags: newline + │ ├── opening_loc: (15,0)-(15,1) = "`" + │ ├── content_loc: (15,1)-(18,0) = "\nfoo\\\nb\\nar\n" + │ ├── closing_loc: (18,0)-(18,1) = "`" + │ └── unescaped: "\nfoob\nar\n" + └── @ XStringNode (location: (20,0)-(21,4)) ├── flags: newline - ├── opening_loc: (15,0)-(15,1) = "`" - ├── content_loc: (15,1)-(16,3) = "\n’" - ├── closing_loc: (16,3)-(16,4) = "`" + ├── opening_loc: (20,0)-(20,1) = "`" + ├── content_loc: (20,1)-(21,3) = "\n’" + ├── closing_loc: (21,3)-(21,4) = "`" └── unescaped: "\n’"