Skip to content

Commit 966aed6

Browse files
stereotype441Commit Queue
authored and
Commit Queue
committed
Shared pattern analysis: add support for pattern variable assignment.
Bug: #50585 Change-Id: I1939c6fd8fac205abeac5b0a9b3da9b3b4adca01 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/274604 Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent 9f2a622 commit 966aed6

File tree

10 files changed

+574
-202
lines changed

10 files changed

+574
-202
lines changed

pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart

+77-35
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,14 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
187187
/// A function parameter is always initialized, so [initialized] is `true`.
188188
void declare(Variable variable, bool initialized);
189189

190+
/// Call this method after visiting a variable pattern in a non-assignment
191+
/// context (or a wildcard pattern).
192+
///
193+
/// [matchedType] should be the static type of the value being matched.
194+
/// [staticType] should be the static type of the variable pattern itself.
195+
void declaredVariablePattern(
196+
{required Type matchedType, required Type staticType});
197+
190198
/// Call this method before visiting the body of a "do-while" statement.
191199
/// [doStatement] should be the same node that was passed to
192200
/// [AssignedVariables.endNode] for the do-while statement.
@@ -518,6 +526,15 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
518526
void parenthesizedExpression(
519527
Expression outerExpression, Expression innerExpression);
520528

529+
/// Call this method just after visiting the right hand side of a pattern
530+
/// assignment expression, and before visiting the pattern.
531+
///
532+
/// [rhs] is the right hand side expression.
533+
void patternAssignment_afterRhs(Expression rhs);
534+
535+
/// Call this method after visiting a pattern assignment expression.
536+
void patternAssignment_end();
537+
521538
/// Call this method just after visiting the initializer of a pattern variable
522539
/// declaration, and before visiting the pattern.
523540
void patternVariableDeclaration_afterInitializer(Expression initializer);
@@ -746,12 +763,6 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
746763
/// statement.
747764
void tryFinallyStatement_finallyBegin(Node body);
748765

749-
/// Call this method after visiting a variable pattern.
750-
///
751-
/// [matchedType] should be the static type of the value being matched.
752-
/// [staticType] should be the static type of the variable pattern itself.
753-
void variablePattern({required Type matchedType, required Type staticType});
754-
755766
/// Call this method when encountering an expression that reads the value of
756767
/// a variable.
757768
///
@@ -950,6 +961,16 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
950961
() => _wrapped.declare(variable, initialized));
951962
}
952963

964+
@override
965+
void declaredVariablePattern(
966+
{required Type matchedType, required Type staticType}) {
967+
_wrap(
968+
'declaredVariablePattern(matchedType: $matchedType, '
969+
'staticType: $staticType)',
970+
() => _wrapped.declaredVariablePattern(
971+
matchedType: matchedType, staticType: staticType));
972+
}
973+
953974
@override
954975
void doStatement_bodyBegin(Statement doStatement) {
955976
return _wrap('doStatement_bodyBegin($doStatement)',
@@ -1243,6 +1264,17 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
12431264
_wrapped.parenthesizedExpression(outerExpression, innerExpression));
12441265
}
12451266

1267+
@override
1268+
void patternAssignment_afterRhs(Expression rhs) {
1269+
_wrap('patternAssignment_afterRhs($rhs)',
1270+
() => _wrapped.patternAssignment_afterRhs(rhs));
1271+
}
1272+
1273+
@override
1274+
void patternAssignment_end() {
1275+
_wrap('patternAssignment_end()', () => _wrapped.patternAssignment_end());
1276+
}
1277+
12461278
@override
12471279
void patternVariableDeclaration_afterInitializer(Expression initializer) {
12481280
_wrap(
@@ -1405,14 +1437,6 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
14051437
() => _wrapped.tryFinallyStatement_finallyBegin(body));
14061438
}
14071439

1408-
@override
1409-
void variablePattern({required Type matchedType, required Type staticType}) {
1410-
_wrap(
1411-
'variablePattern(matchedType: $matchedType, staticType: $staticType)',
1412-
() => _wrapped.variablePattern(
1413-
matchedType: matchedType, staticType: staticType));
1414-
}
1415-
14161440
@override
14171441
Type? variableRead(Expression expression, Variable variable) {
14181442
return _wrap('variableRead($expression, $variable)',
@@ -3371,6 +3395,25 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
33713395
promotionKeyStore.keyForVariable(variable), initialized);
33723396
}
33733397

