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