@@ -970,6 +970,34 @@ abstract class FlowAnalysis<
970970 Type unpromotedType,
971971 );
972972
973+ /// The promotion chain associated with the property named [propertyName] .
974+ ///
975+ /// **For testing only!**
976+ ///
977+ /// The promotion chain only contains the promoted-to types, not the original
978+ /// declared type at the top of the chain. Thus, the list is empty if the
979+ /// property is not currently promoted.
980+ ///
981+ /// The type of [target] determines how the property is looked up:
982+ /// - If [target] is an [ExpressionPropertyTarget] , a property of an
983+ /// expression is queried, and this method should be called just after
984+ /// calling the method(s) that would normally be called when performing flow
985+ /// analysis on the target expression (e.g., [propertyGet] or
986+ /// [variableRead] ).
987+ /// - If [target] is [ThisPropertyTarget] , a property of `this` is queried.
988+ /// - If [target] is [SuperPropertyTarget] , a property of `super` is queried.
989+ ///
990+ /// [propertyMember] should be whatever data structure the client uses to keep
991+ /// track of the field or property being accessed. If not `null` , and field
992+ /// promotion is enabled for the current library,
993+ /// [FlowAnalysisOperations.isPropertyPromotable] will be consulted to find
994+ /// out whether the property is promotable.
995+ List <Type > propertyPromotionChainForTesting (
996+ PropertyTarget <Expression > target,
997+ String propertyName,
998+ Object ? propertyMember,
999+ );
1000+
9731001 /// Call this method just before analyzing a subpattern of an object pattern.
9741002 ///
9751003 /// [propertyName] is the name of the property being accessed by this
@@ -1181,6 +1209,15 @@ abstract class FlowAnalysis<
11811209 /// statement.
11821210 void tryFinallyStatement_finallyBegin (Node body);
11831211
1212+ /// The promotion chain associated with [variable] .
1213+ ///
1214+ /// **For testing only!**
1215+ ///
1216+ /// The promotion chain only contains the promoted-to types, not the original
1217+ /// declared type at the top of the chain. Thus, the list is empty if the
1218+ /// variable is not currently promoted.
1219+ List <Type > variablePromotionChainForTesting (Variable variable);
1220+
11841221 /// Call this method when encountering an expression that reads the value of
11851222 /// a variable.
11861223 ///
@@ -2179,6 +2216,24 @@ class FlowAnalysisDebug<
21792216 );
21802217 }
21812218
2219+ @override
2220+ List <Type > propertyPromotionChainForTesting (
2221+ PropertyTarget <Expression > target,
2222+ String propertyName,
2223+ Object ? propertyMember,
2224+ ) {
2225+ return _wrap (
2226+ 'propertyPromotionChainForTesting($target , $propertyName , '
2227+ '$propertyMember )' ,
2228+ () => _wrapped.propertyPromotionChainForTesting (
2229+ target,
2230+ propertyName,
2231+ propertyMember,
2232+ ),
2233+ isQuery: true ,
2234+ );
2235+ }
2236+
21822237 @override
21832238 Type ? pushPropertySubpattern (
21842239 String propertyName,
@@ -2375,6 +2430,15 @@ class FlowAnalysisDebug<
23752430 );
23762431 }
23772432
2433+ @override
2434+ List <Type > variablePromotionChainForTesting (Variable variable) {
2435+ return _wrap (
2436+ 'variablePromotionChainForTesting($variable )' ,
2437+ () => _wrapped.variablePromotionChainForTesting (variable),
2438+ isQuery: true ,
2439+ );
2440+ }
2441+
23782442 @override
23792443 Type ? variableRead (Expression expression, Variable variable) {
23802444 return _wrap (
@@ -6382,6 +6446,36 @@ class _FlowAnalysisImpl<
63826446 return promotedType;
63836447 }
63846448
6449+ @override
6450+ List <Type > propertyPromotionChainForTesting (
6451+ PropertyTarget <Expression > target,
6452+ String propertyName,
6453+ Object ? propertyMember,
6454+ ) {
6455+ SsaNode <Type >? targetSsaNode = target._getSsaNode (this );
6456+ if (targetSsaNode == null ) return const [];
6457+ // Find the SSA node for the target of the property access, and figure out
6458+ // whether the property in question is promotable.
6459+ bool isPromotable =
6460+ propertyMember != null &&
6461+ typeAnalyzerOptions.fieldPromotionEnabled &&
6462+ operations.isPropertyPromotable (propertyMember);
6463+ if (! isPromotable) return const [];
6464+ _PropertySsaNode <Type > propertySsaNode = targetSsaNode
6465+ .getOrCreatePropertyNode (
6466+ propertyName,
6467+ promotionKeyStore,
6468+ isPromotable: isPromotable,
6469+ );
6470+ PromotionModel <Type >? promotionInfo = _current.promotionInfo? .get (
6471+ this ,
6472+ propertySsaNode.promotionKey,
6473+ );
6474+ if (promotionInfo == null ) return const [];
6475+ assert (promotionInfo.ssaNode == propertySsaNode);
6476+ return promotionInfo.promotedTypes ?? const [];
6477+ }
6478+
63856479 @override
63866480 Type ? pushPropertySubpattern (
63876481 String propertyName,
@@ -6687,6 +6781,13 @@ class _FlowAnalysisImpl<
66876781 context._beforeFinally = _current;
66886782 }
66896783
6784+ @override
6785+ List <Type > variablePromotionChainForTesting (Variable variable) =>
6786+ _current.promotionInfo
6787+ ? .get (this , promotionKeyStore.keyForVariable (variable))
6788+ ? .promotedTypes ??
6789+ const [];
6790+
66906791 @override
66916792 Type ? variableRead (Expression expression, Variable variable) {
66926793 Type unpromotedType = operations.variableType (variable);
0 commit comments