| Index: pkg/analyzer/test/generated/type_system_test.dart
|
| diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
|
| index f679517c84489850306b525d429790bcfcdacb30..c164540b88552dd8aeabf1b6ca6713ddad06a42d 100644
|
| --- a/pkg/analyzer/test/generated/type_system_test.dart
|
| +++ b/pkg/analyzer/test/generated/type_system_test.dart
|
| @@ -43,6 +43,7 @@ abstract class BoundTestBase {
|
| DartType get dynamicType => typeProvider.dynamicType;
|
| InterfaceType get functionType => typeProvider.functionType;
|
| InterfaceType get intType => typeProvider.intType;
|
| + InterfaceType get iterableType => typeProvider.iterableType;
|
| InterfaceType get listType => typeProvider.listType;
|
| InterfaceType get numType => typeProvider.numType;
|
| InterfaceType get objectType => typeProvider.objectType;
|
| @@ -64,14 +65,48 @@ abstract class BoundTestBase {
|
|
|
| void _checkGreatestLowerBound(
|
| DartType type1, DartType type2, DartType expectedResult) {
|
| - expect(strongTypeSystem.getGreatestLowerBound(typeProvider, type1, type2),
|
| - expectedResult);
|
| + DartType glb =
|
| + strongTypeSystem.getGreatestLowerBound(typeProvider, type1, type2);
|
| + expect(glb, expectedResult);
|
| + // Check that the result is a lower bound.
|
| + expect(typeSystem.isSubtypeOf(glb, type1), true);
|
| + expect(typeSystem.isSubtypeOf(glb, type2), true);
|
| + // Check for symmetry while we're at it. Unfortunately,
|
| + // for function types, the current version of equality
|
| + // does not respect re-ordering of named parameters, so
|
| + // for function types we just check if they are mutual subtypes.
|
| + // https://github.com/dart-lang/sdk/issues/26126
|
| + // TODO(leafp): Fix this.
|
| + glb = strongTypeSystem.getGreatestLowerBound(typeProvider, type2, type1);
|
| + if (glb is FunctionTypeImpl) {
|
| + expect(typeSystem.isSubtypeOf(glb, expectedResult), true);
|
| + expect(typeSystem.isSubtypeOf(expectedResult, glb), true);
|
| + } else {
|
| + expect(glb, expectedResult);
|
| + }
|
| }
|
|
|
| void _checkLeastUpperBound(
|
| DartType type1, DartType type2, DartType expectedResult) {
|
| - expect(typeSystem.getLeastUpperBound(typeProvider, type1, type2),
|
| - expectedResult);
|
| + DartType lub = typeSystem.getLeastUpperBound(typeProvider, type1, type2);
|
| + expect(lub, expectedResult);
|
| + // Check that the result is an upper bound.
|
| + expect(typeSystem.isSubtypeOf(type1, lub), true);
|
| + expect(typeSystem.isSubtypeOf(type2, lub), true);
|
| +
|
| + // Check for symmetry while we're at it. Unfortunately,
|
| + // for function types, the current version of equality
|
| + // does not respect re-ordering of named parameters, so
|
| + // for function types we just check if they are mutual subtypes.
|
| + // https://github.com/dart-lang/sdk/issues/26126
|
| + // TODO(leafp): Fix this.
|
| + lub = typeSystem.getLeastUpperBound(typeProvider, type2, type1);
|
| + if (lub is FunctionTypeImpl) {
|
| + expect(typeSystem.isSubtypeOf(lub, expectedResult), true);
|
| + expect(typeSystem.isSubtypeOf(expectedResult, lub), true);
|
| + } else {
|
| + expect(lub, expectedResult);
|
| + }
|
| }
|
|
|
| /**
|
| @@ -148,6 +183,27 @@ class LeastUpperBoundTest extends LeastUpperBoundTestBase {
|
| ]);
|
| _checkLeastUpperBound(type1, type2, expected);
|
| }
|
| +
|
| + /// Check least upper bound of the same class with different type parameters.
|
| + void test_typeParameters_different() {
|
| + // class List<int>
|
| + // class List<double>
|
| + InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
|
| + InterfaceType listOfDoubleType =
|
| + listType.instantiate(<DartType>[doubleType]);
|
| + _checkLeastUpperBound(listOfIntType, listOfDoubleType, objectType);
|
| + }
|
| +
|
| + /// Check least upper bound of two related classes with different
|
| + /// type parameters.
|
| + void test_typeParametersAndClass_different() {
|
| + // class List<int>
|
| + // class Iterable<double>
|
| + InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
|
| + InterfaceType iterableOfDoubleType =
|
| + iterableType.instantiate(<DartType>[doubleType]);
|
| + _checkLeastUpperBound(listOfIntType, iterableOfDoubleType, objectType);
|
| + }
|
| }
|
|
|
| /**
|
| @@ -469,15 +525,6 @@ abstract class LeastUpperBoundTestBase extends BoundTestBase {
|
| _checkLeastUpperBound(typeParam, interfaceType, objectType);
|
| }
|
|
|
| - void test_typeParameters_different() {
|
| - // class List<int>
|
| - // class List<double>
|
| - InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
|
| - InterfaceType listOfDoubleType =
|
| - listType.instantiate(<DartType>[doubleType]);
|
| - _checkLeastUpperBound(listOfIntType, listOfDoubleType, objectType);
|
| - }
|
| -
|
| void test_typeParameters_same() {
|
| // List<int>
|
| // List<int>
|
| @@ -485,22 +532,19 @@ abstract class LeastUpperBoundTestBase extends BoundTestBase {
|
| _checkLeastUpperBound(listOfIntType, listOfIntType, listOfIntType);
|
| }
|
|
|
| - void test_void_bottom() {
|
| - _checkLeastUpperBound(voidType, bottomType, voidType);
|
| - }
|
| -
|
| - void test_void_function() {
|
| - _checkLeastUpperBound(voidType, simpleFunctionType, voidType);
|
| - }
|
| -
|
| - void test_void_interface() {
|
| - DartType interfaceType = ElementFactory.classElement2('A', []).type;
|
| - _checkLeastUpperBound(voidType, interfaceType, voidType);
|
| - }
|
| -
|
| - void test_void_typeParam() {
|
| - DartType typeParam = ElementFactory.typeParameterElement('T').type;
|
| - _checkLeastUpperBound(voidType, typeParam, voidType);
|
| + void test_void() {
|
| + List<DartType> types = [
|
| + bottomType,
|
| + simpleFunctionType,
|
| + ElementFactory.classElement2('A', []).type,
|
| + ElementFactory.typeParameterElement('T').type
|
| + ];
|
| + for (DartType type in types) {
|
| + _checkLeastUpperBound(
|
| + _functionType([], returns: voidType),
|
| + _functionType([], returns: type),
|
| + _functionType([], returns: voidType));
|
| + }
|
| }
|
| }
|
|
|
| @@ -1241,22 +1285,17 @@ class StrongGreatestLowerBoundTest extends BoundTestBase {
|
| _checkGreatestLowerBound(classA.type, classB.type, bottomType);
|
| }
|
|
|
| - void test_void_bottom() {
|
| - _checkGreatestLowerBound(voidType, bottomType, bottomType);
|
| - }
|
| -
|
| - void test_void_function() {
|
| - _checkGreatestLowerBound(voidType, simpleFunctionType, simpleFunctionType);
|
| - }
|
| -
|
| - void test_void_interface() {
|
| - DartType interfaceType = ElementFactory.classElement2('A', []).type;
|
| - _checkGreatestLowerBound(voidType, interfaceType, interfaceType);
|
| - }
|
| -
|
| - void test_void_typeParam() {
|
| - DartType typeParam = ElementFactory.typeParameterElement('T').type;
|
| - _checkGreatestLowerBound(voidType, typeParam, typeParam);
|
| + void test_void() {
|
| + List<DartType> types = [
|
| + bottomType,
|
| + simpleFunctionType,
|
| + ElementFactory.classElement2('A', []).type,
|
| + ElementFactory.typeParameterElement('T').type
|
| + ];
|
| + for (DartType type in types) {
|
| + _checkGreatestLowerBound(_functionType([], returns: voidType),
|
| + _functionType([], returns: type), _functionType([], returns: type));
|
| + }
|
| }
|
| }
|
|
|
| @@ -1315,6 +1354,52 @@ class StrongLeastUpperBoundTest extends LeastUpperBoundTestBase {
|
| ]);
|
| _checkLeastUpperBound(type1, type2, expected);
|
| }
|
| +
|
| + void test_typeParam_boundedByParam() {
|
| + TypeParameterElementImpl typeParamElementT =
|
| + ElementFactory.typeParameterElement('T');
|
| + TypeParameterElementImpl typeParamElementS =
|
| + ElementFactory.typeParameterElement('S');
|
| + DartType typeParamT = typeParamElementT.type;
|
| + DartType typeParamS = typeParamElementS.type;
|
| + typeParamElementT.bound = typeParamS;
|
| + _checkLeastUpperBound(typeParamT, typeParamS, typeParamS);
|
| + }
|
| +
|
| + void test_typeParam_fBounded() {
|
| + ClassElementImpl AClass = ElementFactory.classElement2('A', ["Q"]);
|
| + InterfaceType AType = AClass.type;
|
| +
|
| + DartType s = TypeBuilder.variable("S");
|
| + (s.element as TypeParameterElementImpl).bound = AType.instantiate([s]);
|
| + DartType u = TypeBuilder.variable("U");
|
| + (u.element as TypeParameterElementImpl).bound = AType.instantiate([u]);
|
| +
|
| + _checkLeastUpperBound(s, u, AType.instantiate([objectType]));
|
| + }
|
| +
|
| + /// Check least upper bound of the same class with different type parameters.
|
| + void test_typeParameters_different() {
|
| + // class List<int>
|
| + // class List<double>
|
| + InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
|
| + InterfaceType listOfDoubleType =
|
| + listType.instantiate(<DartType>[doubleType]);
|
| + InterfaceType listOfNum = listType.instantiate(<DartType>[numType]);
|
| + _checkLeastUpperBound(listOfIntType, listOfDoubleType, listOfNum);
|
| + }
|
| +
|
| + /// Check least upper bound of two related classes with different
|
| + /// type parameters.
|
| + void test_typeParametersAndClass_different() {
|
| + // class List<int>
|
| + // class Iterable<double>
|
| + InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
|
| + InterfaceType iterableOfDoubleType =
|
| + iterableType.instantiate(<DartType>[doubleType]);
|
| + // TODO(leafp): this should be iterableOfNumType
|
| + _checkLeastUpperBound(listOfIntType, iterableOfDoubleType, objectType);
|
| + }
|
| }
|
|
|
| @reflectiveTest
|
|
|