Flow analysis: remove `Reference` type hierarchy.
Previously, flow analysis used the class `ReferenceWithType` to track
references for which it knew the type, and `Reference` (and its
subclasses) to track references for which it didn't know the type (or
for which the type was unimportant).
This change removes the `Reference` class hierarchy, in favor of just
using the integer promotion keys. This should reduce the number of
memory allocations that flow analysis needs to make.
A few pieces of information previously maintained by the `Reference`
class hierarchy are now tracked elsewhere: the logic for computing
non-promotion reasons is now in
`_FlowAnalysisImpl._getNonPromotionReasons`, and the property name and
property member (previously maintained by `_PropertyGetReference`) is
now maintained by `_PropertyReferenceWithType` (a new subclass of
`ReferenceWithType`).
Bug: https://github.com/dart-lang/language/issues/2020
Change-Id: I72f2d80b3256bf8b9c9a30bcc55666ecb7c31e47
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250242
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index 39f7c88d..57df318 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -295,7 +295,7 @@
return sb.toString();
}
- Variable variableForKey(int key) => _promotionKeyStore.variableForKey(key);
+ Variable variableForKey(int key) => _promotionKeyStore.variableForKey(key)!;
Set<int> writtenInNode(Node node) => _getInfoForNode(node)._written;
}
@@ -1833,13 +1833,11 @@
///
/// A local variable is [initialized] if its declaration has an initializer.
/// A function parameter is always initialized, so [initialized] is `true`.
- FlowModel<Type> declare<Variable extends Object>(
- Variable variable, int variableKey, bool initialized) {
+ FlowModel<Type> declare(int variableKey, bool initialized) {
VariableModel<Type> newInfoForVar =
new VariableModel.fresh(assigned: initialized);
- return _updateVariableInfo(
- new VariableReference(variable, variableKey), newInfoForVar);
+ return _updateVariableInfo(variableKey, newInfoForVar);
}
/// Gets the info for the given [promotionKey], creating it if it doesn't
@@ -1997,10 +1995,11 @@
///
/// Note that the state is only changed if the previous type of [variable] was
/// potentially nullable.
- ExpressionInfo<Type> tryMarkNonNullable(TypeOperations<Type> typeOperations,
- ReferenceWithType<Type> referenceWithType) {
- VariableModel<Type> info =
- referenceWithType.reference.getInfo(variableInfo);
+ ExpressionInfo<Type> tryMarkNonNullable(
+ TypeOperations<Type> typeOperations,
+ ReferenceWithType<Type> referenceWithType,
+ PromotionKeyStore<Object> promotionKeyStore) {
+ VariableModel<Type> info = _getInfo(referenceWithType.promotionKey);
if (info.writeCaptured) {
return new _TrivialExpressionInfo<Type>(this);
}
@@ -2012,8 +2011,8 @@
}
assert(typeOperations.isSubtypeOf(newType, previousType));
- FlowModel<Type> ifTrue = _finishTypeTest(
- typeOperations, referenceWithType.reference, info, null, newType);
+ FlowModel<Type> ifTrue = _finishTypeTest(typeOperations, referenceWithType,
+ info, null, newType, promotionKeyStore);
return new ExpressionInfo<Type>(after: this, ifTrue: ifTrue, ifFalse: this);
}
@@ -2027,10 +2026,12 @@
///
/// TODO(paulberry): if the type is non-nullable, should this method mark the
/// variable as definitely assigned? Does it matter?
- FlowModel<Type> tryPromoteForTypeCast(TypeOperations<Type> typeOperations,
- ReferenceWithType<Type> referenceWithType, Type type) {
- VariableModel<Type> info =
- referenceWithType.reference.getInfo(variableInfo);
+ FlowModel<Type> tryPromoteForTypeCast(
+ TypeOperations<Type> typeOperations,
+ ReferenceWithType<Type> referenceWithType,
+ Type type,
+ PromotionKeyStore<Object> promotionKeyStore) {
+ VariableModel<Type> info = _getInfo(referenceWithType.promotionKey);
if (info.writeCaptured) {
return this;
}
@@ -2043,8 +2044,8 @@
assert(typeOperations.isSubtypeOf(newType, previousType),
"Expected $newType to be a subtype of $previousType.");
- return _finishTypeTest(
- typeOperations, referenceWithType.reference, info, type, newType);
+ return _finishTypeTest(typeOperations, referenceWithType, info, type,
+ newType, promotionKeyStore);
}
/// Returns an [ExpressionInfo] indicating the result of checking whether the
@@ -2059,9 +2060,9 @@
ExpressionInfo<Type> tryPromoteForTypeCheck(
TypeOperations<Type> typeOperations,
ReferenceWithType<Type> referenceWithType,
- Type type) {
- VariableModel<Type> info =
- referenceWithType.reference.getInfo(variableInfo);
+ Type type,
+ PromotionKeyStore<Object> promotionKeyStore) {
+ VariableModel<Type> info = _getInfo(referenceWithType.promotionKey);
if (info.writeCaptured) {
return new _TrivialExpressionInfo<Type>(this);
}
@@ -2073,8 +2074,8 @@
!typeOperations.isSameType(typeIfSuccess, previousType)) {
assert(typeOperations.isSubtypeOf(typeIfSuccess, previousType),
"Expected $typeIfSuccess to be a subtype of $previousType.");
- ifTrue = _finishTypeTest(typeOperations, referenceWithType.reference,
- info, type, typeIfSuccess);
+ ifTrue = _finishTypeTest(typeOperations, referenceWithType, info, type,
+ typeIfSuccess, promotionKeyStore);
}
Type factoredType = typeOperations.factor(previousType, type);
@@ -2089,8 +2090,8 @@
} else {
typeIfFalse = factoredType;
}
- FlowModel<Type> ifFalse = _finishTypeTest(
- typeOperations, referenceWithType.reference, info, type, typeIfFalse);
+ FlowModel<Type> ifFalse = _finishTypeTest(typeOperations, referenceWithType,
+ info, type, typeIfFalse, promotionKeyStore);
return new ExpressionInfo<Type>(
after: this, ifTrue: ifTrue, ifFalse: ifFalse);
@@ -2135,8 +2136,7 @@
promoteToTypeOfInterest: promoteToTypeOfInterest);
if (identical(newInfoForVar, infoForVar)) return this;
- return _updateVariableInfo(
- new VariableReference(variable, variableKey), newInfoForVar);
+ return _updateVariableInfo(variableKey, newInfoForVar);
}
/// Common algorithm for [tryMarkNonNullable], [tryPromoteForTypeCast],
@@ -2151,12 +2151,12 @@
/// no redundant or side-promotions)
/// - The variable should not be write-captured.
FlowModel<Type> _finishTypeTest(
- TypeOperations<Type> typeOperations,
- Reference<Type> reference,
- VariableModel<Type> info,
- Type? testedType,
- Type? promotedType,
- ) {
+ TypeOperations<Type> typeOperations,
+ ReferenceWithType<Type> reference,
+ VariableModel<Type> info,
+ Type? testedType,
+ Type? promotedType,
+ PromotionKeyStore<Object> promotionKeyStore) {
List<Type> newTested = info.tested;
if (testedType != null) {
newTested = VariableModel._addTypeToUniqueList(
@@ -2168,7 +2168,7 @@
if (promotedType != null) {
newPromotedTypes =
VariableModel._addToPromotedTypes(info.promotedTypes, promotedType);
- if (reference is VariableReference<Object, Object> &&
+ if (reference.isPromotable(promotionKeyStore) &&
typeOperations.isNever(promotedType)) {
newReachable = reachable.setUnreachable();
}
@@ -2179,7 +2179,7 @@
newReachable == reachable
? this
: _updateVariableInfo(
- reference,
+ reference.promotionKey,
new VariableModel<Type>(
promotedTypes: newPromotedTypes,
tested: newTested,
@@ -2190,15 +2190,20 @@
reachable: newReachable);
}
+ /// Gets the info for [promotionKey] reference, creating it if it doesn't
+ /// exist.
+ VariableModel<Type> _getInfo(int promotionKey) =>
+ variableInfo[promotionKey] ?? new VariableModel<Type>.fresh();
+
/// Returns a new [FlowModel] where the information for [reference] is
/// replaced with [model].
FlowModel<Type> _updateVariableInfo(
- Reference<Type> reference, VariableModel<Type> model,
+ int promotionKey, VariableModel<Type> model,
{Reachability? reachable}) {
reachable ??= this.reachable;
Map<int, VariableModel<Type>> newVariableInfo =
new Map<int, VariableModel<Type>>.of(variableInfo);
- reference.storeInfo(newVariableInfo, model);
+ newVariableInfo[promotionKey] = model;
return new FlowModel<Type>.withInfo(reachable, newVariableInfo);
}
@@ -2445,7 +2450,7 @@
_variableKeys[variable] ??= _makeNewKey(variable);
@visibleForTesting
- Variable variableForKey(int variableKey) => _keyToVariable[variableKey]!;
+ Variable? variableForKey(int variableKey) => _keyToVariable[variableKey];
int _makeNewKey(Variable? variable) {
int key = _keyToVariable.length;
@@ -2626,60 +2631,20 @@
}
}
-/// Abstract base class representing a reference to a storage location that
-/// might be of interest to flow analysis to track. This could be a variable,
-/// `this`, or the result of a property access on some other reference.
-///
-/// Note that only variables can undergo promotion, but flow analysis may track
-/// other references in order to give useful error messages to the user about
-/// why promotion did not occur.
-@visibleForTesting
-abstract class Reference<Type extends Object> {
- /// The reference's corresponding key, as assigned by [PromotionKeyStore].
- final int promotionKey;
-
- Reference(this.promotionKey);
-
- /// Gets the info for this reference, creating it if it doesn't exist.
- VariableModel<Type> getInfo(Map<int, VariableModel<Type>> variableInfo) =>
- _getInfo(variableInfo) ?? new VariableModel<Type>.fresh();
-
- /// Gets a map of non-promotion reasons associated with this reference. This
- /// is the map that will be returned from [FlowAnalysis.whyNotPromoted].
- Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
- Map<int, VariableModel<Type>> variableInfo,
- Type staticType,
- TypeOperations<Type> operations);
-
- /// Creates a reference representing a get of a property called [propertyName]
- /// on the reference represented by `this`.
- Reference<Type> propertyGet(PromotionKeyStore promotionKeyStore,
- String propertyName, Object? propertyMember) =>
- new _PropertyGetReference<Type>(propertyName, propertyMember,
- promotionKeyStore.getProperty(promotionKey, propertyName));
-
- /// Stores info for this reference in [variableInfo].
- void storeInfo(Map<int, VariableModel<Type>> variableInfo,
- VariableModel<Type> variableModel) {
- variableInfo[promotionKey] = variableModel;
- }
-
- /// Gets the info for this reference, or `null` if it doesn't exist.
- VariableModel<Type>? _getInfo(Map<int, VariableModel<Type>> variableInfo) =>
- variableInfo[promotionKey];
-}
-
/// Container object combining a [Reference] object with its static type.
@visibleForTesting
class ReferenceWithType<Type extends Object> {
- final Reference<Type> reference;
+ int promotionKey;
final Type type;
- ReferenceWithType(this.reference, this.type);
+ ReferenceWithType(this.promotionKey, this.type);
+
+ bool isPromotable(PromotionKeyStore<Object> promotionKeyStore) =>
+ promotionKeyStore.variableForKey(promotionKey) != null;
@override
- String toString() => 'ReferenceWithType($reference, $type)';
+ String toString() => 'ReferenceWithType($promotionKey, $type)';
}
/// Data structure representing a unique value that a variable might take on
@@ -3352,46 +3317,6 @@
Type variableType(Variable variable);
}
-/// Specialization of [Reference] representing a reference to a local variable
-/// (or function parameter).
-@visibleForTesting
-class VariableReference<Variable extends Object, Type extends Object>
- extends Reference<Type> {
- /// The variable being referred to.
- final Variable variable;
-
- VariableReference(this.variable, super.promotionKey);
-
- @override
- Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
- Map<int, VariableModel<Type>> variableInfo,
- Type staticType,
- covariant Operations<Variable, Type> operations) {
- VariableModel<Type>? currentVariableInfo = variableInfo[promotionKey];
- if (currentVariableInfo == null) {
- return () => {};
- }
- return () {
- Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
- Type currentType = currentVariableInfo.promotedTypes?.last ??
- operations.variableType(variable);
- NonPromotionHistory? nonPromotionHistory =
- currentVariableInfo.nonPromotionHistory;
- while (nonPromotionHistory != null) {
- Type nonPromotedType = nonPromotionHistory.type;
- if (!operations.isSubtypeOf(currentType, nonPromotedType)) {
- result[nonPromotedType] ??= nonPromotionHistory.nonPromotionReason;
- }
- nonPromotionHistory = nonPromotionHistory.previous;
- }
- return result;
- };
- }
-
- @override
- String toString() => 'VariableReference($variable, $promotionKey)';
-}
-
class WhyNotPromotedInfo {}
/// [_FlowContext] representing an assert statement or assert initializer.
@@ -3526,8 +3451,7 @@
Set<int> implicitlyDeclaredVars = {...anywhere._read, ...anywhere._written};
implicitlyDeclaredVars.removeAll(anywhere._declared);
for (int variableKey in implicitlyDeclaredVars) {
- _current = _current.declare(
- _promotionKeyStore.variableForKey(variableKey), variableKey, true);
+ _current = _current.declare(variableKey, true);
}
}
@@ -3539,8 +3463,8 @@
ReferenceWithType<Type>? referenceWithType =
_getExpressionReference(subExpression);
if (referenceWithType == null) return;
- _current =
- _current.tryPromoteForTypeCast(operations, referenceWithType, type);
+ _current = _current.tryPromoteForTypeCast(
+ operations, referenceWithType, type, _promotionKeyStore);
}
@override
@@ -3613,7 +3537,7 @@
@override
void declare(Variable variable, bool initialized) {
_current = _current.declare(
- variable, _promotionKeyStore.keyForVariable(variable), initialized);
+ _promotionKeyStore.keyForVariable(variable), initialized);
}
@override
@@ -3676,14 +3600,14 @@
// either result is possible.
} else if (leftOperandInfo._expressionInfo is _NullInfo<Type> &&
rhsReference != null) {
- ExpressionInfo<Type> equalityInfo =
- _current.tryMarkNonNullable(operations, rhsReference);
+ ExpressionInfo<Type> equalityInfo = _current.tryMarkNonNullable(
+ operations, rhsReference, _promotionKeyStore);
_storeExpressionInfo(
wholeExpression, notEqual ? equalityInfo : equalityInfo.invert());
} else if (rightOperandInfo._expressionInfo is _NullInfo<Type> &&
lhsReference != null) {
- ExpressionInfo<Type> equalityInfo =
- _current.tryMarkNonNullable(operations, lhsReference);
+ ExpressionInfo<Type> equalityInfo = _current.tryMarkNonNullable(
+ operations, lhsReference, _promotionKeyStore);
_storeExpressionInfo(
wholeExpression, notEqual ? equalityInfo : equalityInfo.invert());
}
@@ -3821,8 +3745,8 @@
FlowModel<Type> promoted;
_current = _current.split();
if (lhsReference != null) {
- ExpressionInfo<Type> promotionInfo =
- _current.tryMarkNonNullable(operations, lhsReference);
+ ExpressionInfo<Type> promotionInfo = _current.tryMarkNonNullable(
+ operations, lhsReference, _promotionKeyStore);
_current = promotionInfo.ifFalse;
promoted = promotionInfo.ifTrue;
} else {
@@ -3893,10 +3817,10 @@
_current = _current
.tryPromoteForTypeCheck(
operations,
- new ReferenceWithType<Type>(
- new VariableReference<Variable, Type>(variable, variableKey),
+ new ReferenceWithType<Type>(variableKey,
promotedType(variable) ?? operations.variableType(variable)),
- initializerType)
+ initializerType,
+ _promotionKeyStore)
.ifTrue;
}
}
@@ -3915,7 +3839,7 @@
_getExpressionReference(subExpression);
if (subExpressionReference != null) {
ExpressionInfo<Type> expressionInfo = _current.tryPromoteForTypeCheck(
- operations, subExpressionReference, type);
+ operations, subExpressionReference, type, _promotionKeyStore);
_storeExpressionInfo(
isExpression, isNot ? expressionInfo.invert() : expressionInfo);
}
@@ -4011,8 +3935,9 @@
ReferenceWithType<Type>? operandReference =
_getExpressionReference(operand);
if (operandReference != null) {
- _current =
- _current.tryMarkNonNullable(operations, operandReference).ifTrue;
+ _current = _current
+ .tryMarkNonNullable(operations, operandReference, _promotionKeyStore)
+ .ifTrue;
}
}
@@ -4031,8 +3956,9 @@
_stack.add(new _NullAwareAccessContext<Type>(_current));
ReferenceWithType<Type>? targetReference = _getExpressionReference(target);
if (targetReference != null) {
- _current =
- _current.tryMarkNonNullable(operations, targetReference).ifTrue;
+ _current = _current
+ .tryMarkNonNullable(operations, targetReference, _promotionKeyStore)
+ .ifTrue;
}
}
@@ -4058,13 +3984,14 @@
@override
void propertyGet(Expression wholeExpression, Expression target,
String propertyName, Object? propertyMember, Type staticType) {
- Reference<Type>? reference = _getExpressionReference(target)?.reference;
- if (reference != null) {
+ int? targetKey = _getExpressionReference(target)?.promotionKey;
+ if (targetKey != null) {
_storeExpressionReference(
wholeExpression,
- new ReferenceWithType<Type>(
- reference.propertyGet(
- _promotionKeyStore, propertyName, propertyMember),
+ new _PropertyReferenceWithType<Type>(
+ propertyName,
+ propertyMember,
+ _promotionKeyStore.getProperty(targetKey, propertyName),
staticType));
}
}
@@ -4116,8 +4043,7 @@
_storeExpressionReference(
expression,
new ReferenceWithType<Type>(
- new _ThisReference<Type>(_promotionKeyStore.thisPromotionKey),
- staticType));
+ _promotionKeyStore.thisPromotionKey, staticType));
}
@override
@@ -4125,9 +4051,11 @@
Object? propertyMember, Type staticType) {
_storeExpressionReference(
expression,
- new ReferenceWithType<Type>(
- new _ThisReference<Type>(_promotionKeyStore.thisPromotionKey)
- .propertyGet(_promotionKeyStore, propertyName, propertyMember),
+ new _PropertyReferenceWithType<Type>(
+ propertyName,
+ propertyMember,
+ _promotionKeyStore.getProperty(
+ _promotionKeyStore.thisPromotionKey, propertyName),
staticType));
}
@@ -4160,14 +4088,12 @@
if (exceptionVariable != null) {
int exceptionVariableKey =
_promotionKeyStore.keyForVariable(exceptionVariable);
- _current =
- _current.declare(exceptionVariable, exceptionVariableKey, true);
+ _current = _current.declare(exceptionVariableKey, true);
}
if (stackTraceVariable != null) {
int stackTraceVariableKey =
_promotionKeyStore.keyForVariable(stackTraceVariable);
- _current =
- _current.declare(stackTraceVariable, stackTraceVariableKey, true);
+ _current = _current.declare(stackTraceVariableKey, true);
}
}
@@ -4210,14 +4136,11 @@
@override
Type? variableRead(Expression expression, Variable variable) {
int variableKey = _promotionKeyStore.keyForVariable(variable);
- VariableReference<Variable, Type> variableReference =
- new VariableReference<Variable, Type>(variable, variableKey);
- VariableModel<Type> variableModel =
- variableReference.getInfo(_current.variableInfo);
+ VariableModel<Type> variableModel = _current._getInfo(variableKey);
Type? promotedType = variableModel.promotedTypes?.last;
Type currentType = promotedType ?? operations.variableType(variable);
- _storeExpressionReference(expression,
- new ReferenceWithType<Type>(variableReference, currentType));
+ _storeExpressionReference(
+ expression, new ReferenceWithType<Type>(variableKey, currentType));
ExpressionInfo<Type>? expressionInfo = variableModel.ssaNode?.expressionInfo
?.rebaseForward(operations, _current);
if (expressionInfo != null) {
@@ -4256,8 +4179,12 @@
if (identical(target, _expressionWithReference)) {
ReferenceWithType<Type>? referenceWithType = _expressionReference;
if (referenceWithType != null) {
- return referenceWithType.reference.getNonPromotionReasons(
- _current.variableInfo, referenceWithType.type, operations);
+ VariableModel<Type>? currentVariableInfo =
+ _current.variableInfo[referenceWithType.promotionKey];
+ if (currentVariableInfo != null) {
+ return _getNonPromotionReasons(
+ referenceWithType, currentVariableInfo);
+ }
}
}
return () => {};
@@ -4266,8 +4193,15 @@
@override
Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
Type staticType) {
- return new _ThisReference<Type>(_promotionKeyStore.thisPromotionKey)
- .getNonPromotionReasons(_current.variableInfo, staticType, operations);
+ VariableModel<Type>? currentThisInfo =
+ _current.variableInfo[_promotionKeyStore.thisPromotionKey];
+ if (currentThisInfo == null) {
+ return () => {};
+ }
+ return _getNonPromotionReasons(
+ new ReferenceWithType<Type>(
+ _promotionKeyStore.thisPromotionKey, staticType),
+ currentThisInfo);
}
@override
@@ -4335,6 +4269,57 @@
}
}
+ Map<Type, NonPromotionReason> Function() _getNonPromotionReasons(
+ ReferenceWithType<Type> reference,
+ VariableModel<Type> currentVariableInfo) {
+ if (reference is _PropertyReferenceWithType<Type>) {
+ List<Type>? promotedTypes = currentVariableInfo.promotedTypes;
+ if (promotedTypes != null) {
+ return () {
+ Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+ for (Type type in promotedTypes) {
+ result[type] = new PropertyNotPromoted(reference.propertyName,
+ reference.propertyMember, reference.type);
+ }
+ return result;
+ };
+ }
+ } else {
+ Variable? variable =
+ _promotionKeyStore.variableForKey(reference.promotionKey);
+ if (variable == null) {
+ List<Type>? promotedTypes = currentVariableInfo.promotedTypes;
+ if (promotedTypes != null) {
+ return () {
+ Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+ for (Type type in promotedTypes) {
+ result[type] = new ThisNotPromoted();
+ }
+ return result;
+ };
+ }
+ } else {
+ return () {
+ Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+ Type currentType = currentVariableInfo.promotedTypes?.last ??
+ operations.variableType(variable);
+ NonPromotionHistory? nonPromotionHistory =
+ currentVariableInfo.nonPromotionHistory;
+ while (nonPromotionHistory != null) {
+ Type nonPromotedType = nonPromotionHistory.type;
+ if (!operations.isSubtypeOf(currentType, nonPromotedType)) {
+ result[nonPromotedType] ??=
+ nonPromotionHistory.nonPromotionReason;
+ }
+ nonPromotionHistory = nonPromotionHistory.previous;
+ }
+ return result;
+ };
+ }
+ }
+ return () => {};
+ }
+
FlowModel<Type> _join(FlowModel<Type>? first, FlowModel<Type>? second) =>
FlowModel.join(operations, first, second, _current._emptyVariableMap);
@@ -4991,41 +4976,24 @@
null;
}
-/// [Reference] object representing a property get applied to another reference.
-class _PropertyGetReference<Type extends Object> extends Reference<Type> {
+/// [ReferenceWithType] object representing a property get.
+class _PropertyReferenceWithType<Type extends Object>
+ extends ReferenceWithType<Type> {
/// The name of the property.
final String propertyName;
- /// The field or property being accessed. This matches a `propertyMember`
+ /// /// The field or property being accessed. This matches a `propertyMember`
/// value that was passed to either [FlowAnalysis.propertyGet] or
/// [FlowAnalysis.thisOrSuperPropertyGet].
final Object? propertyMember;
- _PropertyGetReference(
- this.propertyName, this.propertyMember, super.promotionKey);
-
- @override
- Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
- Map<int, VariableModel<Type>> variableInfo,
- Type staticType,
- TypeOperations<Type> typeOperations) {
- List<Type>? promotedTypes = _getInfo(variableInfo)?.promotedTypes;
- if (promotedTypes != null) {
- return () {
- Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
- for (Type type in promotedTypes) {
- result[type] =
- new PropertyNotPromoted(propertyName, propertyMember, staticType);
- }
- return result;
- };
- }
- return () => {};
- }
+ _PropertyReferenceWithType(
+ this.propertyName, this.propertyMember, super.promotionKey, super.type);
@override
String toString() =>
- '_PropertyGetReference($propertyName, $propertyMember, $promotionKey)';
+ '_PropertyReferenceWithType($propertyName, $propertyMember, '
+ '$promotionKey, $type)';
}
/// [_FlowContext] representing a language construct for which flow analysis
@@ -5061,29 +5029,6 @@
'checkpoint: $_checkpoint)';
}
-/// [Reference] object representing an implicit or explicit reference to `this`.
-class _ThisReference<Type extends Object> extends Reference<Type> {
- _ThisReference(super.promotionKey);
-
- @override
- Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
- Map<int, VariableModel<Type>> variableInfo,
- Type staticType,
- TypeOperations<Type> typeOperations) {
- List<Type>? promotedTypes = _getInfo(variableInfo)?.promotedTypes;
- if (promotedTypes != null) {
- return () {
- Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
- for (Type type in promotedTypes) {
- result[type] = new ThisNotPromoted();
- }
- return result;
- };
- }
- return () => {};
- }
-}
-
/// Specialization of [ExpressionInfo] for the case where the information we
/// have about the expression is trivial (meaning we know by construction that
/// the expression's [after], [ifTrue], and [ifFalse] models are all the same).
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index d2195c0..e6ee94a 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -5923,21 +5923,21 @@
for (Var v in capturedVariables) _promotionKeyStore.keyForVariable(v)
]);
- FlowModel<Type> _declare(Var variable, bool initialized) => this.declare(
- variable, _promotionKeyStore.keyForVariable(variable), initialized);
+ FlowModel<Type> _declare(Var variable, bool initialized) =>
+ this.declare(_promotionKeyStore.keyForVariable(variable), initialized);
VariableModel<Type> _infoFor(Var variable) =>
infoFor(_promotionKeyStore.keyForVariable(variable));
ExpressionInfo<Type> _tryMarkNonNullable(Harness h, Var variable) =>
- tryMarkNonNullable(h, _varRefWithType(variable));
+ tryMarkNonNullable(h, _varRefWithType(variable), _promotionKeyStore);
ExpressionInfo<Type> _tryPromoteForTypeCheck(
Harness h, Var variable, String type) =>
- tryPromoteForTypeCheck(h, _varRefWithType(variable), Type(type));
+ tryPromoteForTypeCheck(
+ h, _varRefWithType(variable), Type(type), _promotionKeyStore);
- Reference<Type> _varRef(Var variable) => new VariableReference<Var, Type>(
- variable, _promotionKeyStore.keyForVariable(variable));
+ int _varRef(Var variable) => _promotionKeyStore.keyForVariable(variable);
ReferenceWithType<Type> _varRefWithType(Var variable) =>
new ReferenceWithType<Type>(