summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-10-10 10:24:57 -0400
committergit <svn-admin@ruby-lang.org>2024-10-10 14:45:59 +0000
commit82c76f18965487a705c13903a7c6dce35d6554d5 (patch)
treec1b63e243ce75998502f883dbeb27543fb3c4053
parent146ff6617326893130e5f29935cdaeae0836cfb5 (diff)
[ruby/prism] Reject invalid splat as last statement of parentheses
https://github.com/ruby/prism/commit/3a0b1c6110
-rw-r--r--prism/prism.c26
-rw-r--r--test/prism/errors/invalid_splat.txt4
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(&current_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
+