@@ -13034,7 +13034,7 @@ parse_unwriteable_target(pm_parser_t *parser, pm_node_t *target) {
13034
13034
* Convert the given node into a valid target node.
13035
13035
*/
13036
13036
static pm_node_t *
13037
- parse_target(pm_parser_t *parser, pm_node_t *target) {
13037
+ parse_target(pm_parser_t *parser, pm_node_t *target, bool multiple ) {
13038
13038
switch (PM_NODE_TYPE(target)) {
13039
13039
case PM_MISSING_NODE:
13040
13040
return target;
@@ -13102,7 +13102,7 @@ parse_target(pm_parser_t *parser, pm_node_t *target) {
13102
13102
pm_splat_node_t *splat = (pm_splat_node_t *) target;
13103
13103
13104
13104
if (splat->expression != NULL) {
13105
- splat->expression = parse_target(parser, splat->expression);
13105
+ splat->expression = parse_target(parser, splat->expression, multiple );
13106
13106
}
13107
13107
13108
13108
return (pm_node_t *) splat;
@@ -13140,6 +13140,10 @@ parse_target(pm_parser_t *parser, pm_node_t *target) {
13140
13140
}
13141
13141
13142
13142
if (*call->message_loc.start == '_' || parser->encoding->alnum_char(call->message_loc.start, call->message_loc.end - call->message_loc.start)) {
13143
+ if (multiple && PM_NODE_FLAG_P(call, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) {
13144
+ pm_parser_err_node(parser, (const pm_node_t *) call, PM_ERR_UNEXPECTED_SAFE_NAVIGATION);
13145
+ }
13146
+
13143
13147
parse_write_name(parser, &call->name);
13144
13148
return (pm_node_t *) pm_call_target_node_create(parser, call);
13145
13149
}
@@ -13167,8 +13171,8 @@ parse_target(pm_parser_t *parser, pm_node_t *target) {
13167
13171
* assignment.
13168
13172
*/
13169
13173
static pm_node_t *
13170
- parse_target_validate(pm_parser_t *parser, pm_node_t *target) {
13171
- pm_node_t *result = parse_target(parser, target);
13174
+ parse_target_validate(pm_parser_t *parser, pm_node_t *target, bool multiple ) {
13175
+ pm_node_t *result = parse_target(parser, target, multiple );
13172
13176
13173
13177
// Ensure that we have one of an =, an 'in' in for indexes, and a ')' in parens after the targets.
13174
13178
if (
@@ -13405,7 +13409,7 @@ parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t b
13405
13409
bool has_rest = PM_NODE_TYPE_P(first_target, PM_SPLAT_NODE);
13406
13410
13407
13411
pm_multi_target_node_t *result = pm_multi_target_node_create(parser);
13408
- pm_multi_target_node_targets_append(parser, result, parse_target(parser, first_target));
13412
+ pm_multi_target_node_targets_append(parser, result, parse_target(parser, first_target, true ));
13409
13413
13410
13414
while (accept1(parser, PM_TOKEN_COMMA)) {
13411
13415
if (accept1(parser, PM_TOKEN_USTAR)) {
@@ -13421,15 +13425,15 @@ parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t b
13421
13425
13422
13426
if (token_begins_expression_p(parser->current.type)) {
13423
13427
name = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR);
13424
- name = parse_target(parser, name);
13428
+ name = parse_target(parser, name, true );
13425
13429
}
13426
13430
13427
13431
pm_node_t *splat = (pm_node_t *) pm_splat_node_create(parser, &star_operator, name);
13428
13432
pm_multi_target_node_targets_append(parser, result, splat);
13429
13433
has_rest = true;
13430
13434
} else if (token_begins_expression_p(parser->current.type)) {
13431
13435
pm_node_t *target = parse_expression(parser, binding_power, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA);
13432
- target = parse_target(parser, target);
13436
+ target = parse_target(parser, target, true );
13433
13437
13434
13438
pm_multi_target_node_targets_append(parser, result, target);
13435
13439
} else if (!match1(parser, PM_TOKEN_EOF)) {
@@ -14450,7 +14454,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node, pm_rescues_type
14450
14454
pm_rescue_node_operator_set(rescue, &parser->previous);
14451
14455
14452
14456
pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_RESCUE_VARIABLE);
14453
- reference = parse_target(parser, reference);
14457
+ reference = parse_target(parser, reference, false );
14454
14458
14455
14459
pm_rescue_node_reference_set(rescue, reference);
14456
14460
break;
@@ -14480,7 +14484,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node, pm_rescues_type
14480
14484
pm_rescue_node_operator_set(rescue, &parser->previous);
14481
14485
14482
14486
pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, PM_ERR_RESCUE_VARIABLE);
14483
- reference = parse_target(parser, reference);
14487
+ reference = parse_target(parser, reference, false );
14484
14488
14485
14489
pm_rescue_node_reference_set(rescue, reference);
14486
14490
break;
@@ -17264,7 +17268,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
17264
17268
return (pm_node_t *) multi_target;
17265
17269
}
17266
17270
17267
- return parse_target_validate(parser, (pm_node_t *) multi_target);
17271
+ return parse_target_validate(parser, (pm_node_t *) multi_target, false );
17268
17272
}
17269
17273
17270
17274
// If we have a single statement and are ending on a right parenthesis
@@ -18564,7 +18568,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18564
18568
if (match1(parser, PM_TOKEN_COMMA)) {
18565
18569
index = parse_targets(parser, index, PM_BINDING_POWER_INDEX);
18566
18570
} else {
18567
- index = parse_target(parser, index);
18571
+ index = parse_target(parser, index, false );
18568
18572
}
18569
18573
18570
18574
context_pop(parser);
@@ -19343,7 +19347,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19343
19347
if (match1(parser, PM_TOKEN_COMMA)) {
19344
19348
return parse_targets_validate(parser, splat, PM_BINDING_POWER_INDEX);
19345
19349
} else {
19346
- return parse_target_validate(parser, splat);
19350
+ return parse_target_validate(parser, splat, false );
19347
19351
}
19348
19352
}
19349
19353
case PM_TOKEN_BANG: {
0 commit comments