diff --git a/lib/prism/translation/parser/lexer.rb b/lib/prism/translation/parser/lexer.rb index 22ca3b6321..dd4867415c 100644 --- a/lib/prism/translation/parser/lexer.rb +++ b/lib/prism/translation/parser/lexer.rb @@ -425,7 +425,12 @@ def to_a end current_string << unescape_string(value, quote_stack.last) - if (backslash_count = token.value[/(\\{1,})\n/, 1]&.length).nil? || backslash_count.even? || !interpolation?(quote_stack.last) + relevant_backslash_count = if quote_stack.last.start_with?("%W", "%I") + 0 # the last backslash escapes the newline + else + token.value[/(\\{1,})\n/, 1]&.length || 0 + end + if relevant_backslash_count.even? || !interpolation?(quote_stack.last) tokens << [:tSTRING_CONTENT, [current_string, range(start_offset, start_offset + current_length)]] break end diff --git a/snapshots/strings.txt b/snapshots/strings.txt index 2ca8a6c9ed..bbaa66f53a 100644 --- a/snapshots/strings.txt +++ b/snapshots/strings.txt @@ -1,10 +1,10 @@ -@ ProgramNode (location: (1,0)-(157,15)) +@ ProgramNode (location: (1,0)-(185,15)) ├── flags: ∅ ├── locals: [] └── statements: - @ StatementsNode (location: (1,0)-(157,15)) + @ StatementsNode (location: (1,0)-(185,15)) ├── flags: ∅ - └── body: (length: 67) + └── body: (length: 71) ├── @ StringNode (location: (1,0)-(1,6)) │ ├── flags: newline │ ├── opening_loc: (1,0)-(1,2) = "%%" @@ -529,296 +529,436 @@ │ │ └── unescaped: "d" │ ├── opening_loc: (96,0)-(96,3) = "%w[" │ └── closing_loc: (100,0)-(100,1) = "]" - ├── @ ArrayNode (location: (102,0)-(102,18)) + ├── @ ArrayNode (location: (102,0)-(105,1)) + │ ├── flags: newline + │ ├── elements: (length: 3) + │ │ ├── @ StringNode (location: (103,2)-(103,10)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (103,2)-(103,10) = "foo\\nbar" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "foo\\nbar" + │ │ ├── @ StringNode (location: (103,11)-(104,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (103,11)-(104,0) = "baz\\n\\n\\\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "baz\\n\\n\n" + │ │ └── @ StringNode (location: (104,2)-(104,15)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (104,2)-(104,15) = "bat\\n\\\\\\n\\foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "bat\\n\\\\n\\foo" + │ ├── opening_loc: (102,0)-(102,3) = "%w[" + │ └── closing_loc: (105,0)-(105,1) = "]" + ├── @ ArrayNode (location: (107,0)-(110,1)) + │ ├── flags: newline + │ ├── elements: (length: 3) + │ │ ├── @ StringNode (location: (108,2)-(108,10)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (108,2)-(108,10) = "foo\\nbar" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "foo\nbar" + │ │ ├── @ StringNode (location: (108,11)-(109,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (108,11)-(109,0) = "baz\\n\\n\\\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "baz\n\n\n" + │ │ └── @ StringNode (location: (109,2)-(109,15)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (109,2)-(109,15) = "bat\\n\\\\\\n\\foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "bat\n\\\n\foo" + │ ├── opening_loc: (107,0)-(107,3) = "%W[" + │ └── closing_loc: (110,0)-(110,1) = "]" + ├── @ ArrayNode (location: (112,0)-(119,1)) + │ ├── flags: newline + │ ├── elements: (length: 7) + │ │ ├── @ StringNode (location: (112,3)-(113,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (112,3)-(113,0) = "foo\\\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "foo\n" + │ │ ├── @ StringNode (location: (113,2)-(113,5)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (113,2)-(113,5) = "bar" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "bar" + │ │ ├── @ StringNode (location: (114,2)-(114,7)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (114,2)-(114,7) = "baz\\\\" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "baz\\" + │ │ ├── @ StringNode (location: (115,2)-(115,5)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (115,2)-(115,5) = "bat" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "bat" + │ │ ├── @ StringNode (location: (116,2)-(116,5)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (116,2)-(116,5) = "1\\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "1\\n" + │ │ ├── @ StringNode (location: (117,2)-(117,3)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (117,2)-(117,3) = "2" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "2" + │ │ └── @ StringNode (location: (118,2)-(118,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (118,2)-(118,6) = "3\\\\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "3\\n" + │ ├── opening_loc: (112,0)-(112,3) = "%w[" + │ └── closing_loc: (119,0)-(119,1) = "]" + ├── @ ArrayNode (location: (121,0)-(128,1)) + │ ├── flags: newline + │ ├── elements: (length: 7) + │ │ ├── @ StringNode (location: (121,3)-(122,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (121,3)-(122,0) = "foo\\\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "foo\n" + │ │ ├── @ StringNode (location: (122,2)-(122,5)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (122,2)-(122,5) = "bar" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "bar" + │ │ ├── @ StringNode (location: (123,2)-(123,7)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (123,2)-(123,7) = "baz\\\\" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "baz\\" + │ │ ├── @ StringNode (location: (124,2)-(124,5)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (124,2)-(124,5) = "bat" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "bat" + │ │ ├── @ StringNode (location: (125,2)-(125,5)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (125,2)-(125,5) = "1\\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "1\n" + │ │ ├── @ StringNode (location: (126,2)-(126,3)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (126,2)-(126,3) = "2" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "2" + │ │ └── @ StringNode (location: (127,2)-(127,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (127,2)-(127,6) = "3\\\\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "3\\n" + │ ├── opening_loc: (121,0)-(121,3) = "%W[" + │ └── closing_loc: (128,0)-(128,1) = "]" + ├── @ ArrayNode (location: (130,0)-(130,18)) │ ├── flags: newline │ ├── elements: (length: 1) - │ │ └── @ StringNode (location: (102,3)-(102,17)) + │ │ └── @ StringNode (location: (130,3)-(130,17)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (102,3)-(102,17) = "f\\u{006f 006f}" + │ │ ├── content_loc: (130,3)-(130,17) = "f\\u{006f 006f}" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "foo" - │ ├── opening_loc: (102,0)-(102,3) = "%W[" - │ └── closing_loc: (102,17)-(102,18) = "]" - ├── @ ArrayNode (location: (104,0)-(104,14)) + │ ├── opening_loc: (130,0)-(130,3) = "%W[" + │ └── closing_loc: (130,17)-(130,18) = "]" + ├── @ ArrayNode (location: (132,0)-(132,14)) │ ├── flags: newline │ ├── elements: (length: 3) - │ │ ├── @ StringNode (location: (104,3)-(104,4)) + │ │ ├── @ StringNode (location: (132,3)-(132,4)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (104,3)-(104,4) = "a" + │ │ │ ├── content_loc: (132,3)-(132,4) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ ├── @ InterpolatedStringNode (location: (104,5)-(104,11)) + │ │ ├── @ InterpolatedStringNode (location: (132,5)-(132,11)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ │ │ │ ├── parts: (length: 3) - │ │ │ │ ├── @ StringNode (location: (104,5)-(104,6)) + │ │ │ │ ├── @ StringNode (location: (132,5)-(132,6)) │ │ │ │ │ ├── flags: static_literal, frozen │ │ │ │ │ ├── opening_loc: ∅ - │ │ │ │ │ ├── content_loc: (104,5)-(104,6) = "b" + │ │ │ │ │ ├── content_loc: (132,5)-(132,6) = "b" │ │ │ │ │ ├── closing_loc: ∅ │ │ │ │ │ └── unescaped: "b" - │ │ │ │ ├── @ EmbeddedStatementsNode (location: (104,6)-(104,10)) + │ │ │ │ ├── @ EmbeddedStatementsNode (location: (132,6)-(132,10)) │ │ │ │ │ ├── flags: ∅ - │ │ │ │ │ ├── opening_loc: (104,6)-(104,8) = "\#{" + │ │ │ │ │ ├── opening_loc: (132,6)-(132,8) = "\#{" │ │ │ │ │ ├── statements: - │ │ │ │ │ │ @ StatementsNode (location: (104,8)-(104,9)) + │ │ │ │ │ │ @ StatementsNode (location: (132,8)-(132,9)) │ │ │ │ │ │ ├── flags: ∅ │ │ │ │ │ │ └── body: (length: 1) - │ │ │ │ │ │ └── @ CallNode (location: (104,8)-(104,9)) + │ │ │ │ │ │ └── @ CallNode (location: (132,8)-(132,9)) │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility │ │ │ │ │ │ ├── receiver: ∅ │ │ │ │ │ │ ├── call_operator_loc: ∅ │ │ │ │ │ │ ├── name: :c - │ │ │ │ │ │ ├── message_loc: (104,8)-(104,9) = "c" + │ │ │ │ │ │ ├── message_loc: (132,8)-(132,9) = "c" │ │ │ │ │ │ ├── opening_loc: ∅ │ │ │ │ │ │ ├── arguments: ∅ │ │ │ │ │ │ ├── closing_loc: ∅ │ │ │ │ │ │ └── block: ∅ - │ │ │ │ │ └── closing_loc: (104,9)-(104,10) = "}" - │ │ │ │ └── @ StringNode (location: (104,10)-(104,11)) + │ │ │ │ │ └── closing_loc: (132,9)-(132,10) = "}" + │ │ │ │ └── @ StringNode (location: (132,10)-(132,11)) │ │ │ │ ├── flags: static_literal, frozen │ │ │ │ ├── opening_loc: ∅ - │ │ │ │ ├── content_loc: (104,10)-(104,11) = "d" + │ │ │ │ ├── content_loc: (132,10)-(132,11) = "d" │ │ │ │ ├── closing_loc: ∅ │ │ │ │ └── unescaped: "d" │ │ │ └── closing_loc: ∅ - │ │ └── @ StringNode (location: (104,12)-(104,13)) + │ │ └── @ StringNode (location: (132,12)-(132,13)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (104,12)-(104,13) = "e" + │ │ ├── content_loc: (132,12)-(132,13) = "e" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "e" - │ ├── opening_loc: (104,0)-(104,3) = "%W[" - │ └── closing_loc: (104,13)-(104,14) = "]" - ├── @ ArrayNode (location: (106,0)-(106,9)) + │ ├── opening_loc: (132,0)-(132,3) = "%W[" + │ └── closing_loc: (132,13)-(132,14) = "]" + ├── @ ArrayNode (location: (134,0)-(134,9)) │ ├── flags: newline │ ├── elements: (length: 3) - │ │ ├── @ StringNode (location: (106,3)-(106,4)) + │ │ ├── @ StringNode (location: (134,3)-(134,4)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (106,3)-(106,4) = "a" + │ │ │ ├── content_loc: (134,3)-(134,4) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ ├── @ StringNode (location: (106,5)-(106,6)) + │ │ ├── @ StringNode (location: (134,5)-(134,6)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (106,5)-(106,6) = "b" + │ │ │ ├── content_loc: (134,5)-(134,6) = "b" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "b" - │ │ └── @ StringNode (location: (106,7)-(106,8)) + │ │ └── @ StringNode (location: (134,7)-(134,8)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (106,7)-(106,8) = "c" + │ │ ├── content_loc: (134,7)-(134,8) = "c" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "c" - │ ├── opening_loc: (106,0)-(106,3) = "%W[" - │ └── closing_loc: (106,8)-(106,9) = "]" - ├── @ ArrayNode (location: (108,0)-(112,1)) + │ ├── opening_loc: (134,0)-(134,3) = "%W[" + │ └── closing_loc: (134,8)-(134,9) = "]" + ├── @ ArrayNode (location: (136,0)-(140,1)) │ ├── flags: newline │ ├── elements: (length: 3) - │ │ ├── @ StringNode (location: (109,2)-(109,3)) + │ │ ├── @ StringNode (location: (137,2)-(137,3)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (109,2)-(109,3) = "a" + │ │ │ ├── content_loc: (137,2)-(137,3) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ ├── @ StringNode (location: (110,2)-(110,3)) + │ │ ├── @ StringNode (location: (138,2)-(138,3)) │ │ │ ├── flags: ∅ │ │ │ ├── opening_loc: ∅ - │ │ │ ├── content_loc: (110,2)-(110,3) = "b" + │ │ │ ├── content_loc: (138,2)-(138,3) = "b" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "b" - │ │ └── @ StringNode (location: (111,2)-(111,3)) + │ │ └── @ StringNode (location: (139,2)-(139,3)) │ │ ├── flags: ∅ │ │ ├── opening_loc: ∅ - │ │ ├── content_loc: (111,2)-(111,3) = "c" + │ │ ├── content_loc: (139,2)-(139,3) = "c" │ │ ├── closing_loc: ∅ │ │ └── unescaped: "c" - │ ├── opening_loc: (108,0)-(108,3) = "%w[" - │ └── closing_loc: (112,0)-(112,1) = "]" - ├── @ StringNode (location: (114,0)-(114,15)) + │ ├── opening_loc: (136,0)-(136,3) = "%w[" + │ └── closing_loc: (140,0)-(140,1) = "]" + ├── @ StringNode (location: (142,0)-(142,15)) │ ├── flags: newline - │ ├── opening_loc: (114,0)-(114,1) = "'" - │ ├── content_loc: (114,1)-(114,14) = "\\' foo \\' bar" - │ ├── closing_loc: (114,14)-(114,15) = "'" + │ ├── opening_loc: (142,0)-(142,1) = "'" + │ ├── content_loc: (142,1)-(142,14) = "\\' foo \\' bar" + │ ├── closing_loc: (142,14)-(142,15) = "'" │ └── unescaped: "' foo ' bar" - ├── @ StringNode (location: (116,0)-(116,15)) + ├── @ StringNode (location: (144,0)-(144,15)) │ ├── flags: newline - │ ├── opening_loc: (116,0)-(116,1) = "'" - │ ├── content_loc: (116,1)-(116,14) = "\\\\ foo \\\\ bar" - │ ├── closing_loc: (116,14)-(116,15) = "'" + │ ├── opening_loc: (144,0)-(144,1) = "'" + │ ├── content_loc: (144,1)-(144,14) = "\\\\ foo \\\\ bar" + │ ├── closing_loc: (144,14)-(144,15) = "'" │ └── unescaped: "\\ foo \\ bar" - ├── @ StringNode (location: (118,0)-(121,1)) + ├── @ StringNode (location: (146,0)-(149,1)) │ ├── flags: newline - │ ├── opening_loc: (118,0)-(118,1) = "'" - │ ├── content_loc: (118,1)-(121,0) = "foo\\\nbar\\\\\nbaz\n" - │ ├── closing_loc: (121,0)-(121,1) = "'" + │ ├── opening_loc: (146,0)-(146,1) = "'" + │ ├── content_loc: (146,1)-(149,0) = "foo\\\nbar\\\\\nbaz\n" + │ ├── closing_loc: (149,0)-(149,1) = "'" │ └── unescaped: "foo\\\nbar\\\nbaz\n" - ├── @ InterpolatedStringNode (location: (123,0)-(123,7)) + ├── @ InterpolatedStringNode (location: (151,0)-(151,7)) │ ├── flags: newline - │ ├── opening_loc: (123,0)-(123,1) = "\"" + │ ├── opening_loc: (151,0)-(151,1) = "\"" │ ├── parts: (length: 1) - │ │ └── @ EmbeddedVariableNode (location: (123,1)-(123,6)) + │ │ └── @ EmbeddedVariableNode (location: (151,1)-(151,6)) │ │ ├── flags: ∅ - │ │ ├── operator_loc: (123,1)-(123,2) = "#" + │ │ ├── operator_loc: (151,1)-(151,2) = "#" │ │ └── variable: - │ │ @ GlobalVariableReadNode (location: (123,2)-(123,6)) + │ │ @ GlobalVariableReadNode (location: (151,2)-(151,6)) │ │ ├── flags: ∅ │ │ └── name: :$foo - │ └── closing_loc: (123,6)-(123,7) = "\"" - ├── @ InterpolatedStringNode (location: (125,0)-(125,7)) + │ └── closing_loc: (151,6)-(151,7) = "\"" + ├── @ InterpolatedStringNode (location: (153,0)-(153,7)) │ ├── flags: newline - │ ├── opening_loc: (125,0)-(125,1) = "\"" + │ ├── opening_loc: (153,0)-(153,1) = "\"" │ ├── parts: (length: 1) - │ │ └── @ EmbeddedVariableNode (location: (125,1)-(125,6)) + │ │ └── @ EmbeddedVariableNode (location: (153,1)-(153,6)) │ │ ├── flags: ∅ - │ │ ├── operator_loc: (125,1)-(125,2) = "#" + │ │ ├── operator_loc: (153,1)-(153,2) = "#" │ │ └── variable: - │ │ @ InstanceVariableReadNode (location: (125,2)-(125,6)) + │ │ @ InstanceVariableReadNode (location: (153,2)-(153,6)) │ │ ├── flags: ∅ │ │ └── name: :@foo - │ └── closing_loc: (125,6)-(125,7) = "\"" - ├── @ StringNode (location: (127,0)-(127,15)) + │ └── closing_loc: (153,6)-(153,7) = "\"" + ├── @ StringNode (location: (155,0)-(155,15)) │ ├── flags: newline - │ ├── opening_loc: (127,0)-(127,1) = "\"" - │ ├── content_loc: (127,1)-(127,14) = "\\x7 \\x23 \\x61" - │ ├── closing_loc: (127,14)-(127,15) = "\"" + │ ├── opening_loc: (155,0)-(155,1) = "\"" + │ ├── content_loc: (155,1)-(155,14) = "\\x7 \\x23 \\x61" + │ ├── closing_loc: (155,14)-(155,15) = "\"" │ └── unescaped: "\a # a" - ├── @ StringNode (location: (129,0)-(129,13)) + ├── @ StringNode (location: (157,0)-(157,13)) │ ├── flags: newline - │ ├── opening_loc: (129,0)-(129,1) = "\"" - │ ├── content_loc: (129,1)-(129,12) = "\\7 \\43 \\141" - │ ├── closing_loc: (129,12)-(129,13) = "\"" + │ ├── opening_loc: (157,0)-(157,1) = "\"" + │ ├── content_loc: (157,1)-(157,12) = "\\7 \\43 \\141" + │ ├── closing_loc: (157,12)-(157,13) = "\"" │ └── unescaped: "\a # a" - ├── @ StringNode (location: (131,0)-(131,17)) + ├── @ StringNode (location: (159,0)-(159,17)) │ ├── flags: newline, forced_utf8_encoding - │ ├── opening_loc: (131,0)-(131,1) = "\"" - │ ├── content_loc: (131,1)-(131,16) = "ち\\xE3\\x81\\xFF" - │ ├── closing_loc: (131,16)-(131,17) = "\"" + │ ├── opening_loc: (159,0)-(159,1) = "\"" + │ ├── content_loc: (159,1)-(159,16) = "ち\\xE3\\x81\\xFF" + │ ├── closing_loc: (159,16)-(159,17) = "\"" │ └── unescaped: "ち\xE3\x81\xFF" - ├── @ StringNode (location: (133,0)-(133,6)) + ├── @ StringNode (location: (161,0)-(161,6)) │ ├── flags: newline, forced_utf8_encoding - │ ├── opening_loc: (133,0)-(133,1) = "\"" - │ ├── content_loc: (133,1)-(133,5) = "\\777" - │ ├── closing_loc: (133,5)-(133,6) = "\"" + │ ├── opening_loc: (161,0)-(161,1) = "\"" + │ ├── content_loc: (161,1)-(161,5) = "\\777" + │ ├── closing_loc: (161,5)-(161,6) = "\"" │ └── unescaped: "\xFF" - ├── @ StringNode (location: (135,0)-(135,6)) + ├── @ StringNode (location: (163,0)-(163,6)) │ ├── flags: newline - │ ├── opening_loc: (135,0)-(135,2) = "%[" - │ ├── content_loc: (135,2)-(135,5) = "abc" - │ ├── closing_loc: (135,5)-(135,6) = "]" + │ ├── opening_loc: (163,0)-(163,2) = "%[" + │ ├── content_loc: (163,2)-(163,5) = "abc" + │ ├── closing_loc: (163,5)-(163,6) = "]" │ └── unescaped: "abc" - ├── @ StringNode (location: (137,0)-(137,6)) + ├── @ StringNode (location: (165,0)-(165,6)) │ ├── flags: newline - │ ├── opening_loc: (137,0)-(137,2) = "%(" - │ ├── content_loc: (137,2)-(137,5) = "abc" - │ ├── closing_loc: (137,5)-(137,6) = ")" + │ ├── opening_loc: (165,0)-(165,2) = "%(" + │ ├── content_loc: (165,2)-(165,5) = "abc" + │ ├── closing_loc: (165,5)-(165,6) = ")" │ └── unescaped: "abc" - ├── @ StringNode (location: (139,0)-(139,6)) + ├── @ StringNode (location: (167,0)-(167,6)) │ ├── flags: newline - │ ├── opening_loc: (139,0)-(139,2) = "%@" - │ ├── content_loc: (139,2)-(139,5) = "abc" - │ ├── closing_loc: (139,5)-(139,6) = "@" + │ ├── opening_loc: (167,0)-(167,2) = "%@" + │ ├── content_loc: (167,2)-(167,5) = "abc" + │ ├── closing_loc: (167,5)-(167,6) = "@" │ └── unescaped: "abc" - ├── @ StringNode (location: (141,0)-(141,6)) + ├── @ StringNode (location: (169,0)-(169,6)) │ ├── flags: newline - │ ├── opening_loc: (141,0)-(141,2) = "%$" - │ ├── content_loc: (141,2)-(141,5) = "abc" - │ ├── closing_loc: (141,5)-(141,6) = "$" + │ ├── opening_loc: (169,0)-(169,2) = "%$" + │ ├── content_loc: (169,2)-(169,5) = "abc" + │ ├── closing_loc: (169,5)-(169,6) = "$" │ └── unescaped: "abc" - ├── @ StringNode (location: (143,0)-(143,2)) + ├── @ StringNode (location: (171,0)-(171,2)) │ ├── flags: newline - │ ├── opening_loc: (143,0)-(143,1) = "?" - │ ├── content_loc: (143,1)-(143,2) = "a" + │ ├── opening_loc: (171,0)-(171,1) = "?" + │ ├── content_loc: (171,1)-(171,2) = "a" │ ├── closing_loc: ∅ │ └── unescaped: "a" - ├── @ InterpolatedStringNode (location: (145,0)-(145,6)) + ├── @ InterpolatedStringNode (location: (173,0)-(173,6)) │ ├── flags: newline, static_literal │ ├── opening_loc: ∅ │ ├── parts: (length: 2) - │ │ ├── @ StringNode (location: (145,0)-(145,2)) + │ │ ├── @ StringNode (location: (173,0)-(173,2)) │ │ │ ├── flags: static_literal, frozen - │ │ │ ├── opening_loc: (145,0)-(145,1) = "?" - │ │ │ ├── content_loc: (145,1)-(145,2) = "a" + │ │ │ ├── opening_loc: (173,0)-(173,1) = "?" + │ │ │ ├── content_loc: (173,1)-(173,2) = "a" │ │ │ ├── closing_loc: ∅ │ │ │ └── unescaped: "a" - │ │ └── @ StringNode (location: (145,3)-(145,6)) + │ │ └── @ StringNode (location: (173,3)-(173,6)) │ │ ├── flags: static_literal, frozen - │ │ ├── opening_loc: (145,3)-(145,4) = "\"" - │ │ ├── content_loc: (145,4)-(145,5) = "a" - │ │ ├── closing_loc: (145,5)-(145,6) = "\"" + │ │ ├── opening_loc: (173,3)-(173,4) = "\"" + │ │ ├── content_loc: (173,4)-(173,5) = "a" + │ │ ├── closing_loc: (173,5)-(173,6) = "\"" │ │ └── unescaped: "a" │ └── closing_loc: ∅ - ├── @ StringNode (location: (147,0)-(147,7)) + ├── @ StringNode (location: (175,0)-(175,7)) │ ├── flags: newline - │ ├── opening_loc: (147,0)-(147,3) = "%Q{" - │ ├── content_loc: (147,3)-(147,6) = "abc" - │ ├── closing_loc: (147,6)-(147,7) = "}" + │ ├── opening_loc: (175,0)-(175,3) = "%Q{" + │ ├── content_loc: (175,3)-(175,6) = "abc" + │ ├── closing_loc: (175,6)-(175,7) = "}" │ └── unescaped: "abc" - ├── @ StringNode (location: (149,0)-(149,7)) + ├── @ StringNode (location: (177,0)-(177,7)) │ ├── flags: newline - │ ├── opening_loc: (149,0)-(149,3) = "%Q(" - │ ├── content_loc: (149,3)-(149,6) = "\\«" - │ ├── closing_loc: (149,6)-(149,7) = ")" + │ ├── opening_loc: (177,0)-(177,3) = "%Q(" + │ ├── content_loc: (177,3)-(177,6) = "\\«" + │ ├── closing_loc: (177,6)-(177,7) = ")" │ └── unescaped: "«" - ├── @ StringNode (location: (151,0)-(151,7)) + ├── @ StringNode (location: (179,0)-(179,7)) │ ├── flags: newline - │ ├── opening_loc: (151,0)-(151,3) = "%q(" - │ ├── content_loc: (151,3)-(151,6) = "\\«" - │ ├── closing_loc: (151,6)-(151,7) = ")" + │ ├── opening_loc: (179,0)-(179,3) = "%q(" + │ ├── content_loc: (179,3)-(179,6) = "\\«" + │ ├── closing_loc: (179,6)-(179,7) = ")" │ └── unescaped: "\\«" - ├── @ StringNode (location: (153,0)-(153,5)) + ├── @ StringNode (location: (181,0)-(181,5)) │ ├── flags: newline - │ ├── opening_loc: (153,0)-(153,2) = "%^" - │ ├── content_loc: (153,2)-(153,4) = "\#$" - │ ├── closing_loc: (153,4)-(153,5) = "^" + │ ├── opening_loc: (181,0)-(181,2) = "%^" + │ ├── content_loc: (181,2)-(181,4) = "\#$" + │ ├── closing_loc: (181,4)-(181,5) = "^" │ └── unescaped: "\#$" - ├── @ StringNode (location: (155,0)-(155,4)) + ├── @ StringNode (location: (183,0)-(183,4)) │ ├── flags: newline - │ ├── opening_loc: (155,0)-(155,2) = "%@" - │ ├── content_loc: (155,2)-(155,3) = "#" - │ ├── closing_loc: (155,3)-(155,4) = "@" + │ ├── opening_loc: (183,0)-(183,2) = "%@" + │ ├── content_loc: (183,2)-(183,3) = "#" + │ ├── closing_loc: (183,3)-(183,4) = "@" │ └── unescaped: "#" - └── @ InterpolatedStringNode (location: (157,0)-(157,15)) + └── @ InterpolatedStringNode (location: (185,0)-(185,15)) ├── flags: newline - ├── opening_loc: (157,0)-(157,1) = "\"" + ├── opening_loc: (185,0)-(185,1) = "\"" ├── parts: (length: 2) - │ ├── @ EmbeddedStatementsNode (location: (157,1)-(157,12)) + │ ├── @ EmbeddedStatementsNode (location: (185,1)-(185,12)) │ │ ├── flags: ∅ - │ │ ├── opening_loc: (157,1)-(157,3) = "\#{" + │ │ ├── opening_loc: (185,1)-(185,3) = "\#{" │ │ ├── statements: - │ │ │ @ StatementsNode (location: (157,3)-(157,11)) + │ │ │ @ StatementsNode (location: (185,3)-(185,11)) │ │ │ ├── flags: ∅ │ │ │ └── body: (length: 1) - │ │ │ └── @ InterpolatedStringNode (location: (157,3)-(157,11)) + │ │ │ └── @ InterpolatedStringNode (location: (185,3)-(185,11)) │ │ │ ├── flags: ∅ - │ │ │ ├── opening_loc: (157,3)-(157,4) = "\"" + │ │ │ ├── opening_loc: (185,3)-(185,4) = "\"" │ │ │ ├── parts: (length: 2) - │ │ │ │ ├── @ EmbeddedStatementsNode (location: (157,4)-(157,8)) + │ │ │ │ ├── @ EmbeddedStatementsNode (location: (185,4)-(185,8)) │ │ │ │ │ ├── flags: ∅ - │ │ │ │ │ ├── opening_loc: (157,4)-(157,6) = "\#{" + │ │ │ │ │ ├── opening_loc: (185,4)-(185,6) = "\#{" │ │ │ │ │ ├── statements: - │ │ │ │ │ │ @ StatementsNode (location: (157,6)-(157,7)) + │ │ │ │ │ │ @ StatementsNode (location: (185,6)-(185,7)) │ │ │ │ │ │ ├── flags: ∅ │ │ │ │ │ │ └── body: (length: 1) - │ │ │ │ │ │ └── @ ConstantReadNode (location: (157,6)-(157,7)) + │ │ │ │ │ │ └── @ ConstantReadNode (location: (185,6)-(185,7)) │ │ │ │ │ │ ├── flags: ∅ │ │ │ │ │ │ └── name: :B - │ │ │ │ │ └── closing_loc: (157,7)-(157,8) = "}" - │ │ │ │ └── @ StringNode (location: (157,8)-(157,10)) + │ │ │ │ │ └── closing_loc: (185,7)-(185,8) = "}" + │ │ │ │ └── @ StringNode (location: (185,8)-(185,10)) │ │ │ │ ├── flags: static_literal, frozen │ │ │ │ ├── opening_loc: ∅ - │ │ │ │ ├── content_loc: (157,8)-(157,10) = " C" + │ │ │ │ ├── content_loc: (185,8)-(185,10) = " C" │ │ │ │ ├── closing_loc: ∅ │ │ │ │ └── unescaped: " C" - │ │ │ └── closing_loc: (157,10)-(157,11) = "\"" - │ │ └── closing_loc: (157,11)-(157,12) = "}" - │ └── @ StringNode (location: (157,12)-(157,14)) + │ │ │ └── closing_loc: (185,10)-(185,11) = "\"" + │ │ └── closing_loc: (185,11)-(185,12) = "}" + │ └── @ StringNode (location: (185,12)-(185,14)) │ ├── flags: static_literal, frozen │ ├── opening_loc: ∅ - │ ├── content_loc: (157,12)-(157,14) = " D" + │ ├── content_loc: (185,12)-(185,14) = " D" │ ├── closing_loc: ∅ │ └── unescaped: " D" - └── closing_loc: (157,14)-(157,15) = "\"" + └── closing_loc: (185,14)-(185,15) = "\"" diff --git a/test/prism/fixtures/strings.txt b/test/prism/fixtures/strings.txt index 77e1e4acff..1419f975b7 100644 --- a/test/prism/fixtures/strings.txt +++ b/test/prism/fixtures/strings.txt @@ -99,6 +99,34 @@ bar) d ] +%w[ + foo\nbar baz\n\n\ + bat\n\\\n\foo +] + +%W[ + foo\nbar baz\n\n\ + bat\n\\\n\foo +] + +%w[foo\ + bar + baz\\ + bat + 1\n + 2 + 3\\n +] + +%W[foo\ + bar + baz\\ + bat + 1\n + 2 + 3\\n +] + %W[f\u{006f 006f}] %W[a b#{c}d e]