[cfe] Merge TypeConstraintGatherer and TypeSchemaConstraintGatherer
This is a follow up to
https://dart-review.googlesource.com/c/sdk/+/349881
Now that there's only one implementation of TypeConstraintGatherer, it
can be merged with the abstract class.
Change-Id: Iaf50548da2841c7dfb51126de9f746fac1a8ad0d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/350242
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
index 911154c..8259e27 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
@@ -4,8 +4,6 @@
import 'package:kernel/ast.dart';
-import 'package:kernel/core_types.dart';
-
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
@@ -20,40 +18,37 @@
/// Creates a collection of [TypeConstraint]s corresponding to type parameters,
/// based on an attempt to make one type schema a subtype of another.
-abstract class TypeConstraintGatherer {
+class TypeConstraintGatherer {
final List<_ProtoConstraint> _protoConstraints = [];
final List<StructuralParameter> _parametersToConstrain;
- final bool isNonNullableByDefault;
+ final bool _isNonNullableByDefault;
final OperationsCfe _typeOperations;
- /// Creates a [TypeConstraintGatherer] which is prepared to gather type
- /// constraints for the given [typeParameters].
- TypeConstraintGatherer.subclassing(
- Iterable<StructuralParameter> typeParameters,
- {required this.isNonNullableByDefault,
- required OperationsCfe typeOperations})
- : _parametersToConstrain = typeParameters.toList(),
- _typeOperations = typeOperations;
+ final TypeSchemaEnvironment _environment;
- factory TypeConstraintGatherer(TypeSchemaEnvironment environment,
- Iterable<StructuralParameter> typeParameters,
+ TypeConstraintGatherer(
+ this._environment, Iterable<StructuralParameter> typeParameters,
{required bool isNonNullableByDefault,
- required OperationsCfe typeOperations}) {
- return new TypeSchemaConstraintGatherer(environment, typeParameters,
- isNonNullableByDefault: isNonNullableByDefault,
- typeOperations: typeOperations);
- }
-
- CoreTypes get coreTypes;
+ required OperationsCfe typeOperations})
+ : _typeOperations = typeOperations,
+ _isNonNullableByDefault = isNonNullableByDefault,
+ _parametersToConstrain =
+ new List<StructuralParameter>.of(typeParameters);
void addUpperBound(TypeConstraint constraint, DartType upper,
- {required bool isNonNullableByDefault});
+ {required bool isNonNullableByDefault}) {
+ _environment.addUpperBound(constraint, upper,
+ isNonNullableByDefault: isNonNullableByDefault);
+ }
void addLowerBound(TypeConstraint constraint, DartType lower,
- {required bool isNonNullableByDefault});
+ {required bool isNonNullableByDefault}) {
+ _environment.addLowerBound(constraint, lower,
+ isNonNullableByDefault: isNonNullableByDefault);
+ }
/// Applies all the argument constraints implied by trying to make
/// [actualTypes] assignable to [formalTypes].
@@ -67,15 +62,22 @@
}
}
- Member? getInterfaceMember(Class class_, Name name, {bool setter = false});
+ Member? getInterfaceMember(Class class_, Name name, {bool setter = false}) {
+ return _environment.hierarchy
+ .getInterfaceMember(class_, name, setter: setter);
+ }
List<DartType>? getTypeArgumentsAsInstanceOf(
- TypeDeclarationType type, TypeDeclaration typeDeclaration);
+ TypeDeclarationType type, TypeDeclaration typeDeclaration) {
+ return _environment.getTypeArgumentsAsInstanceOf(type, typeDeclaration);
+ }
List<DartType>? getExtensionTypeArgumentsAsInstanceOf(
- ExtensionType type, ExtensionTypeDeclaration superclass);
-
- InterfaceType futureType(DartType type, Nullability nullability);
+ ExtensionType type, ExtensionTypeDeclaration superclass) {
+ return _environment.hierarchy
+ .getExtensionTypeArgumentsAsInstanceOfExtensionTypeDeclaration(
+ type, superclass);
+ }
/// Returns the set of type constraints that was gathered.
Map<StructuralParameter, TypeConstraint> computeConstraints(
@@ -101,7 +103,7 @@
/// Doesn't change the already accumulated set of constraints if [bound] isn't
/// a subtype of [type] under any set of constraints.
bool tryConstrainLower(DartType type, DartType bound) {
- if (isNonNullableByDefault) {
+ if (_isNonNullableByDefault) {
return _tryNullabilityAwareSubtypeMatch(bound, type,
constrainSupertype: true);
} else {
@@ -114,7 +116,7 @@
/// Doesn't change the already accumulated set of constraints if [type] isn't
/// a subtype of [bound] under any set of constraints.
bool tryConstrainUpper(DartType type, DartType bound) {
- if (isNonNullableByDefault) {
+ if (_isNonNullableByDefault) {
return _tryNullabilityAwareSubtypeMatch(type, bound,
constrainSupertype: false);
} else {
@@ -440,7 +442,7 @@
// condition will always fail for them.
if (p is StructuralParameterType &&
isStructuralParameterTypeWithoutNullabilityMarker(p,
- isNonNullableByDefault: isNonNullableByDefault) &&
+ isNonNullableByDefault: _isNonNullableByDefault) &&
_parametersToConstrain.contains(p.parameter)) {
_constrainParameterUpper(p.parameter, q);
return true;
@@ -454,7 +456,7 @@
// condition will always fail for them.
if (q is StructuralParameterType &&
isStructuralParameterTypeWithoutNullabilityMarker(q,
- isNonNullableByDefault: isNonNullableByDefault) &&
+ isNonNullableByDefault: _isNonNullableByDefault) &&
_parametersToConstrain.contains(q.parameter)) {
_constrainParameterLower(q.parameter, p);
return true;
@@ -474,10 +476,10 @@
//
// Only if P0 is a subtype match for Q under constraint set C.
if (isLegacyTypeConstructorApplication(p,
- isNonNullableByDefault: isNonNullableByDefault)) {
+ isNonNullableByDefault: _isNonNullableByDefault)) {
return _isNullabilityAwareSubtypeMatch(
computeTypeWithoutNullabilityMarker(p,
- isNonNullableByDefault: isNonNullableByDefault),
+ isNonNullableByDefault: _isNonNullableByDefault),
q,
constrainSupertype: constrainSupertype);
}
@@ -489,14 +491,14 @@
// Or if P is not dynamic or void and P is a subtype match for Q0? under
// constraint set C.
if (isLegacyTypeConstructorApplication(q,
- isNonNullableByDefault: isNonNullableByDefault)) {
+ isNonNullableByDefault: _isNonNullableByDefault)) {
final int baseConstraintCount = _protoConstraints.length;
if ((p is DynamicType || p is VoidType) &&
_isNullabilityAwareSubtypeMatch(
p,
computeTypeWithoutNullabilityMarker(q,
- isNonNullableByDefault: isNonNullableByDefault),
+ isNonNullableByDefault: _isNonNullableByDefault),
constrainSupertype: constrainSupertype)) {
return true;
}
@@ -530,7 +532,7 @@
_protoConstraints.length = baseConstraintCount;
bool isMatchWithFuture = _isNullabilityAwareSubtypeMatch(
- p, futureType(q.typeArgument, Nullability.nonNullable),
+ p, _environment.futureType(q.typeArgument, Nullability.nonNullable),
constrainSupertype: constrainSupertype);
bool matchWithFutureAddsConstraints =
_protoConstraints.length != baseConstraintCount;
@@ -562,9 +564,9 @@
if (isNullableTypeConstructorApplication(q)) {
final int baseConstraintCount = _protoConstraints.length;
final DartType rawP = computeTypeWithoutNullabilityMarker(p,
- isNonNullableByDefault: isNonNullableByDefault);
+ isNonNullableByDefault: _isNonNullableByDefault);
final DartType rawQ = computeTypeWithoutNullabilityMarker(q,
- isNonNullableByDefault: isNonNullableByDefault);
+ isNonNullableByDefault: _isNonNullableByDefault);
if (isNullableTypeConstructorApplication(p) &&
_isNullabilityAwareSubtypeMatch(rawP, rawQ,
@@ -575,7 +577,7 @@
if ((p is DynamicType || p is VoidType) &&
_isNullabilityAwareSubtypeMatch(
- coreTypes.objectNonNullableRawType, rawQ,
+ _environment.coreTypes.objectNonNullableRawType, rawQ,
constrainSupertype: constrainSupertype)) {
return true;
}
@@ -609,7 +611,8 @@
if (p is FutureOrType) {
final int baseConstraintCount = _protoConstraints.length;
if (_isNullabilityAwareSubtypeMatch(
- futureType(p.typeArgument, Nullability.nonNullable), q,
+ _environment.futureType(p.typeArgument, Nullability.nonNullable),
+ q,
constrainSupertype: constrainSupertype) &&
_isNullabilityAwareSubtypeMatch(p.typeArgument, q,
constrainSupertype: constrainSupertype)) {
@@ -626,7 +629,7 @@
final int baseConstraintCount = _protoConstraints.length;
if (_isNullabilityAwareSubtypeMatch(
computeTypeWithoutNullabilityMarker(p,
- isNonNullableByDefault: isNonNullableByDefault),
+ isNonNullableByDefault: _isNonNullableByDefault),
q,
constrainSupertype: constrainSupertype) &&
_isNullabilityAwareSubtypeMatch(const NullType(), q,
@@ -640,7 +643,7 @@
// constraints.
if (q is DynamicType ||
q is VoidType ||
- q == coreTypes.objectNullableRawType) {
+ q == _environment.coreTypes.objectNullableRawType) {
return true;
}
@@ -652,7 +655,7 @@
// If Q is Object, then the match holds under no constraints:
//
// Only if P is non-nullable.
- if (q == coreTypes.objectNonNullableRawType) {
+ if (q == _environment.coreTypes.objectNonNullableRawType) {
return p.nullability == Nullability.nonNullable;
}
@@ -745,7 +748,8 @@
// If Q is Function then the match holds under no constraints:
//
// If P is a function type.
- if (q == coreTypes.functionNonNullableRawType && p is FunctionType) {
+ if (q == _environment.coreTypes.functionNonNullableRawType &&
+ p is FunctionType) {
return true;
}
@@ -871,8 +875,9 @@
structuralEliminationTargets: p.typeParameters.toSet(),
nominalEliminationTargets: {},
bottomType: const NeverType.nonNullable(),
- topType: coreTypes.objectNullableRawType,
- topFunctionType: coreTypes.functionNonNullableRawType,
+ topType: _environment.coreTypes.objectNullableRawType,
+ topFunctionType:
+ _environment.coreTypes.functionNonNullableRawType,
unhandledTypeHandler: (DartType type, ignored) =>
type is UnknownType
? false
@@ -897,7 +902,8 @@
// constraints:
//
// If P is a record type or Record.
- if (q == coreTypes.recordNonNullableRawType && p is RecordType) {
+ if (q == _environment.coreTypes.recordNonNullableRawType &&
+ p is RecordType) {
return true;
}
@@ -1010,9 +1016,9 @@
// constraints `C0`.
// - And `P` is a subtype match for `Q` with respect to `L` under
// constraints `C1`.
- InterfaceType subtypeFuture = futureType(
+ InterfaceType subtypeFuture = _environment.futureType(
subtypeArg,
- isNonNullableByDefault
+ _isNonNullableByDefault
? Nullability.nonNullable
: Nullability.legacy);
return _isNullabilityObliviousSubtypeMatch(subtypeFuture, supertype) &&
@@ -1046,7 +1052,8 @@
supertype.typeArgument.nullability, supertype.nullability);
DartType supertypeArg =
supertype.typeArgument.withDeclaredNullability(unitedNullability);
- DartType supertypeFuture = futureType(supertypeArg, unitedNullability);
+ DartType supertypeFuture =
+ _environment.futureType(supertypeArg, unitedNullability);
// The match against FutureOr<X> succeeds if the match against either
// Future<X> or X succeeds. If they both succeed, the one adding new
@@ -1111,8 +1118,8 @@
}
if (subtype is FunctionType) {
if (supertype is InterfaceType) {
- return supertype == coreTypes.functionLegacyRawType ||
- supertype == coreTypes.objectLegacyRawType;
+ return supertype == _environment.coreTypes.functionLegacyRawType ||
+ supertype == _environment.coreTypes.objectLegacyRawType;
} else if (supertype is FunctionType) {
return _isFunctionSubtypeMatch(subtype, supertype);
}
@@ -1143,7 +1150,7 @@
bool _isTop(DartType type) =>
type is DynamicType ||
type is VoidType ||
- type == coreTypes.objectLegacyRawType;
+ type == _environment.coreTypes.objectLegacyRawType;
/// Given two lists of function type formal parameters, checks that their
/// bounds are compatible.
@@ -1181,60 +1188,6 @@
}
}
-class TypeSchemaConstraintGatherer extends TypeConstraintGatherer {
- final TypeSchemaEnvironment environment;
-
- TypeSchemaConstraintGatherer(
- this.environment, Iterable<StructuralParameter> typeParameters,
- {required bool isNonNullableByDefault,
- required OperationsCfe typeOperations})
- : super.subclassing(typeParameters,
- isNonNullableByDefault: isNonNullableByDefault,
- typeOperations: typeOperations);
-
- @override
- CoreTypes get coreTypes => environment.coreTypes;
-
- @override
- void addUpperBound(TypeConstraint constraint, DartType upper,
- {required bool isNonNullableByDefault}) {
- environment.addUpperBound(constraint, upper,
- isNonNullableByDefault: isNonNullableByDefault);
- }
-
- @override
- void addLowerBound(TypeConstraint constraint, DartType lower,
- {required bool isNonNullableByDefault}) {
- environment.addLowerBound(constraint, lower,
- isNonNullableByDefault: isNonNullableByDefault);
- }
-
- @override
- Member? getInterfaceMember(Class class_, Name name, {bool setter = false}) {
- return environment.hierarchy
- .getInterfaceMember(class_, name, setter: setter);
- }
-
- @override
- List<DartType>? getTypeArgumentsAsInstanceOf(
- TypeDeclarationType type, TypeDeclaration typeDeclaration) {
- return environment.getTypeArgumentsAsInstanceOf(type, typeDeclaration);
- }
-
- @override
- List<DartType>? getExtensionTypeArgumentsAsInstanceOf(
- ExtensionType type, ExtensionTypeDeclaration superclass) {
- return environment.hierarchy
- .getExtensionTypeArgumentsAsInstanceOfExtensionTypeDeclaration(
- type, superclass);
- }
-
- @override
- InterfaceType futureType(DartType type, Nullability nullability) {
- return environment.futureType(type, nullability);
- }
-}
-
/// Tracks a single constraint on a single type variable.
///
/// This is called "_ProtoConstraint" to distinguish from [TypeConstraint],