@@ -2566,12 +2566,8 @@ class _EqualityOpContext<Variable, Type> extends _BranchContext {
2566
2566
/// The type of the expression on the LHS of `==` or `!=` .
2567
2567
final Type _leftOperandType;
2568
2568
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)
2575
2571
: super (conditionInfo);
2576
2572
2577
2573
@override
@@ -2606,14 +2602,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
2606
2602
/// corresponding to it. Otherwise `null` .
2607
2603
ExpressionInfo <Variable , Type > _expressionInfo;
2608
2604
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
-
2617
2605
int _functionNestingLevel = 0 ;
2618
2606
2619
2607
final AssignedVariables <Node , Variable > _assignedVariables;
@@ -2627,8 +2615,14 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
2627
2615
2628
2616
@override
2629
2617
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
+ }
2632
2626
_current = _current.tryPromoteForTypeCast (typeOperations, variable, type);
2633
2627
}
2634
2628
@@ -2736,10 +2730,8 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
2736
2730
_EqualityOpContext <Variable , Type > context =
2737
2731
_stack.removeLast () as _EqualityOpContext <Variable , Type >;
2738
2732
ExpressionInfo <Variable , Type > lhsInfo = context._conditionInfo;
2739
- Variable lhsVariable = context._leftOperandVariable;
2740
2733
Type leftOperandType = context._leftOperandType;
2741
2734
ExpressionInfo <Variable , Type > rhsInfo = _getExpressionInfo (rightOperand);
2742
- Variable rhsVariable = _getExpressionVariable (rightOperand);
2743
2735
TypeClassification leftOperandTypeClassification =
2744
2736
typeOperations.classifyType (leftOperandType);
2745
2737
TypeClassification rightOperandTypeClassification =
@@ -2757,16 +2749,18 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
2757
2749
// but weak mode it might produce an "equal" result. We don't want flow
2758
2750
// analysis behavior to depend on mode, so we conservatively assume that
2759
2751
// 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 >) {
2761
2754
assert (
2762
2755
leftOperandTypeClassification == TypeClassification .nullOrEquivalent);
2763
2756
ExpressionInfo <Variable , Type > equalityInfo =
2764
- _current.tryMarkNonNullable (typeOperations, rhsVariable );
2757
+ _current.tryMarkNonNullable (typeOperations, rhsInfo._variable );
2765
2758
_storeExpressionInfo (wholeExpression,
2766
2759
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 >) {
2768
2762
ExpressionInfo <Variable , Type > equalityInfo =
2769
- _current.tryMarkNonNullable (typeOperations, lhsVariable );
2763
+ _current.tryMarkNonNullable (typeOperations, lhsInfo._variable );
2770
2764
_storeExpressionInfo (wholeExpression,
2771
2765
notEqual ? equalityInfo : ExpressionInfo .invert (equalityInfo));
2772
2766
}
@@ -2775,9 +2769,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
2775
2769
@override
2776
2770
void equalityOp_rightBegin (Expression leftOperand, Type leftOperandType) {
2777
2771
_stack.add (new _EqualityOpContext <Variable , Type >(
2778
- _getExpressionInfo (leftOperand),
2779
- leftOperandType,
2780
- _getExpressionVariable (leftOperand)));
2772
+ _getExpressionInfo (leftOperand), leftOperandType));
2781
2773
}
2782
2774
2783
2775
@override
@@ -2852,9 +2844,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
2852
2844
if (identical (_expressionWithInfo, oldExpression)) {
2853
2845
_expressionWithInfo = newExpression;
2854
2846
}
2855
- if (identical (_expressionWithVariable, oldExpression)) {
2856
- _expressionWithVariable = newExpression;
2857
- }
2858
2847
}
2859
2848
2860
2849
@override
@@ -2912,12 +2901,12 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
2912
2901
@override
2913
2902
void ifNullExpression_rightBegin (
2914
2903
Expression leftHandSide, Type leftHandSideType) {
2915
- Variable lhsVariable = _getExpressionVariable (leftHandSide);
2904
+ ExpressionInfo < Variable , Type > lhsInfo = _getExpressionInfo (leftHandSide);
2916
2905
FlowModel <Variable , Type > promoted;
2917
2906
_current = _current.split ();
2918
- if (lhsVariable != null ) {
2907
+ if (lhsInfo is _VariableReadInfo < Variable , Type > ) {
2919
2908
ExpressionInfo <Variable , Type > promotionInfo =
2920
- _current.tryMarkNonNullable (typeOperations, lhsVariable );
2909
+ _current.tryMarkNonNullable (typeOperations, lhsInfo._variable );
2921
2910
_current = promotionInfo.ifFalse;
2922
2911
promoted = promotionInfo.ifTrue;
2923
2912
} else {
@@ -2970,10 +2959,12 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
2970
2959
@override
2971
2960
void isExpression_end (Expression isExpression, Expression subExpression,
2972
2961
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);
2977
2968
_storeExpressionInfo (isExpression,
2978
2969
isNot ? ExpressionInfo .invert (expressionInfo) : expressionInfo);
2979
2970
}
@@ -3063,10 +3054,11 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
3063
3054
3064
3055
@override
3065
3056
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;
3070
3062
}
3071
3063
}
3072
3064
@@ -3083,10 +3075,11 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
3083
3075
_current = _current.split ();
3084
3076
_stack.add (new _NullAwareAccessContext <Variable , Type >(_current));
3085
3077
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;
3090
3083
}
3091
3084
}
3092
3085
}
@@ -3233,7 +3226,7 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
3233
3226
3234
3227
@override
3235
3228
Type variableRead (Expression expression, Variable variable) {
3236
- _storeExpressionVariable (expression, variable);
3229
+ _storeExpressionInfo (expression, new _VariableReadInfo (_current, variable) );
3237
3230
return _current.infoFor (variable).promotedTypes? .last;
3238
3231
}
3239
3232
@@ -3280,8 +3273,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
3280
3273
print (' current: $_current ' );
3281
3274
print (' expressionWithInfo: $_expressionWithInfo ' );
3282
3275
print (' expressionInfo: $_expressionInfo ' );
3283
- print (' expressionWithVariable: $_expressionWithVariable ' );
3284
- print (' expressionVariable: $_expressionVariable ' );
3285
3276
print (' stack:' );
3286
3277
for (_FlowContext stackEntry in _stack.reversed) {
3287
3278
print (' $stackEntry ' );
@@ -3310,19 +3301,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
3310
3301
}
3311
3302
}
3312
3303
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
-
3326
3304
FlowModel <Variable , Type > _join (
3327
3305
FlowModel <Variable , Type > first, FlowModel <Variable , Type > second) =>
3328
3306
FlowModel .join (typeOperations, first, second, _current._emptyVariableMap);
@@ -3341,14 +3319,6 @@ class _FlowAnalysisImpl<Node, Statement extends Node, Expression, Variable,
3341
3319
_expressionInfo = expressionInfo;
3342
3320
_current = expressionInfo.after;
3343
3321
}
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
- }
3352
3322
}
3353
3323
3354
3324
/// Base class for objects representing constructs in the Dart programming
@@ -3467,6 +3437,28 @@ class _TryContext<Variable, Type> extends _SimpleContext<Variable, Type> {
3467
3437
'afterBodyAndCatches: $_afterBodyAndCatches )' ;
3468
3438
}
3469
3439
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
+
3470
3462
/// [_FlowContext] representing a `while` loop (or a C-style `for` loop, which
3471
3463
/// is functionally similar).
3472
3464
class _WhileContext <Variable , Type >
0 commit comments