diff options
| author | Kevin Newton <kddnewton@gmail.com> | 2024-10-10 10:24:57 -0400 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2024-10-10 14:45:59 +0000 |
| commit | 82c76f18965487a705c13903a7c6dce35d6554d5 (patch) | |
| tree | c1b63e243ce75998502f883dbeb27543fb3c4053 | |
| parent | 146ff6617326893130e5f29935cdaeae0836cfb5 (diff) | |
[ruby/prism] Reject invalid splat as last statement of parentheses
https://github.com/ruby/prism/commit/3a0b1c6110
| -rw-r--r-- | prism/prism.c | 26 | ||||
| -rw-r--r-- | test/prism/errors/invalid_splat.txt | 4 |
2 files changed, 25 insertions, 5 deletions
diff --git a/prism/prism.c b/prism/prism.c index 7ef92ef5a5..74c86d1622 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -18254,21 +18254,37 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b } } + context_pop(parser); + pm_accepts_block_stack_pop(parser); + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN); + // When we're parsing multi targets, we allow them to be followed by // a right parenthesis if they are at the statement level. This is // only possible if they are the final statement in a parentheses. // We need to explicitly reject that here. { - const pm_node_t *statement = statements->body.nodes[statements->body.size - 1]; + pm_node_t *statement = statements->body.nodes[statements->body.size - 1]; + + if (PM_NODE_TYPE_P(statement, PM_SPLAT_NODE)) { + pm_multi_target_node_t *multi_target = pm_multi_target_node_create(parser); + pm_multi_target_node_targets_append(parser, multi_target, statement); + + statement = (pm_node_t *) multi_target; + statements->body.nodes[statements->body.size - 1] = statement; + } + if (PM_NODE_TYPE_P(statement, PM_MULTI_TARGET_NODE)) { + const uint8_t *offset = statement->location.end; + pm_token_t operator = { .type = PM_TOKEN_EQUAL, .start = offset, .end = offset }; + pm_node_t *value = (pm_node_t *) pm_missing_node_create(parser, offset, offset); + + statement = (pm_node_t *) pm_multi_write_node_create(parser, (pm_multi_target_node_t *) statement, &operator, value); + statements->body.nodes[statements->body.size - 1] = statement; + pm_parser_err_node(parser, statement, PM_ERR_WRITE_TARGET_UNEXPECTED); } } - context_pop(parser); - pm_accepts_block_stack_pop(parser); - expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN); - pop_block_exits(parser, previous_block_exits); pm_node_list_free(¤t_block_exits); diff --git a/test/prism/errors/invalid_splat.txt b/test/prism/errors/invalid_splat.txt new file mode 100644 index 0000000000..cffd0f9879 --- /dev/null +++ b/test/prism/errors/invalid_splat.txt @@ -0,0 +1,4 @@ +(1 +*a) +^~ unexpected write target + |
