Skip to content

Commit 2eab962

Browse files
st0012matzbot
authored andcommitted
[ruby/prism] Allow command calls in endless method bodies within assignments
Previously, endless method definitions in assignment contexts like `x = def f = p 1` would fail to parse because command calls (method calls without parentheses) were only accepted when the surrounding binding power was less than `PM_BINDING_POWER_COMPOSITION`. This fix specifically checks for assignment context and allows command calls in those cases while maintaining the existing behavior for other contexts. This ensures that: - `x = def f = p 1` parses correctly (previously failed) - `private def f = puts "Hello"` still produces the expected error ruby/prism@722af59ba3
1 parent 0260799 commit 2eab962

File tree

3 files changed

+14
-1
lines changed

3 files changed

+14
-1
lines changed

prism/prism.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19524,7 +19524,15 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1952419524
pm_do_loop_stack_push(parser, false);
1952519525
statements = (pm_node_t *) pm_statements_node_create(parser);
1952619526

19527-
pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_DEFINED + 1, binding_power < PM_BINDING_POWER_COMPOSITION, false, PM_ERR_DEF_ENDLESS, (uint16_t) (depth + 1));
19527+
// In endless method bodies, we need to handle command calls carefully.
19528+
// We want to allow command calls in assignment context but maintain
19529+
// the same binding power to avoid changing how operators are parsed.
19530+
// Note that we're intentionally NOT allowing code like `private def foo = puts "Hello"`
19531+
// because the original parser, parse.y, can't handle it and we want to maintain the same behavior
19532+
bool allow_command_call = (binding_power == PM_BINDING_POWER_ASSIGNMENT) ||
19533+
(binding_power < PM_BINDING_POWER_COMPOSITION);
19534+
19535+
pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_DEFINED + 1, allow_command_call, false, PM_ERR_DEF_ENDLESS, (uint16_t) (depth + 1));
1952819536

1952919537
if (accept1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
1953019538
context_push(parser, PM_CONTEXT_RESCUE_MODIFIER);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
private def foo = puts "Hello"
2+
^ unexpected string literal, expecting end-of-input
3+

test/prism/fixtures/endless_methods.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ def foo = 1
33
def bar = A ""
44

55
def method = 1 + 2 + 3
6+
7+
x = def f = p 1

0 commit comments

Comments
 (0)