3398+
@override
3399+
void declaredVariablePattern(
3400+
{required Type matchedType, required Type staticType}) {
3401+
_PatternContext<Type> context = _stack.last as _PatternContext<Type>;
3402+
ReferenceWithType<Type>? scrutineeReference = context._scrutineeReference;
3403+
bool coversMatchedType =
3404+
typeOperations.isSubtypeOf(matchedType, staticType);
3405+
if (scrutineeReference != null) {
3406+
ExpressionInfo<Type> promotionInfo =
3407+
_current.tryPromoteForTypeCheck(this, scrutineeReference, staticType);
3408+
_current = promotionInfo.ifTrue;
3409+
if (!coversMatchedType) {
3410+
context._unmatched = _join(context._unmatched, promotionInfo.ifFalse);
3411+
}
3412+
} else if (!coversMatchedType) {
3413+
context._unmatched = _join(context._unmatched, _current);
3414+
}
3415+
}
3416+
33743417
@override
33753418
void doStatement_bodyBegin(Statement doStatement) {
33763419
AssignedVariablesNodeInfo info =
@@ -3848,6 +3891,16 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
38483891
forwardExpression(outerExpression, innerExpression);
38493892
}
38503893

3894+
@override
3895+
void patternAssignment_afterRhs(Expression rhs) {
3896+
_pushPattern(_getExpressionReference(rhs));
3897+
}
3898+
3899+
@override
3900+
void patternAssignment_end() {
3901+
_popPattern(null);
3902+
}
3903+
38513904
@override
38523905
void patternVariableDeclaration_afterInitializer(Expression initializer) {
38533906
_pushPattern(_getExpressionReference(initializer));
@@ -4048,24 +4101,6 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
40484101
context._beforeFinally = _current;
40494102
}
40504103

4051-
@override
4052-
void variablePattern({required Type matchedType, required Type staticType}) {
4053-
_PatternContext<Type> context = _stack.last as _PatternContext<Type>;
4054-
ReferenceWithType<Type>? scrutineeReference = context._scrutineeReference;
4055-
bool coversMatchedType =
4056-
typeOperations.isSubtypeOf(matchedType, staticType);
4057-
if (scrutineeReference != null) {
4058-
ExpressionInfo<Type> promotionInfo =
4059-
_current.tryPromoteForTypeCheck(this, scrutineeReference, staticType);
4060-
_current = promotionInfo.ifTrue;
4061-
if (!coversMatchedType) {
4062-
context._unmatched = _join(context._unmatched, promotionInfo.ifFalse);
4063-
}
4064-
} else if (!coversMatchedType) {
4065-
context._unmatched = _join(context._unmatched, _current);
4066-
}
4067-
}
4068-
40694104
@override
40704105
Type? variableRead(Expression expression, Variable variable) {
40714106
int variableKey = promotionKeyStore.keyForVariable(variable);
@@ -4510,6 +4545,10 @@ class _LegacyTypePromotion<Node extends Object, Statement extends Node,
45104545
@override
45114546
void declare(Variable variable, bool initialized) {}
45124547

4548+
@override
4549+
void declaredVariablePattern(
4550+
{required Type matchedType, required Type staticType}) {}
4551+
45134552
@override
45144553
void doStatement_bodyBegin(Statement doStatement) {}
45154554

@@ -4778,6 +4817,12 @@ class _LegacyTypePromotion<Node extends Object, Statement extends Node,
47784817
forwardExpression(outerExpression, innerExpression);
47794818
}
47804819

4820+
@override
4821+
void patternAssignment_afterRhs(Expression rhs) {}
4822+
4823+
@override
4824+
void patternAssignment_end() {}
4825+
47814826
@override
47824827
void patternVariableDeclaration_afterInitializer(Expression initializer) {}
47834828

@@ -4858,9 +4903,6 @@ class _LegacyTypePromotion<Node extends Object, Statement extends Node,
48584903
@override
48594904
void tryFinallyStatement_finallyBegin(Node body) {}
48604905

4861-
@override
4862-
void variablePattern({required Type matchedType, required Type staticType}) {}
4863-
48644906
@override
48654907
Type? variableRead(Expression expression, Variable variable) {
48664908
int variableKey = _promotionKeyStore.keyForVariable(variable);

0 commit comments

Comments
 (0)