[cfe] Remove state from InferenceVisitor
This adds a _MapLiteralEntryOffsets class used to collect information
during map entry inferences instead of passing it through fields
on the visitor itself.
Change-Id: Id575bc56b8fce707fb038a695bfe347ca4d6432d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247964
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 4549c6b..d52aaff 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -48,18 +48,6 @@
Class? mapEntryClass;
- // Stores the offset of the map entry found by inferMapEntry.
- int? mapEntryOffset = null;
-
- // Stores the offset of the map spread found by inferMapEntry.
- int? mapSpreadOffset = null;
-
- // Stores the offset of the iterable spread found by inferMapEntry.
- int? iterableSpreadOffset = null;
-
- // Stores the type of the iterable spread found by inferMapEntry.
- DartType? iterableSpreadType = null;
-
InferenceVisitor(this.inferrer);
/// Computes uri and offset for [node] for internal errors in a way that is
@@ -2174,7 +2162,8 @@
Map<TreeNode, DartType> inferredSpreadTypes,
Map<Expression, DartType> inferredConditionTypes,
bool inferenceNeeded,
- bool typeChecksNeeded) {
+ bool typeChecksNeeded,
+ _MapLiteralEntryOffsets offsets) {
if (entry is SpreadMapEntry) {
ExpressionInferenceResult spreadResult = inferrer.inferExpression(
entry.expression, spreadContext, inferenceNeeded || typeChecksNeeded,
@@ -2230,7 +2219,7 @@
// Don't report the error here, it might be an ambiguous Set. The
// error is reported in checkMapEntry if it's disambiguated as map.
- iterableSpreadType = spreadType;
+ offsets.iterableSpreadType = spreadType;
} else {
Expression receiver = entry.expression;
Expression problem = inferrer.helper.buildProblem(
@@ -2389,10 +2378,10 @@
inferrer.coreTypes.iterableRawType(inferrer.libraryBuilder.nullable),
SubtypeCheckMode.withNullabilities);
if (isMap && !isIterable) {
- mapSpreadOffset = entry.fileOffset;
+ offsets.mapSpreadOffset = entry.fileOffset;
}
if (!isMap && isIterable) {
- iterableSpreadOffset = entry.expression.fileOffset;
+ offsets.iterableSpreadOffset = entry.expression.fileOffset;
}
return replacement;
@@ -2421,9 +2410,9 @@
inferredSpreadTypes,
inferredConditionTypes,
inferenceNeeded,
- typeChecksNeeded);
+ typeChecksNeeded,
+ offsets);
entry.then = then..parent = entry;
- MapLiteralEntry otherwise;
if (entry.otherwise != null) {
inferrer.flowAnalysis.ifStatement_elseBegin();
// We need to modify the actual types added in the recursive call to
@@ -2431,7 +2420,7 @@
DartType? actualValueType = actualTypes.removeLast();
DartType? actualKeyType = actualTypes.removeLast();
DartType actualTypeForSet = actualTypesForSet.removeLast();
- otherwise = inferMapEntry(
+ MapLiteralEntry otherwise = inferMapEntry(
entry.otherwise!,
entry,
inferredKeyType,
@@ -2442,7 +2431,8 @@
inferredSpreadTypes,
inferredConditionTypes,
inferenceNeeded,
- typeChecksNeeded);
+ typeChecksNeeded,
+ offsets);
int length = actualTypes.length;
actualTypes[length - 2] = inferrer.typeSchemaEnvironment
.getStandardUpperBound(actualKeyType, actualTypes[length - 2],
@@ -2524,7 +2514,8 @@
inferredSpreadTypes,
inferredConditionTypes,
inferenceNeeded,
- typeChecksNeeded);
+ typeChecksNeeded,
+ offsets);
entry.body = body..parent = entry;
inferrer.flowAnalysis.for_updaterBegin();
for (int index = 0; index < entry.updates.length; index++) {
@@ -2576,7 +2567,8 @@
inferredSpreadTypes,
inferredConditionTypes,
inferenceNeeded,
- typeChecksNeeded);
+ typeChecksNeeded,
+ offsets);
entry.body = body..parent = entry;
// This is matched by the call to [forEach_bodyBegin] in
// [handleForInWithoutVariable] or [handleForInDeclaringVariable].
@@ -2603,7 +2595,7 @@
actualTypes.add(valueResult.inferredType);
// Use 'dynamic' for error recovery.
actualTypesForSet.add(const DynamicType());
- mapEntryOffset = entry.fileOffset;
+ offsets.mapEntryOffset = entry.fileOffset;
return entry;
}
}
@@ -2613,18 +2605,19 @@
DartType keyType,
DartType valueType,
Map<TreeNode, DartType> inferredSpreadTypes,
- Map<Expression, DartType> inferredConditionTypes) {
+ Map<Expression, DartType> inferredConditionTypes,
+ _MapLiteralEntryOffsets offsets) {
// It's disambiguated as a map literal.
MapLiteralEntry replacement = entry;
- if (iterableSpreadOffset != null) {
+ if (offsets.iterableSpreadOffset != null) {
replacement = new MapLiteralEntry(
inferrer.helper.buildProblem(
templateSpreadMapEntryTypeMismatch.withArguments(
- iterableSpreadType!, inferrer.isNonNullableByDefault),
- iterableSpreadOffset!,
+ offsets.iterableSpreadType!, inferrer.isNonNullableByDefault),
+ offsets.iterableSpreadOffset!,
1),
new NullLiteral())
- ..fileOffset = iterableSpreadOffset!;
+ ..fileOffset = offsets.iterableSpreadOffset!;
}
if (entry is SpreadMapEntry) {
DartType? spreadType = inferredSpreadTypes[entry.expression];
@@ -2638,11 +2631,11 @@
}
} else if (entry is IfMapEntry) {
MapLiteralEntry then = checkMapEntry(entry.then, keyType, valueType,
- inferredSpreadTypes, inferredConditionTypes);
+ inferredSpreadTypes, inferredConditionTypes, offsets);
entry.then = then..parent = entry;
if (entry.otherwise != null) {
MapLiteralEntry otherwise = checkMapEntry(entry.otherwise!, keyType,
- valueType, inferredSpreadTypes, inferredConditionTypes);
+ valueType, inferredSpreadTypes, inferredConditionTypes, offsets);
entry.otherwise = otherwise..parent = entry;
}
} else if (entry is ForMapEntry) {
@@ -2655,11 +2648,11 @@
entry.condition = condition..parent = entry;
}
MapLiteralEntry body = checkMapEntry(entry.body, keyType, valueType,
- inferredSpreadTypes, inferredConditionTypes);
+ inferredSpreadTypes, inferredConditionTypes, offsets);
entry.body = body..parent = entry;
} else if (entry is ForInMapEntry) {
MapLiteralEntry body = checkMapEntry(entry.body, keyType, valueType,
- inferredSpreadTypes, inferredConditionTypes);
+ inferredSpreadTypes, inferredConditionTypes, offsets);
entry.body = body..parent = entry;
} else {
// Do nothing. Assignability checks are done during type inference.
@@ -2735,11 +2728,8 @@
bool hasMapEntry = false;
bool hasMapSpread = false;
bool hasIterableSpread = false;
+ _MapLiteralEntryOffsets offsets = new _MapLiteralEntryOffsets();
if (inferenceNeeded || typeChecksNeeded) {
- mapEntryOffset = null;
- mapSpreadOffset = null;
- iterableSpreadOffset = null;
- iterableSpreadType = null;
DartType spreadTypeContext = const UnknownType();
if (typeContextIsIterable && !typeContextIsMap) {
spreadTypeContext = inferrer.typeSchemaEnvironment.getTypeAsInstanceOf(
@@ -2754,9 +2744,8 @@
<DartType>[inferredKeyType, inferredValueType]);
}
for (int index = 0; index < node.entries.length; ++index) {
- MapLiteralEntry entry = node.entries[index];
- entry = inferMapEntry(
- entry,
+ MapLiteralEntry entry = inferMapEntry(
+ node.entries[index],
node,
inferredKeyType,
inferredValueType,
@@ -2766,16 +2755,17 @@
inferredSpreadTypes!,
inferredConditionTypes!,
inferenceNeeded,
- typeChecksNeeded);
+ typeChecksNeeded,
+ offsets);
node.entries[index] = entry..parent = node;
if (inferenceNeeded) {
formalTypes!.add(mapType.typeArguments[0]);
formalTypes.add(mapType.typeArguments[1]);
}
}
- hasMapEntry = mapEntryOffset != null;
- hasMapSpread = mapSpreadOffset != null;
- hasIterableSpread = iterableSpreadOffset != null;
+ hasMapEntry = offsets.mapEntryOffset != null;
+ hasMapSpread = offsets.mapSpreadOffset != null;
+ hasIterableSpread = offsets.iterableSpreadOffset != null;
}
if (inferenceNeeded) {
bool canBeSet = !hasMapSpread && !hasMapEntry && !typeContextIsMap;
@@ -2880,8 +2870,13 @@
}
if (typeChecksNeeded) {
for (int index = 0; index < node.entries.length; ++index) {
- MapLiteralEntry entry = checkMapEntry(node.entries[index], node.keyType,
- node.valueType, inferredSpreadTypes!, inferredConditionTypes!);
+ MapLiteralEntry entry = checkMapEntry(
+ node.entries[index],
+ node.keyType,
+ node.valueType,
+ inferredSpreadTypes!,
+ inferredConditionTypes!,
+ offsets);
node.entries[index] = entry..parent = node;
}
}
@@ -7348,3 +7343,18 @@
_UriOffset(this.uri, this.fileOffset);
}
+
+/// Offset and type information collection in [InferenceVisitor.inferMapEntry].
+class _MapLiteralEntryOffsets {
+ // Stores the offset of the map entry found by inferMapEntry.
+ int? mapEntryOffset;
+
+ // Stores the offset of the map spread found by inferMapEntry.
+ int? mapSpreadOffset;
+
+ // Stores the offset of the iterable spread found by inferMapEntry.
+ int? iterableSpreadOffset;
+
+ // Stores the type of the iterable spread found by inferMapEntry.
+ DartType? iterableSpreadType;
+}