@@ -13112,6 +13112,20 @@ parse_assignment_value(yp_parser_t *parser, yp_binding_power_t previous_binding_
1311213112 return value;
1311313113}
1311413114
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+
1311513129static inline yp_node_t *
1311613130parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t previous_binding_power, yp_binding_power_t binding_power) {
1311713131 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
1321713231 return result;
1321813232 }
1321913233 case YP_CALL_NODE: {
13220- yp_call_node_t *call_node = (yp_call_node_t *) node;
13221-
1322213234 // If we have a vcall (a method with no arguments and no
1322313235 // receiver that could have been a local variable) then we
1322413236 // 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;
1322713239 yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end);
1322813240
1322913241 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
1324113253 parser_lex(parser);
1324213254 node = parse_target(parser, node);
1324313255
13256+ assert(YP_NODE_TYPE_P(node, YP_CALL_NODE));
13257+ parse_call_operator_write_block(parser, (yp_call_node_t *) node, &token);
13258+
1324413259 yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
1324513260 return (yp_node_t *) yp_call_and_write_node_create(parser, (yp_call_node_t *) node, &token, value);
1324613261 }
@@ -13318,13 +13333,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
1331813333 return result;
1331913334 }
1332013335 case YP_CALL_NODE: {
13321- yp_call_node_t *call_node = (yp_call_node_t *) node;
13322-
1332313336 // If we have a vcall (a method with no arguments and no
1332413337 // receiver that could have been a local variable) then we
1332513338 // 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;
1332813341 yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end);
1332913342
1333013343 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
1334213355 parser_lex(parser);
1334313356 node = parse_target(parser, node);
1334413357
13358+ assert(YP_NODE_TYPE_P(node, YP_CALL_NODE));
13359+ parse_call_operator_write_block(parser, (yp_call_node_t *) node, &token);
13360+
1334513361 yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
1334613362 return (yp_node_t *) yp_call_or_write_node_create(parser, (yp_call_node_t *) node, &token, value);
1334713363 }
@@ -13429,13 +13445,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
1342913445 return result;
1343013446 }
1343113447 case YP_CALL_NODE: {
13432- yp_call_node_t *call_node = (yp_call_node_t *) node;
13433-
1343413448 // If we have a vcall (a method with no arguments and no
1343513449 // receiver that could have been a local variable) then we
1343613450 // 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;
1343913453 yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end);
1344013454
1344113455 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
1345013464 return result;
1345113465 }
1345213466
13453- node = parse_target(parser, node);
1345413467 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);
1345513472
1345613473 yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
1345713474 return (yp_node_t *) yp_call_operator_write_node_create(parser, (yp_call_node_t *) node, &token, value);
0 commit comments