summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi ITO <[email protected]>2024-03-13 02:40:08 +0900
committergit <[email protected]>2024-03-13 11:34:17 +0000
commit7eea268b70b0a401bc8b8094b4ecbaf34aac9fa8 (patch)
treeb2c516f6d299aa10bf3ca2c2331e975b892653a6
parenta5c5f83b24a1b7024d4e7fe3bbce091634da53b2 (diff)
[ruby/prism] Fix an AST incompatibility for `Prism::Translation::Parser`
Fixes ruby/prism#2480. This PR fixes an AST incompatibility between Parser gem and `Prism::Translation::Parser` for xstring literal with line breaks. The following case in ruby/prism#2480 has already been addressed in ruby/prism#2576: ```ruby "foo bar" ``` https://github.com/ruby/prism/commit/cf85e72c55
-rw-r--r--lib/prism/translation/parser/compiler.rb16
-rw-r--r--test/prism/fixtures/xstring.txt4
-rw-r--r--test/prism/snapshots/xstring.txt22
3 files changed, 33 insertions, 9 deletions
diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb
index bf5b85441b..cf628cddd4 100644
--- a/lib/prism/translation/parser/compiler.rb
+++ b/lib/prism/translation/parser/compiler.rb
@@ -1678,9 +1678,23 @@ module Prism
children, closing = visit_heredoc(node.to_interpolated)
builder.xstring_compose(token(node.opening_loc), children, closing)
else
+ parts = if node.unescaped.lines.count <= 1
+ [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.length
+ offsets = srange_offsets(start_offset, end_offset)
+ start_offset = end_offset
+
+ builder.string_internal([line, offsets])
+ end
+ end
+
builder.xstring_compose(
token(node.opening_loc),
- [builder.string_internal([node.unescaped, srange(node.content_loc)])],
+ parts,
token(node.closing_loc)
)
end
diff --git a/test/prism/fixtures/xstring.txt b/test/prism/fixtures/xstring.txt
index 623afd9797..fcbaad91ae 100644
--- a/test/prism/fixtures/xstring.txt
+++ b/test/prism/fixtures/xstring.txt
@@ -3,3 +3,7 @@
`foo #{bar} baz`
`foo`
+
+%x{
+ foo
+}
diff --git a/test/prism/snapshots/xstring.txt b/test/prism/snapshots/xstring.txt
index 0a9d075818..56ba77a8c0 100644
--- a/test/prism/snapshots/xstring.txt
+++ b/test/prism/snapshots/xstring.txt
@@ -1,8 +1,8 @@
-@ ProgramNode (location: (1,0)-(5,5))
+@ ProgramNode (location: (1,0)-(9,1))
├── locals: []
└── statements:
- @ StatementsNode (location: (1,0)-(5,5))
- └── body: (length: 3)
+ @ StatementsNode (location: (1,0)-(9,1))
+ └── body: (length: 4)
├── @ XStringNode (location: (1,0)-(1,7))
│ ├── flags: ∅
│ ├── opening_loc: (1,0)-(1,3) = "%x["
@@ -41,9 +41,15 @@
│ │ ├── closing_loc: ∅
│ │ └── unescaped: " baz"
│ └── closing_loc: (3,15)-(3,16) = "`"
- └── @ XStringNode (location: (5,0)-(5,5))
+ ├── @ XStringNode (location: (5,0)-(5,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (5,0)-(5,1) = "`"
+ │ ├── content_loc: (5,1)-(5,4) = "foo"
+ │ ├── closing_loc: (5,4)-(5,5) = "`"
+ │ └── unescaped: "foo"
+ └── @ XStringNode (location: (7,0)-(9,1))
├── flags: ∅
- ├── opening_loc: (5,0)-(5,1) = "`"
- ├── content_loc: (5,1)-(5,4) = "foo"
- ├── closing_loc: (5,4)-(5,5) = "`"
- └── unescaped: "foo"
+ ├── opening_loc: (7,0)-(7,3) = "%x{"
+ ├── content_loc: (7,3)-(9,0) = "\n foo\n"
+ ├── closing_loc: (9,0)-(9,1) = "}"
+ └── unescaped: "\n foo\n"