Skip to content

Commit e208c2c

Browse files
stereotype441Commit Queue
authored andcommitted
[flow analysis] Rework tests of try/finally ordering.
This change adds test-only methods `propertyPromotionChainForTesting` and `variablePromotionChainForTesting` to flow analysis; these are used by the flow analysis unit tests to query the full promotion chain of a porperty (or variable, respectively). This allows tests to observe the effect of try/finally ordering on promotion chains without having to resort to clever control flow joins. Thanks to Lasse for the suggestion. Change-Id: Ida5349ecc93dbd4b3392becd20882be3eb101024 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432800 Reviewed-by: Lasse Nielsen <[email protected]> Commit-Queue: Paul Berry <[email protected]>
1 parent bbc9994 commit e208c2c

File tree

3 files changed

+343
-260
lines changed

3 files changed

+343
-260
lines changed

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

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)