diff options
| author | Kevin Newton <kddnewton@gmail.com> | 2024-03-05 17:37:10 -0500 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2024-03-06 16:42:46 +0000 |
| commit | c2d6bcc81a827786c2cffefbac0840cc1c9b42d5 (patch) | |
| tree | 129929ace72271143d52bd1b5f7d90ea733f17d7 | |
| parent | a0674a5755f0429ce435432ae2bad7bf696b7314 (diff) | |
[ruby/prism] Revisit call nodes for ripper translation
https://github.com/ruby/prism/commit/372200f970
| -rw-r--r-- | lib/prism/translation/ripper.rb | 211 | ||||
| -rw-r--r-- | test/prism/ripper_test.rb | 30 |
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 |
