Skip to content

Commit 0a3b048

Browse files
authored
Merge pull request #3970 from ruby/command-call-in
2 parents 7d17fd2 + 35470bb commit 0a3b048

8 files changed

Lines changed: 40 additions & 5 deletions

File tree

src/prism.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21621,7 +21621,7 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
2162121621
return node;
2162221622
}
2162321623
break;
21624-
case PM_CALL_NODE:
21624+
case PM_CALL_NODE: {
2162521625
// A do-block can attach to a command-style call
2162621626
// produced by infix operators (e.g., dot-calls like
2162721627
// `obj.method args do end`).
@@ -21635,7 +21635,22 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
2163521635
if (PM_NODE_FLAG_P(node, PM_CALL_NODE_FLAGS_IMPLICIT_ARRAY) && pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER) {
2163621636
return node;
2163721637
}
21638+
21639+
// Command-style calls (calls with arguments but without
21640+
// parentheses) only accept composition (and/or) and modifier
21641+
// (if/unless/etc.) operators. We need to exclude operator calls
21642+
// (e.g., a + b) which also satisfy pm_call_node_command_p but
21643+
// are not commands.
21644+
const pm_call_node_t *cast = (const pm_call_node_t *) node;
21645+
if (
21646+
(pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_COMPOSITION) &&
21647+
(cast->receiver == NULL || cast->call_operator_loc.length > 0) &&
21648+
pm_call_node_command_p(cast)
21649+
) {
21650+
return node;
21651+
}
2163821652
break;
21653+
}
2163921654
case PM_RESCUE_MODIFIER_NODE:
2164021655
// A rescue modifier whose handler is a one-liner pattern match
2164121656
// (=> or in) produces a statement. That means it cannot be
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
a.b x in pattern
2+
^~ unexpected 'in', expecting end-of-input
3+
^~ unexpected 'in', ignoring it
4+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
a.b x: in pattern
2+
^~ unexpected 'in', expecting end-of-input
3+
^~ unexpected 'in', ignoring it
4+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
a.b &x in pattern
2+
^~ unexpected 'in', expecting end-of-input
3+
^~ unexpected 'in', ignoring it
4+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
a.b *x => pattern
2+
^~ unexpected '=>', expecting end-of-input
3+
^~ unexpected '=>', ignoring it
4+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
a.b x: => pattern
2+
^~ unexpected '=>', expecting end-of-input
3+
^~ unexpected '=>', ignoring it
4+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
a.b &x => pattern
2+
^~ unexpected '=>', expecting end-of-input
3+
^~ unexpected '=>', ignoring it
4+

test/prism/errors_test.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@ def test_unterminated_empty_string_closing
6060
assert_nil statement.closing
6161
end
6262

63-
def test_invalid_message_name
64-
assert_equal :"", Prism.parse_statement("+.@foo,+=foo").write_name
65-
end
66-
6763
def test_regexp_encoding_option_mismatch_error
6864
# UTF-8 char with ASCII-8BIT modifier
6965
result = Prism.parse('/Ȃ/n')

0 commit comments

Comments
 (0)