Merge interfaces when building hierarchy
Change-Id: I2d3db2fa653a4caa9f90bdc8557d80f5a2836a52
Reviewed-on: https://dart-review.googlesource.com/c/87641
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index c736ea0..bfea29e 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -4525,7 +4525,6 @@
const MessageCode messageInheritedMembersConflict = const MessageCode(
"InheritedMembersConflict",
analyzerCodes: <String>["CONFLICTS_WITH_INHERITED_MEMBER"],
- severity: Severity.errorLegacyWarning,
message: r"""Can't inherit members that conflict with each other.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 5f7447c..6dc9be2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -14,6 +14,9 @@
LocatedMessage,
messageDeclaredMemberConflictsWithInheritedMember,
messageDeclaredMemberConflictsWithInheritedMemberCause,
+ messageInheritedMembersConflict,
+ messageInheritedMembersConflictCause1,
+ messageInheritedMembersConflictCause2,
templateMissingImplementationCause,
templateMissingImplementationNotAbstract;
@@ -54,7 +57,8 @@
ClassHierarchyBuilder(this.objectClass);
- Declaration handleOverride(Declaration member, Declaration superMember) {
+ Declaration handleOverride(KernelClassBuilder cls, Declaration member,
+ Declaration superMember, bool isMergingInterfaces) {
if (member.next != null || superMember.next != null) {
// Don't check overrides involving duplicated members.
return member;
@@ -64,19 +68,32 @@
if ((memberKind(target) ?? ProcedureKind.Getter) !=
(memberKind(superTarget) ?? ProcedureKind.Getter)) {
String name = member.fullNameForErrors;
- KernelClassBuilder cls = member.parent;
- cls.addProblem(messageDeclaredMemberConflictsWithInheritedMember,
- member.charOffset, name.length,
- context: <LocatedMessage>[
- messageDeclaredMemberConflictsWithInheritedMemberCause.withLocation(
- superMember.fileUri, superMember.charOffset, name.length)
- ]);
+ if (isMergingInterfaces) {
+ cls.addProblem(messageInheritedMembersConflict, cls.charOffset,
+ cls.fullNameForErrors.length,
+ context: <LocatedMessage>[
+ messageInheritedMembersConflictCause1.withLocation(
+ member.fileUri, member.charOffset, name.length),
+ messageInheritedMembersConflictCause2.withLocation(
+ superMember.fileUri, superMember.charOffset, name.length),
+ ]);
+ } else {
+ cls.addProblem(messageDeclaredMemberConflictsWithInheritedMember,
+ member.charOffset, name.length,
+ context: <LocatedMessage>[
+ messageDeclaredMemberConflictsWithInheritedMemberCause
+ .withLocation(
+ superMember.fileUri, superMember.charOffset, name.length)
+ ]);
+ }
}
if (target.name == noSuchMethodName && !target.isAbstract) {
hasNoSuchMethod = true;
}
Declaration result = member;
- if (target.isAbstract) {
+ if (isMergingInterfaces) {
+ // TODO(ahe): Combine the signatures of member and superMember.
+ } else if (target.isAbstract) {
if (!superTarget.isAbstract) {
// An abstract method doesn't override an implemention inherited from a
// superclass.
@@ -88,16 +105,17 @@
return result;
}
- void handleNewMember(Declaration member) {
+ void handleNewMember(Declaration member, bool isMergingInterfaces) {
Member target = member.target;
- if (target.isAbstract) {
+ if (!isMergingInterfaces && target.isAbstract) {
abstractMemberCount++;
}
}
- void handleInheritance(KernelClassBuilder cls, Declaration member) {
+ void handleInheritance(
+ KernelClassBuilder cls, Declaration member, bool isMergingInterfaces) {
Member target = member.target;
- if (target.isAbstract) {
+ if (!isMergingInterfaces && target.isAbstract) {
if (isNameVisibleIn(target.name, cls.library)) {
abstractMemberCount++;
}
@@ -143,16 +161,29 @@
..sort(compareDeclarations);
List<Declaration> allMembers;
List<Declaration> allSetters;
+ List<Declaration> interfaceMembers;
+ List<Declaration> interfaceSetters;
if (supernode == null) {
// This should be Object.
- allMembers = sortedLocals;
- allSetters = sortedSetters;
+ interfaceMembers = allMembers = sortedLocals;
+ interfaceSetters = allSetters = sortedSetters;
} else {
- allMembers = merge(cls, sortedLocals, supernode.classMembers);
- allSetters = merge(cls, sortedSetters, supernode.classSetters);
+ allMembers = merge(cls, sortedLocals, supernode.classMembers, false);
+ allSetters = merge(cls, sortedSetters, supernode.classSetters, false);
+ List<KernelTypeBuilder> interfaces = cls.interfaces;
+ if (interfaces != null) {
+ MergeResult result = mergeInterfaces(cls, supernode, interfaces);
+ interfaceMembers = result.mergedMembers;
+ interfaceSetters = result.mergedSetters;
+ } else {
+ interfaceMembers = allMembers;
+ interfaceSetters = allSetters;
+ }
}
- nodes[cls] = new ClassHierarchyNode(cls, scope, allMembers, allSetters);
+ nodes[cls] = new ClassHierarchyNode(
+ cls, scope, allMembers, allSetters, interfaceMembers, interfaceSetters);
mergeAccessors(cls, allMembers, allSetters);
+
if (abstractMemberCount != 0 && !cls.isAbstract) {
if (!hasNoSuchMethod) {
reportMissingMembers(cls, allMembers, allSetters);
@@ -163,6 +194,46 @@
abstractMemberCount = 0;
}
+ MergeResult mergeInterfaces(KernelClassBuilder cls,
+ ClassHierarchyNode supernode, List<KernelTypeBuilder> interfaces) {
+ List<List<Declaration>> memberLists =
+ List<List<Declaration>>(interfaces.length + 1);
+ List<List<Declaration>> setterLists =
+ List<List<Declaration>>(interfaces.length + 1);
+ memberLists[0] = supernode.interfaceMembers;
+ setterLists[0] = supernode.interfaceSetters;
+ for (int i = 0; i < interfaces.length; i++) {
+ ClassHierarchyNode interfaceNode = getNode(interfaces[i]);
+ if (interfaceNode == null) {
+ memberLists[i + 1] = <Declaration>[];
+ setterLists[i + 1] = <Declaration>[];
+ } else {
+ memberLists[i + 1] = interfaceNode.interfaceMembers;
+ setterLists[i + 1] = interfaceNode.interfaceSetters;
+ }
+ }
+ return new MergeResult(
+ mergeLists(cls, memberLists), mergeLists(cls, setterLists));
+ }
+
+ List<Declaration> mergeLists(
+ KernelClassBuilder cls, List<List<Declaration>> input) {
+ // This is a k-way merge sort (where k is `interfaces.length + 1`). We
+ // merge the lists pairwise, which reduces the number of lists to merge by
+ // half on each iteration. Consequently, we perform O(log k) merges.
+ while (input.length > 1) {
+ List<List<Declaration>> output = <List<Declaration>>[];
+ for (int i = 0; i < input.length - 1; i += 2) {
+ output.add(merge(cls, input[i], input[i + 1], true));
+ }
+ if (input.length.isOdd) {
+ output.add(input.last);
+ }
+ input = output;
+ }
+ return input.single;
+ }
+
/// Merge [and check] accessors. This entails removing setters corresponding
/// to fields, and checking that setters don't override regular methods.
void mergeAccessors(KernelClassBuilder cls, List<Declaration> allMembers,
@@ -284,8 +355,11 @@
return type is KernelNamedTypeBuilder ? type.declaration : null;
}
- List<Declaration> merge(KernelClassBuilder cls,
- List<Declaration> localMembers, List<Declaration> superMembers) {
+ List<Declaration> merge(
+ KernelClassBuilder cls,
+ List<Declaration> localMembers,
+ List<Declaration> superMembers,
+ bool isMergingInterfaces) {
final List<Declaration> mergedMembers = new List<Declaration>.filled(
localMembers.length + superMembers.length, null,
growable: true);
@@ -300,28 +374,28 @@
final int compare = compareDeclarations(localMember, superMember);
if (compare == 0) {
mergedMembers[mergedMemberCount++] =
- handleOverride(localMember, superMember);
+ handleOverride(cls, localMember, superMember, isMergingInterfaces);
i++;
j++;
} else if (compare < 0) {
- handleNewMember(localMember);
+ handleNewMember(localMember, isMergingInterfaces);
mergedMembers[mergedMemberCount++] = localMember;
i++;
} else {
- handleInheritance(cls, superMember);
+ handleInheritance(cls, superMember, isMergingInterfaces);
mergedMembers[mergedMemberCount++] = superMember;
j++;
}
}
while (i < localMembers.length) {
final Declaration localMember = localMembers[i];
- handleNewMember(localMember);
+ handleNewMember(localMember, isMergingInterfaces);
mergedMembers[mergedMemberCount++] = localMember;
i++;
}
while (j < superMembers.length) {
final Declaration superMember = superMembers[j];
- handleInheritance(cls, superMember);
+ handleInheritance(cls, superMember, isMergingInterfaces);
mergedMembers[mergedMemberCount++] = superMember;
j++;
}
@@ -344,8 +418,27 @@
/// superclasses. The members are sorted by [compareDeclarations].
final List<Declaration> classMembers;
+ /// Similar to [classMembers] but for setters.
final List<Declaration> classSetters;
- ClassHierarchyNode(
- this.cls, this.localMembers, this.classMembers, this.classSetters);
+ /// All the interface members of this class including [interfaceMembers] of
+ /// its supertypes. The members are sorted by [compareDeclarations].
+ ///
+ /// In addition to the members of [classMembers] this also contains members
+ /// from interfaces.
+ final List<Declaration> interfaceMembers;
+
+ /// Similar to [interfaceMembers] but for setters.
+ final List<Declaration> interfaceSetters;
+
+ ClassHierarchyNode(this.cls, this.localMembers, this.classMembers,
+ this.classSetters, this.interfaceMembers, this.interfaceSetters);
+}
+
+class MergeResult {
+ final List<Declaration> mergedMembers;
+
+ final List<Declaration> mergedSetters;
+
+ MergeResult(this.mergedMembers, this.mergedSetters);
}
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 76bf2d7..eb90f60 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1947,7 +1947,6 @@
InheritedMembersConflict:
template: "Can't inherit members that conflict with each other."
- severity: ERROR_LEGACY_WARNING
analyzerCode: CONFLICTS_WITH_INHERITED_MEMBER
script:
- >-
diff --git a/pkg/front_end/testcases/abstract_members.dart b/pkg/front_end/testcases/abstract_members.dart
index 82347d4..00f4f14 100644
--- a/pkg/front_end/testcases/abstract_members.dart
+++ b/pkg/front_end/testcases/abstract_members.dart
@@ -2,7 +2,21 @@
// 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.
-abstract class A {
+class Interface1 {
+ void interfaceMethod1() {}
+}
+
+class Interface2 {
+ void interfaceMethod2() {}
+
+ var interfaceMethod1;
+}
+
+class Interface3 {
+ void interfaceMethod3() {}
+}
+
+abstract class A implements Interface1, Interface2, Interface3 {
aMethod() {}
abstractMethod();
void set property1(_);
diff --git a/pkg/front_end/testcases/abstract_members.dart.legacy.expect b/pkg/front_end/testcases/abstract_members.dart.legacy.expect
index 15f50c7..3ac995d 100644
--- a/pkg/front_end/testcases/abstract_members.dart.legacy.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.legacy.expect
@@ -1,6 +1,16 @@
// Formatted problems:
//
-// pkg/front_end/testcases/abstract_members.dart:19:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
+// pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
+// abstract class A implements Interface1, Interface2, Interface3 {
+// ^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: This is one inherited member.
+// void interfaceMethod1() {}
+// ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is the other inherited member.
+// var interfaceMethod1;
+// ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
// - A.abstractMethod
// - A.property3=
// - A.property1=
@@ -12,19 +22,23 @@
//
// class MyClass extends B {
// ^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:7:3: Context: 'A.abstractMethod' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:21:3: Context: 'A.abstractMethod' is defined here.
// abstractMethod();
// ^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:10:12: Context: 'A.property3=' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:24:12: Context: 'A.property3=' is defined here.
// void set property3(_);
// ^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:8:12: Context: 'A.property1=' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:22:12: Context: 'A.property1=' is defined here.
// void set property1(_);
// ^^^^^^^^^
// Unhandled errors:
//
-// pkg/front_end/testcases/abstract_members.dart:19:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
+// pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
+// abstract class A implements Interface1, Interface2, Interface3 {
+// ^
+//
+// pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
// - A.abstractMethod
// - A.property3=
// - A.property1=
@@ -41,7 +55,26 @@
import self as self;
import "dart:core" as core;
-abstract class A extends core::Object {
+class Interface1 extends core::Object {
+ synthetic constructor •() → self::Interface1
+ : super core::Object::•()
+ ;
+ method interfaceMethod1() → void {}
+}
+class Interface2 extends core::Object {
+ field dynamic interfaceMethod1 = null;
+ synthetic constructor •() → self::Interface2
+ : super core::Object::•()
+ ;
+ method interfaceMethod2() → void {}
+}
+class Interface3 extends core::Object {
+ synthetic constructor •() → self::Interface3
+ : super core::Object::•()
+ ;
+ method interfaceMethod3() → void {}
+}
+abstract class A extends core::Object implements self::Interface1, self::Interface2, self::Interface3 {
synthetic constructor •() → self::A
: super core::Object::•()
;
@@ -68,8 +101,12 @@
method aMethod() → dynamic {}
method bMethod() → dynamic {}
method cMethod() → dynamic {}
+ no-such-method-forwarder get interfaceMethod1() → dynamic
+ return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
no-such-method-forwarder set property3(dynamic _) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#property3=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ no-such-method-forwarder set interfaceMethod1(dynamic value) → void
+ return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
no-such-method-forwarder set property1(dynamic _) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#property1=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
diff --git a/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect b/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
index ea90b55..1e1ebac 100644
--- a/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
@@ -1,6 +1,10 @@
// Unhandled errors:
//
-// pkg/front_end/testcases/abstract_members.dart:19:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
+// pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
+// abstract class A implements Interface1, Interface2, Interface3 {
+// ^
+//
+// pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
// - A.abstractMethod
// - A.property3=
// - A.property1=
@@ -17,7 +21,26 @@
import self as self;
import "dart:core" as core;
-abstract class A extends core::Object {
+class Interface1 extends core::Object {
+ synthetic constructor •() → self::Interface1
+ : super core::Object::•()
+ ;
+ method interfaceMethod1() → void {}
+}
+class Interface2 extends core::Object {
+ field dynamic interfaceMethod1 = null;
+ synthetic constructor •() → self::Interface2
+ : super core::Object::•()
+ ;
+ method interfaceMethod2() → void {}
+}
+class Interface3 extends core::Object {
+ synthetic constructor •() → self::Interface3
+ : super core::Object::•()
+ ;
+ method interfaceMethod3() → void {}
+}
+abstract class A extends core::Object implements self::Interface1, self::Interface2, self::Interface3 {
synthetic constructor •() → self::A
: super core::Object::•()
;
@@ -44,8 +67,12 @@
method aMethod() → dynamic {}
method bMethod() → dynamic {}
method cMethod() → dynamic {}
+ no-such-method-forwarder get interfaceMethod1() → dynamic
+ return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
no-such-method-forwarder set property3(dynamic _) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#property3=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ no-such-method-forwarder set interfaceMethod1(dynamic value) → void
+ return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
no-such-method-forwarder set property1(dynamic _) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#property1=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
diff --git a/pkg/front_end/testcases/abstract_members.dart.outline.expect b/pkg/front_end/testcases/abstract_members.dart.outline.expect
index 93b459c..1c95548 100644
--- a/pkg/front_end/testcases/abstract_members.dart.outline.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.outline.expect
@@ -1,6 +1,16 @@
// Formatted problems:
//
-// pkg/front_end/testcases/abstract_members.dart:19:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
+// pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
+// abstract class A implements Interface1, Interface2, Interface3 {
+// ^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: This is one inherited member.
+// void interfaceMethod1() {}
+// ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is the other inherited member.
+// var interfaceMethod1;
+// ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
// - A.abstractMethod
// - A.property3=
// - A.property1=
@@ -12,13 +22,13 @@
//
// class MyClass extends B {
// ^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:7:3: Context: 'A.abstractMethod' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:21:3: Context: 'A.abstractMethod' is defined here.
// abstractMethod();
// ^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:10:12: Context: 'A.property3=' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:24:12: Context: 'A.property3=' is defined here.
// void set property3(_);
// ^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:8:12: Context: 'A.property1=' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:22:12: Context: 'A.property1=' is defined here.
// void set property1(_);
// ^^^^^^^^^
@@ -26,7 +36,26 @@
import self as self;
import "dart:core" as core;
-abstract class A extends core::Object {
+class Interface1 extends core::Object {
+ synthetic constructor •() → self::Interface1
+ ;
+ method interfaceMethod1() → void
+ ;
+}
+class Interface2 extends core::Object {
+ field dynamic interfaceMethod1;
+ synthetic constructor •() → self::Interface2
+ ;
+ method interfaceMethod2() → void
+ ;
+}
+class Interface3 extends core::Object {
+ synthetic constructor •() → self::Interface3
+ ;
+ method interfaceMethod3() → void
+ ;
+}
+abstract class A extends core::Object implements self::Interface1, self::Interface2, self::Interface3 {
synthetic constructor •() → self::A
;
method aMethod() → dynamic
@@ -57,8 +86,12 @@
;
method cMethod() → dynamic
;
+ no-such-method-forwarder get interfaceMethod1() → dynamic
+ return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
no-such-method-forwarder set property3(dynamic _) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#property3=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ no-such-method-forwarder set interfaceMethod1(dynamic value) → void
+ return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
no-such-method-forwarder set property1(dynamic _) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#property1=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
diff --git a/pkg/front_end/testcases/abstract_members.dart.strong.expect b/pkg/front_end/testcases/abstract_members.dart.strong.expect
index 9067a7e..81ff760 100644
--- a/pkg/front_end/testcases/abstract_members.dart.strong.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.strong.expect
@@ -1,8 +1,23 @@
// Formatted problems:
//
-// pkg/front_end/testcases/abstract_members.dart:19:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
+// pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
+// abstract class A implements Interface1, Interface2, Interface3 {
+// ^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: This is one inherited member.
+// void interfaceMethod1() {}
+// ^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is the other inherited member.
+// var interfaceMethod1;
+// ^
+//
+// pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
+// - 'interfaceMethod2'
// - 'abstractMethod'
+// - 'interfaceMethod1'
+// - 'interfaceMethod1'
+// - 'interfaceMethod3'
// - 'property3='
+// - 'interfaceMethod1='
// - 'property1='
// Try to either
// - provide an implementation,
@@ -12,21 +27,45 @@
//
// class MyClass extends B {
// ^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:7:3: Context: 'abstractMethod' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:10:8: Context: 'interfaceMethod2' is defined here.
+// void interfaceMethod2() {}
+// ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:21:3: Context: 'abstractMethod' is defined here.
// abstractMethod();
// ^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:10:12: Context: 'property3=' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: 'interfaceMethod1' is defined here.
+// void interfaceMethod1() {}
+// ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: 'interfaceMethod1' is defined here.
+// var interfaceMethod1;
+// ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'interfaceMethod3' is defined here.
+// void interfaceMethod3() {}
+// ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:24:12: Context: 'property3=' is defined here.
// void set property3(_);
// ^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:8:12: Context: 'property1=' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: 'interfaceMethod1=' is defined here.
+// var interfaceMethod1;
+// ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:22:12: Context: 'property1=' is defined here.
// void set property1(_);
// ^^^^^^^^^
// Unhandled errors:
//
-// pkg/front_end/testcases/abstract_members.dart:19:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
+// pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
+// abstract class A implements Interface1, Interface2, Interface3 {
+// ^
+//
+// pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
+// - 'interfaceMethod2'
// - 'abstractMethod'
+// - 'interfaceMethod1'
+// - 'interfaceMethod1'
+// - 'interfaceMethod3'
// - 'property3='
+// - 'interfaceMethod1='
// - 'property1='
// Try to either
// - provide an implementation,
@@ -41,7 +80,26 @@
import self as self;
import "dart:core" as core;
-abstract class A extends core::Object {
+class Interface1 extends core::Object {
+ synthetic constructor •() → self::Interface1
+ : super core::Object::•()
+ ;
+ method interfaceMethod1() → void {}
+}
+class Interface2 extends core::Object {
+ field dynamic interfaceMethod1 = null;
+ synthetic constructor •() → self::Interface2
+ : super core::Object::•()
+ ;
+ method interfaceMethod2() → void {}
+}
+class Interface3 extends core::Object {
+ synthetic constructor •() → self::Interface3
+ : super core::Object::•()
+ ;
+ method interfaceMethod3() → void {}
+}
+abstract class A extends core::Object implements self::Interface1, self::Interface2, self::Interface3 {
synthetic constructor •() → self::A
: super core::Object::•()
;
@@ -68,8 +126,12 @@
method aMethod() → dynamic {}
method bMethod() → dynamic {}
method cMethod() → dynamic {}
+ no-such-method-forwarder get interfaceMethod1() → dynamic
+ return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
no-such-method-forwarder set property3(dynamic _) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#property3=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ no-such-method-forwarder set interfaceMethod1(dynamic value) → void
+ return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
no-such-method-forwarder set property1(dynamic _) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#property1=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 92b5ce5..20f95d6 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -6,6 +6,7 @@
# Kernel ASTs directly, that is, code in pkg/fasta/lib/src/kernel/ with
# strong-mode enabled.
+abstract_members: TypeCheckError
accessors: RuntimeError
ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
argument_mismatch: InstrumentationMismatch # Test assumes Dart 1.0 semantics
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 5e30091..94e38cd 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -6,6 +6,7 @@
# the round trip for Kernel textual serialization where the initial binary
# Kernel files are produced by compiling Dart code via Fasta.
+abstract_members: TypeCheckError
accessors: RuntimeError
ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
argument_mismatch: InstrumentationMismatch # Test assumes Dart 1.0 semantics