[ruby/prism] Fix LocalVariableTargetNode depth in patterns

Fix https://github.com/ruby/prism/pull/1821

7d023a26b4
This commit is contained in:
TSUYUSATO Kitsune 2023-11-23 00:06:59 +09:00 committed by git
parent a31cdc6ee9
commit 7b20dd9f91
3 changed files with 139 additions and 32 deletions

View file

@ -4136,6 +4136,22 @@ pm_local_variable_target_node_create(pm_parser_t *parser, const pm_token_t *name
); );
} }
/**
* Allocate and initialize a new LocalVariableTargetNode node with the given depth.
*/
static pm_local_variable_target_node_t *
pm_local_variable_target_node_create_depth(pm_parser_t *parser, const pm_token_t *name, uint32_t depth) {
pm_refute_numbered_parameter(parser, name->start, name->end);
return pm_local_variable_target_node_create_values(
parser,
&(pm_location_t) { .start = name->start, .end = name->end },
pm_parser_constant_id_token(parser, name),
depth
);
}
/** /**
* Allocate and initialize a new MatchPredicateNode node. * Allocate and initialize a new MatchPredicateNode node.
*/ */
@ -13003,8 +13019,13 @@ parse_pattern_primitive(pm_parser_t *parser, pm_diagnostic_id_t diag_id) {
case PM_TOKEN_IDENTIFIER: case PM_TOKEN_IDENTIFIER:
case PM_TOKEN_METHOD_NAME: { case PM_TOKEN_METHOD_NAME: {
parser_lex(parser); parser_lex(parser);
pm_parser_local_add_token(parser, &parser->previous); pm_token_t name = parser->previous;
return (pm_node_t *) pm_local_variable_target_node_create(parser, &parser->previous); int depth = pm_parser_local_depth(parser, &name);
if (depth < 0) {
depth = 0;
pm_parser_local_add_token(parser, &name);
}
return (pm_node_t *) pm_local_variable_target_node_create_depth(parser, &name, (uint32_t) depth);
} }
case PM_TOKEN_BRACKET_LEFT_ARRAY: { case PM_TOKEN_BRACKET_LEFT_ARRAY: {
pm_token_t opening = parser->current; pm_token_t opening = parser->current;
@ -13321,9 +13342,13 @@ parse_pattern_primitives(pm_parser_t *parser, pm_diagnostic_id_t diag_id) {
expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_PATTERN_IDENT_AFTER_HROCKET); expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_PATTERN_IDENT_AFTER_HROCKET);
pm_token_t identifier = parser->previous; pm_token_t identifier = parser->previous;
pm_parser_local_add_token(parser, &identifier); int depth = pm_parser_local_depth(parser, &identifier);
if (depth < 0) {
depth = 0;
pm_parser_local_add_token(parser, &identifier);
}
pm_node_t *target = (pm_node_t *) pm_local_variable_target_node_create(parser, &identifier); pm_node_t *target = (pm_node_t *) pm_local_variable_target_node_create_depth(parser, &identifier, (uint32_t) depth);
node = (pm_node_t *) pm_capture_pattern_node_create(parser, node, target, &operator); node = (pm_node_t *) pm_capture_pattern_node_create(parser, node, target, &operator);
} }

View file

