Skip to content

Commit a4a4834

Browse files
committed
Check value expressions on parsing arguments and assignments
They are corresponding to `arg_value` in `parse.y`.
1 parent 37fad74 commit a4a4834

File tree

2 files changed

+90
-17
lines changed

2 files changed

+90
-17
lines changed

src/prism.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10231,11 +10231,11 @@ static pm_node_t *
1023110231
parse_starred_expression(pm_parser_t *parser, pm_binding_power_t binding_power, pm_diagnostic_id_t diag_id) {
1023210232
if (accept1(parser, PM_TOKEN_USTAR)) {
1023310233
pm_token_t operator = parser->previous;
10234-
pm_node_t *expression = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
10234+
pm_node_t *expression = parse_value_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
1023510235
return (pm_node_t *) pm_splat_node_create(parser, &operator, expression);
1023610236
}
1023710237

10238-
return parse_expression(parser, binding_power, diag_id);
10238+
return parse_value_expression(parser, binding_power, diag_id);
1023910239
}
1024010240

1024110241
/**
@@ -10726,7 +10726,7 @@ parse_assocs(pm_parser_t *parser, pm_node_t *node) {
1072610726
pm_node_t *value = NULL;
1072710727

1072810728
if (token_begins_expression_p(parser->current.type)) {
10729-
value = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
10729+
value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
1073010730
} else if (pm_parser_local_depth(parser, &operator) == -1) {
1073110731
pm_parser_err_token(parser, &operator, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH);
1073210732
}
@@ -10744,7 +10744,7 @@ parse_assocs(pm_parser_t *parser, pm_node_t *node) {
1074410744
pm_node_t *value = NULL;
1074510745

1074610746
if (token_begins_expression_p(parser->current.type)) {
10747-
value = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_EXPRESSION_AFTER_LABEL);
10747+
value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_EXPRESSION_AFTER_LABEL);
1074810748
} else {
1074910749
if (parser->encoding.isupper_char(label.start, (label.end - 1) - label.start)) {
1075010750
pm_token_t constant = { .type = PM_TOKEN_CONSTANT, .start = label.start, .end = label.end - 1 };
@@ -10768,7 +10768,7 @@ parse_assocs(pm_parser_t *parser, pm_node_t *node) {
1076810768
break;
1076910769
}
1077010770
default: {
10771-
pm_node_t *key = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_KEY);
10771+
pm_node_t *key = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_KEY);
1077210772
pm_token_t operator;
1077310773

1077410774
if (pm_symbol_node_label_p(key)) {
@@ -10778,7 +10778,7 @@ parse_assocs(pm_parser_t *parser, pm_node_t *node) {
1077810778
operator = parser->previous;
1077910779
}
1078010780

10781-
pm_node_t *value = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_VALUE);
10781+
pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_VALUE);
1078210782
element = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value);
1078310783
break;
1078410784
}
@@ -10874,7 +10874,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
1087410874
pm_node_t *expression = NULL;
1087510875

1087610876
if (token_begins_expression_p(parser->current.type)) {
10877-
expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_ARGUMENT);
10877+
expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_ARGUMENT);
1087810878
} else if (pm_parser_local_depth(parser, &operator) == -1) {
1087910879
pm_parser_err_token(parser, &operator, PM_ERR_ARGUMENT_NO_FORWARDING_AMP);
1088010880
}
@@ -10900,7 +10900,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
1090010900

1090110901
argument = (pm_node_t *) pm_splat_node_create(parser, &operator, NULL);
1090210902
} else {
10903-
pm_node_t *expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT);
10903+
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT);
1090410904

1090510905
if (parsed_bare_hash) {
1090610906
pm_parser_err(parser, operator.start, expression->location.end, PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT);
@@ -10936,7 +10936,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
1093610936
/* fallthrough */
1093710937
default: {
1093810938
if (argument == NULL) {
10939-
argument = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_ARGUMENT);
10939+
argument = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_ARGUMENT);
1094010940
}
1094110941

1094210942
bool contains_keyword_splat = false;
@@ -10955,7 +10955,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
1095510955
pm_keyword_hash_node_t *bare_hash = pm_keyword_hash_node_create(parser);
1095610956

1095710957
// Finish parsing the one we are part way through
10958-
pm_node_t *value = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_VALUE);
10958+
pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_HASH_VALUE);
1095910959

