summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEarlopain <14981592+Earlopain@users.noreply.github.com>2026-04-23 15:26:25 +0200
committergit <svn-admin@ruby-lang.org>2026-04-23 23:49:06 +0000
commitfd9cee5fc39a858ab513a102c9b7f7296feeb860 (patch)
tree4e7a3a62cd3533c81f39aa276f182e30c8f3978f
parent7d4941d3e1c5721a551eeb1d7410e3ead4a6b432 (diff)
[ruby/prism] Fix incompatibilities for `on_word_sep` in ripper
It was mostly good, just a few edgecases: * word_sep always only contains a single line. if there are multiple lines, it is also multiple word_sep * Handle trailing whitespace The excluded testcase is interpolation mixed with heredoc. That is not currently handled properly and word_sep contains the content of the heredoc I also switched start/end_offset names in the method, they seem to be backwards https://github.com/ruby/prism/commit/2e151ad41b
-rw-r--r--lib/prism/translation/ripper.rb28
-rw-r--r--test/prism/ruby/ripper_test.rb5
2 files changed, 24 insertions, 9 deletions
diff --git a/lib/prism/translation/ripper.rb b/lib/prism/translation/ripper.rb
index b066f3e3ac..00506d650e 100644
--- a/lib/prism/translation/ripper.rb
+++ b/lib/prism/translation/ripper.rb
@@ -704,6 +704,8 @@ module Prism
previous = element
end
+ visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
+
bounds(node.closing_loc)
on_tstring_end(node.closing)
when /^%i/
@@ -723,6 +725,8 @@ module Prism
previous = element
end
+ visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
+
bounds(node.closing_loc)
on_tstring_end(node.closing)
when /^%W/
@@ -760,6 +764,8 @@ module Prism
previous = element
end
+ visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
+
bounds(node.closing_loc)
on_tstring_end(node.closing)
when /^%I/
@@ -797,6 +803,8 @@ module Prism
previous = element
end
+ visit_words_sep(opening_loc, node.elements.last, node.closing_loc)
+
bounds(node.closing_loc)
on_tstring_end(node.closing)
else
@@ -813,15 +821,21 @@ module Prism
on_array(elements)
end
- # Dispatch a words_sep event that contains the space between the elements
+ # Dispatch words_sep events that contains the whitespace between the elements
# of list literals.
private def visit_words_sep(opening_loc, previous, current)
- end_offset = (previous.nil? ? opening_loc : previous.location).end_offset
- start_offset = current.location.start_offset
-
- if end_offset != start_offset
- bounds(current.location.copy(start_offset: end_offset))
- on_words_sep(source.byteslice(end_offset...start_offset))
+ start_offset = (previous.nil? ? opening_loc : previous.location).end_offset
+ end_offset = current.start_offset
+ length = end_offset - start_offset
+
+ if length > 0
+ whitespace = source.byteslice(start_offset, length)
+ current_offset = start_offset
+ whitespace.each_line do |part|
+ bounds(opening_loc.copy(start_offset: current_offset, length: part.bytesize))
+ on_words_sep(part)
+ current_offset += part.bytesize
+ end
end
end
diff --git a/test/prism/ruby/ripper_test.rb b/test/prism/ruby/ripper_test.rb
index 61065e3ffc..cdb8375f96 100644
--- a/test/prism/ruby/ripper_test.rb
+++ b/test/prism/ruby/ripper_test.rb
@@ -101,6 +101,7 @@ module Prism
"seattlerb/messy_op_asgn_lineno.txt",
"seattlerb/op_asgn_primary_colon_const_command_call.txt",
"seattlerb/parse_pattern_076.txt",
+ "seattlerb/pct_w_heredoc_interp_nested.txt",
"tilde_heredocs.txt",
"unparser/corpus/literal/assignment.txt",
"unparser/corpus/literal/pattern.txt",
@@ -138,11 +139,11 @@ module Prism
end
end
- UNSUPPORTED_EVENTS = %i[comma ignored_nl label_end nl semicolon sp words_sep ignored_sp]
+ UNSUPPORTED_EVENTS = %i[comma ignored_nl label_end nl semicolon sp ignored_sp]
# Events that are currently not emitted
SUPPORTED_EVENTS = Translation::Ripper::EVENTS - UNSUPPORTED_EVENTS
# Events that assert against their line/column
- CHECK_LOCATION_EVENTS = %i[kw op lbrace rbrace lbracket rbracket lparen rparen]
+ CHECK_LOCATION_EVENTS = %i[kw op lbrace rbrace lbracket rbracket lparen rparen words_sep]
module Events
attr_reader :events