From a0217025969097709928657acab58321bf0adedf Mon Sep 17 00:00:00 2001 From: Haldun Bayhantopcu Date: Thu, 15 Feb 2024 16:30:58 +0100 Subject: [PATCH] [ruby/prism] Fix parsing rescue modifier https://github.com/ruby/prism/commit/b7407ae3c0 --- prism/prism.c | 13 ++- test/prism/fixtures/rescue.txt | 2 + test/prism/snapshots/rescue.txt | 140 ++++++++++++++++++++++---------- 3 files changed, 112 insertions(+), 43 deletions(-) diff --git a/prism/prism.c b/prism/prism.c index e517a0cc21..d87391d637 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -16769,7 +16769,18 @@ parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding if (is_single_value && match1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) { pm_token_t rescue = parser->current; parser_lex(parser); - pm_node_t *right = parse_expression(parser, binding_power, false, PM_ERR_RESCUE_MODIFIER_VALUE); + + bool accepts_command_call_inner = false; + + // RHS can accept command call iff the value is a call with arguments but without paranthesis. + if (PM_NODE_TYPE_P(value, PM_CALL_NODE)) { + pm_call_node_t *call_node = (pm_call_node_t *)value; + if ((call_node->arguments != NULL) && (call_node->opening_loc.start == NULL)) { + accepts_command_call_inner = true; + } + } + + pm_node_t *right = parse_expression(parser, binding_power, accepts_command_call_inner, PM_ERR_RESCUE_MODIFIER_VALUE); return (pm_node_t *) pm_rescue_modifier_node_create(parser, value, &rescue, right); } diff --git a/test/prism/fixtures/rescue.txt b/test/prism/fixtures/rescue.txt index 90530b7021..7cce866379 100644 --- a/test/prism/fixtures/rescue.txt +++ b/test/prism/fixtures/rescue.txt @@ -31,3 +31,5 @@ rescue end foo if bar rescue baz + +z = x y rescue c d diff --git a/test/prism/snapshots/rescue.txt b/test/prism/snapshots/rescue.txt index e75fe481a0..fab9a8f70d 100644 --- a/test/prism/snapshots/rescue.txt +++ b/test/prism/snapshots/rescue.txt @@ -1,8 +1,8 @@ -@ ProgramNode (location: (1,0)-(33,21)) -├── locals: [:a] +@ ProgramNode (location: (1,0)-(35,18)) +├── locals: [:a, :z] └── statements: - @ StatementsNode (location: (1,0)-(33,21)) - └── body: (length: 13) + @ StatementsNode (location: (1,0)-(35,18)) + └── body: (length: 14) ├── @ RescueModifierNode (location: (1,0)-(1,14)) │ ├── expression: │ │ @ CallNode (location: (1,0)-(1,3)) @@ -386,46 +386,102 @@ │ ├── rparen_loc: ∅ │ ├── equal_loc: ∅ │ └── end_keyword_loc: (31,0)-(31,3) = "end" - └── @ RescueModifierNode (location: (33,0)-(33,21)) - ├── expression: - │ @ IfNode (location: (33,0)-(33,10)) - │ ├── if_keyword_loc: (33,4)-(33,6) = "if" - │ ├── predicate: - │ │ @ CallNode (location: (33,7)-(33,10)) - │ │ ├── flags: variable_call, ignore_visibility + ├── @ RescueModifierNode (location: (33,0)-(33,21)) + │ ├── expression: + │ │ @ IfNode (location: (33,0)-(33,10)) + │ │ ├── if_keyword_loc: (33,4)-(33,6) = "if" + │ │ ├── predicate: + │ │ │ @ CallNode (location: (33,7)-(33,10)) + │ │ │ ├── flags: variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :bar + │ │ │ ├── message_loc: (33,7)-(33,10) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ └── block: ∅ + │ │ ├── then_keyword_loc: ∅ + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (33,0)-(33,3)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (33,0)-(33,3)) + │ │ │ ├── flags: variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :foo + │ │ │ ├── message_loc: (33,0)-(33,3) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ └── block: ∅ + │ │ ├── consequent: ∅ + │ │ └── end_keyword_loc: ∅ + │ ├── keyword_loc: (33,11)-(33,17) = "rescue" + │ └── rescue_expression: + │ @ CallNode (location: (33,18)-(33,21)) + │ ├── flags: variable_call, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :baz + │ ├── message_loc: (33,18)-(33,21) = "baz" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: ∅ + └── @ LocalVariableWriteNode (location: (35,0)-(35,18)) + ├── name: :z + ├── depth: 0 + ├── name_loc: (35,0)-(35,1) = "z" + ├── value: + │ @ RescueModifierNode (location: (35,4)-(35,18)) + │ ├── expression: + │ │ @ CallNode (location: (35,4)-(35,7)) + │ │ ├── flags: ignore_visibility │ │ ├── receiver: ∅ │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :bar - │ │ ├── message_loc: (33,7)-(33,10) = "bar" + │ │ ├── name: :x + │ │ ├── message_loc: (35,4)-(35,5) = "x" │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (35,6)-(35,7)) + │ │ │ ├── flags: ∅ + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (35,6)-(35,7)) + │ │ │ ├── flags: variable_call, ignore_visibility + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── name: :y + │ │ │ ├── message_loc: (35,6)-(35,7) = "y" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ └── block: ∅ │ │ ├── closing_loc: ∅ │ │ └── block: ∅ - │ ├── then_keyword_loc: ∅ - │ ├── statements: - │ │ @ StatementsNode (location: (33,0)-(33,3)) - │ │ └── body: (length: 1) - │ │ └── @ CallNode (location: (33,0)-(33,3)) - │ │ ├── flags: variable_call, ignore_visibility - │ │ ├── receiver: ∅ - │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :foo - │ │ ├── message_loc: (33,0)-(33,3) = "foo" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── consequent: ∅ - │ └── end_keyword_loc: ∅ - ├── keyword_loc: (33,11)-(33,17) = "rescue" - └── rescue_expression: - @ CallNode (location: (33,18)-(33,21)) - ├── flags: variable_call, ignore_visibility - ├── receiver: ∅ - ├── call_operator_loc: ∅ - ├── name: :baz - ├── message_loc: (33,18)-(33,21) = "baz" - ├── opening_loc: ∅ - ├── arguments: ∅ - ├── closing_loc: ∅ - └── block: ∅ + │ ├── keyword_loc: (35,8)-(35,14) = "rescue" + │ └── rescue_expression: + │ @ CallNode (location: (35,15)-(35,18)) + │ ├── flags: ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :c + │ ├── message_loc: (35,15)-(35,16) = "c" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (35,17)-(35,18)) + │ │ ├── flags: ∅ + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (35,17)-(35,18)) + │ │ ├── flags: variable_call, ignore_visibility + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── name: :d + │ │ ├── message_loc: (35,17)-(35,18) = "d" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ └── block: ∅ + │ ├── closing_loc: ∅ + │ └── block: ∅ + └── operator_loc: (35,2)-(35,3) = "="