@@ -3590,7 +3590,7 @@ class BodyBuilder extends StackListenerImpl
3590
3590
assert (checkState (token, [ValueKinds .Scope ]));
3591
3591
Scope thenScope = scope.createNestedScope (
3592
3592
debugName: "then body" , kind: ScopeKind .statementLocalScope);
3593
- exitLocalScope ();
3593
+ exitLocalScope (expectedScopeKinds : const [ ScopeKind .ifCaseHead] );
3594
3594
push (condition);
3595
3595
enterLocalScope (thenScope);
3596
3596
} else {
@@ -6473,10 +6473,39 @@ class BodyBuilder extends StackListenerImpl
6473
6473
6474
6474
@override
6475
6475
void handleThenControlFlow (Token token) {
6476
+ assert (checkState (token, [ValueKinds .Condition ]));
6476
6477
// This is matched by the call to [deferNode] in
6477
6478
// [handleElseControlFlow] and by the call to [endNode] in
6478
6479
// [endIfControlFlow].
6479
6480
typeInferrer.assignedVariables.beginNode ();
6481
+
6482
+ Condition condition = pop () as Condition ;
6483
+ PatternGuard ? patternGuard = condition.patternGuard;
6484
+ if (patternGuard != null ) {
6485
+ if (patternGuard.guard != null ) {
6486
+ Scope thenScope = scope.createNestedScope (
6487
+ debugName: "then-control-flow" , kind: ScopeKind .ifElement);
6488
+ exitLocalScope (expectedScopeKinds: const [ScopeKind .ifCaseHead]);
6489
+ enterLocalScope (thenScope);
6490
+ } else {
6491
+ createAndEnterLocalScope (
6492
+ debugName: "if-case-head" , kind: ScopeKind .ifCaseHead);
6493
+ for (VariableDeclaration variable
6494
+ in patternGuard.pattern.declaredVariables) {
6495
+ declareVariable (variable, scope);
6496
+ typeInferrer.assignedVariables.declare (variable);
6497
+ }
6498
+ Scope thenScope = scope.createNestedScope (
6499
+ debugName: "then-control-flow" , kind: ScopeKind .ifElement);
6500
+ exitLocalScope (expectedScopeKinds: const [ScopeKind .ifCaseHead]);
6501
+ enterLocalScope (thenScope);
6502
+ }
6503
+ } else {
6504
+ createAndEnterLocalScope (
6505
+ debugName: "then-control-flow" , kind: ScopeKind .ifElement);
6506
+ }
6507
+ push (condition);
6508
+
6480
6509
super .handleThenControlFlow (token);
6481
6510
}
6482
6511
@@ -6504,22 +6533,33 @@ class BodyBuilder extends StackListenerImpl
6504
6533
ValueKinds .MapLiteralEntry ,
6505
6534
]),
6506
6535
ValueKinds .Condition ,
6536
+ ValueKinds .Scope ,
6507
6537
ValueKinds .Token ,
6508
6538
]));
6509
6539
6510
6540
Object ? entry = pop ();
6511
6541
Condition condition = pop () as Condition ;
6512
- assert (condition.patternGuard == null ,
6513
- "Unexpected pattern in control flow if: ${condition .patternGuard }." );
6542
+ exitLocalScope (expectedScopeKinds: const [ScopeKind .ifElement]);
6514
6543
Token ifToken = pop () as Token ;
6515
6544
6545
+ PatternGuard ? patternGuard = condition.patternGuard;
6516
6546
TreeNode node;
6517
6547
if (entry is MapLiteralEntry ) {
6518
- node = forest.createIfMapEntry (
6519
- offsetForToken (ifToken), condition.expression, entry);
6548
+ if (patternGuard == null ) {
6549
+ node = forest.createIfMapEntry (
6550
+ offsetForToken (ifToken), condition.expression, entry);
6551
+ } else {
6552
+ node = forest.createIfCaseMapEntry (
6553
+ offsetForToken (ifToken), condition.expression, patternGuard, entry);
6554
+ }
6520
6555
} else {
6521
- node = forest.createIfElement (
6522
- offsetForToken (ifToken), condition.expression, toValue (entry));
6556
+ if (patternGuard == null ) {
6557
+ node = forest.createIfElement (
6558
+ offsetForToken (ifToken), condition.expression, toValue (entry));
6559
+ } else {
6560
+ node = forest.createIfCaseElement (offsetForToken (ifToken),
6561
+ condition.expression, patternGuard, toValue (entry));
6562
+ }
6523
6563
}
6524
6564
push (node);
6525
6565
// This is matched by the call to [beginNode] in
@@ -6545,6 +6585,7 @@ class BodyBuilder extends StackListenerImpl
6545
6585
]),
6546
6586
ValueKinds .AssignedVariablesNodeInfo ,
6547
6587
ValueKinds .Condition ,
6588
+ ValueKinds .Scope ,
6548
6589
ValueKinds .Token ,
6549
6590
]));
6550
6591
@@ -6553,8 +6594,7 @@ class BodyBuilder extends StackListenerImpl
6553
6594
AssignedVariablesNodeInfo assignedVariablesInfo =
6554
6595
pop () as AssignedVariablesNodeInfo ;
6555
6596
Condition condition = pop () as Condition ; // parenthesized expression
6556
- assert (condition.patternGuard == null ,
6557
- "Unexpected pattern in control flow if: ${condition .patternGuard }." );
6597
+ exitLocalScope (expectedScopeKinds: const [ScopeKind .ifElement]);
6558
6598
Token ifToken = pop () as Token ;
6559
6599
6560
6600
TreeNode node;
@@ -6612,8 +6652,17 @@ class BodyBuilder extends StackListenerImpl
6612
6652
..fileOffset = offsetForToken (ifToken);
6613
6653
}
6614
6654
} else {
6615
- node = forest.createIfElement (offsetForToken (ifToken),
6616
- condition.expression, toValue (thenEntry), toValue (elseEntry));
6655
+ if (condition.patternGuard == null ) {
6656
+ node = forest.createIfElement (offsetForToken (ifToken),
6657
+ condition.expression, toValue (thenEntry), toValue (elseEntry));
6658
+ } else {
6659
+ node = forest.createIfCaseElement (
6660
+ offsetForToken (ifToken),
6661
+ condition.expression,
6662
+ condition.patternGuard! ,
6663
+ toValue (thenEntry),
6664
+ toValue (elseEntry));
6665
+ }
6617
6666
}
6618
6667
push (node);
6619
6668
// This is matched by the call to [deferNode] in
0 commit comments