@@ -2566,12 +2566,8 @@ class _EqualityOpContext<Variable, Type> extends _BranchContext {
25662566 /// The type of the expression on the LHS of `==` or `!=` .
25672567 final Type _leftOperandType;
25682568
2569- /// If the LHS of `==` or `!=` is a variable reference, the variable.
2570- /// Otherwise `null` .
2571- final Variable _leftOperandVariable;
2572-
2573- _EqualityOpContext (ExpressionInfo <Variable , Type > conditionInfo,
2574- this ._leftOperandType, this ._leftOperandVariable)
2569+ _EqualityOpContext (
2570+ ExpressionInfo <Variable , Type > conditionInfo, this ._leftOperandType)
25752571 : super (conditionInfo);
25762572
25772573 @override
@@ -2606,14 +2602,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
26062602 /// corresponding to it. Otherwise `null` .
26072603 ExpressionInfo <Variable , Type > _expressionInfo;
26082604
2609- /// The most recently visited expression which was a variable reference, or
2610- /// `null` if no expression has been visited that was a variable reference.
2611- Expression _expressionWithVariable;
2612-
2613- /// If [_expressionVariable] is not `null` , the variable corresponding to it.
2614- /// Otherwise `null` .
2615- Variable _expressionVariable;
2616-
26172605 int _functionNestingLevel = 0 ;
26182606
26192607 final AssignedVariables <Node , Variable > _assignedVariables;
@@ -2627,8 +2615,14 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
26272615
26282616 @override
26292617 void asExpression_end (Expression subExpression, Type type) {
2630- Variable variable = _getExpressionVariable (subExpression);
2631- if (variable == null ) return ;
2618+ ExpressionInfo <Variable , Type > subExpressionInfo =
2619+ _getExpressionInfo (subExpression);
2620+ Variable variable;
2621+ if (subExpressionInfo is _VariableReadInfo <Variable , Type >) {
2622+ variable = subExpressionInfo._variable;
2623+ } else {
2624+ return ;
2625+ }
26322626 _current = _current.tryPromoteForTypeCast (typeOperations, variable, type);
26332627 }
26342628
@@ -2736,10 +2730,8 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
27362730 _EqualityOpContext <Variable , Type > context =
27372731 _stack.removeLast () as _EqualityOpContext <Variable , Type >;
27382732 ExpressionInfo <Variable , Type > lhsInfo = context._conditionInfo;
2739- Variable lhsVariable = context._leftOperandVariable;
27402733 Type leftOperandType = context._leftOperandType;
27412734 ExpressionInfo <Variable , Type > rhsInfo = _getExpressionInfo (rightOperand);
2742- Variable rhsVariable = _getExpressionVariable (rightOperand);
27432735 TypeClassification leftOperandTypeClassification =
27442736 typeOperations.classifyType (leftOperandType);
27452737 TypeClassification rightOperandTypeClassification =
@@ -2757,16 +2749,18 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
27572749 // but weak mode it might produce an "equal" result. We don't want flow
27582750 // analysis behavior to depend on mode, so we conservatively assume that
27592751 // either result is possible.
2760- } else if (lhsInfo is _NullInfo <Variable , Type > && rhsVariable != null ) {
2752+ } else if (lhsInfo is _NullInfo <Variable , Type > &&
2753+ rhsInfo is _VariableReadInfo <Variable , Type >) {
27612754 assert (
27622755 leftOperandTypeClassification == TypeClassification .nullOrEquivalent);
27632756 ExpressionInfo <Variable , Type > equalityInfo =
2764- _current.tryMarkNonNullable (typeOperations, rhsVariable );
2757+ _current.tryMarkNonNullable (typeOperations, rhsInfo._variable );
27652758 _storeExpressionInfo (wholeExpression,
27662759 notEqual ? equalityInfo : ExpressionInfo .invert (equalityInfo));
2767- } else if (rhsInfo is _NullInfo <Variable , Type > && lhsVariable != null ) {
2760+ } else if (rhsInfo is _NullInfo <Variable , Type > &&
2761+ lhsInfo is _VariableReadInfo <Variable , Type >) {
27682762 ExpressionInfo <Variable , Type > equalityInfo =
2769- _current.tryMarkNonNullable (typeOperations, lhsVariable );
2763+ _current.tryMarkNonNullable (typeOperations, lhsInfo._variable );
27702764 _storeExpressionInfo (wholeExpression,
27712765 notEqual ? equalityInfo : ExpressionInfo .invert (equalityInfo));
27722766 }
@@ -2775,9 +2769,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
27752769 @override
27762770 void equalityOp_rightBegin (Expression leftOperand, Type leftOperandType) {
27772771 _stack.add (new _EqualityOpContext <Variable , Type >(
2778- _getExpressionInfo (leftOperand),
2779- leftOperandType,
2780- _getExpressionVariable (leftOperand)));
2772+ _getExpressionInfo (leftOperand), leftOperandType));
27812773 }
27822774
27832775 @override
@@ -2852,9 +2844,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
28522844 if (identical (_expressionWithInfo, oldExpression)) {
28532845 _expressionWithInfo = newExpression;
28542846 }
2855- if (identical (_expressionWithVariable, oldExpression)) {
2856- _expressionWithVariable = newExpression;
2857- }
28582847 }
28592848
28602849 @override
@@ -2912,12 +2901,12 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
29122901 @override
29132902 void ifNullExpression_rightBegin (
29142903 Expression leftHandSide, Type leftHandSideType) {
2915- Variable lhsVariable = _getExpressionVariable (leftHandSide);
2904+ ExpressionInfo < Variable , Type > lhsInfo = _getExpressionInfo (leftHandSide);
29162905 FlowModel <Variable , Type > promoted;
29172906 _current = _current.split ();
2918- if (lhsVariable != null ) {
2907+ if (lhsInfo is _VariableReadInfo < Variable , Type > ) {
29192908 ExpressionInfo <Variable , Type > promotionInfo =
2920- _current.tryMarkNonNullable (typeOperations, lhsVariable );
2909+ _current.tryMarkNonNullable (typeOperations, lhsInfo._variable );
29212910 _current = promotionInfo.ifFalse;
29222911 promoted = promotionInfo.ifTrue;
29232912 } else {
@@ -2970,10 +2959,12 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
29702959 @override
29712960 void isExpression_end (Expression isExpression, Expression subExpression,
29722961 bool isNot, Type type) {
2973- Variable subExpressionVariable = _getExpressionVariable (subExpression);
2974- if (subExpressionVariable != null ) {
2975- ExpressionInfo <Variable , Type > expressionInfo = _current
2976- .tryPromoteForTypeCheck (typeOperations, subExpressionVariable, type);
2962+ ExpressionInfo <Variable , Type > subExpressionInfo =
2963+ _getExpressionInfo (subExpression);
2964+ if (subExpressionInfo is _VariableReadInfo <Variable , Type >) {
2965+ ExpressionInfo <Variable , Type > expressionInfo =
2966+ _current.tryPromoteForTypeCheck (
2967+ typeOperations, subExpressionInfo._variable, type);
29772968 _storeExpressionInfo (isExpression,
29782969 isNot ? ExpressionInfo .invert (expressionInfo) : expressionInfo);
29792970 }
@@ -3063,10 +3054,11 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
30633054
30643055 @override
30653056 void nonNullAssert_end (Expression operand) {
3066- Variable operandVariable = _getExpressionVariable (operand);
3067- if (operandVariable != null ) {
3068- _current =
3069- _current.tryMarkNonNullable (typeOperations, operandVariable).ifTrue;
3057+ ExpressionInfo <Variable , Type > operandInfo = _getExpressionInfo (operand);
3058+ if (operandInfo is _VariableReadInfo <Variable , Type >) {
3059+ _current = _current
3060+ .tryMarkNonNullable (typeOperations, operandInfo._variable)
3061+ .ifTrue;
30703062 }
30713063 }
30723064
@@ -3083,10 +3075,11 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
30833075 _current = _current.split ();
30843076 _stack.add (new _NullAwareAccessContext <Variable , Type >(_current));
30853077 if (target != null ) {
3086- Variable targetVariable = _getExpressionVariable (target);
3087- if (targetVariable != null ) {
3088- _current =
3089- _current.tryMarkNonNullable (typeOperations, targetVariable).ifTrue;
3078+ ExpressionInfo <Variable , Type > targetInfo = _getExpressionInfo (target);
3079+ if (targetInfo is _VariableReadInfo <Variable , Type >) {
3080+ _current = _current
3081+ .tryMarkNonNullable (typeOperations, targetInfo._variable)
3082+ .ifTrue;
30903083 }
30913084 }
30923085 }
@@ -3233,7 +3226,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
32333226
32343227 @override
32353228 Type variableRead (Expression expression, Variable variable) {
3236- _storeExpressionVariable (expression, variable);
3229+ _storeExpressionInfo (expression, new _VariableReadInfo (_current, variable) );
32373230 return _current.infoFor (variable).promotedTypes? .last;
32383231 }
32393232
@@ -3280,8 +3273,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
32803273 print (' current: $_current ' );
32813274 print (' expressionWithInfo: $_expressionWithInfo ' );
32823275 print (' expressionInfo: $_expressionInfo ' );
3283- print (' expressionWithVariable: $_expressionWithVariable ' );
3284- print (' expressionVariable: $_expressionVariable ' );
32853276 print (' stack:' );
32863277 for (_FlowContext stackEntry in _stack.reversed) {
32873278 print (' $stackEntry ' );
@@ -3310,19 +3301,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
33103301 }
33113302 }
33123303
3313- /// Gets the [Variable] associated with the [expression] (which should be the
3314- /// last expression that was traversed). If there is no [Variable] associated
3315- /// with the [expression] , then `null` is returned.
3316- Variable _getExpressionVariable (Expression expression) {
3317- if (identical (expression, _expressionWithVariable)) {
3318- Variable expressionVariable = _expressionVariable;
3319- _expressionVariable = null ;
3320- return expressionVariable;
3321- } else {
3322- return null ;
3323- }
3324- }
3325-
33263304 FlowModel <Variable , Type > _join (
33273305 FlowModel <Variable , Type > first, FlowModel <Variable , Type > second) =>
33283306 FlowModel .join (typeOperations, first, second, _current._emptyVariableMap);
@@ -3341,14 +3319,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
33413319 _expressionInfo = expressionInfo;
33423320 _current = expressionInfo.after;
33433321 }
3344-
3345- /// Associates [expression] , which should be the most recently visited
3346- /// expression, with the given [Variable] object.
3347- void _storeExpressionVariable (
3348- Expression expression, Variable expressionVariable) {
3349- _expressionWithVariable = expression;
3350- _expressionVariable = expressionVariable;
3351- }
33523322}
33533323
33543324/// Base class for objects representing constructs in the Dart programming
@@ -3467,6 +3437,28 @@ class _TryContext<Variable, Type> extends _SimpleContext<Variable, Type> {
34673437 'afterBodyAndCatches: $_afterBodyAndCatches )' ;
34683438}
34693439
3440+ /// [ExpressionInfo] representing an expression that reads the value of a
3441+ /// variable.
3442+ class _VariableReadInfo <Variable , Type >
3443+ implements ExpressionInfo <Variable , Type > {
3444+ @override
3445+ final FlowModel <Variable , Type > after;
3446+
3447+ /// The variable that is being read.
3448+ final Variable _variable;
3449+
3450+ _VariableReadInfo (this .after, this ._variable);
3451+
3452+ @override
3453+ FlowModel <Variable , Type > get ifFalse => after;
3454+
3455+ @override
3456+ FlowModel <Variable , Type > get ifTrue => after;
3457+
3458+ @override
3459+ String toString () => '_VariableReadInfo(after: $after , variable: $_variable )' ;
3460+ }
3461+
34703462/// [_FlowContext] representing a `while` loop (or a C-style `for` loop, which
34713463/// is functionally similar).
34723464class _WhileContext <Variable , Type >
0 commit comments