Fix gatherMixinSupertypeConstraints to handle named mixin applications.

In a named mixin application, the superclass doesn't include the last
type appearing in the "with" clause, so that class isn't considered a
superclass constraint.

Fixes some test cases broken by 46e5954b0a0280e54270873b3d2616ed2aa90482.

Change-Id: I2e824d38017fe2c7eaa23e8f185cea07fe2222b7
Reviewed-on: https://dart-review.googlesource.com/75940
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 84e7322..57c163b 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -1762,16 +1762,15 @@
     if (mixinElement.isMixin) {
       return mixinElement.superclassConstraints;
     }
-    var mixinSupertypeConstraints = <InterfaceType>[];
-    void addIfGeneric(InterfaceType type) {
-      if (type.element.typeParameters.isNotEmpty) {
-        mixinSupertypeConstraints.add(type);
-      }
-    }
 
-    addIfGeneric(mixinElement.supertype);
-    mixinElement.mixins.forEach(addIfGeneric);
-    return mixinSupertypeConstraints;
+    var candidates = [mixinElement.supertype];
+    candidates.addAll(mixinElement.mixins);
+    if (mixinElement.isMixinApplication) {
+      candidates.removeLast();
+    }
+    return candidates
+        .where((type) => type.element.typeParameters.isNotEmpty)
+        .toList();
   }
 
   /**
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 4f36053..107edab 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -70,6 +70,12 @@
 
   @override
   @failingTest // Does not work with old task model
+  test_mixin_of_mixin_type_argument_inference_cascaded_mixin() {
+    return super.test_mixin_of_mixin_type_argument_inference_cascaded_mixin();
+  }
+
+  @override
+  @failingTest // Does not work with old task model
   test_mixinInference_with_actual_mixins() {
     return super.test_mixinInference_with_actual_mixins();
   }
@@ -3859,6 +3865,43 @@
     verify([source]);
   }
 
+  test_mixin_of_mixin_type_argument_inference() async {
+    // In the code below, B's superclass constraints don't include A, because
+    // superclass constraints are determined from the mixin's superclass, and
+    // B's superclass is Object.  So no mixin type inference is attempted, and
+    // "with B" is interpreted as "with B<dynamic>".
+    Source source = addSource('''
+class A<T> {}
+class B<T> = Object with A<T>;
+class C = Object with B;
+''');
+    var result = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    var bReference = result.unit.declaredElement.getType('C').mixins[0];
+    expect(bReference.typeArguments[0].toString(), 'dynamic');
+  }
+
+  test_mixin_of_mixin_type_argument_inference_cascaded_mixin() async {
+    // In the code below, B has a single superclass constraint, A1, because
+    // superclass constraints are determined from the mixin's superclass, and
+    // B's superclass is "Object with A1<T>".  So mixin type inference succeeds
+    // (since C's base class implements A1<int>), and "with B" is interpreted as
+    // "with B<int>".
+    Source source = addSource('''
+class A1<T> {}
+class A2<T> {}
+class B<T> = Object with A1<T>, A2<T>;
+class Base implements A1<int> {}
+class C = Base with B;
+''');
+    var result = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    var bReference = result.unit.declaredElement.getType('C').mixins[0];
+    expect(bReference.typeArguments[0].toString(), 'int');
+  }
+
   test_mixinDeclaresConstructor() async {
     Source source = addSource(r'''
 class A {
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index e5c15f0..0389ef8 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -75,8 +75,6 @@
 mixin_declaration/mixin_declaration_inference_invalid_07_test: MissingCompileTimeError
 mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError # Issue 30552
 mixin_method_override_test/01: MissingCompileTimeError
-mixin_mixin6_test: CompileTimeError # TODO(paulberry): triage
-mixin_mixin7_test: CompileTimeError # TODO(paulberry): triage
 mixin_super_2_test/01: MissingCompileTimeError
 mixin_super_2_test/03: MissingCompileTimeError
 mixin_supertype_subclass2_test/02: MissingStaticWarning # Issue 25614
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 23d52cf..b7b4c3b 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -145,8 +145,6 @@
 mixin_declaration/mixin_declaration_inference_valid_C13_test: CompileTimeError # Issue #34164
 mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError    # Analyzer chooses wrong(?) super method.
 mixin_method_override_test/01: MissingCompileTimeError # Issue 34235
-mixin_mixin6_test: CompileTimeError # TODO(paulberry): triage
-mixin_mixin7_test: CompileTimeError # TODO(paulberry): triage
 mixin_super_2_test/01: MissingCompileTimeError
 mixin_super_2_test/03: MissingCompileTimeError
 mixin_super_test: RuntimeError