Deprecate isMoreSpecificThan() and isDirectSupertypeOf().

R=brianwilkerson@google.com, paulberry@google.com

Change-Id: I57a884f411d006ed720b372826288cf39c91901e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/110752
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 8525f29..579ae93 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 e7134fc..fb46760 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -136,6 +136,7 @@
   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 @@
   /// * <i>I</i> is listed in the implements clause of <i>J</i>.
   /// * <i>I</i> is listed in the with clause of <i>J</i>.
   /// * <i>J</i> is a mixin application of the mixin of <i>I</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 <i>T</i> is more specific than an interface type <i>S</i>,
-  /// written <i>T &laquo; S</i>, if one of the following conditions is met:
-  ///
-  /// * Reflexivity: <i>T</i> is <i>S</i>.
-  /// * <i>T</i> is bottom.
-  /// * <i>S</i> is dynamic.
-  /// * Direct supertype: <i>S</i> is a direct supertype of <i>T</i>.
-  /// * <i>T</i> is a type parameter and <i>S</i> is the upper bound of
-  /// <i>T</i>.
-  /// * Covariance: <i>T</i> is of the form <i>I&lt;T<sub>1</sub>, &hellip;,
-  ///   T<sub>n</sub>&gt;</i> and S</i> is of the form <i>I&lt;S<sub>1</sub>,
-  ///   &hellip;, S<sub>n</sub>&gt;</i> and <i>T<sub>i</sub> &laquo;
-  ///   S<sub>i</sub></i>, <i>1 <= i <= n</i>.
-  /// * Transitivity: <i>T &laquo; U</i> and <i>U &laquo; S</i>.
-  @override
-  bool isMoreSpecificThan(DartType type);
-
   /// Return `true` if this type is a subtype of the given [type]. An interface
   /// type <i>T</i> is a subtype of an interface type <i>S</i>, written <i>T</i>
   /// <: <i>S</i>, iff <i>[bottom/dynamic]T</i> &laquo; <i>S</i> (<i>T</i> is
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 9da7fe6..231fdf5 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1798,6 +1798,7 @@
       //
       // 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 @@
     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 @@
       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 390784f..30bcdfe 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -5552,7 +5552,7 @@
       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 21703a6..7bc8f1a 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1202,8 +1202,8 @@
           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 @@
         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 cef8495..fb4e379 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -2429,6 +2429,7 @@
    *
    * In strong mode, this is equivalent to [isSubtypeOf].
    */
+  @Deprecated('Use isSubtypeOf() instead.')
   bool isMoreSpecificThan(DartType leftType, DartType rightType);
 
   @override
@@ -2632,14 +2633,6 @@
   /**
    * 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 e724a66..6a54e6e 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 @@
     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 @@
     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 @@
     InterfaceType typeA = classA.type;
     InterfaceType typeB = classB.type;
     classB.interfaces = <InterfaceType>[typeA];
+    // ignore: deprecated_member_use_from_same_package
     expect(typeA.isDirectSupertypeOf(typeB), isTrue);
   }
 
@@ -2475,6 +2478,7 @@
     InterfaceType typeA = classA.type;
     InterfaceType typeB = classB.type;
     classB.mixins = <InterfaceType>[typeA];
+    // ignore: deprecated_member_use_from_same_package
     expect(typeA.isDirectSupertypeOf(typeB), isTrue);
   }
 
@@ -2500,13 +2504,16 @@
     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 @@
     InterfaceType typeAOfDynamic =
         classA.type.instantiate(<DartType>[dynamicType]);
     InterfaceType typeAOfB = classA.type.instantiate(<DartType>[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 @@
     classC.interfaces = <InterfaceType>[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 @@
     classC.mixins = <InterfaceType>[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 @@
     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 @@
     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 @@
     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 @@
     parameterEA.bound = typeA;
     parameterEA.type = parameterAEType;
     classB.typeParameters = <TypeParameterElementImpl>[parameterEA];
+    // ignore: deprecated_member_use_from_same_package
     expect(parameterAEType.isMoreSpecificThan(typeA), isTrue);
   }
 
@@ -3651,14 +3668,17 @@
 
   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 671bdef5..100d12e 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 @@
 
     var element = findElement.mixin('M');
     var type = element.type;
+    // ignore: deprecated_member_use_from_same_package
     expect(type.isMoreSpecificThan(intType), isFalse);
   }