From 9ea09330f1c5750d7b31d0389b00908446e60bbd Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Tue, 26 May 2026 11:54:56 +0200 Subject: [PATCH] Don't replicate unary method bug in parser translator Closes https://github.com/ruby/prism/issues/4112 Also see https://github.com/ruby/prism/issues/2501, for which this was done. The expectation in rubocop is incorrect (produces code with semantic difference), so the test should be updated instead. In any way, it should also have applied to `+`, where the same happens --- lib/prism/translation/parser/compiler.rb | 21 ----------- snapshots/unary_method_calls.txt | 44 ++++++++++++++++++---- test/prism/fixtures/unary_method_calls.txt | 6 +++ 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb index d4e94ae5e0..aaccee64c1 100644 --- a/lib/prism/translation/parser/compiler.rb +++ b/lib/prism/translation/parser/compiler.rb @@ -297,11 +297,6 @@ def visit_call_node(node) if node.call_operator_loc.nil? case name - when :-@ - case (receiver = node.receiver).type - when :integer_node, :float_node, :rational_node, :imaginary_node - return visit(numeric_negate(node.message_loc, receiver)) - end when :! return visit_block(builder.not_op(token(node.message_loc), token(node.opening_loc), visit(node.receiver), token(node.closing_loc)), block) when :=~ @@ -1973,22 +1968,6 @@ def multi_target_elements(node) elements end - # Negate the value of a numeric node. This is a special case where you - # have a negative sign on one line and then a number on the next line. - # In normal Ruby, this will always be a method call. The parser gem, - # however, marks this as a numeric literal. We have to massage the tree - # here to get it into the correct form. - def numeric_negate(message_loc, receiver) - case receiver.type - when :integer_node, :float_node - receiver.copy(value: -receiver.value, location: message_loc.join(receiver.location)) - when :rational_node - receiver.copy(numerator: -receiver.numerator, location: message_loc.join(receiver.location)) - when :imaginary_node - receiver.copy(numeric: numeric_negate(message_loc, receiver.numeric), location: message_loc.join(receiver.location)) - end - end - # Blocks can have a special set of parameters that automatically expand # when given arrays if they have a single required parameter and no # other parameters. diff --git a/snapshots/unary_method_calls.txt b/snapshots/unary_method_calls.txt index 4f793866c5..451da443fe 100644 --- a/snapshots/unary_method_calls.txt +++ b/snapshots/unary_method_calls.txt @@ -1,10 +1,10 @@ -@ ProgramNode (location: (1,0)-(2,5)) +@ ProgramNode (location: (1,0)-(8,2)) ├── flags: ∅ ├── locals: [] └── statements: - @ StatementsNode (location: (1,0)-(2,5)) + @ StatementsNode (location: (1,0)-(8,2)) ├── flags: ∅ - └── body: (length: 2) + └── body: (length: 4) ├── @ CallNode (location: (1,0)-(1,5)) │ ├── flags: newline │ ├── receiver: @@ -19,15 +19,43 @@ │ ├── closing_loc: ∅ │ ├── equal_loc: ∅ │ └── block: ∅ - └── @ CallNode (location: (2,0)-(2,5)) + ├── @ CallNode (location: (2,0)-(2,5)) + │ ├── flags: newline + │ ├── receiver: + │ │ @ IntegerNode (location: (2,0)-(2,2)) + │ │ ├── flags: static_literal, decimal + │ │ └── value: 42 + │ ├── call_operator_loc: (2,2)-(2,3) = "." + │ ├── name: :! + │ ├── message_loc: (2,3)-(2,5) = "!@" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── equal_loc: ∅ + │ └── block: ∅ + ├── @ CallNode (location: (4,0)-(5,2)) + │ ├── flags: newline + │ ├── receiver: + │ │ @ IntegerNode (location: (5,0)-(5,2)) + │ │ ├── flags: static_literal, decimal + │ │ └── value: 42 + │ ├── call_operator_loc: ∅ + │ ├── name: :-@ + │ ├── message_loc: (4,0)-(4,1) = "-" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── equal_loc: ∅ + │ └── block: ∅ + └── @ CallNode (location: (7,0)-(8,2)) ├── flags: newline ├── receiver: - │ @ IntegerNode (location: (2,0)-(2,2)) + │ @ IntegerNode (location: (8,0)-(8,2)) │ ├── flags: static_literal, decimal │ └── value: 42 - ├── call_operator_loc: (2,2)-(2,3) = "." - ├── name: :! - ├── message_loc: (2,3)-(2,5) = "!@" + ├── call_operator_loc: ∅ + ├── name: :+@ + ├── message_loc: (7,0)-(7,1) = "+" ├── opening_loc: ∅ ├── arguments: ∅ ├── closing_loc: ∅ diff --git a/test/prism/fixtures/unary_method_calls.txt b/test/prism/fixtures/unary_method_calls.txt index dda85e4bdb..a8327d23cc 100644 --- a/test/prism/fixtures/unary_method_calls.txt +++ b/test/prism/fixtures/unary_method_calls.txt @@ -1,2 +1,8 @@ 42.~@ 42.!@ + +- +42 + ++ +42