Skip to content

Commit

Permalink
[ruby/prism] Fix some corner cases
Browse files Browse the repository at this point in the history
  • Loading branch information
makenowjust authored and matzbot committed Dec 5, 2023
1 parent dcd75fd commit 3d4a4b2
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 31 deletions.
10 changes: 5 additions & 5 deletions prism/prism.c
Expand Up @@ -15058,7 +15058,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
}
}
} else {
receiver = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_NOT_EXPRESSION, true);
receiver = parse_expression(parser, PM_BINDING_POWER_NOT, PM_ERR_NOT_EXPRESSION, true);
pm_conditional_predicate(receiver);
}

Expand Down Expand Up @@ -15707,7 +15707,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
parser_lex(parser);

pm_token_t operator = parser->previous;
pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, PM_ERR_UNARY_RECEIVER_BANG, binding_power < PM_BINDING_POWER_COMPOSITION);
pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, PM_ERR_UNARY_RECEIVER_BANG, binding_power < PM_BINDING_POWER_MATCH);
pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "!");

pm_conditional_predicate(receiver);
Expand Down Expand Up @@ -15870,7 +15870,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b

static inline pm_node_t *
parse_assignment_value(pm_parser_t *parser, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, pm_diagnostic_id_t diag_id, bool accepts_command_call) {
pm_node_t *value = parse_value_expression(parser, binding_power, diag_id, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_COMPOSITION);
pm_node_t *value = parse_value_expression(parser, binding_power, diag_id, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_MATCH);

// Contradicting binding powers, the right-hand-side value of rthe assignment allows the `rescue` modifier.
if (match1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
Expand All @@ -15887,7 +15887,7 @@ parse_assignment_value(pm_parser_t *parser, pm_binding_power_t previous_binding_

static inline pm_node_t *
parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, pm_diagnostic_id_t diag_id, bool accepts_command_call) {
pm_node_t *value = parse_starred_expression(parser, binding_power, diag_id, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_COMPOSITION);
pm_node_t *value = parse_starred_expression(parser, binding_power, diag_id, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_MATCH);

bool is_single_value = true;
if (previous_binding_power == PM_BINDING_POWER_STATEMENT && (PM_NODE_TYPE_P(value, PM_SPLAT_NODE) || match1(parser, PM_TOKEN_COMMA))) {
Expand Down Expand Up @@ -16898,12 +16898,12 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, pm_diagn
!(
cast->call_operator_loc.start != NULL &&
cast->arguments == NULL &&
cast->block == NULL &&
cast->opening_loc.start == NULL
) &&
// (3) foo.bar(1)
!(
cast->call_operator_loc.start != NULL &&
cast->arguments != NULL &&
cast->opening_loc.start != NULL
) &&
// (4) foo.bar do end
Expand Down
1 change: 1 addition & 0 deletions test/prism/errors_test.rb
Expand Up @@ -1915,6 +1915,7 @@ def test_command_calls
a, b = c = d f
a ? b c : d e
defined? a b
! ! a b
def f a = b c; end
def f(a = b c); end
->a=b c{}
Expand Down
8 changes: 8 additions & 0 deletions test/prism/fixtures/command_method_call.txt
Expand Up @@ -29,3 +29,11 @@ def foo = bar 1
1.foo[2].bar 3

1.foo(2).bar 3

1.foo(&2).bar 3

!foo 1 and !bar 2

!foo 1 or !bar 2

not !foo 1
227 changes: 201 additions & 26 deletions test/prism/snapshots/command_method_call.txt
@@ -1,8 +1,8 @@
@ ProgramNode (location: (1,0)-(31,14))
@ ProgramNode (location: (1,0)-(39,10))
├── locals: [:foo, :bar]
└── statements:
@ StatementsNode (location: (1,0)-(31,14))
└── body: (length: 16)
@ StatementsNode (location: (1,0)-(39,10))
└── body: (length: 20)
├── @ CallNode (location: (1,0)-(1,5))
│ ├── receiver: ∅
│ ├── call_operator_loc: ∅
Expand Down Expand Up @@ -474,35 +474,210 @@
│ ├── closing_loc: ∅
│ ├── block: ∅
│ └── flags: ∅
└── @ CallNode (location: (31,0)-(31,14))
├── @ CallNode (location: (31,0)-(31,14))
│ ├── receiver:
│ │ @ CallNode (location: (31,0)-(31,8))
│ │ ├── receiver:
│ │ │ @ IntegerNode (location: (31,0)-(31,1))
│ │ │ └── flags: decimal
│ │ ├── call_operator_loc: (31,1)-(31,2) = "."
│ │ ├── name: :foo
│ │ ├── message_loc: (31,2)-(31,5) = "foo"
│ │ ├── opening_loc: (31,5)-(31,6) = "("
│ │ ├── arguments:
│ │ │ @ ArgumentsNode (location: (31,6)-(31,7))
│ │ │ ├── arguments: (length: 1)
│ │ │ │ └── @ IntegerNode (location: (31,6)-(31,7))
│ │ │ │ └── flags: decimal
│ │ │ └── flags: ∅
│ │ ├── closing_loc: (31,7)-(31,8) = ")"
│ │ ├── block: ∅
│ │ └── flags: ∅
│ ├── call_operator_loc: (31,8)-(31,9) = "."
│ ├── name: :bar
│ ├── message_loc: (31,9)-(31,12) = "bar"
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (31,13)-(31,14))
│ │ ├── arguments: (length: 1)
│ │ │ └── @ IntegerNode (location: (31,13)-(31,14))
│ │ │ └── flags: decimal
│ │ └── flags: ∅
│ ├── closing_loc: ∅
│ ├── block: ∅
│ └── flags: ∅
├── @ CallNode (location: (33,0)-(33,15))
│ ├── receiver:
│ │ @ CallNode (location: (33,0)-(33,9))
│ │ ├── receiver:
│ │ │ @ IntegerNode (location: (33,0)-(33,1))
│ │ │ └── flags: decimal
│ │ ├── call_operator_loc: (33,1)-(33,2) = "."
│ │ ├── name: :foo
│ │ ├── message_loc: (33,2)-(33,5) = "foo"
│ │ ├── opening_loc: (33,5)-(33,6) = "("
│ │ ├── arguments: ∅
│ │ ├── closing_loc: (33,8)-(33,9) = ")"
│ │ ├── block:
│ │ │ @ BlockArgumentNode (location: (33,6)-(33,8))
│ │ │ ├── expression:
│ │ │ │ @ IntegerNode (location: (33,7)-(33,8))
│ │ │ │ └── flags: decimal
│ │ │ └── operator_loc: (33,6)-(33,7) = "&"
│ │ └── flags: ∅
│ ├── call_operator_loc: (33,9)-(33,10) = "."
│ ├── name: :bar
│ ├── message_loc: (33,10)-(33,13) = "bar"
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (33,14)-(33,15))
│ │ ├── arguments: (length: 1)
│ │ │ └── @ IntegerNode (location: (33,14)-(33,15))
│ │ │ └── flags: decimal
│ │ └── flags: ∅
│ ├── closing_loc: ∅
│ ├── block: ∅
│ └── flags: ∅
├── @ AndNode (location: (35,0)-(35,17))
│ ├── left:
│ │ @ CallNode (location: (35,0)-(35,6))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (35,1)-(35,6))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── name: :foo
│ │ │ ├── message_loc: (35,1)-(35,4) = "foo"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments:
│ │ │ │ @ ArgumentsNode (location: (35,5)-(35,6))
│ │ │ │ ├── arguments: (length: 1)
│ │ │ │ │ └── @ IntegerNode (location: (35,5)-(35,6))
│ │ │ │ │ └── flags: decimal
│ │ │ │ └── flags: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ └── flags: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── name: :!
│ │ ├── message_loc: (35,0)-(35,1) = "!"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ └── flags: ∅
│ ├── right:
│ │ @ CallNode (location: (35,11)-(35,17))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (35,12)-(35,17))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── name: :bar
│ │ │ ├── message_loc: (35,12)-(35,15) = "bar"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments:
│ │ │ │ @ ArgumentsNode (location: (35,16)-(35,17))
│ │ │ │ ├── arguments: (length: 1)
│ │ │ │ │ └── @ IntegerNode (location: (35,16)-(35,17))
│ │ │ │ │ └── flags: decimal
│ │ │ │ └── flags: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ └── flags: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── name: :!
│ │ ├── message_loc: (35,11)-(35,12) = "!"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ └── flags: ∅
│ └── operator_loc: (35,7)-(35,10) = "and"
├── @ OrNode (location: (37,0)-(37,16))
│ ├── left:
│ │ @ CallNode (location: (37,0)-(37,6))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (37,1)-(37,6))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── name: :foo
│ │ │ ├── message_loc: (37,1)-(37,4) = "foo"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments:
│ │ │ │ @ ArgumentsNode (location: (37,5)-(37,6))
│ │ │ │ ├── arguments: (length: 1)
│ │ │ │ │ └── @ IntegerNode (location: (37,5)-(37,6))
│ │ │ │ │ └── flags: decimal
│ │ │ │ └── flags: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ └── flags: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── name: :!
│ │ ├── message_loc: (37,0)-(37,1) = "!"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ └── flags: ∅
│ ├── right:
│ │ @ CallNode (location: (37,10)-(37,16))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (37,11)-(37,16))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── name: :bar
│ │ │ ├── message_loc: (37,11)-(37,14) = "bar"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments:
│ │ │ │ @ ArgumentsNode (location: (37,15)-(37,16))
│ │ │ │ ├── arguments: (length: 1)
│ │ │ │ │ └── @ IntegerNode (location: (37,15)-(37,16))
│ │ │ │ │ └── flags: decimal
│ │ │ │ └── flags: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ └── flags: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── name: :!
│ │ ├── message_loc: (37,10)-(37,11) = "!"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ └── flags: ∅
│ └── operator_loc: (37,7)-(37,9) = "or"
└── @ CallNode (location: (39,0)-(39,10))
├── receiver:
│ @ CallNode (location: (31,0)-(31,8))
│ @ CallNode (location: (39,4)-(39,10))
│ ├── receiver:
│ │ @ IntegerNode (location: (31,0)-(31,1))
│ │ └── flags: decimal
│ ├── call_operator_loc: (31,1)-(31,2) = "."
│ ├── name: :foo
│ ├── message_loc: (31,2)-(31,5) = "foo"
│ ├── opening_loc: (31,5)-(31,6) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (31,6)-(31,7))
│ │ ├── arguments: (length: 1)
│ │ │ └── @ IntegerNode (location: (31,6)-(31,7))
│ │ │ └── flags: decimal
│ │ @ CallNode (location: (39,5)-(39,10))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── name: :foo
│ │ ├── message_loc: (39,5)-(39,8) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments:
│ │ │ @ ArgumentsNode (location: (39,9)-(39,10))
│ │ │ ├── arguments: (length: 1)
│ │ │ │ └── @ IntegerNode (location: (39,9)-(39,10))
│ │ │ │ └── flags: decimal
│ │ │ └── flags: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ └── flags: ∅
│ ├── closing_loc: (31,7)-(31,8) = ")"
│ ├── call_operator_loc: ∅
│ ├── name: :!
│ ├── message_loc: (39,4)-(39,5) = "!"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── block: ∅
│ └── flags: ∅
├── call_operator_loc: (31,8)-(31,9) = "."
├── name: :bar
├── message_loc: (31,9)-(31,12) = "bar"
├── call_operator_loc:
├── name: :!
├── message_loc: (39,0)-(39,3) = "not"
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (31,13)-(31,14))
│ ├── arguments: (length: 1)
│ │ └── @ IntegerNode (location: (31,13)-(31,14))
│ │ └── flags: decimal
│ └── flags: ∅
├── arguments: ∅
├── closing_loc: ∅
├── block: ∅
└── flags: ∅

0 comments on commit 3d4a4b2

Please sign in to comment.