summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-03-05 17:37:10 -0500
committergit <svn-admin@ruby-lang.org>2024-03-06 16:42:46 +0000
commitc2d6bcc81a827786c2cffefbac0840cc1c9b42d5 (patch)
tree129929ace72271143d52bd1b5f7d90ea733f17d7
parenta0674a5755f0429ce435432ae2bad7bf696b7314 (diff)
[ruby/prism] Revisit call nodes for ripper translation
https://github.com/ruby/prism/commit/372200f970
-rw-r--r--lib/prism/translation/ripper.rb211
-rw-r--r--test/prism/ripper_test.rb30
2 files changed, 99 insertions, 142 deletions
diff --git a/lib/prism/translation/ripper.rb b/lib/prism/translation/ripper.rb
index 136ccad44c..5addc69318 100644
--- a/lib/prism/translation/ripper.rb
+++ b/lib/prism/translation/ripper.rb
@@ -469,44 +469,22 @@ module Prism
# foo.bar() {}
# ^^^^^^^^^^^^
def visit_call_node(node)
- case node.name
- when :[]
- if node.opening == "["
+ if node.call_operator_loc.nil?
+ case node.name
+ when :[]
receiver = visit(node.receiver)
- arguments = node.arguments&.arguments || []
- block = node.block
-
- if block.is_a?(BlockArgumentNode)
- arguments << block
- block = nil
- end
-
- 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
+ arguments, block = visit_call_node_arguments(node.arguments, node.block)
bounds(node.location)
call = on_aref(receiver, arguments)
if block.nil?
- return call
+ call
else
- block = visit(block)
-
bounds(node.location)
- return on_method_add_block(call, block)
+ on_method_add_block(call, block)
end
- end
- when :[]=
- if node.opening == "["
+ when :[]=
receiver = visit(node.receiver)
*arguments, last_argument = node.arguments.arguments
@@ -529,34 +507,107 @@ module Prism
value = visit(last_argument)
bounds(last_argument.location)
- return on_assign(call, value)
+ on_assign(call, value)
+ when :-@, :+@, :~@, :!@
+ receiver = visit(node.receiver)
+
+ bounds(node.location)
+ on_unary(node.message == "not" ? :not : node.name, receiver)
+ when :!=, :!~, :=~, :==, :===, :<=>, :>, :>=, :<, :<=, :&, :|, :^, :>>, :<<, :-, :+, :%, :/, :*, :**
+ receiver = visit(node.receiver)
+ value = visit(node.arguments.arguments.first)
+
+ bounds(node.location)
+ on_binary(receiver, node.name, value)
+ else
+ bounds(node.message_loc)
+ message = on_ident(node.message)
+
+ if node.variable_call?
+ on_vcall(message)
+ else
+ arguments, block = visit_call_node_arguments(node.arguments, node.block)
+ call =
+ if node.opening_loc.nil? && (arguments&.any? || block.nil?)
+ bounds(node.location)
+ on_command(message, arguments)
+ elsif !node.opening_loc.nil?
+ bounds(node.location)
+ on_method_add_arg(on_fcall(message), on_arg_paren(arguments))
+ else
+ bounds(node.location)
+ on_method_add_arg(on_fcall(message), on_args_new)
+ end
+
+ if block.nil?
+ call
+ else
+ bounds(node.block.location)
+ on_method_add_block(call, block)
+ end
+ end
end
- end
+ else
+ receiver = visit(node.receiver)
+
+ bounds(node.call_operator_loc)
+ call_operator = visit_token(node.call_operator)
- if node.variable_call?
bounds(node.message_loc)
- return on_vcall(on_ident(node.message))
- end
+ message = visit_token(node.message)
- if node.opening_loc.nil?
- return visit_no_paren_call(node)
- end
+ arguments, block = visit_call_node_arguments(node.arguments, node.block)
+ call =
+ if node.opening_loc.nil?
+ bounds(node.location)
- # A non-operator method call with parentheses
- args = on_arg_paren(node.arguments.nil? ? nil : visit(node.arguments))
+ if !arguments || arguments.empty?
+ on_call(receiver, call_operator, message)
+ else
+ on_command_call(receiver, call_operator, message, arguments)
+ end
+ else
+ bounds(node.opening_loc)
+ arguments = on_arg_paren(arguments)
- bounds(node.message_loc)
- ident_val = on_ident(node.message)
+ bounds(node.location)
+ on_method_add_arg(on_call(receiver, call_operator, message), arguments)
+ end
- bounds(node.location)
- args_call_val = on_method_add_arg(on_fcall(ident_val), args)
- if node.block
- block_val = visit(node.block)
+ if block.nil?
+ call
+ else
+ bounds(node.block.location)
+ on_method_add_block(call, block)
+ end
+ end
+ end
- return on_method_add_block(args_call_val, block_val)
- else
- return args_call_val
+ # Visit the arguments and block of a call node and return the arguments
+ # and block as they should be used.
+ private def visit_call_node_arguments(arguments_node, block_node)
+ arguments = arguments_node&.arguments || []
+ block = block_node
+
+ if block.is_a?(BlockArgumentNode)
+ arguments << block
+ block = nil
end
+
+ arguments =
+ if arguments.any?
+ args = visit_arguments(arguments)
+
+ if block.is_a?(BlockArgumentNode)
+ args
+ else
+ bounds(arguments.first.location)
+ on_args_add_block(args, false)
+ end
+ end
+
+ block = visit(block) if !block.nil?
+ [arguments, block]
end
# foo.bar += baz
@@ -2427,70 +2478,6 @@ module Prism
end
end
- # Generate Ripper events for a CallNode with no opening_loc
- def visit_no_paren_call(node)
- # No opening_loc can mean an operator. It can also mean a
- # method call with no parentheses.
- if node.message.match?(/^[[:punct:]]/)
- left = visit(node.receiver)
- if node.arguments&.arguments&.length == 1
- right = visit(node.arguments.arguments.first)
-
- return on_binary(left, node.name, right)
- elsif !node.arguments || node.arguments.empty?
- return on_unary(node.name, left)
- else
- raise NoMethodError, __method__, "More than two arguments for operator"
- end
- elsif node.call_operator_loc.nil?
- # In Ripper a method call like "puts myvar" with no parentheses is a "command".
- bounds(node.message_loc)
- ident_val = on_ident(node.message)
-
- # Unless it has a block, and then it's an fcall (e.g. "foo { bar }")
- if node.block
- block_val = visit(node.block)
- # In these calls, even if node.arguments is nil, we still get an :args_new call.
- args = if node.arguments.nil?
- on_args_new
- else
- on_args_add_block(visit_arguments(node.arguments.arguments))
- end
- method_args_val = on_method_add_arg(on_fcall(ident_val), args)
- return on_method_add_block(method_args_val, block_val)
- else
- if node.arguments.nil?
- return on_command(ident_val, nil)
- else
- args = on_args_add_block(visit_arguments(node.arguments.arguments), false)
- return on_command(ident_val, args)
- end
- end
- else
- operator = node.call_operator_loc.slice
- if operator == "." || operator == "&."
- left_val = visit(node.receiver)
-
- bounds(node.call_operator_loc)
- operator_val = operator == "." ? on_period(node.call_operator) : on_op(node.call_operator)
-
- bounds(node.message_loc)
- right_val = on_ident(node.message)
-
- call_val = on_call(left_val, operator_val, right_val)
-
- if node.block
- block_val = visit(node.block)
- return on_method_add_block(call_val, block_val)
- else
- return call_val
- end
- else
- raise NoMethodError, __method__, "operator other than . or &. for call: #{operator.inspect}"
- end
- end
- 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 0deb486999..37e6e764e4 100644
--- a/test/prism/ripper_test.rb
+++ b/test/prism/ripper_test.rb
@@ -12,7 +12,6 @@ module Prism
skips = %w[
arrays.txt
- begin_ensure.txt
begin_rescue.txt
blocks.txt
case.txt
@@ -48,7 +47,6 @@ module Prism
rescue.txt
return.txt
seattlerb/TestRubyParserShared.txt
- seattlerb/and_multi.txt
seattlerb/array_lits_trailing_calls.txt
seattlerb/attr_asgn_colon_id.txt
seattlerb/attrasgn_primary_dot_constant.txt
@@ -56,9 +54,6 @@ module Prism
seattlerb/begin_rescue_else_ensure_no_bodies.txt
seattlerb/block_break.txt
seattlerb/block_call_dot_op2_brace_block.txt
- seattlerb/block_call_dot_op2_cmd_args_do_block.txt
- seattlerb/block_call_operation_colon.txt
- seattlerb/block_call_operation_dot.txt
seattlerb/block_call_paren_call_block_call.txt
seattlerb/block_command_operation_colon.txt
seattlerb/block_command_operation_dot.txt
@@ -79,19 +74,16 @@ module Prism
seattlerb/bug_comma.txt
seattlerb/bug_hash_args_trailing_comma.txt
seattlerb/bug_hash_interp_array.txt
- seattlerb/bug_not_parens.txt
seattlerb/call_args_assoc_quoted.txt
seattlerb/call_args_assoc_trailing_comma.txt
seattlerb/call_args_command.txt
seattlerb/call_array_lambda_block_call.txt
seattlerb/call_assoc_new_if_multiline.txt
seattlerb/call_assoc_trailing_comma.txt
- seattlerb/call_bang_command_call.txt
seattlerb/call_block_arg_named.txt
seattlerb/call_colon2.txt
seattlerb/call_colon_parens.txt
seattlerb/call_dot_parens.txt
- seattlerb/call_not.txt
seattlerb/call_stabby_do_end_with_block.txt
seattlerb/call_stabby_with_braces_block.txt
seattlerb/call_trailing_comma.txt
@@ -114,7 +106,6 @@ module Prism
seattlerb/defs_oneliner.txt
seattlerb/defs_oneliner_eq2.txt
seattlerb/defs_oneliner_rescue.txt
- seattlerb/difficult1_line_numbers.txt
seattlerb/difficult2_.txt
seattlerb/difficult3_.txt
seattlerb/difficult3_4.txt
@@ -151,7 +142,6 @@ module Prism
seattlerb/interpolated_symbol_array_line_breaks.txt
seattlerb/interpolated_word_array_line_breaks.txt
seattlerb/lambda_do_vs_brace.txt
- seattlerb/lasgn_command.txt
seattlerb/lasgn_middle_splat.txt
seattlerb/magic_encoding_comment.txt
seattlerb/masgn_anon_splat_arg.txt
@@ -159,7 +149,6 @@ module Prism
seattlerb/masgn_arg_splat_arg.txt
seattlerb/masgn_colon2.txt
seattlerb/masgn_colon3.txt
- seattlerb/masgn_command_call.txt
seattlerb/masgn_double_paren.txt
seattlerb/masgn_lhs_splat.txt
seattlerb/masgn_paren.txt
@@ -174,13 +163,11 @@ module Prism
seattlerb/mlhs_back_splat.txt
seattlerb/mlhs_front_anonsplat.txt
seattlerb/mlhs_front_splat.txt
- seattlerb/mlhs_keyword.txt
seattlerb/mlhs_mid_anonsplat.txt
seattlerb/mlhs_mid_splat.txt
seattlerb/module_comments.txt
seattlerb/non_interpolated_symbol_array_line_breaks.txt
seattlerb/non_interpolated_word_array_line_breaks.txt
- seattlerb/op_asgn_command_call.txt
seattlerb/op_asgn_primary_colon_identifier1.txt
seattlerb/op_asgn_primary_colon_identifier_command_call.txt
seattlerb/parse_if_not_canonical.txt
@@ -190,7 +177,6 @@ module Prism
seattlerb/parse_line_dstr_soft_newline.txt
seattlerb/parse_line_evstr_after_break.txt
seattlerb/parse_line_heredoc_hardnewline.txt
- seattlerb/parse_line_iter_call_no_parens.txt
seattlerb/parse_line_multiline_str_literal_n.txt
seattlerb/parse_line_return.txt
seattlerb/parse_line_str_with_newline_escape.txt
@@ -200,10 +186,6 @@ module Prism
seattlerb/parse_pattern_058.txt
seattlerb/parse_pattern_058_2.txt
seattlerb/parse_pattern_076.txt
- seattlerb/parse_until_not_canonical.txt
- seattlerb/parse_until_not_noncanonical.txt
- seattlerb/parse_while_not_canonical.txt
- seattlerb/parse_while_not_noncanonical.txt
seattlerb/pctW_lineno.txt
seattlerb/pct_nl.txt
seattlerb/pct_w_heredoc_interp_nested.txt
@@ -230,8 +212,6 @@ module Prism
seattlerb/safe_attrasgn.txt
seattlerb/safe_attrasgn_constant.txt
seattlerb/safe_call_dot_parens.txt
- seattlerb/safe_call_operator.txt
- seattlerb/safe_calls.txt
seattlerb/slashy_newlines_within_string.txt
seattlerb/stabby_arg_no_paren.txt
seattlerb/stabby_block_iter_call.txt
@@ -288,7 +268,6 @@ module Prism
unparser/corpus/semantic/dstr.txt
unparser/corpus/semantic/kwbegin.txt
unparser/corpus/semantic/literal.txt
- unparser/corpus/semantic/send.txt
unparser/corpus/semantic/while.txt
until.txt
variables.txt
@@ -316,12 +295,9 @@ module Prism
whitequark/asgn_mrhs.txt
whitequark/break_block.txt
whitequark/bug_435.txt
- whitequark/bug_447.txt
whitequark/bug_452.txt
- whitequark/bug_466.txt
whitequark/bug_480.txt
whitequark/bug_ascii_8bit_in_literal.txt
- whitequark/bug_cmd_string_lookahead.txt
whitequark/bug_cmdarg.txt
whitequark/bug_do_block_in_cmdarg.txt
whitequark/bug_do_block_in_hash_brace.txt
@@ -368,16 +344,11 @@ module Prism
whitequark/method_definition_in_while_cond.txt
whitequark/newline_in_hash_argument.txt
whitequark/next_block.txt
- whitequark/not.txt
- whitequark/not_cmd.txt
whitequark/numbered_args_after_27.txt
whitequark/numparam_outside_block.txt
whitequark/op_asgn.txt
whitequark/op_asgn_cmd.txt
- whitequark/parser_bug_272.txt
whitequark/parser_bug_507.txt
- whitequark/parser_bug_525.txt
- whitequark/parser_bug_604.txt
whitequark/parser_bug_640.txt
whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt
whitequark/parser_slash_slash_n_escaping_in_literals.txt
@@ -394,7 +365,6 @@ module Prism
whitequark/ruby_bug_11380.txt
whitequark/ruby_bug_11873.txt
whitequark/ruby_bug_11873_a.txt
- whitequark/ruby_bug_11873_b.txt
whitequark/ruby_bug_11989.txt
whitequark/ruby_bug_11990.txt
whitequark/ruby_bug_12073.txt