summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi ITO <koic.ito@gmail.com>2024-03-03 21:25:10 +0900
committergit <svn-admin@ruby-lang.org>2024-03-07 14:05:20 +0000
commit0e4bfd08e548e90faf5d91bddccf418dc9a62a42 (patch)
tree12ac92dffdedf181274593cf0f53798a1e8bb4de
parent78725f14b287bff19d48dea076be169c74e18b77 (diff)
[ruby/prism] Fix an AST and token incompatibility for `Prism::Translation::Parser`
Fixes https://github.com/ruby/prism/pull/2506. This PR fixes an AST and token incompatibility between Parser gem and `Prism::Translation::Parser` for symbols quoted with line breaks. https://github.com/ruby/prism/commit/06ab4df8cd
-rw-r--r--lib/prism/translation/parser/compiler.rb16
-rw-r--r--lib/prism/translation/parser/lexer.rb10
-rw-r--r--test/prism/fixtures/dsym_str.txt2
-rw-r--r--test/prism/snapshots/dsym_str.txt11
4 files changed, 38 insertions, 1 deletions
diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb
index 8170e1953b..d64e382c78 100644
--- a/lib/prism/translation/parser/compiler.rb
+++ b/lib/prism/translation/parser/compiler.rb
@@ -1528,9 +1528,23 @@ module Prism
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.length
+ offsets = srange_offsets(start_offset, end_offset)
+ start_offset = end_offset
+
+ builder.string_internal([line, offsets])
+ end
+ end
+
builder.symbol_compose(
token(node.opening_loc),
- [builder.string_internal([node.unescaped, srange(node.value_loc)])],
+ parts,
token(node.closing_loc)
)
end
diff --git a/lib/prism/translation/parser/lexer.rb b/lib/prism/translation/parser/lexer.rb
index 9a0a48a00f..62ce17c7ea 100644
--- a/lib/prism/translation/parser/lexer.rb
+++ b/lib/prism/translation/parser/lexer.rb
@@ -291,6 +291,16 @@ module Prism
quote = value[2] == "-" || value[2] == "~" ? value[3] : value[2]
value = "<<#{quote == "'" || quote == "\"" ? quote : "\""}"
end
+ when :tSTRING_CONTENT
+ unless (lines = token.value.lines).one?
+ start_offset = offset_cache[token.location.start_offset]
+ lines.map do |line|
+ end_offset = start_offset + line.length
+ tokens << [:tSTRING_CONTENT, [line, Range.new(source_buffer, start_offset, offset_cache[end_offset])]]
+ start_offset = end_offset
+ end
+ next
+ end
when :tSTRING_DVAR
value = nil
when :tSTRING_END
diff --git a/test/prism/fixtures/dsym_str.txt b/test/prism/fixtures/dsym_str.txt
new file mode 100644
index 0000000000..ee68dde88d
--- /dev/null
+++ b/test/prism/fixtures/dsym_str.txt
@@ -0,0 +1,2 @@
+:"foo
+ bar"
diff --git a/test/prism/snapshots/dsym_str.txt b/test/prism/snapshots/dsym_str.txt
new file mode 100644
index 0000000000..33a5e2da21
--- /dev/null
+++ b/test/prism/snapshots/dsym_str.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(2,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,6))
+ └── body: (length: 1)
+ └── @ SymbolNode (location: (1,0)-(2,6))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (1,0)-(1,2) = ":\""
+ ├── value_loc: (1,2)-(2,5) = "foo\n bar"
+ ├── closing_loc: (2,5)-(2,6) = "\""
+ └── unescaped: "foo\n bar"