@@ -13112,6 +13112,20 @@ parse_assignment_value(yp_parser_t *parser, yp_binding_power_t previous_binding_
13112
13112
return value;
13113
13113
}
13114
13114
13115
+ // Ensures a call node that is about to become a call operator node does not
13116
+ // have a block attached. If it does, then we'll need to add an error message
13117
+ // and destroy the block. Ideally we would keep the node around so that
13118
+ // consumers would still have access to it, but we don't have a great structure
13119
+ // for that at the moment.
13120
+ static void
13121
+ parse_call_operator_write_block(yp_parser_t *parser, yp_call_node_t *call_node, const yp_token_t *operator) {
13122
+ if (call_node->block != NULL) {
13123
+ yp_diagnostic_list_append(&parser->error_list, operator->start, operator->end, YP_ERR_OPERATOR_WRITE_BLOCK);
13124
+ yp_node_destroy(parser, (yp_node_t *) call_node->block);
13125
+ call_node->block = NULL;
13126
+ }
13127
+ }
13128
+
13115
13129
static inline yp_node_t *
13116
13130
parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t previous_binding_power, yp_binding_power_t binding_power) {
13117
13131
yp_token_t token = parser->current;
@@ -13217,13 +13231,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
13217
13231
return result;
13218
13232
}
13219
13233
case YP_CALL_NODE: {
13220
- yp_call_node_t *call_node = (yp_call_node_t *) node;
13221
-
13222
13234
// If we have a vcall (a method with no arguments and no
13223
13235
// receiver that could have been a local variable) then we
13224
13236
// will transform it into a local variable write.
13225
- if (yp_call_node_variable_call_p(call_node )) {
13226
- yp_location_t message_loc = call_node ->message_loc;
13237
+ if (yp_call_node_variable_call_p((yp_call_node_t *) node )) {
13238
+ yp_location_t message_loc = ((yp_call_node_t *) node) ->message_loc;
13227
13239
yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end);
13228
13240
13229
13241
if (token_is_numbered_parameter(message_loc.start, message_loc.end)) {
@@ -13241,6 +13253,9 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
13241
13253
parser_lex(parser);
13242
13254
node = parse_target(parser, node);
13243
13255
13256
+ assert(YP_NODE_TYPE_P(node, YP_CALL_NODE));
13257
+ parse_call_operator_write_block(parser, (yp_call_node_t *) node, &token);
13258
+
13244
13259
yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
13245
13260
return (yp_node_t *) yp_call_and_write_node_create(parser, (yp_call_node_t *) node, &token, value);
13246
13261
}
@@ -13318,13 +13333,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
13318
13333
return result;
13319
13334
}
13320
13335
case YP_CALL_NODE: {
13321
- yp_call_node_t *call_node = (yp_call_node_t *) node;
13322
-
13323
13336
// If we have a vcall (a method with no arguments and no
13324
13337
// receiver that could have been a local variable) then we
13325
13338
// will transform it into a local variable write.
13326
- if (yp_call_node_variable_call_p(call_node )) {
13327
- yp_location_t message_loc = call_node ->message_loc;
13339
+ if (yp_call_node_variable_call_p((yp_call_node_t *) node )) {
13340
+ yp_location_t message_loc = ((yp_call_node_t *) node) ->message_loc;
13328
13341
yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end);
13329
13342
13330
13343
if (token_is_numbered_parameter(message_loc.start, message_loc.end)) {
@@ -13342,6 +13355,9 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
13342
13355
parser_lex(parser);
13343
13356
node = parse_target(parser, node);
13344
13357
13358
+ assert(YP_NODE_TYPE_P(node, YP_CALL_NODE));
13359
+ parse_call_operator_write_block(parser, (yp_call_node_t *) node, &token);
13360
+
13345
13361
yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
13346
13362
return (yp_node_t *) yp_call_or_write_node_create(parser, (yp_call_node_t *) node, &token, value);
13347
13363
}
@@ -13429,13 +13445,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
13429
13445
return result;
13430
13446
}
13431
13447
case YP_CALL_NODE: {
13432
- yp_call_node_t *call_node = (yp_call_node_t *) node;
13433
-
13434
13448
// If we have a vcall (a method with no arguments and no
13435
13449
// receiver that could have been a local variable) then we
13436
13450
// will transform it into a local variable write.
13437
- if (yp_call_node_variable_call_p(call_node )) {
13438
- yp_location_t message_loc = call_node ->message_loc;
13451
+ if (yp_call_node_variable_call_p((yp_call_node_t *) node )) {
13452
+ yp_location_t message_loc = ((yp_call_node_t *) node) ->message_loc;
13439
13453
yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end);
13440
13454
13441
13455
if (token_is_numbered_parameter(message_loc.start, message_loc.end)) {
@@ -13450,8 +13464,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
13450
13464
return result;
13451
13465
}
13452
13466
13453
- node = parse_target(parser, node);
13454
13467
parser_lex(parser);
13468
+ node = parse_target(parser, node);
13469
+
13470
+ assert(YP_NODE_TYPE_P(node, YP_CALL_NODE));
13471
+ parse_call_operator_write_block(parser, (yp_call_node_t *) node, &token);
13455
13472
13456
13473
yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
13457
13474
return (yp_node_t *) yp_call_operator_write_node_create(parser, (yp_call_node_t *) node, &token, value);
0 commit comments