mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
Expose greatestLowerBound() from TypeSystem.
Bug: https://github.com/dart-lang/sdk/issues/53042 Change-Id: Ib332a7ab005a432d98066d79c2e48a5f06e88716 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/318000 Reviewed-by: Phil Quitslund <pquitslund@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
2edf0d3720
commit
8cb82a35e8
|
@ -1,6 +1,7 @@
|
|||
## 6.1.0-dev
|
||||
* Added `InstanceElement`, a super-interface for `InterfaceElement`
|
||||
and `ExtensionElement`.
|
||||
* Added `TypeSystem.greatestLowerBound`.
|
||||
|
||||
## 6.0.0
|
||||
* Remove deprecated `declaredElement2` from AST.
|
||||
|
|
|
@ -34,6 +34,12 @@ abstract class TypeSystem {
|
|||
/// Other type systems may define this operation differently.
|
||||
DartType flatten(DartType type);
|
||||
|
||||
/// Computes the greatest lower bound of [T1] and [T2].
|
||||
///
|
||||
/// https://github.com/dart-lang/language
|
||||
/// See `resources/type-system/upper-lower-bounds.md`
|
||||
DartType greatestLowerBound(DartType T1, DartType T2);
|
||||
|
||||
/// Instantiate the given [element] with default type arguments.
|
||||
InterfaceType instantiateInterfaceToBounds({
|
||||
required InterfaceElement element,
|
||||
|
@ -151,16 +157,11 @@ abstract class TypeSystem {
|
|||
/// Other type systems may define this operation differently.
|
||||
bool isSubtypeOf(DartType leftType, DartType rightType);
|
||||
|
||||
/// Compute the least upper bound of two types. This operation if commutative,
|
||||
/// meaning that `leastUpperBound(t, s) == leastUpperBound(s, t)` for all `t`
|
||||
/// and `s`.
|
||||
/// Computes the least upper bound of [T1] and [T2].
|
||||
///
|
||||
/// For the Dart 2.0 type system, the definition of the least upper bound is
|
||||
/// given in the Dart Language Specification, section 19.9.2 Least Upper
|
||||
/// Bounds.
|
||||
///
|
||||
/// Other type systems may define this operation differently.
|
||||
DartType leastUpperBound(DartType leftType, DartType rightType);
|
||||
/// https://github.com/dart-lang/language
|
||||
/// See `resources/type-system/upper-lower-bounds.md`
|
||||
DartType leastUpperBound(DartType T1, DartType T2);
|
||||
|
||||
/// Returns a non-nullable version of [type]. This is equivalent to the
|
||||
/// operation `NonNull` defined in the spec.
|
||||
|
|
|
@ -380,8 +380,8 @@ class GenericInferrer {
|
|||
//
|
||||
// This resulting constraint may be unsatisfiable; in that case inference
|
||||
// will fail.
|
||||
upper = _typeSystem.getGreatestLowerBound(upper, constraint.upperBound);
|
||||
lower = _typeSystem.getLeastUpperBound(lower, constraint.lowerBound);
|
||||
upper = _typeSystem.greatestLowerBound(upper, constraint.upperBound);
|
||||
lower = _typeSystem.leastUpperBound(lower, constraint.lowerBound);
|
||||
upper = _toLegacyElementIfOptOut(upper);
|
||||
lower = _toLegacyElementIfOptOut(lower);
|
||||
}
|
||||
|
|
|
@ -300,7 +300,7 @@ class GreatestLowerBoundHelper {
|
|||
gIndex++;
|
||||
parameters.add(
|
||||
fParameter.copyWith(
|
||||
type: _typeSystem.getLeastUpperBound(
|
||||
type: _typeSystem.leastUpperBound(
|
||||
fParameter.type,
|
||||
gParameter.type,
|
||||
),
|
||||
|
@ -320,7 +320,7 @@ class GreatestLowerBoundHelper {
|
|||
gIndex++;
|
||||
parameters.add(
|
||||
fParameter.copyWith(
|
||||
type: _typeSystem.getLeastUpperBound(
|
||||
type: _typeSystem.leastUpperBound(
|
||||
fParameter.type,
|
||||
gParameter.type,
|
||||
),
|
||||
|
|
|
@ -211,9 +211,9 @@ class InterfaceLeastUpperBoundHelper {
|
|||
Variance parameterVariance =
|
||||
(params[i] as TypeParameterElementImpl).variance;
|
||||
if (parameterVariance.isCovariant) {
|
||||
args.add(typeSystem.getLeastUpperBound(args1[i], args2[i]));
|
||||
args.add(typeSystem.leastUpperBound(args1[i], args2[i]));
|
||||
} else if (parameterVariance.isContravariant) {
|
||||
args.add(typeSystem.getGreatestLowerBound(args1[i], args2[i]));
|
||||
args.add(typeSystem.greatestLowerBound(args1[i], args2[i]));
|
||||
} else if (parameterVariance.isInvariant) {
|
||||
if (!typeSystem.isSubtypeOf(args1[i], args2[i]) ||
|
||||
!typeSystem.isSubtypeOf(args2[i], args1[i])) {
|
||||
|
@ -915,7 +915,7 @@ class LeastUpperBoundHelper {
|
|||
}
|
||||
|
||||
DartType _parameterType(ParameterElement a, ParameterElement b) {
|
||||
return _typeSystem.getGreatestLowerBound(a.type, b.type);
|
||||
return _typeSystem.greatestLowerBound(a.type, b.type);
|
||||
}
|
||||
|
||||
DartType _recordType(RecordTypeImpl T1, RecordTypeImpl T2) {
|
||||
|
|
|
@ -72,12 +72,12 @@ class TypeConstraintGatherer {
|
|||
var parameter = constraint.parameter;
|
||||
var mergedConstraint = result[parameter]!;
|
||||
|
||||
var lower = _typeSystem.getLeastUpperBound(
|
||||
var lower = _typeSystem.leastUpperBound(
|
||||
mergedConstraint.lower,
|
||||
constraint.lower,
|
||||
);
|
||||
|
||||
var upper = _typeSystem.getGreatestLowerBound(
|
||||
var upper = _typeSystem.greatestLowerBound(
|
||||
mergedConstraint.upper,
|
||||
constraint.upper,
|
||||
);
|
||||
|
|
|
@ -602,19 +602,6 @@ class TypeSystemImpl implements TypeSystem {
|
|||
return parameters;
|
||||
}
|
||||
|
||||
/// Computes the greatest lower bound of [T1] and [T2].
|
||||
DartType getGreatestLowerBound(DartType T1, DartType T2) {
|
||||
return _greatestLowerBoundHelper.getGreatestLowerBound(T1, T2);
|
||||
}
|
||||
|
||||
/// Compute the least upper bound of two types.
|
||||
///
|
||||
/// https://github.com/dart-lang/language
|
||||
/// See `resources/type-system/upper-lower-bounds.md`
|
||||
DartType getLeastUpperBound(DartType T1, DartType T2) {
|
||||
return _leastUpperBoundHelper.getLeastUpperBound(T1, T2);
|
||||
}
|
||||
|
||||
/// Returns the greatest closure of [type] with respect to [typeParameters].
|
||||
///
|
||||
/// https://github.com/dart-lang/language
|
||||
|
@ -677,6 +664,11 @@ class TypeSystemImpl implements TypeSystem {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
DartType greatestLowerBound(DartType T1, DartType T2) {
|
||||
return _greatestLowerBoundHelper.getGreatestLowerBound(T1, T2);
|
||||
}
|
||||
|
||||
/// Given a generic function type `F<T0, T1, ... Tn>` and a context type C,
|
||||
/// infer an instantiation of F, such that `F<S0, S1, ..., Sn>` <: C.
|
||||
///
|
||||
|
@ -1558,8 +1550,8 @@ class TypeSystemImpl implements TypeSystem {
|
|||
}
|
||||
|
||||
@override
|
||||
DartType leastUpperBound(DartType leftType, DartType rightType) {
|
||||
return getLeastUpperBound(leftType, rightType);
|
||||
DartType leastUpperBound(DartType T1, DartType T2) {
|
||||
return _leastUpperBoundHelper.getLeastUpperBound(T1, T2);
|
||||
}
|
||||
|
||||
/// Returns a nullable version of [type]. The result would be equivalent to
|
||||
|
|
|
@ -296,7 +296,7 @@ class AssignmentExpressionResolver {
|
|||
leftType = _typeSystem.promoteToNonNull(leftType);
|
||||
}
|
||||
|
||||
nodeType = _typeSystem.getLeastUpperBound(leftType, assignedType);
|
||||
nodeType = _typeSystem.leastUpperBound(leftType, assignedType);
|
||||
} else {
|
||||
nodeType = assignedType;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ class BinaryExpressionResolver {
|
|||
void _analyzeLeastUpperBoundTypes(
|
||||
ExpressionImpl node, DartType staticType1, DartType staticType2,
|
||||
{required DartType? contextType}) {
|
||||
var staticType = _typeSystem.getLeastUpperBound(staticType1, staticType2);
|
||||
var staticType = _typeSystem.leastUpperBound(staticType1, staticType2);
|
||||
|
||||
staticType = _resolver.toLegacyTypeIfOptOut(staticType);
|
||||
|
||||
|
|
|
@ -152,13 +152,13 @@ class BodyInferenceContext {
|
|||
if (_returnTypes.isEmpty) {
|
||||
return DynamicTypeImpl.instance;
|
||||
}
|
||||
return _returnTypes.reduce(_typeSystem.getLeastUpperBound);
|
||||
return _returnTypes.reduce(_typeSystem.leastUpperBound);
|
||||
}
|
||||
|
||||
var initialType = endOfBlockIsReachable
|
||||
? _typeProvider.nullType
|
||||
: _typeProvider.neverType;
|
||||
return _returnTypes.fold(initialType, _typeSystem.getLeastUpperBound);
|
||||
return _returnTypes.fold(initialType, _typeSystem.leastUpperBound);
|
||||
}
|
||||
|
||||
static BodyInferenceContext? of(FunctionBody node) {
|
||||
|
|
|
@ -420,7 +420,7 @@ class TypeSystemOperations
|
|||
|
||||
@override
|
||||
DartType glb(DartType type1, DartType type2) {
|
||||
return typeSystem.getGreatestLowerBound(type1, type2);
|
||||
return typeSystem.greatestLowerBound(type1, type2);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -205,7 +205,7 @@ class TypedLiteralResolver {
|
|||
}
|
||||
|
||||
var elseType = _computeElementType(elseElement);
|
||||
return _typeSystem.getLeastUpperBound(thenType, elseType);
|
||||
return _typeSystem.leastUpperBound(thenType, elseType);
|
||||
} else if (element is MapLiteralEntry) {
|
||||
// This error will be reported elsewhere.
|
||||
return _typeProvider.dynamicType;
|
||||
|
@ -847,7 +847,7 @@ class _InferredCollectionElementTypeInformation {
|
|||
} else if (second == null) {
|
||||
return first;
|
||||
} else {
|
||||
return typeSystem.getLeastUpperBound(first, second);
|
||||
return typeSystem.leastUpperBound(first, second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -308,8 +308,7 @@ class StaticTypeAnalyzer {
|
|||
void _analyzeLeastUpperBoundTypes(
|
||||
ExpressionImpl node, DartType staticType1, DartType staticType2,
|
||||
{required DartType? contextType}) {
|
||||
DartType staticType =
|
||||
_typeSystem.getLeastUpperBound(staticType1, staticType2);
|
||||
DartType staticType = _typeSystem.leastUpperBound(staticType1, staticType2);
|
||||
|
||||
staticType = _resolver.toLegacyTypeIfOptOut(staticType);
|
||||
|
||||
|
|
|
@ -1557,7 +1557,7 @@ class LowerBoundTest extends _BoundsTestBase {
|
|||
{bool checkSubtype = true}) {
|
||||
var expectedStr = typeString(expected);
|
||||
|
||||
var result = typeSystem.getGreatestLowerBound(T1, T2);
|
||||
var result = typeSystem.greatestLowerBound(T1, T2);
|
||||
var resultStr = typeString(result);
|
||||
expect(result, expected, reason: '''
|
||||
expected: $expectedStr
|
||||
|
@ -1571,7 +1571,7 @@ actual: $resultStr
|
|||
}
|
||||
|
||||
// Check for symmetry.
|
||||
result = typeSystem.getGreatestLowerBound(T2, T1);
|
||||
result = typeSystem.greatestLowerBound(T2, T1);
|
||||
resultStr = typeString(result);
|
||||
expect(result, expected, reason: '''
|
||||
expected: $expectedStr
|
||||
|
@ -2132,12 +2132,12 @@ class UpperBound_FunctionTypes_Test extends _BoundsTestBase {
|
|||
typeFormals: [U],
|
||||
);
|
||||
{
|
||||
final result = typeSystem.getLeastUpperBound(T1, T2);
|
||||
final result = typeSystem.leastUpperBound(T1, T2);
|
||||
final resultStr = typeString(result);
|
||||
expect(resultStr, 'T Function<T extends num>()');
|
||||
}
|
||||
{
|
||||
final result = typeSystem.getLeastUpperBound(T2, T1);
|
||||
final result = typeSystem.leastUpperBound(T2, T1);
|
||||
final resultStr = typeString(result);
|
||||
expect(resultStr, 'U Function<U extends num>()');
|
||||
}
|
||||
|
@ -2260,8 +2260,8 @@ class UpperBound_InterfaceTypes_Test extends _BoundsTestBase {
|
|||
var bNoneNone = bTypeNoneElement(NullabilitySuffix.none);
|
||||
|
||||
void assertLUB(DartType type1, DartType type2, DartType expected) {
|
||||
expect(typeSystem.getLeastUpperBound(type1, type2), expected);
|
||||
expect(typeSystem.getLeastUpperBound(type2, type1), expected);
|
||||
expect(typeSystem.leastUpperBound(type1, type2), expected);
|
||||
expect(typeSystem.leastUpperBound(type2, type1), expected);
|
||||
}
|
||||
|
||||
assertLUB(bStarQuestion, aQuestion, aQuestion);
|
||||
|
@ -2340,8 +2340,8 @@ class UpperBound_InterfaceTypes_Test extends _BoundsTestBase {
|
|||
var aNone = interfaceTypeNone(aElement);
|
||||
|
||||
void assertLUB(DartType type1, DartType type2, DartType expected) {
|
||||
expect(typeSystem.getLeastUpperBound(type1, type2), expected);
|
||||
expect(typeSystem.getLeastUpperBound(type2, type1), expected);
|
||||
expect(typeSystem.leastUpperBound(type1, type2), expected);
|
||||
expect(typeSystem.leastUpperBound(type2, type1), expected);
|
||||
}
|
||||
|
||||
assertLUB(aQuestion, aQuestion, aQuestion);
|
||||
|
@ -2498,8 +2498,8 @@ class UpperBound_InterfaceTypes_Test extends _BoundsTestBase {
|
|||
var cStarNone = cTypeElementStar(NullabilitySuffix.none);
|
||||
|
||||
void assertLUB(DartType type1, DartType type2, DartType expected) {
|
||||
expect(typeSystem.getLeastUpperBound(type1, type2), expected);
|
||||
expect(typeSystem.getLeastUpperBound(type2, type1), expected);
|
||||
expect(typeSystem.leastUpperBound(type1, type2), expected);
|
||||
expect(typeSystem.leastUpperBound(type2, type1), expected);
|
||||
}
|
||||
|
||||
assertLUB(bNoneQuestion, cNoneQuestion, aQuestion);
|
||||
|
@ -3678,7 +3678,7 @@ class _BoundsTestBase extends AbstractTypeSystemTest with StringTypes {
|
|||
void _checkLeastUpperBound(DartType T1, DartType T2, DartType expected) {
|
||||
var expectedStr = typeString(expected);
|
||||
|
||||
var result = typeSystem.getLeastUpperBound(T1, T2);
|
||||
var result = typeSystem.leastUpperBound(T1, T2);
|
||||
var resultStr = typeString(result);
|
||||
expect(result, expected, reason: '''
|
||||
expected: $expectedStr
|
||||
|
@ -3690,7 +3690,7 @@ actual: $resultStr
|
|||
expect(typeSystem.isSubtypeOf(T2, result), true);
|
||||
|
||||
// Check for symmetry.
|
||||
result = typeSystem.getLeastUpperBound(T2, T1);
|
||||
result = typeSystem.leastUpperBound(T2, T1);
|
||||
resultStr = typeString(result);
|
||||
expect(result, expected, reason: '''
|
||||
expected: $expectedStr
|
||||
|
|
|
@ -701,7 +701,7 @@ class MigrationResolutionHooksImpl
|
|||
} else {
|
||||
_flowAnalysis!.asExpression_end(node, contextType);
|
||||
var glb = _fixBuilder._typeSystem
|
||||
.getGreatestLowerBound(contextType, expressionType);
|
||||
.greatestLowerBound(contextType, expressionType);
|
||||
|
||||
if (glb != _fixBuilder._typeSystem.typeProvider.neverType &&
|
||||
!identical(glb, expressionType)) {
|
||||
|
|
Loading…
Reference in a new issue