Skip to content

Commit e2c886d

Browse files
Earlopainkddnewton
authored andcommitted
[ruby/prism] Reject p(p a, &block => value) and similar
Redo of ruby/prism#3669 with more tests ruby/prism@48b403ea79
1 parent 7624840 commit e2c886d

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

prism/prism.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13412,6 +13412,30 @@ parse_assocs(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *nod
1341213412
return contains_keyword_splat;
1341313413
}
1341413414

13415+
static inline bool
13416+
argument_allowed_for_bare_hash(pm_parser_t *parser, pm_node_t *argument) {
13417+
if (pm_symbol_node_label_p(argument)) {
13418+
return true;
13419+
}
13420+
13421+
switch (PM_NODE_TYPE(argument)) {
13422+
case PM_CALL_NODE: {
13423+
pm_call_node_t *cast = (pm_call_node_t *) argument;
13424+
if (cast->opening_loc.start == NULL && cast->arguments != NULL) {
13425+
if (PM_NODE_FLAG_P(cast->arguments, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS | PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT)) {
13426+
return false;
13427+
}
13428+
if (cast->block != NULL) {
13429+
return false;
13430+
}
13431+
}
13432+
break;
13433+
}
13434+
default: break;
13435+
}
13436+
return accept1(parser, PM_TOKEN_EQUAL_GREATER);
13437+
}
13438+
1341513439
/**
1341613440
* Append an argument to a list of arguments.
1341713441
*/
@@ -13569,7 +13593,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
1356913593
bool contains_keywords = false;
1357013594
bool contains_keyword_splat = false;
1357113595

13572-
if (pm_symbol_node_label_p(argument) || accept1(parser, PM_TOKEN_EQUAL_GREATER)) {
13596+
if (argument_allowed_for_bare_hash(parser, argument)){
1357313597
if (parsed_bare_hash) {
1357413598
pm_parser_err_previous(parser, PM_ERR_ARGUMENT_BARE_HASH);
1357513599
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
p(p a, x: b => value)
2+
^~ unexpected '=>'; expected a `)` to close the arguments
3+
^ unexpected ')', expecting end-of-input
4+
^ unexpected ')', ignoring it
5+
6+
p(p a, x: => value)
7+
^~ unexpected '=>'; expected a `)` to close the arguments
8+
^ unexpected ')', expecting end-of-input
9+
^ unexpected ')', ignoring it
10+
11+
p(p a, &block => value)
12+
^~ unexpected '=>'; expected a `)` to close the arguments
13+
^ unexpected ')', expecting end-of-input
14+
^ unexpected ')', ignoring it
15+
16+
p(p a do end => value)
17+
^~ unexpected '=>'; expected a `)` to close the arguments
18+
^ unexpected ')', expecting end-of-input
19+
^ unexpected ')', ignoring it
20+
21+
p(p a, *args => value)
22+
^~ unexpected '=>'; expected a `)` to close the arguments
23+
^ unexpected ')', expecting end-of-input
24+
^ unexpected ')', ignoring it
25+
26+
p(p a, **kwargs => value)
27+
^~ unexpected '=>'; expected a `)` to close the arguments
28+
^ unexpected ')', expecting end-of-input
29+
^ unexpected ')', ignoring it
30+
31+
p p 1, &block => 2, &block
32+
^~ unexpected '=>', expecting end-of-input
33+
^~ unexpected '=>', ignoring it
34+
^ unexpected ',', expecting end-of-input
35+
^ unexpected ',', ignoring it
36+
^ unexpected '&', ignoring it
37+
38+
p p p 1 => 2 => 3 => 4
39+
^~ unexpected '=>', expecting end-of-input
40+
^~ unexpected '=>', ignoring it
41+
42+
p[p a, x: b => value]
43+
^ expected a matching `]`
44+
^ unexpected ']', expecting end-of-input
45+
^ unexpected ']', ignoring it
46+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
foo(bar 1, key => '2')
2+
3+
foo(bar 1, KEY => '2')
4+
5+
foo(bar 1, :key => '2')
6+
7+
foo(bar 1, { baz: :bat } => '2')
8+
9+
foo bar - %i[baz] => '2'
10+
11+
foo(bar {} => '2')
12+
13+
foo(bar baz {} => '2')
14+
15+
foo(bar do end => '2')
16+
17+
foo(1, bar {} => '2')
18+
19+
foo(1, bar do end => '2')

0 commit comments

Comments
 (0)