summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEarlopain <[email protected]>2025-06-12 14:12:40 +0200
committergit <[email protected]>2025-06-30 12:32:31 +0000
commit3071c5d04cb4369ee8118ece30fb2887205f6c61 (patch)
tree6caee4669ab609ae90c20e11314d421faa604d0d
parent4e5c8c19a722f979007c83cf15a3a270a0de8f53 (diff)
[ruby/prism] Fix parser translator with trailing backslash in `%W` /`%I` array
https://docs.ruby-lang.org/en/master/syntax/literals_rdoc.html#label-25w+and+-25W-3A+String-Array+Literals > %W allow escape sequences described in Escape Sequences. However the continuation line <newline> is not usable because it is interpreted as the escaped newline described above. https://github.com/ruby/prism/commit/f5c7460ad5
-rw-r--r--lib/prism/translation/parser/lexer.rb7
-rw-r--r--test/prism/fixtures/strings.txt28
2 files changed, 34 insertions, 1 deletions
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 @@ module Prism
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/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]