Tests for ClassElement.allSupertypes for mixins.

R=brianwilkerson@google.com

Change-Id: If8818fba6e3de02c94d098957eaacecb58938abd
Reviewed-on: https://dart-review.googlesource.com/74821
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index 533ae56..8384f10 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -273,6 +273,113 @@
     assertTestErrors([CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
   }
 
+  test_element_allSupertypes() async {
+    addTestFile(r'''
+class A {}
+class B {}
+class C {}
+class D {}
+class E {}
+
+class X1 extends A {}
+class X2 implements B {}
+class X3 extends A implements B {}
+class X4 extends A with B implements C {}
+class X5 extends A with B, C implements D, E {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    var c = findElement.class_('C');
+    var d = findElement.class_('D');
+    var e = findElement.class_('E');
+    assertElementTypes(
+      findElement.class_('X1').allSupertypes,
+      [a.type, objectType],
+    );
+    assertElementTypes(
+      findElement.class_('X2').allSupertypes,
+      [objectType, b.type],
+    );
+    assertElementTypes(
+      findElement.class_('X3').allSupertypes,
+      [a.type, objectType, b.type],
+    );
+    assertElementTypes(
+      findElement.class_('X4').allSupertypes,
+      [a.type, b.type, objectType, c.type],
+    );
+    assertElementTypes(
+      findElement.class_('X5').allSupertypes,
+      [a.type, b.type, c.type, objectType, d.type, e.type],
+    );
+  }
+
+  test_element_allSupertypes_generic() async {
+    addTestFile(r'''
+class A<T> {}
+class B<T, U> {}
+class C<T> extends B<int, T> {}
+
+class X1 extends A<String> {}
+class X2 extends B<String, List<int>> {}
+class X3 extends C<double> {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    var c = findElement.class_('C');
+    assertElementTypes(
+      findElement.class_('X1').allSupertypes,
+      [
+        a.type.instantiate([stringType]),
+        objectType
+      ],
+    );
+    assertElementTypes(
+      findElement.class_('X2').allSupertypes,
+      [
+        b.type.instantiate([
+          stringType,
+          typeProvider.listType.instantiate([intType])
+        ]),
+        objectType
+      ],
+    );
+    assertElementTypes(
+      findElement.class_('X3').allSupertypes,
+      [
+        c.type.instantiate([doubleType]),
+        b.type.instantiate([intType, doubleType]),
+        objectType
+      ],
+    );
+  }
+
+  test_element_allSupertypes_recursive() async {
+    addTestFile(r'''
+class A extends B {}
+class B extends C {}
+class C extends A {}
+
+class X extends A {}
+''');
+    await resolveTestFile();
+    assertHasTestErrors();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    var c = findElement.class_('C');
+    assertElementTypes(
+      findElement.class_('X').allSupertypes,
+      [a.type, b.type, c.type],
+    );
+  }
+
   test_error_conflictingConstructorAndStaticField_field() async {
     addTestFile(r'''
 class C {
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 92750a6..489cfba 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -165,6 +165,61 @@
     assertElementTypes(element.superclassConstraints, [objectType]);
   }
 
+  test_element_allSupertypes() async {
+    addTestFile(r'''
+class A {}
+class B {}
+class C {}
+
+mixin M1 on A, B {}
+mixin M2 on A implements B, C {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    var c = findElement.class_('C');
+    assertElementTypes(
+      findElement.mixin('M1').allSupertypes,
+      [a.type, b.type, objectType],
+    );
+    assertElementTypes(
+      findElement.mixin('M2').allSupertypes,
+      [a.type, objectType, b.type, c.type],
+    );
+  }
+
+  test_element_allSupertypes_generic() async {
+    addTestFile(r'''
+class A<T, U> {}
+class B<T> extends A<int, T> {}
+
+mixin M1 on A<int, double> {}
+mixin M2 on B<String> {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    assertElementTypes(
+      findElement.mixin('M1').allSupertypes,
+      [
+        a.type.instantiate([intType, doubleType]),
+        objectType
+      ],
+    );
+    assertElementTypes(
+      findElement.mixin('M2').allSupertypes,
+      [
+        b.type.instantiate([stringType]),
+        a.type.instantiate([intType, stringType]),
+        objectType
+      ],
+    );
+  }
+
   test_error_builtInIdentifierAsTypeName() async {
     addTestFile(r'''
 mixin as {}
@@ -906,20 +961,6 @@
     ]);
   }
 
-  test_error_mixinApplicationNotImplementedInterface_OK_generic() async {
-    addTestFile(r'''
-class A<T> {}
-
-mixin M<T> on A<T> {}
-
-class B<T> implements A<T> {}
-
-class C<T> = B<T> with M<T>;
-''');
-    await resolveTestFile();
-    assertNoTestErrors();
-  }
-
   test_error_mixinApplicationNotImplementedInterface_OK_0() async {
     addTestFile(r'''
 mixin M {}
@@ -942,6 +983,20 @@
     assertNoTestErrors();
   }
 
+  test_error_mixinApplicationNotImplementedInterface_OK_generic() async {
+    addTestFile(r'''
+class A<T> {}
+
+mixin M<T> on A<T> {}
+
+class B<T> implements A<T> {}
+
+class C<T> = B<T> with M<T>;
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
   test_error_mixinApplicationNotImplementedInterface_oneOfTwo() async {
     addTestFile(r'''
 class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index b46646c..69c1580 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -47,6 +47,8 @@
 
   InterfaceType get objectType => typeProvider.objectType;
 
+  InterfaceType get stringType => typeProvider.stringType;
+
   TypeProvider get typeProvider =>
       result.unit.declaredElement.context.typeProvider;
 
@@ -77,10 +79,12 @@
     expect(type, expected);
   }
 
-  void assertElementTypes(List<DartType> types, List<DartType> expected) {
-    expect(types, hasLength(expected.length));
-    for (var i = 0; i < types.length; ++i) {
-      assertElementType(types[i], expected[i]);
+  void assertElementTypes(List<DartType> types, List<DartType> expected,
+      {bool ordered = false}) {
+    if (ordered) {
+      expect(types, expected);
+    } else {
+      expect(types, unorderedEquals(expected));
     }
   }