1096010960
argument = (pm_node_t *) pm_assoc_node_create(parser, argument, &operator, value);
1096110961
pm_keyword_hash_node_elements_append(bare_hash, argument);
@@ -11259,7 +11259,7 @@ parse_parameters(
1125911259
if (accept1(parser, PM_TOKEN_EQUAL)) {
1126011260
pm_token_t operator = parser->previous;
1126111261
context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
11262-
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_PARAMETER_NO_DEFAULT);
11262+
pm_node_t *value = parse_value_expression(parser, binding_power, PM_ERR_PARAMETER_NO_DEFAULT);
1126311263

1126411264
pm_optional_parameter_node_t *param = pm_optional_parameter_node_create(parser, &name, &operator, value);
1126511265
pm_parameters_node_optionals_append(params, param);
@@ -11318,7 +11318,7 @@ parse_parameters(
1131811318

1131911319
if (token_begins_expression_p(parser->current.type)) {
1132011320
context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
11321-
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_PARAMETER_NO_DEFAULT_KW);
11321+
pm_node_t *value = parse_value_expression(parser, binding_power, PM_ERR_PARAMETER_NO_DEFAULT_KW);
1132211322
context_pop(parser);
1132311323
param = (pm_node_t *) pm_optional_keyword_parameter_node_create(parser, &name, value);
1132411324
}
@@ -13953,14 +13953,14 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
1395313953
do {
1395413954
if (accept1(parser, PM_TOKEN_USTAR)) {
1395513955
pm_token_t operator = parser->previous;
13956-
pm_node_t *expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
13956+
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
1395713957

1395813958
pm_splat_node_t *splat_node = pm_splat_node_create(parser, &operator, expression);
1395913959
pm_when_node_conditions_append(when_node, (pm_node_t *) splat_node);
1396013960

1396113961
if (PM_NODE_TYPE_P(expression, PM_MISSING_NODE)) break;
1396213962
} else {
13963-
pm_node_t *condition = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_CASE_EXPRESSION_AFTER_WHEN);
13963+
pm_node_t *condition = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_CASE_EXPRESSION_AFTER_WHEN);
1396413964
pm_when_node_conditions_append(when_node, condition);
1396513965

1396613966
if (PM_NODE_TYPE_P(condition, PM_MISSING_NODE)) break;
@@ -14001,11 +14001,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
1400114001
// for guard clauses in the form of `if` or `unless` statements.
1400214002
if (accept1(parser, PM_TOKEN_KEYWORD_IF_MODIFIER)) {
1400314003
pm_token_t keyword = parser->previous;
14004-
pm_node_t *predicate = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_CONDITIONAL_IF_PREDICATE);
14004+
pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_CONDITIONAL_IF_PREDICATE);
1400514005
pattern = (pm_node_t *) pm_if_node_modifier_create(parser, pattern, &keyword, predicate);
1400614006
} else if (accept1(parser, PM_TOKEN_KEYWORD_UNLESS_MODIFIER)) {
1400714007
pm_token_t keyword = parser->previous;
14008-
pm_node_t *predicate = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_CONDITIONAL_UNLESS_PREDICATE);
14008+
pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_CONDITIONAL_UNLESS_PREDICATE);
1400914009
pattern = (pm_node_t *) pm_unless_node_modifier_create(parser, pattern, &keyword, predicate);
1401014010
}
1401114011

@@ -14362,7 +14362,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
1436214362
case PM_TOKEN_PARENTHESIS_LEFT: {
1436314363
parser_lex(parser);
1436414364
pm_token_t lparen = parser->previous;
14365-
pm_node_t *expression = parse_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_DEF_RECEIVER);
14365+
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_DEF_RECEIVER);
1436614366

1436714367
expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN);
1436814368
pm_token_t rparen = parser->previous;

test/prism/errors_test.rb

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,39 @@ class A < (return)
15111511
], compare_ripper: false # Ripper does not check 'void value expression'.
15121512
end
15131513

1514+
def test_void_value_expression_in_def
1515+
source = <<~RUBY
1516+
def (return).x
1517+
end
1518+
def x(a = return)
1519+
end
1520+
def x(a: return)
1521+
end
1522+
RUBY
1523+
message = 'Unexpected void value expression'
1524+
assert_errors expression(source), source, [
1525+
[message, 5..11],
1526+
[message, 29..35],
1527+
[message, 50..56],
1528+
], compare_ripper: false # Ripper does not check 'void value expression'.
1529+
end
1530+
1531+
def test_void_value_expression_in_assignment
1532+
source = <<~RUBY
1533+
a = return
1534+
a = 1, return
1535+
a, b = return, 1
1536+
a, b = 1, *return
1537+
RUBY
1538+
message = 'Unexpected void value expression'
1539+
assert_errors expression(source), source, [
1540+
[message, 4..10],
1541+
[message, 18..24],
1542+
[message, 32..38],
1543+
[message, 53..59],
1544+
], compare_ripper: false # Ripper does not check 'void value expression'.
1545+
end
1546+
15141547
def test_void_value_expression_in_modifier
15151548
source = <<~RUBY
15161549
1 if (return)
@@ -1527,6 +1560,46 @@ def test_void_value_expression_in_modifier
15271560
], compare_ripper: false # Ripper does not check 'void value expression'.
15281561
end
15291562

1563+
def test_void_value_expression_in_arguments
1564+
source = <<~RUBY
1565+
foo(return)
1566+
foo(1, return)
1567+
foo(*return)
1568+
foo(**return)
1569+
foo(&return)
1570+
foo(return => 1)
1571+
foo(:a => return)
1572+
foo(a: return)
1573+
RUBY
1574+
message = 'Unexpected void value expression'
1575+
assert_errors expression(source), source, [
1576+
[message, 4..10],
1577+
[message, 19..25],
1578+
[message, 32..38],
1579+
[message, 46..52],
1580+
[message, 59..65],
1581+
[message, 71..77],
1582+
[message, 94..100],
1583+
[message, 109..115],
1584+
], compare_ripper: false # Ripper does not check 'void value expression'.
1585+
end
1586+
1587+
def test_void_value_expression_in_hash
1588+
source = <<~RUBY
1589+
{ return => 1 }
1590+
{ 1 => return }
1591+
{ a: return }
1592+
{ **return }
1593+
RUBY
1594+
message = 'Unexpected void value expression'
1595+
assert_errors expression(source), source, [
1596+
[message, 2..8],
1597+
[message, 23..29],
1598+
[message, 37..43],
1599+
[message, 50..56],
1600+
], compare_ripper: false # Ripper does not check 'void value expression'.
1601+
end
1602+
15301603
private
15311604

15321605
def assert_errors(expected, source, errors, compare_ripper: RUBY_ENGINE == "ruby")

0 commit comments

Comments
 (0)