From 871ed4b462cdfc317409288896346f798367f55c Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Sat, 11 Jan 2025 15:38:41 -0500 Subject: [PATCH] Fix `not` receiver `not foo` should be `!foo` `not()` should be `!nil` Fixes [Bug #21027] --- lib/prism/translation/ripper.rb | 16 +++++++++++++--- src/prism.c | 5 +++-- test/prism/snapshots/whitequark/not.txt | 11 ++++++++--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/prism/translation/ripper.rb b/lib/prism/translation/ripper.rb index 018842715b..dce96e01ab 100644 --- a/lib/prism/translation/ripper.rb +++ b/lib/prism/translation/ripper.rb @@ -1045,10 +1045,20 @@ def visit_call_node(node) bounds(node.location) on_unary(node.name, receiver) when :! - receiver = visit(node.receiver) + if node.message == "not" + receiver = + if !node.receiver.is_a?(ParenthesesNode) || !node.receiver.body.nil? + visit(node.receiver) + end - bounds(node.location) - on_unary(node.message == "not" ? :not : :!, receiver) + bounds(node.location) + on_unary(:not, receiver) + else + receiver = visit(node.receiver) + + bounds(node.location) + on_unary(:!, receiver) + end when *BINARY_OPERATORS receiver = visit(node.receiver) value = visit(node.arguments.arguments.first) diff --git a/src/prism.c b/src/prism.c index 1a9404445a..daaddd196d 100644 --- a/src/prism.c +++ b/src/prism.c @@ -19712,11 +19712,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b accept1(parser, PM_TOKEN_NEWLINE); if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) { - arguments.opening_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous); + pm_token_t lparen = parser->previous; if (accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { - arguments.closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous); + receiver = (pm_node_t *) pm_parentheses_node_create(parser, &lparen, NULL, &parser->previous); } else { + arguments.opening_loc = PM_LOCATION_TOKEN_VALUE(&lparen); receiver = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_NOT_EXPRESSION, (uint16_t) (depth + 1)); if (!parser->recovering) { diff --git a/test/prism/snapshots/whitequark/not.txt b/test/prism/snapshots/whitequark/not.txt index b70792f154..08037eae9a 100644 --- a/test/prism/snapshots/whitequark/not.txt +++ b/test/prism/snapshots/whitequark/not.txt @@ -27,13 +27,18 @@ │ └── block: ∅ ├── @ CallNode (location: (3,0)-(3,5)) │ ├── flags: newline - │ ├── receiver: ∅ + │ ├── receiver: + │ │ @ ParenthesesNode (location: (3,3)-(3,5)) + │ │ ├── flags: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (3,3)-(3,4) = "(" + │ │ └── closing_loc: (3,4)-(3,5) = ")" │ ├── call_operator_loc: ∅ │ ├── name: :! │ ├── message_loc: (3,0)-(3,3) = "not" - │ ├── opening_loc: (3,3)-(3,4) = "(" + │ ├── opening_loc: ∅ │ ├── arguments: ∅ - │ ├── closing_loc: (3,4)-(3,5) = ")" + │ ├── closing_loc: ∅ │ └── block: ∅ └── @ CallNode (location: (5,0)-(5,8)) ├── flags: newline