Skip to content

Commit bed4271

Browse files
committed
Check using Prism nodes if a command call has any arguments in Ripper translator
* We don't know what `on_*` events might return so we cannot assume it's an Array. * See #3838 (comment)
1 parent 63719d8 commit bed4271

2 files changed

Lines changed: 25 additions & 5 deletions

File tree

lib/prism/translation/ripper.rb

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,7 @@ def visit_call_node(node)
11121112
else
11131113
arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc || node.location))
11141114
call =
1115-
if node.opening_loc.nil? && arguments&.any?
1115+
if node.opening_loc.nil? && get_arguments_and_block(node.arguments, node.block).first.any?
11161116
bounds(node.location)
11171117
on_command(message, arguments)
11181118
elsif !node.opening_loc.nil?
@@ -1179,17 +1179,25 @@ def visit_call_node(node)
11791179
end
11801180
end
11811181

1182-
# Visit the arguments and block of a call node and return the arguments
1183-
# and block as they should be used.
1184-
private def visit_call_node_arguments(arguments_node, block_node, trailing_comma)
1182+
# Extract the arguments and block Ripper-style, which means if the block
1183+
# is like `&b` then it's moved to arguments.
1184+
private def get_arguments_and_block(arguments_node, block_node)
11851185
arguments = arguments_node&.arguments || []
11861186
block = block_node
11871187

11881188
if block.is_a?(BlockArgumentNode)
1189-
arguments << block
1189+
arguments += [block]
11901190
block = nil
11911191
end
11921192

1193+
[arguments, block]
1194+
end
1195+
1196+
# Visit the arguments and block of a call node and return the arguments
1197+
# and block as they should be used.
1198+
private def visit_call_node_arguments(arguments_node, block_node, trailing_comma)
1199+
arguments, block = get_arguments_and_block(arguments_node, block_node)
1200+
11931201
[
11941202
if arguments.length == 1 && arguments.first.is_a?(ForwardingArgumentsNode)
11951203
visit(arguments.first)

test/prism/ruby/ripper_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,14 @@ class PrismEvents < Translation::Ripper
110110
include Events
111111
end
112112

113+
class ObjectEvents < Translation::Ripper
114+
Prism::Translation::Ripper::PARSER_EVENTS.each do |event|
115+
define_method(:"on_#{event}") do |*args|
116+
Object.new
117+
end
118+
end
119+
end
120+
113121
def test_events
114122
source = "1 rescue 2"
115123
ripper = RipperEvents.new(source)
@@ -152,6 +160,10 @@ def test_internals
152160

153161
def assert_ripper_sexp_raw(source)
154162
assert_equal Ripper.sexp_raw(source), Prism::Translation::Ripper.sexp_raw(source)
163+
164+
# Similar to test/ripper/assert_parse_files.rb in CRuby
165+
object_events = ObjectEvents.new(source)
166+
assert_nothing_raised { object_events.parse }
155167
end
156168

157169
def assert_ripper_lex(source)

0 commit comments

Comments
 (0)