diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md index 8525f29fb3f..579ae934ec6 100644 --- a/pkg/analyzer/CHANGELOG.md +++ b/pkg/analyzer/CHANGELOG.md @@ -5,6 +5,9 @@ * Deprecated the `isEquivalentTo(DartType)` method of `DartType`. The operator `==` now correctly considers two types equal if and only if they represent the same type as defined by the spec. +* Deprecated the `isMoreSpecificThan(DartType)` method of `DartType`. + Deprecated the `isMoreSpecificThan(DartType)` method of `TypeSystem`. + Use `TypeSystem.isSubtypeOf(DartType)` instead. ## 0.37.0 * Removed deprecated getter `DartType.isUndefined`. diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart index e7134fc5838..fb46760fb4d 100644 --- a/pkg/analyzer/lib/dart/element/type.dart +++ b/pkg/analyzer/lib/dart/element/type.dart @@ -136,6 +136,7 @@ abstract class DartType { bool isEquivalentTo(DartType dest); /// Return `true` if this type is more specific than the given [type]. + @Deprecated('Use TypeSystem.isSubtypeOf() instead.') bool isMoreSpecificThan(DartType type); /// Return `true` if this type is a subtype of the given [type]. @@ -378,26 +379,9 @@ abstract class InterfaceType implements ParameterizedType { /// * I is listed in the implements clause of J. /// * I is listed in the with clause of J. /// * J is a mixin application of the mixin of I. + @Deprecated('This method was used internally, and is not used anymore.') bool isDirectSupertypeOf(InterfaceType type); - /// Return `true` if this type is more specific than the given [type]. An - /// interface type T is more specific than an interface type S, - /// written T « S, if one of the following conditions is met: - /// - /// * Reflexivity: T is S. - /// * T is bottom. - /// * S is dynamic. - /// * Direct supertype: S is a direct supertype of T. - /// * T is a type parameter and S is the upper bound of - /// T. - /// * Covariance: T is of the form I<T1, …, - /// Tn> and S is of the form I<S1, - /// …, Sn> and Ti « - /// Si, 1 <= i <= n. - /// * Transitivity: T « U and U « S. - @override - bool isMoreSpecificThan(DartType type); - /// Return `true` if this type is a subtype of the given [type]. An interface /// type T is a subtype of an interface type S, written T /// <: S, iff [bottom/dynamic]T « S (T is diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart index 9da7fe6a6f7..231fdf5a1e6 100644 --- a/pkg/analyzer/lib/src/dart/element/type.dart +++ b/pkg/analyzer/lib/src/dart/element/type.dart @@ -1798,6 +1798,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { // // Direct supertype: S is a direct supertype of T. // + // ignore: deprecated_member_use_from_same_package if (type.isDirectSupertypeOf(this)) { return true; } @@ -2376,7 +2377,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { for (DartType type in types) { // If any existing type in the bucket is more specific than this type, // then we can ignore this type. - if (bucket.any((DartType t) => typeSystem.isMoreSpecificThan(t, type))) { + if (bucket.any((DartType t) => typeSystem.isSubtypeOf(t, type))) { continue; } // Otherwise, we need to add this type to the bucket and remove any types @@ -2384,7 +2385,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { bool added = false; int i = 0; while (i < bucket.length) { - if (typeSystem.isMoreSpecificThan(type, bucket[i])) { + if (typeSystem.isSubtypeOf(type, bucket[i])) { if (added) { if (i < bucket.length - 1) { bucket[i] = bucket.removeLast(); diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart index 390784fdde9..30bcdfe11c1 100644 --- a/pkg/analyzer/lib/src/generated/error_verifier.dart +++ b/pkg/analyzer/lib/src/generated/error_verifier.dart @@ -5552,7 +5552,7 @@ class ErrorVerifier extends RecursiveAstVisitor { return; } // OK, type parameter is not supertype of its bound - if (!bound.isMoreSpecificThan(element.type)) { + if (!_typeSystem.isSubtypeOf(bound, element.type)) { return; } diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index 21703a64d96..7bc8f1a1af0 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart @@ -1202,8 +1202,8 @@ class BestPracticesVerifier extends RecursiveAstVisitor { elseType != null && !thenType.isDynamic && !elseType.isDynamic && - !thenType.isMoreSpecificThan(elseType) && - !elseType.isMoreSpecificThan(thenType)) { + !_typeSystem.isSubtypeOf(thenType, elseType) && + !_typeSystem.isSubtypeOf(elseType, thenType)) { return false; } } @@ -1213,7 +1213,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor { rhsType != null && !lhsType.isDynamic && !rhsType.isDynamic && - _typeSystem.isMoreSpecificThan(lhsType, rhsType)) { + _typeSystem.isSubtypeOf(lhsType, rhsType)) { _errorReporter.reportErrorForNode(HintCode.UNNECESSARY_CAST, node); return true; } diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart index cef849541f5..fb4e379a438 100644 --- a/pkg/analyzer/lib/src/generated/type_system.dart +++ b/pkg/analyzer/lib/src/generated/type_system.dart @@ -2429,6 +2429,7 @@ abstract class TypeSystem implements public.TypeSystem { * * In strong mode, this is equivalent to [isSubtypeOf]. */ + @Deprecated('Use isSubtypeOf() instead.') bool isMoreSpecificThan(DartType leftType, DartType rightType); @override @@ -2632,14 +2633,6 @@ abstract class TypeSystem implements public.TypeSystem { /** * Tries to promote from the first type from the second type, and returns the * promoted type if it succeeds, otherwise null. - * - * In the Dart 1 type system, it is not possible to promote from or to - * `dynamic`, and we must be promoting to a more specific type, see - * [isMoreSpecificThan]. Also it will always return the promote [to] type or - * null. - * - * In strong mode, this can potentially return a different type, see - * the override in [Dart2TypeSystem]. */ DartType tryPromoteToType(DartType to, DartType from); diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart index e724a66b134..6a54e6e3699 100644 --- a/pkg/analyzer/test/src/dart/element/element_test.dart +++ b/pkg/analyzer/test/src/dart/element/element_test.dart @@ -2448,6 +2448,7 @@ class InterfaceTypeImplTest extends EngineTestCase { ClassElement classB = ElementFactory.classElement("B", classA.type); InterfaceType typeA = classA.type; InterfaceType typeB = classB.type; + // ignore: deprecated_member_use_from_same_package expect(typeA.isDirectSupertypeOf(typeB), isTrue); } @@ -2457,6 +2458,7 @@ class InterfaceTypeImplTest extends EngineTestCase { ClassElement classC = ElementFactory.classElement("C", classB.type); InterfaceType typeA = classA.type; InterfaceType typeC = classC.type; + // ignore: deprecated_member_use_from_same_package expect(typeA.isDirectSupertypeOf(typeC), isFalse); } @@ -2466,6 +2468,7 @@ class InterfaceTypeImplTest extends EngineTestCase { InterfaceType typeA = classA.type; InterfaceType typeB = classB.type; classB.interfaces = [typeA]; + // ignore: deprecated_member_use_from_same_package expect(typeA.isDirectSupertypeOf(typeB), isTrue); } @@ -2475,6 +2478,7 @@ class InterfaceTypeImplTest extends EngineTestCase { InterfaceType typeA = classA.type; InterfaceType typeB = classB.type; classB.mixins = [typeA]; + // ignore: deprecated_member_use_from_same_package expect(typeA.isDirectSupertypeOf(typeB), isTrue); } @@ -2500,13 +2504,16 @@ class InterfaceTypeImplTest extends EngineTestCase { ClassElement classB = ElementFactory.classElement("B", classA.type); InterfaceType typeA = classA.type; InterfaceType typeB = classB.type; + // ignore: deprecated_member_use_from_same_package expect(typeB.isMoreSpecificThan(typeA), isTrue); // the opposite test tests a different branch in isMoreSpecificThan() + // ignore: deprecated_member_use_from_same_package expect(typeA.isMoreSpecificThan(typeB), isFalse); } void test_isMoreSpecificThan_dynamic() { InterfaceType type = ElementFactory.classElement2("A").type; + // ignore: deprecated_member_use_from_same_package expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue); } @@ -2517,12 +2524,15 @@ class InterfaceTypeImplTest extends EngineTestCase { InterfaceType typeAOfDynamic = classA.type.instantiate([dynamicType]); InterfaceType typeAOfB = classA.type.instantiate([classB.type]); + // ignore: deprecated_member_use_from_same_package expect(typeAOfDynamic.isMoreSpecificThan(typeAOfB), isFalse); + // ignore: deprecated_member_use_from_same_package expect(typeAOfB.isMoreSpecificThan(typeAOfDynamic), isTrue); } void test_isMoreSpecificThan_self() { InterfaceType type = ElementFactory.classElement2("A").type; + // ignore: deprecated_member_use_from_same_package expect(type.isMoreSpecificThan(type), isTrue); } @@ -2538,6 +2548,7 @@ class InterfaceTypeImplTest extends EngineTestCase { classC.interfaces = [classB.type]; InterfaceType typeA = classA.type; InterfaceType typeC = classC.type; + // ignore: deprecated_member_use_from_same_package expect(typeC.isMoreSpecificThan(typeA), isTrue); } @@ -2553,6 +2564,7 @@ class InterfaceTypeImplTest extends EngineTestCase { classC.mixins = [classB.type]; InterfaceType typeA = classA.type; InterfaceType typeC = classC.type; + // ignore: deprecated_member_use_from_same_package expect(typeC.isMoreSpecificThan(typeA), isTrue); } @@ -2568,6 +2580,7 @@ class InterfaceTypeImplTest extends EngineTestCase { InterfaceType typeA = classA.type; InterfaceType typeC = classC.type; classA.supertype = classB.type; + // ignore: deprecated_member_use_from_same_package expect(typeA.isMoreSpecificThan(typeC), isFalse); } @@ -2582,6 +2595,7 @@ class InterfaceTypeImplTest extends EngineTestCase { ClassElement classC = ElementFactory.classElement("C", classB.type); InterfaceType typeA = classA.type; InterfaceType typeC = classC.type; + // ignore: deprecated_member_use_from_same_package expect(typeC.isMoreSpecificThan(typeA), isTrue); } @@ -2593,7 +2607,9 @@ class InterfaceTypeImplTest extends EngineTestCase { InterfaceType typeA = classA.type; TypeParameterType parameterType = classA.typeParameters[0].type; DartType objectType = _typeProvider.objectType; + // ignore: deprecated_member_use_from_same_package expect(parameterType.isMoreSpecificThan(objectType), isTrue); + // ignore: deprecated_member_use_from_same_package expect(parameterType.isMoreSpecificThan(typeA), isFalse); } @@ -2611,6 +2627,7 @@ class InterfaceTypeImplTest extends EngineTestCase { parameterEA.bound = typeA; parameterEA.type = parameterAEType; classB.typeParameters = [parameterEA]; + // ignore: deprecated_member_use_from_same_package expect(parameterAEType.isMoreSpecificThan(typeA), isTrue); } @@ -3651,14 +3668,17 @@ class VoidTypeImplTest extends EngineTestCase { void test_isMoreSpecificThan_void_A() { ClassElement classA = ElementFactory.classElement2("A"); + // ignore: deprecated_member_use_from_same_package expect(_voidType.isMoreSpecificThan(classA.type), isFalse); } void test_isMoreSpecificThan_void_dynamic() { + // ignore: deprecated_member_use_from_same_package expect(_voidType.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue); } void test_isMoreSpecificThan_void_void() { + // ignore: deprecated_member_use_from_same_package expect(_voidType.isMoreSpecificThan(_voidType), isTrue); } diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart index 671bdef50cd..100d12e5e42 100644 --- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart @@ -1643,6 +1643,7 @@ mixin M {} var element = findElement.mixin('M'); var type = element.type; + // ignore: deprecated_member_use_from_same_package expect(type.isMoreSpecificThan(intType), isFalse); }