@ -193,3 +193,8 @@ foo in A[
foo in bar => baz foo in bar => baz
foo => bar => baz foo => bar => baz
foo, bar, baz = 1, 2
foo do
[1, 2] => [foo, bar] => baz
end

View file

@ -1,8 +1,8 @@
@ ProgramNode (location: (1,0)-(195,17)) @ ProgramNode (location: (1,0)-(200,3))
├── locals: [:bar, :baz, :qux, :b, :a] ├── locals: [:bar, :baz, :qux, :b, :a, :foo]
└── statements: └── statements:
@ StatementsNode (location: (1,0)-(195,17)) @ StatementsNode (location: (1,0)-(200,3))
└── body: (length: 172) └── body: (length: 174)
├── @ MatchRequiredNode (location: (1,0)-(1,10)) ├── @ MatchRequiredNode (location: (1,0)-(1,10))
│ ├── value: │ ├── value:
│ │ @ CallNode (location: (1,0)-(1,3)) │ │ @ CallNode (location: (1,0)-(1,3))
@ -4575,27 +4575,104 @@
│ │ │ └── depth: 0 │ │ │ └── depth: 0
│ │ └── operator_loc: (194,11)-(194,13) = "=>" │ │ └── operator_loc: (194,11)-(194,13) = "=>"
│ └── operator_loc: (194,4)-(194,6) = "in" │ └── operator_loc: (194,4)-(194,6) = "in"
└── @ MatchRequiredNode (location: (195,0)-(195,17)) ├── @ MatchRequiredNode (location: (195,0)-(195,17))
├── value: │ ├── value:
│ @ CallNode (location: (195,0)-(195,3)) │ │ @ CallNode (location: (195,0)-(195,3))
│ ├── receiver: ∅ │ │ ├── receiver: ∅
│ ├── call_operator_loc: ∅ │ │ ├── call_operator_loc: ∅
│ ├── name: :foo │ │ ├── name: :foo
│ ├── message_loc: (195,0)-(195,3) = "foo" │ │ ├── message_loc: (195,0)-(195,3) = "foo"
│ ├── opening_loc: ∅ │ │ ├── opening_loc: ∅
│ ├── arguments: ∅ │ │ ├── arguments: ∅
│ ├── closing_loc: ∅ │ │ ├── closing_loc: ∅
│ ├── block: ∅ │ │ ├── block: ∅
│ └── flags: variable_call │ │ └── flags: variable_call
├── pattern: │ ├── pattern:
│ @ CapturePatternNode (location: (195,7)-(195,17)) │ │ @ CapturePatternNode (location: (195,7)-(195,17))
│ ├── value: │ │ ├── value:
│ │ @ LocalVariableTargetNode (location: (195,7)-(195,10)) │ │ │ @ LocalVariableTargetNode (location: (195,7)-(195,10))
│ │ ├── name: :bar │ │ │ ├── name: :bar
│ │ └── depth: 0 │ │ │ └── depth: 0
│ ├── target: │ │ ├── target:
│ │ @ LocalVariableTargetNode (location: (195,14)-(195,17)) │ │ │ @ LocalVariableTargetNode (location: (195,14)-(195,17))
│ │ ├── name: :baz │ │ │ ├── name: :baz
│ │ └── depth: 0 │ │ │ └── depth: 0
│ └── operator_loc: (195,11)-(195,13) = "=>" │ │ └── operator_loc: (195,11)-(195,13) = "=>"
└── operator_loc: (195,4)-(195,6) = "=>" │ └── operator_loc: (195,4)-(195,6) = "=>"
├── @ MultiWriteNode (location: (197,0)-(197,20))
│ ├── lefts: (length: 3)
│ │ ├── @ LocalVariableTargetNode (location: (197,0)-(197,3))
│ │ │ ├── name: :foo
│ │ │ └── depth: 0
│ │ ├── @ LocalVariableTargetNode (location: (197,5)-(197,8))
│ │ │ ├── name: :bar
│ │ │ └── depth: 0
│ │ └── @ LocalVariableTargetNode (location: (197,10)-(197,13))
│ │ ├── name: :baz
│ │ └── depth: 0
│ ├── rest: ∅
│ ├── rights: (length: 0)
│ ├── lparen_loc: ∅
│ ├── rparen_loc: ∅
│ ├── operator_loc: (197,14)-(197,15) = "="
│ └── value:
│ @ ArrayNode (location: (197,16)-(197,20))
│ ├── elements: (length: 2)
│ │ ├── @ IntegerNode (location: (197,16)-(197,17))
│ │ │ └── flags: decimal
│ │ └── @ IntegerNode (location: (197,19)-(197,20))
│ │ └── flags: decimal
│ ├── opening_loc: ∅
│ ├── closing_loc: ∅
│ └── flags: ∅
└── @ CallNode (location: (198,0)-(200,3))
├── receiver: ∅
├── call_operator_loc: ∅
├── name: :foo
├── message_loc: (198,0)-(198,3) = "foo"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── block:
│ @ BlockNode (location: (198,4)-(200,3))
│ ├── locals: []
│ ├── parameters: ∅
│ ├── body:
│ │ @ StatementsNode (location: (199,2)-(199,29))
│ │ └── body: (length: 1)
│ │ └── @ MatchRequiredNode (location: (199,2)-(199,29))
│ │ ├── value:
│ │ │ @ ArrayNode (location: (199,2)-(199,8))
│ │ │ ├── elements: (length: 2)
│ │ │ │ ├── @ IntegerNode (location: (199,3)-(199,4))
│ │ │ │ │ └── flags: decimal
│ │ │ │ └── @ IntegerNode (location: (199,6)-(199,7))
│ │ │ │ └── flags: decimal
│ │ │ ├── opening_loc: (199,2)-(199,3) = "["
│ │ │ ├── closing_loc: (199,7)-(199,8) = "]"
│ │ │ └── flags: ∅
│ │ ├── pattern:
│ │ │ @ CapturePatternNode (location: (199,12)-(199,29))
│ │ │ ├── value:
│ │ │ │ @ ArrayPatternNode (location: (199,12)-(199,22))
│ │ │ │ ├── constant: ∅
│ │ │ │ ├── requireds: (length: 2)
│ │ │ │ │ ├── @ LocalVariableTargetNode (location: (199,13)-(199,16))
│ │ │ │ │ │ ├── name: :foo
│ │ │ │ │ │ └── depth: 1
│ │ │ │ │ └── @ LocalVariableTargetNode (location: (199,18)-(199,21))
│ │ │ │ │ ├── name: :bar
│ │ │ │ │ └── depth: 1
│ │ │ │ ├── rest: ∅
│ │ │ │ ├── posts: (length: 0)
│ │ │ │ ├── opening_loc: (199,12)-(199,13) = "["
│ │ │ │ └── closing_loc: (199,21)-(199,22) = "]"
│ │ │ ├── target:
│ │ │ │ @ LocalVariableTargetNode (location: (199,26)-(199,29))
│ │ │ │ ├── name: :baz
│ │ │ │ └── depth: 1
│ │ │ └── operator_loc: (199,23)-(199,25) = "=>"
│ │ └── operator_loc: (199,9)-(199,11) = "=>"
│ ├── opening_loc: (198,4)-(198,6) = "do"
│ └── closing_loc: (200,0)-(200,3) = "end"
└── flags: ∅