[ruby/yarp] Fix multi target parentheses locations

7f71527522
This commit is contained in:
Kevin Newton 2023-09-14 11:19:20 -04:00 committed by git
parent b098c4247b
commit fb1328e467
4 changed files with 34 additions and 33 deletions

View file

@ -556,6 +556,8 @@ module YARP
def test_MultiWriteNode
assert_location(MultiWriteNode, "foo, bar = baz")
assert_location(MultiWriteNode, "(foo, bar) = baz")
assert_location(MultiWriteNode, "((foo, bar)) = baz")
end
def test_NextNode

View file

@ -1,9 +1,9 @@
@ ProgramNode (location: (1...9))
@ ProgramNode (location: (0...9))
├── locals: [:a, :b]
└── statements:
@ StatementsNode (location: (1...9))
@ StatementsNode (location: (0...9))
└── body: (length: 1)
└── @ MultiWriteNode (location: (1...9))
└── @ MultiWriteNode (location: (0...9))
├── targets: (length: 1)
│ └── @ MultiTargetNode (location: (1...6))
│ ├── targets: (length: 2)
@ -15,8 +15,8 @@
│ │ └── depth: 0
│ ├── lparen_loc: (1...2) = "("
│ └── rparen_loc: (5...6) = ")"
├── lparen_loc:
├── rparen_loc:
├── lparen_loc: (0...1) = "("
├── rparen_loc: (6...7) = ")"
├── operator_loc: (7...8) = "="
└── value:
@ CallNode (location: (8...9))

View file

@ -1,9 +1,9 @@
@ ProgramNode (location: (1...30))
@ ProgramNode (location: (0...30))
├── locals: [:b, :a, :c]
└── statements:
@ StatementsNode (location: (1...30))
@ StatementsNode (location: (0...30))
└── body: (length: 2)
├── @ MultiWriteNode (location: (1...13))
├── @ MultiWriteNode (location: (0...13))
│ ├── targets: (length: 1)
│ │ └── @ MultiTargetNode (location: (1...6))
│ │ ├── targets: (length: 2)
@ -15,8 +15,8 @@
│ │ │ └── expression: ∅
│ │ ├── lparen_loc: (1...2) = "("
│ │ └── rparen_loc: (5...6) = ")"
│ ├── lparen_loc:
│ ├── rparen_loc:
│ ├── lparen_loc: (0...1) = "("
│ ├── rparen_loc: (6...7) = ")"
│ ├── operator_loc: (8...9) = "="
│ └── value:
│ @ CallNode (location: (10...13))

View file

@ -11298,28 +11298,27 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
parser_lex(parser);
yp_accepts_block_stack_pop(parser);
// If we have a single statement and are ending on a right parenthesis,
// then we need to check if this is possibly a multiple target node.
// If we have a single statement and are ending on a right
// parenthesis, then we need to check if this is possibly a
// multiple target node.
if (binding_power == YP_BINDING_POWER_STATEMENT && YP_NODE_TYPE_P(statement, YP_MULTI_TARGET_NODE)) {
yp_node_t *target;
yp_multi_target_node_t *multi_target = (yp_multi_target_node_t *) statement;
yp_multi_target_node_t *multi_target;
if (((yp_multi_target_node_t *) statement)->lparen_loc.start == NULL) {
multi_target = (yp_multi_target_node_t *) statement;
} else {
multi_target = yp_multi_target_node_create(parser);
yp_multi_target_node_targets_append(multi_target, statement);
}
yp_location_t lparen_loc = YP_LOCATION_TOKEN_VALUE(&opening);
yp_location_t rparen_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous);
if (multi_target->lparen_loc.start == NULL) {
multi_target->base.location.start = lparen_loc.start;
multi_target->base.location.end = rparen_loc.end;
multi_target->lparen_loc = lparen_loc;
multi_target->rparen_loc = rparen_loc;
target = (yp_node_t *) multi_target;
} else {
yp_multi_target_node_t *parent_target = yp_multi_target_node_create(parser);
yp_multi_target_node_targets_append(parent_target, (yp_node_t *) multi_target);
target = (yp_node_t *) parent_target;
}
multi_target->base.location.start = lparen_loc.start;
multi_target->base.location.end = rparen_loc.end;
return parse_targets(parser, target, YP_BINDING_POWER_INDEX);
return parse_targets(parser, (yp_node_t *) multi_target, YP_BINDING_POWER_INDEX);
}
// If we have a single statement and are ending on a right parenthesis
@ -11331,9 +11330,9 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
return (yp_node_t *) yp_parentheses_node_create(parser, &opening, (yp_node_t *) statements, &parser->previous);
}
// If we have more than one statement in the set of parentheses, then we
// are going to parse all of them as a list of statements. We'll do that
// here.
// If we have more than one statement in the set of parentheses,
// then we are going to parse all of them as a list of statements.
// We'll do that here.
context_push(parser, YP_CONTEXT_PARENS);
yp_statements_node_t *statements = yp_statements_node_create(parser);
yp_statements_node_body_append(statements, statement);
@ -11345,11 +11344,11 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_CANNOT_PARSE_EXPRESSION);
yp_statements_node_body_append(statements, node);
// If we're recovering from a syntax error, then we need to stop parsing the
// statements now.
// If we're recovering from a syntax error, then we need to stop
// parsing the statements now.
if (parser->recovering) {
// If this is the level of context where the recovery has happened, then
// we can mark the parser as done recovering.
// If this is the level of context where the recovery has
// happened, then we can mark the parser as done recovering.
if (match1(parser, YP_TOKEN_PARENTHESIS_RIGHT)) parser->recovering = false;
break;
}