Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Unified Diff: tests/compiler/dart2js/members_test.dart

Issue 141753002: Reapply "Implement new model for class members." and "Implement new model for interface members." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix dart2dart bug. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tests/compiler/dart2js/lookup_member_test.dart ('k') | tests/compiler/dart2js/memory_compiler.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/compiler/dart2js/members_test.dart
diff --git a/tests/compiler/dart2js/members_test.dart b/tests/compiler/dart2js/members_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..155c5313eadc06ad051f78be6f905589633914a3
--- /dev/null
+++ b/tests/compiler/dart2js/members_test.dart
@@ -0,0 +1,681 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library members_test;
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'type_test_helper.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
+import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart"
+ show Element, ClassElement, MemberSignature, Name, PublicName;
+import "../../../sdk/lib/_internal/compiler/implementation/resolution/class_members.dart"
+ show SyntheticMember, ErroneousMember;
+
+void main() {
+ testClassMembers();
+ testInterfaceMembers();
+ testClassVsInterfaceMembers();
+ testMixinMembers();
+}
+
+MemberSignature getMember(InterfaceType cls, String name,
+ {bool isSetter: false,
+ int checkType: CHECK_INTERFACE}) {
+ Name memberName =
+ new Name(name, cls.element.getLibrary(), isSetter: isSetter);
+ MemberSignature member = checkType == CHECK_CLASS
+ ? cls.element.lookupClassMember(memberName)
+ : cls.element.lookupInterfaceMember(memberName);
+ if (member != null) {
+ Expect.equals(memberName, member.name);
+ }
+ return member;
+}
+
+/// Check interface member only.
+const int CHECK_INTERFACE = 0;
+/// Check class member only.
+const int CHECK_CLASS = 1;
+/// Check that there is no class member for the interface member.
+const int NO_CLASS_MEMBER = 2;
+/// Check that the interface member is also a class member.
+const int ALSO_CLASS_MEMBER = 3;
+
+/**
+ * Checks [member] or interface member [name] of the declaration of [cls].
+ *
+ * If [inheritFrom] is set, the member from [cls] must be identical to the
+ * member from [inheritedFrom].
+ *
+ * Otherwise, the properties of member are checked against the values of
+ * [isStatic], [isSetter], [isGetter], [declarer], [type] and
+ * [functionType].
+ *
+ * If [synthesizedFrom] or [erroneousFrom] is not `null`, the member is checked
+ * to be synthesized for the corresponding members found on the type is
+ * [synthesizedFrom] or or [erroneousFrom], respectively.
+ * Otherwise, if [declarer] is `null`, the declarer is checked to be [cls], and
+ * if [declarer] is not `null`, the declarer is checked to be [declarer].
+ * If [type] is `null` it is checked that the type of the member is also the
+ * member type, otherwise the type is checked to be [type].
+ *
+ * If [isClassMember] is `true` it is checked that the member is also a class
+ * member.
+ */
+MemberSignature checkMember(InterfaceType cls,
+ String name,
+ {bool isStatic: false,
+ bool isSetter: false,
+ bool isGetter: false,
+ InterfaceType declarer,
+ DartType type,
+ FunctionType functionType,
+ InterfaceType inheritedFrom,
+ List<InterfaceType> synthesizedFrom,
+ List<InterfaceType> erroneousFrom,
+ int checkType: ALSO_CLASS_MEMBER}) {
+ String memberKind = checkType == CHECK_CLASS ? 'class' : 'interface';
+ MemberSignature member =
+ getMember(cls, name, isSetter: isSetter, checkType: checkType);
+ Expect.isNotNull(member, "No $memberKind member '$name' in $cls.");
+ Name memberName = member.name;
+ if (checkType == ALSO_CLASS_MEMBER) {
+ MemberSignature classMember = cls.element.lookupClassMember(memberName);
+ Expect.isNotNull(classMember, "No class member '$memberName' in $cls.");
+ Expect.equals(member, classMember);
+ } else if (checkType == NO_CLASS_MEMBER) {
+ Expect.isNull(cls.element.lookupClassMember(memberName));
+ }
+
+ if (inheritedFrom != null) {
+ MemberSignature inherited = checkType == CHECK_CLASS
+ ? inheritedFrom.element.lookupClassMember(memberName)
+ : inheritedFrom.element.lookupInterfaceMember(memberName);
+ Expect.isNotNull(inherited,
+ "No $memberKind member '$memberName' in $inheritedFrom.");
+ Expect.equals(inherited.inheritFrom(inheritedFrom), member);
+ } else {
+ if (erroneousFrom != null || synthesizedFrom != null) {
+ Expect.notEquals(checkType, CHECK_CLASS,
+ "Arguments 'erroneousFrom' and 'synthesizedFrom' only apply "
+ "to interface members.");
+ if (synthesizedFrom != null) {
+ Expect.isTrue(member is SyntheticMember,
+ "Member '$member' is not synthesized.");
+ } else {
+ Expect.isTrue(member is ErroneousMember,
+ "Member '$member' is not erroneous.");
+ }
+ Set<MemberSignature> members = new Set<MemberSignature>();
+ List from = synthesizedFrom != null ? synthesizedFrom : erroneousFrom;
+ for (InterfaceType type in from) {
+ MemberSignature inheritedMember =
+ type.element.lookupInterfaceMember(memberName);
+ Expect.isNotNull(inheritedMember);
+ members.add(inheritedMember.inheritFrom(type));
+ }
+ Expect.setEquals(members, member.declarations);
+ } else if (declarer != null) {
+ Expect.equals(declarer, member.declarer,
+ "Unexpected declarer '${member.declarer}' of $memberKind member "
+ "'$member'. Expected '${declarer}'.");
+ } else {
+ Expect.equals(cls.element, member.element.getEnclosingClass());
+ Expect.equals(cls, member.declarer);
+ }
+ Expect.equals(isSetter, member.isSetter);
+ Expect.equals(isGetter, member.isGetter);
+ if (type != null) {
+ Expect.equals(type, member.type,
+ "Unexpected type of $memberKind member '$member'.");
+ }
+ if (functionType != null) {
+ if (type == null) {
+ Expect.equals(member.type, member.functionType,
+ "Unexpected type of $memberKind member '$member'.");
+ }
+ Expect.equals(functionType, member.functionType,
+ "Unexpected member type of $memberKind member '$member'.");
+ }
+ }
+ return member;
+}
+
+void checkMemberCount(InterfaceType cls, int expectedCount,
+ {bool interfaceMembers: true}) {
+ int count = 0;
+ if (interfaceMembers) {
+ cls.element.forEachInterfaceMember((_) => count++);
+ } else {
+ cls.element.forEachClassMember((_) => count++);
+ }
+ Expect.equals(expectedCount, count);
+}
+
+void testClassMembers() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ abstract class A {
+ int field;
+ final finalField = 0;
+ static var staticField;
+
+ int get getter => 0;
+ get abstractGetter;
+ void set setter(int _) {}
+ set abstractSetter(_);
+
+ method() {}
+ abstractMethod();
+ static staticMethod() {}
+ }
+ class B<T> {
+ T field;
+ void method(T t) {}
+ static staticMethod() {}
+ toString([T t]) {}
+ }
+ class C<S> extends B<S> {}
+ class D extends C<int> {}
+ class E extends D {}
+ """, useMockCompiler: false).then((env) {
+
+ InterfaceType bool_ = env['bool'];
+ InterfaceType String_ = env['String'];
+ InterfaceType num_ = env['num'];
+ InterfaceType int_ = env['int'];
+ InterfaceType dynamic_ = env['dynamic'];
+ VoidType void_ = env['void'];
+ InterfaceType Type_ = env['Type'];
+ InterfaceType Invocation_ = env['Invocation'];
+
+ InterfaceType Object_ = env['Object'];
+ checkMemberCount(Object_, 5 /*declared*/, interfaceMembers: true);
+ checkMemberCount(Object_, 5 /*declared*/, interfaceMembers: false);
+
+ checkMember(Object_, '==',
+ functionType: env.functionType(bool_, [dynamic_]));
+ checkMember(Object_, 'hashCode',
+ isGetter: true,
+ type: int_, functionType: env.functionType(int_, []));
+ checkMember(Object_, 'noSuchMethod',
+ functionType: env.functionType(dynamic_, [Invocation_]));
+ checkMember(Object_, 'runtimeType',
+ isGetter: true,
+ type: Type_, functionType: env.functionType(Type_, []));
+ checkMember(Object_, 'toString',
+ functionType: env.functionType(String_, []));
+
+ InterfaceType A = env['A'];
+ checkMemberCount(A, 5 /*inherited*/ + 9 /*non-static declared*/,
+ interfaceMembers: true);
+ checkMemberCount(A, 5 /*inherited*/ + 9 /*non-abstract declared*/,
+ interfaceMembers: false);
+
+ checkMember(A, '==', inheritedFrom: Object_);
+ checkMember(A, 'hashCode', inheritedFrom: Object_);
+ checkMember(A, 'noSuchMethod', inheritedFrom: Object_);
+ checkMember(A, 'runtimeType', inheritedFrom: Object_);
+ checkMember(A, 'toString', inheritedFrom: Object_);
+
+ checkMember(A, 'field', isGetter: true,
+ type: int_, functionType: env.functionType(int_, []));
+ checkMember(A, 'field', isSetter: true,
+ type: int_, functionType: env.functionType(void_, [int_]));
+ checkMember(A, 'finalField', isGetter: true,
+ type: dynamic_, functionType: env.functionType(dynamic_, []));
+ checkMember(A, 'staticField', isGetter: true, isStatic: true,
+ checkType: CHECK_CLASS,
+ type: dynamic_, functionType: env.functionType(dynamic_, []));
+ checkMember(A, 'staticField', isSetter: true, isStatic: true,
+ checkType: CHECK_CLASS, type: dynamic_,
+ functionType: env.functionType(void_, [dynamic_]));
+
+ checkMember(A, 'getter', isGetter: true,
+ type: int_, functionType: env.functionType(int_, []));
+ checkMember(A, 'abstractGetter', isGetter: true,
+ checkType: NO_CLASS_MEMBER,
+ type: dynamic_, functionType: env.functionType(dynamic_, []));
+ checkMember(A, 'setter', isSetter: true,
+ type: int_, functionType: env.functionType(void_, [int_]));
+ checkMember(A, 'abstractSetter', isSetter: true,
+ checkType: NO_CLASS_MEMBER, type: dynamic_,
+ functionType: env.functionType(dynamic_, [dynamic_]));
+
+ checkMember(A, 'method', functionType: env.functionType(dynamic_, []));
+ checkMember(A, 'abstractMethod',
+ checkType: NO_CLASS_MEMBER,
+ functionType: env.functionType(dynamic_, []));
+ checkMember(A, 'staticMethod',
+ checkType: CHECK_CLASS,
+ isStatic: true, functionType: env.functionType(dynamic_, []));
+
+ ClassElement B = env.getElement('B');
+ InterfaceType B_this = B.thisType;
+ TypeVariableType B_T = B_this.typeArguments.head;
+ checkMemberCount(B_this, 4 /*inherited*/ + 4 /*non-static declared*/,
+ interfaceMembers: true);
+ checkMemberCount(B_this, 4 /*inherited*/ + 5 /*declared*/,
+ interfaceMembers: false);
+
+ checkMember(B_this, '==', inheritedFrom: Object_);
+ checkMember(B_this, 'hashCode', inheritedFrom: Object_);
+ checkMember(B_this, 'noSuchMethod', inheritedFrom: Object_);
+ checkMember(B_this, 'runtimeType', inheritedFrom: Object_);
+
+ checkMember(B_this, 'field', isGetter: true,
+ type: B_T, functionType: env.functionType(B_T, []));
+ checkMember(B_this, 'field', isSetter: true,
+ type: B_T, functionType: env.functionType(void_, [B_T]));
+ checkMember(B_this, 'method', functionType: env.functionType(void_, [B_T]));
+ checkMember(B_this, 'staticMethod',
+ checkType: CHECK_CLASS,
+ isStatic: true, functionType: env.functionType(dynamic_, []));
+ checkMember(B_this, 'toString',
+ functionType: env.functionType(dynamic_, [],
+ optionalParameters: [B_T]));
+
+ ClassElement C = env.getElement('C');
+ InterfaceType C_this = C.thisType;
+ TypeVariableType C_S = C_this.typeArguments.head;
+ checkMemberCount(C_this, 8 /*inherited*/, interfaceMembers: true);
+ checkMemberCount(C_this, 8 /*inherited*/, interfaceMembers: false);
+ InterfaceType B_S = instantiate(B, [C_S]);
+
+ checkMember(C_this, '==', inheritedFrom: Object_);
+ checkMember(C_this, 'hashCode', inheritedFrom: Object_);
+ checkMember(C_this, 'noSuchMethod', inheritedFrom: Object_);
+ checkMember(C_this, 'runtimeType', inheritedFrom: Object_);
+
+ checkMember(C_this, 'field', isGetter: true,
+ declarer: B_S,
+ type: C_S, functionType: env.functionType(C_S, []));
+ checkMember(C_this, 'field', isSetter: true,
+ declarer: B_S,
+ type: C_S, functionType: env.functionType(void_, [C_S]));
+ checkMember(C_this, 'method',
+ declarer: B_S,
+ functionType: env.functionType(void_, [C_S]));
+ checkMember(C_this, 'toString',
+ declarer: B_S,
+ functionType: env.functionType(dynamic_, [],
+ optionalParameters: [C_S]));
+
+ InterfaceType D = env['D'];
+ checkMemberCount(D, 8 /*inherited*/, interfaceMembers: true);
+ checkMemberCount(D, 8 /*inherited*/, interfaceMembers: false);
+ InterfaceType B_int = instantiate(B, [int_]);
+
+ checkMember(D, '==', inheritedFrom: Object_);
+ checkMember(D, 'hashCode', inheritedFrom: Object_);
+ checkMember(D, 'noSuchMethod', inheritedFrom: Object_);
+ checkMember(D, 'runtimeType', inheritedFrom: Object_);
+
+ checkMember(D, 'field', isGetter: true,
+ declarer: B_int,
+ type: int_, functionType: env.functionType(int_, []));
+ checkMember(D, 'field', isSetter: true,
+ declarer: B_int,
+ type: int_, functionType: env.functionType(void_, [int_]));
+ checkMember(D, 'method',
+ declarer: B_int,
+ functionType: env.functionType(void_, [int_]));
+ checkMember(D, 'toString',
+ declarer: B_int,
+ functionType: env.functionType(dynamic_, [],
+ optionalParameters: [int_]));
+
+ InterfaceType E = env['E'];
+ checkMemberCount(E, 8 /*inherited*/, interfaceMembers: true);
+ checkMemberCount(E, 8 /*inherited*/, interfaceMembers: false);
+
+ checkMember(E, '==', inheritedFrom: Object_);
+ checkMember(E, 'hashCode', inheritedFrom: Object_);
+ checkMember(E, 'noSuchMethod', inheritedFrom: Object_);
+ checkMember(E, 'runtimeType', inheritedFrom: Object_);
+
+ checkMember(E, 'field', isGetter: true,
+ declarer: B_int,
+ type: int_, functionType: env.functionType(int_, []));
+ checkMember(E, 'field', isSetter: true,
+ declarer: B_int,
+ type: int_, functionType: env.functionType(void_, [int_]));
+ checkMember(E, 'method',
+ declarer: B_int,
+ functionType: env.functionType(void_, [int_]));
+ checkMember(E, 'toString',
+ declarer: B_int,
+ functionType: env.functionType(dynamic_, [],
+ optionalParameters: [int_]));
+ }));
+}
+
+void testInterfaceMembers() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ abstract class A {
+ num method1();
+ void method2();
+ void method3();
+ void method4();
+ method5(a);
+ method6(a);
+ method7(a);
+ method8(a, b);
+ method9(a, b, c);
+ method10(a, {b, c});
+ method11(a, {b, c});
+ num get getter1;
+ num get getter2;
+ void set setter1(num _);
+ void set setter2(num _);
+ void set setter3(num _);
+ get getterAndMethod;
+ }
+ abstract class B {
+ int method1();
+ int method2();
+ num method3();
+ num method4();
+ method5([a]);
+ method6([a, b]);
+ method7(a, [b]);
+ method8([a]);
+ method9(a, [b]);
+ method10(a, {c, d});
+ method11(a, b, {c, d});
+ num get getter1;
+ int get getter2;
+ void set setter1(num _);
+ set setter2(num _);
+ void set setter3(int _);
+ getterAndMethod();
+ }
+ abstract class C {
+ int method3();
+ num method4();
+ }
+ abstract class D implements A, B, C {}
+ """).then((env) {
+
+ InterfaceType dynamic_ = env['dynamic'];
+ VoidType void_ = env['void'];
+ InterfaceType num_ = env['num'];
+ InterfaceType int_ = env['int'];
+
+ InterfaceType A = env['A'];
+ InterfaceType B = env['B'];
+ InterfaceType C = env['C'];
+ InterfaceType D = env['D'];
+
+ // A: num method1()
+ // B: int method1()
+ // D: dynamic method1() -- synthesized from A and B.
+ checkMember(D, 'method1',
+ synthesizedFrom: [A, B],
+ functionType: env.functionType(dynamic_ , []),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: void method2()
+ // B: int method2()
+ // D: int method2() -- inherited from B
+ checkMember(D, 'method2', inheritedFrom: B, checkType: NO_CLASS_MEMBER);
+
+ // A: void method3()
+ // B: num method3()
+ // C: int method3()
+ // D: dynamic method3() -- synthesized from A, B, and C.
+ checkMember(D, 'method3',
+ synthesizedFrom: [A, B, C],
+ functionType: env.functionType(dynamic_ , []),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: void method4()
+ // B: num method4()
+ // C: num method4()
+ // D: num method4() -- synthesized from B and C.
+ checkMember(D, 'method4',
+ synthesizedFrom: [B, C],
+ functionType: env.functionType(num_, []),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: method5(a)
+ // B: method5([a])
+ // D: method5([a]) -- inherited from B
+ checkMember(D, 'method5', inheritedFrom: B, checkType: NO_CLASS_MEMBER);
+
+ // A: method6(a)
+ // B: method6([a, b])
+ // D: method6([a, b]) -- inherited from B
+ checkMember(D, 'method6', inheritedFrom: B, checkType: NO_CLASS_MEMBER);
+
+ // A: method7(a)
+ // B: method7(a, [b])
+ // D: method7(a, [b]) -- inherited from B
+ checkMember(D, 'method7', inheritedFrom: B, checkType: NO_CLASS_MEMBER);
+
+ // A: method8(a, b)
+ // B: method8([a])
+ // D: method8([a, b]) -- synthesized from A and B.
+ checkMember(D, 'method8',
+ synthesizedFrom: [A, B],
+ functionType: env.functionType(
+ dynamic_, [], optionalParameters: [dynamic_, dynamic_]),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: method9(a, b, c)
+ // B: method9(a, [b])
+ // D: method9(a, [b, c]) -- synthesized from A and B.
+ checkMember(D, 'method9',
+ synthesizedFrom: [A, B],
+ functionType: env.functionType(
+ dynamic_, [dynamic_], optionalParameters: [dynamic_, dynamic_]),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: method10(a, {b, c})
+ // B: method10(a, {c, d})
+ // D: method10(a, {b, c, d}) -- synthesized from A and B.
+ checkMember(D, 'method10',
+ synthesizedFrom: [A, B],
+ functionType: env.functionType(dynamic_, [dynamic_],
+ namedParameters: {'b': dynamic_,
+ 'c': dynamic_,
+ 'd': dynamic_}),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: method11(a, {b, c})
+ // B: method11(a, b, {c, d})
+ // D: method11(a, [b], {c, d}) -- synthesized from A and B.
+ // TODO(johnniwinther): Change to check synthesized member when function
+ // types with both optional and named parameters are supported.
+ Expect.isNull(getMember(D, 'method11'));
+ /*checkMember(D, 'method11',
+ synthesizedFrom: [A, B],
+ functionType: env.functionType(dynamic_, [dynamic_],
+ optionalParameters: [dynamic_],
+ namedParameters: {'c': dynamic_,
+ 'd': dynamic_,}),
+ checkType: NO_CLASS_MEMBER);*/
+
+ // A: num get getter1
+ // B: num get getter1
+ // D: num get getter1 -- synthesized from A and B.
+ checkMember(D, 'getter1',
+ isGetter: true,
+ synthesizedFrom: [A, B], type: num_,
+ functionType: env.functionType(num_ , []),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: num get getter2
+ // B: int get getter2
+ // D: dynamic get getter2 -- synthesized from A and B.
+ checkMember(D, 'getter2',
+ isGetter: true,
+ synthesizedFrom: [A, B], type: dynamic_,
+ functionType: env.functionType(dynamic_ , []),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: void set setter1(num _)
+ // B: void set setter1(num _)
+ // D: void set setter1(num _) -- synthesized from A and B.
+ checkMember(D, 'setter1',
+ isSetter: true,
+ synthesizedFrom: [A, B], type: num_,
+ functionType: env.functionType(void_ , [num_]),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: void set setter2(num _)
+ // B: set setter2(num _)
+ // D: dynamic set setter2(dynamic _) -- synthesized from A and B.
+ checkMember(D, 'setter2',
+ isSetter: true,
+ synthesizedFrom: [A, B], type: dynamic_,
+ functionType: env.functionType(dynamic_ , [dynamic_]),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: void set setter3(num _)
+ // B: void set setter3(int _)
+ // D: dynamic set setter3(dynamic _) -- synthesized from A and B.
+ checkMember(D, 'setter3',
+ isSetter: true,
+ synthesizedFrom: [A, B], type: dynamic_,
+ functionType: env.functionType(dynamic_ , [dynamic_]),
+ checkType: NO_CLASS_MEMBER);
+
+ // A: get getterAndMethod
+ // B: getterAndMethod()
+ // D: nothing inherited
+ checkMember(D, 'getterAndMethod',
+ erroneousFrom: [A, B],
+ checkType: NO_CLASS_MEMBER);
+ }));
+}
+
+void testClassVsInterfaceMembers() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class A {
+ method1() {}
+ method2() {}
+ }
+ abstract class B {
+ method1();
+ method2(a);
+ }
+ abstract class C extends A implements B {}
+ """).then((env) {
+
+ InterfaceType dynamic_ = env['dynamic'];
+ VoidType void_ = env['void'];
+ InterfaceType num_ = env['num'];
+ InterfaceType int_ = env['int'];
+
+ InterfaceType A = env['A'];
+ InterfaceType B = env['B'];
+ InterfaceType C = env['C'];
+
+ // A: method1()
+ // B: method1()
+ // C class: method1() -- inherited from A.
+ // C interface: dynamic method1() -- synthesized from A and B.
+ MemberSignature interfaceMember =
+ checkMember(C, 'method1', checkType: CHECK_INTERFACE,
+ synthesizedFrom: [A, B],
+ functionType: env.functionType(dynamic_ , []));
+ MemberSignature classMember =
+ checkMember(C, 'method1', checkType: CHECK_CLASS, inheritedFrom: A);
+ Expect.notEquals(interfaceMember, classMember);
+
+ // A: method2()
+ // B: method2(a)
+ // C class: method2() -- inherited from A.
+ // C interface: dynamic method2([a]) -- synthesized from A and B.
+ interfaceMember =
+ checkMember(C, 'method2', checkType: CHECK_INTERFACE,
+ synthesizedFrom: [A, B],
+ functionType: env.functionType(dynamic_ , [],
+ optionalParameters: [dynamic_]));
+ classMember =
+ checkMember(C, 'method2', checkType: CHECK_CLASS, inheritedFrom: A);
+ Expect.notEquals(interfaceMember, classMember);
+ }));
+}
+
+
+void testMixinMembers() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class A<T> {
+ method1() {}
+ method2() {}
+ method3(T a) {}
+ method4(T a) {}
+ }
+ abstract class B<S> {
+ method1();
+ method2(a);
+ method3(S a) {}
+ }
+ abstract class C<U, V> extends Object with A<U> implements B<V> {}
+ """).then((env) {
+
+ InterfaceType dynamic_ = env['dynamic'];
+ VoidType void_ = env['void'];
+ InterfaceType num_ = env['num'];
+ InterfaceType int_ = env['int'];
+
+ ClassElement A = env.getElement('A');
+ ClassElement B = env.getElement('B');
+ ClassElement C = env.getElement('C');
+ InterfaceType C_this = C.thisType;
+ TypeVariableType C_U = C_this.typeArguments.head;
+ TypeVariableType C_V = C_this.typeArguments.tail.head;
+ InterfaceType A_U = instantiate(A, [C_U]);
+ InterfaceType B_V = instantiate(B, [C_V]);
+
+ // A: method1()
+ // B: method1()
+ // C class: method1() -- inherited from A.
+ // C interface: dynamic method1() -- synthesized from A and B.
+ MemberSignature interfaceMember =
+ checkMember(C_this, 'method1', checkType: CHECK_INTERFACE,
+ synthesizedFrom: [A_U, B_V],
+ functionType: env.functionType(dynamic_ , []));
+ MemberSignature classMember =
+ checkMember(C_this, 'method1', checkType: CHECK_CLASS,
+ inheritedFrom: A_U);
+ Expect.notEquals(interfaceMember, classMember);
+
+ // A: method2()
+ // B: method2(a)
+ // C class: method2() -- inherited from A.
+ // C interface: dynamic method2([a]) -- synthesized from A and B.
+ interfaceMember =
+ checkMember(C_this, 'method2', checkType: CHECK_INTERFACE,
+ synthesizedFrom: [A_U, B_V],
+ functionType: env.functionType(dynamic_ , [],
+ optionalParameters: [dynamic_]));
+ classMember =
+ checkMember(C_this, 'method2', checkType: CHECK_CLASS,
+ inheritedFrom: A_U);
+ Expect.notEquals(interfaceMember, classMember);
+
+ // A: method3(U a)
+ // B: method3(V a)
+ // C class: method3(U a) -- inherited from A.
+ // C interface: dynamic method3(a) -- synthesized from A and B.
+ interfaceMember =
+ checkMember(C_this, 'method3', checkType: CHECK_INTERFACE,
+ synthesizedFrom: [A_U, B_V],
+ functionType: env.functionType(dynamic_ , [dynamic_]));
+ classMember =
+ checkMember(C_this, 'method3', checkType: CHECK_CLASS,
+ inheritedFrom: A_U);
+ Expect.notEquals(interfaceMember, classMember);
+
+ // A: method4(U a)
+ // B: --
+ // C class: method4(U a) -- inherited from A.
+ // C interface: method4(U a) -- inherited from A.
+ checkMember(C_this, 'method4', checkType: ALSO_CLASS_MEMBER,
+ inheritedFrom: A_U);
+ }));
+}
« no previous file with comments | « tests/compiler/dart2js/lookup_member_test.dart ('k') | tests/compiler/dart2js/memory_compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698