summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-03-05 16:58:24 -0500
committergit <svn-admin@ruby-lang.org>2024-03-06 16:42:46 +0000
commita0674a5755f0429ce435432ae2bad7bf696b7314 (patch)
tree94ecb04ee68d47f61b915b0343dd904e9788e717
parentcb116420816163bd7b271313b7b4a18d3d5b0638 (diff)
[ruby/prism] Fix implementation of [] and []= for ripper translation
https://github.com/ruby/prism/commit/d31cf63d45
-rw-r--r--lib/prism/translation/ripper.rb84
-rw-r--r--test/prism/ripper_test.rb6
2 files changed, 63 insertions, 27 deletions
diff --git a/lib/prism/translation/ripper.rb b/lib/prism/translation/ripper.rb
index 339b42c003..136ccad44c 100644
--- a/lib/prism/translation/ripper.rb
+++ b/lib/prism/translation/ripper.rb
@@ -469,12 +469,71 @@ module Prism
# foo.bar() {}
# ^^^^^^^^^^^^
def visit_call_node(node)
- return visit_aref_node(node) if node.name == :[]
- return visit_aref_field_node(node) if node.name == :[]=
+ case node.name
+ when :[]
+ if node.opening == "["
+ receiver = visit(node.receiver)
+ arguments = node.arguments&.arguments || []
+ block = node.block
+
+ if block.is_a?(BlockArgumentNode)
+ arguments << block
+ block = nil
+ end
- if node.variable_call?
- raise NoMethodError, __method__ unless node.receiver.nil?
+ arguments =
+ if arguments.any?
+ args = visit_arguments(arguments)
+
+ if node.block.is_a?(BlockArgumentNode)
+ args
+ else
+ bounds(arguments.first.location)
+ on_args_add_block(args, false)
+ end
+ end
+
+ bounds(node.location)
+ call = on_aref(receiver, arguments)
+ if block.nil?
+ return call
+ else
+ block = visit(block)
+
+ bounds(node.location)
+ return on_method_add_block(call, block)
+ end
+ end
+ when :[]=
+ if node.opening == "["
+ receiver = visit(node.receiver)
+
+ *arguments, last_argument = node.arguments.arguments
+ arguments << node.block if !node.block.nil?
+
+ arguments =
+ if arguments.any?
+ args = visit_arguments(arguments)
+
+ if !node.block.nil?
+ args
+ else
+ bounds(arguments.first.location)
+ on_args_add_block(args, false)
+ end
+ end
+
+ bounds(node.location)
+ call = on_aref_field(receiver, arguments)
+
+ value = visit(last_argument)
+ bounds(last_argument.location)
+ return on_assign(call, value)
+ end
+ end
+
+ if node.variable_call?
bounds(node.message_loc)
return on_vcall(on_ident(node.message))
end
@@ -2432,23 +2491,6 @@ module Prism
end
end
- # In Prism this is a CallNode with :[] as the operator.
- # In Ripper it's an :aref.
- def visit_aref_node(node)
- first_arg_val = visit(node.arguments.arguments[0])
- args_val = on_args_add_block(on_args_add(on_args_new, first_arg_val), false)
- on_aref(visit(node.receiver), args_val)
- end
-
- # In Prism this is a CallNode with :[]= as the operator.
- # In Ripper it's an :aref_field.
- def visit_aref_field_node(node)
- first_arg_val = visit(node.arguments.arguments[0])
- args_val = on_args_add_block(on_args_add(on_args_new, first_arg_val), false)
- assign_val = visit(node.arguments.arguments[1])
- on_assign(on_aref_field(visit(node.receiver), args_val), assign_val)
- end
-
# Ripper has several methods of emitting a symbol literal. Inside an alias
# sometimes it suppresses the [:symbol] wrapper around ident. If the symbol
# is also the name of a keyword (e.g. :if) it will emit a :@kw wrapper, not
diff --git a/test/prism/ripper_test.rb b/test/prism/ripper_test.rb
index bdc6529790..0deb486999 100644
--- a/test/prism/ripper_test.rb
+++ b/test/prism/ripper_test.rb
@@ -148,7 +148,6 @@ module Prism
seattlerb/heredoc_with_only_carriage_returns.txt
seattlerb/heredoc_with_only_carriage_returns_windows.txt
seattlerb/if_elsif.txt
- seattlerb/index_0.txt
seattlerb/interpolated_symbol_array_line_breaks.txt
seattlerb/interpolated_word_array_line_breaks.txt
seattlerb/lambda_do_vs_brace.txt
@@ -401,18 +400,13 @@ module Prism
whitequark/ruby_bug_12073.txt
whitequark/ruby_bug_12402.txt
whitequark/ruby_bug_12686.txt
- whitequark/ruby_bug_13547.txt
whitequark/ruby_bug_14690.txt
whitequark/ruby_bug_15789.txt
whitequark/send_attr_asgn.txt
whitequark/send_attr_asgn_conditional.txt
whitequark/send_block_chain_cmd.txt
whitequark/send_call.txt
- whitequark/send_index.txt
- whitequark/send_index_asgn.txt
- whitequark/send_index_asgn_legacy.txt
whitequark/send_index_cmd.txt
- whitequark/send_index_legacy.txt
whitequark/send_lambda.txt
whitequark/send_lambda_args_noparen.txt
whitequark/send_lambda_legacy.txt