Move a few mixin inference tests to element model tests.
Bug: https://github.com/dart-lang/sdk/issues/49208
Change-Id: I2e3fba9ef4d8023549486e7dc810c57dc8e1eaa1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247800
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index da702a3..20aa8ab 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -86,6 +86,10 @@
throw 0;
}
+ factory Stream.value(T value) {
+ throw 0;
+ }
+
Future<T> get first;
StreamSubscription<T> listen(void onData(T event)?,
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 00a42fb..66ec302 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -1733,60 +1733,6 @@
''');
}
- test_infer_mixin_new_syntax() async {
- await assertNoErrorsInCode('''
-abstract class A<T> {}
-
-class B {}
-
-mixin M<T> on A<T> {}
-
-class C extends A<B> with M {}
-''');
- CompilationUnit unit = result.unit;
- ClassElement classC = unit.declaredElement!.getType('C')!;
- expect(classC.mixins, hasLength(1));
- assertType(classC.mixins[0], 'M<B>');
- }
-
- test_infer_mixin_with_substitution_functionType_new_syntax() async {
- await assertErrorsInCode('''
-abstract class A<T> {}
-
-class B {}
-
-mixin M<T, U> on A<T Function(U)> {}
-
-class C extends A<int Function(String)> with M {}
-''', [
- error(
- CompileTimeErrorCode.WRONG_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE,
- 47,
- 1,
- ),
- ]);
- CompilationUnit unit = result.unit;
- ClassElement classC = unit.declaredElement!.getType('C')!;
- expect(classC.mixins, hasLength(1));
- assertType(classC.mixins[0], 'M<int, String>');
- }
-
- test_infer_mixin_with_substitution_new_syntax() async {
- await assertNoErrorsInCode('''
-abstract class A<T> {}
-
-class B {}
-
-mixin M<T> on A<List<T>> {}
-
-class C extends A<List<B>> with M {}
-''');
- CompilationUnit unit = result.unit;
- ClassElement classC = unit.declaredElement!.getType('C')!;
- expect(classC.mixins, hasLength(1));
- assertType(classC.mixins[0], 'M<B>');
- }
-
test_initializingFormalForNonExistentField() async {
await assertNoErrorsInCode(r'''
class A {
@@ -2393,39 +2339,6 @@
''');
}
- 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>".
- await assertNoErrorsInCode('''
-class A<T> {}
-class B<T> = Object with A<T>;
-class C = Object with B;
-''');
- var bReference = result.unit.declaredElement!.getType('C')!.mixins[0];
- assertTypeDynamic(bReference.typeArguments[0]);
- }
-
- 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>".
- await assertErrorsInCode('''
-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;
-''', [
- error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 122, 1),
- ]);
- var bReference = result.unit.declaredElement!.getType('C')!.mixins[0];
- assertType(bReference.typeArguments[0], 'int');
- }
-
test_mixinDeclaresConstructor() async {
await assertNoErrorsInCode(r'''
class A {
@@ -2444,30 +2357,6 @@
''');
}
- test_mixinInference_with_actual_mixins() async {
- await assertNoErrorsInCode('''
-class I<X> {}
-
-mixin M0<T> on I<T> {}
-
-mixin M1<T> on I<T> {
- T foo(T a) => a;
-}
-
-class A = I<int> with M0, M1;
-
-void main () {
- var x = new A().foo(0);
- x;
-}
-''');
- var main = result.unit.declarations.last as FunctionDeclaration;
- var mainBody = main.functionExpression.body as BlockFunctionBody;
- var xDecl = mainBody.block.statements[0] as VariableDeclarationStatement;
- var xElem = xDecl.variables.variables[0].declaredElement!;
- assertType(xElem.type, 'int');
- }
-
test_multipleSuperInitializers_no() async {
await assertNoErrorsInCode(r'''
class A {}
diff --git a/pkg/analyzer/test/src/summary/elements_test.dart b/pkg/analyzer/test/src/summary/elements_test.dart
index 30a655d..7101cab 100644
--- a/pkg/analyzer/test/src/summary/elements_test.dart
+++ b/pkg/analyzer/test/src/summary/elements_test.dart
@@ -30683,6 +30683,129 @@
''');
}
+ test_mixin_inference_classAlias_oneMixin() 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>".
+ var library = await buildLibrary(r'''
+class A<T> {}
+class B<T> = Object with A<T>;
+class C = A<int> with B;
+''');
+ checkElementText(library, r'''
+library
+ definingUnit
+ classes
+ class A @6
+ typeParameters
+ covariant T @8
+ defaultType: dynamic
+ constructors
+ synthetic @-1
+ class alias B @20
+ typeParameters
+ covariant T @22
+ defaultType: dynamic
+ supertype: Object
+ mixins
+ A<T>
+ constructors
+ synthetic const @-1
+ constantInitializers
+ SuperConstructorInvocation
+ superKeyword: super @0
+ argumentList: ArgumentList
+ leftParenthesis: ( @0
+ rightParenthesis: ) @0
+ staticElement: dart:core::@class::Object::@constructor::•
+ class alias C @51
+ supertype: A<int>
+ mixins
+ B<dynamic>
+ constructors
+ synthetic @-1
+ constantInitializers
+ SuperConstructorInvocation
+ superKeyword: super @0
+ argumentList: ArgumentList
+ leftParenthesis: ( @0
+ rightParenthesis: ) @0
+ staticElement: self::@class::A::@constructor::•
+ superConstructor: ConstructorMember
+ base: self::@class::A::@constructor::•
+ substitution: {T: int}
+''');
+ }
+
+ test_mixin_inference_classAlias_twoMixins() 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>".
+ var library = await buildLibrary(r'''
+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;
+''');
+ checkElementText(library, r'''
+library
+ definingUnit
+ classes
+ class A1 @6
+ typeParameters
+ covariant T @9
+ defaultType: dynamic
+ constructors
+ synthetic @-1
+ class A2 @21
+ typeParameters
+ covariant T @24
+ defaultType: dynamic
+ constructors
+ synthetic @-1
+ class alias B @36
+ typeParameters
+ covariant T @38
+ defaultType: dynamic
+ supertype: Object
+ mixins
+ A1<T>
+ A2<T>
+ constructors
+ synthetic const @-1
+ constantInitializers
+ SuperConstructorInvocation
+ superKeyword: super @0
+ argumentList: ArgumentList
+ leftParenthesis: ( @0
+ rightParenthesis: ) @0
+ staticElement: dart:core::@class::Object::@constructor::•
+ class Base @75
+ interfaces
+ A1<int>
+ constructors
+ synthetic @-1
+ class alias C @108
+ supertype: Base
+ mixins
+ B<int>
+ constructors
+ synthetic @-1
+ constantInitializers
+ SuperConstructorInvocation
+ superKeyword: super @0
+ argumentList: ArgumentList
+ leftParenthesis: ( @0
+ rightParenthesis: ) @0
+ staticElement: self::@class::Base::@constructor::•
+ superConstructor: self::@class::Base::@constructor::•
+''');
+ }
+
test_mixin_inference_legacy() async {
var library = await buildLibrary(r'''
// @dart = 2.9
@@ -30719,6 +30842,78 @@
''');
}
+ test_mixin_inference_nested_functionType() async {
+ var library = await buildLibrary(r'''
+class A<T> {}
+mixin M<T, U> on A<T Function(U)> {}
+class C extends A<int Function(String)> with M {}
+''');
+ checkElementText(library, r'''
+library
+ definingUnit
+ classes
+ class A @6
+ typeParameters
+ covariant T @8
+ defaultType: dynamic
+ constructors
+ synthetic @-1
+ class C @57
+ supertype: A<int Function(String)>
+ mixins
+ M<int, String>
+ constructors
+ synthetic @-1
+ superConstructor: ConstructorMember
+ base: self::@class::A::@constructor::•
+ substitution: {T: int Function(String)}
+ mixins
+ mixin M @20
+ typeParameters
+ covariant T @22
+ defaultType: dynamic
+ covariant U @25
+ defaultType: dynamic
+ superclassConstraints
+ A<T Function(U)>
+''');
+ }
+
+ test_mixin_inference_nested_interfaceType() async {
+ var library = await buildLibrary(r'''
+abstract class A<T> {}
+mixin M<T> on A<List<T>> {}
+class C extends A<List<int>> with M {}
+''');
+ checkElementText(library, r'''
+library
+ definingUnit
+ classes
+ abstract class A @15
+ typeParameters
+ covariant T @17
+ defaultType: dynamic
+ constructors
+ synthetic @-1
+ class C @57
+ supertype: A<List<int>>
+ mixins
+ M<int>
+ constructors
+ synthetic @-1
+ superConstructor: ConstructorMember
+ base: self::@class::A::@constructor::•
+ substitution: {T: List<int>}
+ mixins
+ mixin M @29
+ typeParameters
+ covariant T @31
+ defaultType: dynamic
+ superclassConstraints
+ A<List<T>>
+''');
+ }
+
test_mixin_inference_nullSafety() async {
var library = await buildLibrary(r'''
class A<T> {}
@@ -30834,6 +31029,57 @@
''');
}
+ test_mixin_inference_twoMixins() async {
+ // Both `M1` and `M2` have their type arguments inferred.
+ var library = await buildLibrary(r'''
+class I<X> {}
+mixin M1<T> on I<T> {}
+mixin M2<T> on I<T> {}
+class A = I<int> with M1, M2;
+''');
+ checkElementText(library, r'''
+library
+ definingUnit
+ classes
+ class I @6
+ typeParameters
+ covariant X @8
+ defaultType: dynamic
+ constructors
+ synthetic @-1
+ class alias A @66
+ supertype: I<int>
+ mixins
+ M1<int>
+ M2<int>
+ constructors
+ synthetic @-1
+ constantInitializers
+ SuperConstructorInvocation
+ superKeyword: super @0
+ argumentList: ArgumentList
+ leftParenthesis: ( @0
+ rightParenthesis: ) @0
+ staticElement: self::@class::I::@constructor::•
+ superConstructor: ConstructorMember
+ base: self::@class::I::@constructor::•
+ substitution: {X: int}
+ mixins
+ mixin M1 @20
+ typeParameters
+ covariant T @23
+ defaultType: dynamic
+ superclassConstraints
+ I<T>
+ mixin M2 @43
+ typeParameters
+ covariant T @46
+ defaultType: dynamic
+ superclassConstraints
+ I<T>
+''');
+ }
+
test_mixin_method_invokesSuperSelf() async {
var library = await buildLibrary(r'''
mixin M on A {