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);
}