Compute supertypes
Change-Id: I85fd7894b026180b1bc418602c0f09fcfea0a543
Reviewed-on: https://dart-review.googlesource.com/c/89543
Commit-Queue: Peter von der Ahé <ahe@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
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 af41c71..7e17f6d 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
@@ -288,11 +288,22 @@
/// superclasses.
List<Declaration> interfaceSetters;
+ List<KernelTypeBuilder> superclasses;
+
+ List<KernelTypeBuilder> interfaces;
+
if (supernode == null) {
// This should be Object.
classMembers = localMembers;
classSetters = localSetters;
+ superclasses = new List<KernelTypeBuilder>(0);
+ interfaces = new List<KernelTypeBuilder>(0);
} else {
+ superclasses =
+ new List<KernelTypeBuilder>(supernode.superclasses.length + 1);
+ superclasses.setRange(0, superclasses.length - 1, supernode.superclasses);
+ superclasses[superclasses.length - 1] = cls.supertype;
+
classMembers = merge(
cls, localMembers, supernode.classMembers, MergeKind.superclass);
classSetters = merge(
@@ -307,21 +318,47 @@
// only need to check the local setters.
merge(cls, localSetters, classMembers, MergeKind.accessors);
- List<KernelTypeBuilder> interfaces = cls.interfaces;
+ List<KernelTypeBuilder> directInterfaces = cls.interfaces;
if (cls.isMixinApplication) {
- if (interfaces == null) {
- interfaces = <KernelTypeBuilder>[cls.mixedInType];
+ if (directInterfaces == null) {
+ directInterfaces = <KernelTypeBuilder>[cls.mixedInType];
} else {
- interfaces = <KernelTypeBuilder>[cls.mixedInType]..addAll(interfaces);
+ directInterfaces = <KernelTypeBuilder>[cls.mixedInType]
+ ..addAll(directInterfaces);
}
}
- if (interfaces != null) {
- MergeResult result = mergeInterfaces(cls, supernode, interfaces);
+ if (directInterfaces != null) {
+ MergeResult result = mergeInterfaces(cls, supernode, directInterfaces);
interfaceMembers = result.mergedMembers;
interfaceSetters = result.mergedSetters;
+ interfaces = <KernelTypeBuilder>[];
+ if (supernode.interfaces != null) {
+ List<KernelTypeBuilder> types = supernode.interfaces;
+ for (int i = 0; i < types.length; i++) {
+ addInterface(interfaces, superclasses, types[i]);
+ }
+ }
+ for (int i = 0; i < directInterfaces.length; i++) {
+ addInterface(interfaces, superclasses, directInterfaces[i]);
+ ClassHierarchyNode interfaceNode = getNode(directInterfaces[i]);
+ if (interfaceNode != null) {
+ List<KernelTypeBuilder> types = interfaceNode.superclasses;
+ for (int i = 0; i < types.length; i++) {
+ addInterface(interfaces, superclasses, types[i]);
+ }
+
+ if (interfaceNode.interfaces != null) {
+ List<KernelTypeBuilder> types = interfaceNode.interfaces;
+ for (int i = 0; i < types.length; i++) {
+ addInterface(interfaces, superclasses, types[i]);
+ }
+ }
+ }
+ }
} else {
interfaceMembers = supernode.interfaceMembers;
interfaceSetters = supernode.interfaceSetters;
+ interfaces = supernode.interfaces;
}
if (interfaceMembers != null) {
interfaceMembers =
@@ -340,8 +377,15 @@
merge(cls, classMembers, interfaceSetters, MergeKind.accessors);
}
}
- nodes[cls] = new ClassHierarchyNode(cls, scope, classMembers, classSetters,
- interfaceMembers, interfaceSetters);
+ nodes[cls] = new ClassHierarchyNode(
+ cls,
+ classMembers,
+ classSetters,
+ interfaceMembers,
+ interfaceSetters,
+ superclasses,
+ interfaces,
+ );
if (abstractMembers != null && !cls.isAbstract) {
if (!hasNoSuchMethod) {
@@ -354,6 +398,29 @@
abstractMembers = null;
}
+ KernelTypeBuilder addInterface(List<KernelTypeBuilder> interfaces,
+ List<KernelTypeBuilder> superclasses, KernelTypeBuilder type) {
+ ClassHierarchyNode node = getNode(type);
+ if (node == null) return null;
+ int depth = node.depth;
+ int myDepth = superclasses.length;
+ if (depth < myDepth && superclasses[depth].declaration == node.cls) {
+ // This is a potential conflict.
+ return superclasses[depth];
+ } else {
+ for (int i = 0; i < interfaces.length; i++) {
+ // This is a quadratic algorithm, but normally, the number of
+ // interfaces is really small.
+ if (interfaces[i].declaration == type.declaration) {
+ // This is a potential conflict.
+ return interfaces[i];
+ }
+ }
+ }
+ interfaces.add(type);
+ return null;
+ }
+
MergeResult mergeInterfaces(KernelClassBuilder cls,
ClassHierarchyNode supernode, List<KernelTypeBuilder> interfaces) {
List<List<Declaration>> memberLists =
@@ -569,13 +636,6 @@
/// The class corresponding to this hierarchy node.
final KernelClassBuilder cls;
- /// The local members of [cls]. For regular classes, this is simply
- /// `cls.scope`, but for mixin-applications this is the mixed-in type's
- /// scope. The members are sorted in order of declaration.
- // TODO(ahe): Do we need to copy the scope from the mixed-in type to remove
- // static members?
- final Scope localMembers;
-
/// All the members of this class including [classMembers] of its
/// superclasses. The members are sorted by [compareDeclarations].
final List<Declaration> classMembers;
@@ -593,8 +653,75 @@
/// Similar to [interfaceMembers] but for setters.
final List<Declaration> interfaceSetters;
- ClassHierarchyNode(this.cls, this.localMembers, this.classMembers,
- this.classSetters, this.interfaceMembers, this.interfaceSetters);
+ /// All superclasses of [cls] excluding itself. The classes are sorted by
+ /// depth from the root (Object) in ascending order.
+ final List<KernelTypeBuilder> superclasses;
+
+ /// The list of all classes implemented by [cls] and its supertypes excluding
+ /// any classes from [superclasses].
+ final List<KernelTypeBuilder> interfaces;
+
+ int get depth => superclasses.length;
+
+ ClassHierarchyNode(
+ this.cls,
+ this.classMembers,
+ this.classSetters,
+ this.interfaceMembers,
+ this.interfaceSetters,
+ this.superclasses,
+ this.interfaces);
+
+ String toString([StringBuffer sb]) {
+ sb ??= new StringBuffer();
+ sb
+ ..write(cls.fullNameForErrors)
+ ..writeln(":")
+ ..writeln(" superclasses:");
+ int depth = 0;
+ for (KernelTypeBuilder superclass in superclasses) {
+ sb.write(" " * (depth + 2));
+ if (depth != 0) sb.write("-> ");
+ superclass.printOn(sb);
+ sb.writeln();
+ depth++;
+ }
+ if (interfaces != null) {
+ sb.write(" interfaces:");
+ bool first = true;
+ for (KernelTypeBuilder i in interfaces) {
+ if (!first) sb.write(",");
+ sb.write(" ");
+ i.printOn(sb);
+ first = false;
+ }
+ sb.writeln();
+ }
+ printMembers(classMembers, sb, "classMembers");
+ printMembers(classSetters, sb, "classSetters");
+ if (interfaceMembers != null) {
+ printMembers(interfaceMembers, sb, "interfaceMembers");
+ }
+ if (interfaceSetters != null) {
+ printMembers(interfaceSetters, sb, "interfaceSetters");
+ }
+ return "$sb";
+ }
+
+ void printMembers(
+ List<Declaration> members, StringBuffer sb, String heading) {
+ sb.write(" ");
+ sb.write(heading);
+ sb.writeln(":");
+ for (Declaration member in members) {
+ sb
+ ..write(" ")
+ ..write(member.parent.fullNameForErrors)
+ ..write(".")
+ ..write(member.fullNameForErrors)
+ ..writeln();
+ }
+ }
}
class MergeResult {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index f1b78d6..d52394c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -84,6 +84,7 @@
import 'kernel_builder.dart'
show
ClassBuilder,
+ ClassHierarchyBuilder,
Declaration,
InvalidTypeBuilder,
KernelClassBuilder,
@@ -145,6 +146,8 @@
loader = createLoader();
}
+ void set builderHierarchy(ClassHierarchyBuilder o) {}
+
SourceLoader<Library> createLoader() =>
new SourceLoader<Library>(fileSystem, includeComments, this);
@@ -254,7 +257,8 @@
component =
link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
computeCoreTypes();
- loader.buildClassHierarchy(myClasses, objectClassBuilder);
+ builderHierarchy =
+ loader.buildClassHierarchy(myClasses, objectClassBuilder);
loader.computeHierarchy();
loader.performTopLevelInference(myClasses);
loader.checkSupertypes(myClasses);
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index d951035..8679e5a 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -926,7 +926,7 @@
ticker.logMs("Checked mixin declaration applications");
}
- void buildClassHierarchy(
+ ClassHierarchyBuilder buildClassHierarchy(
List<SourceClassBuilder> sourceClasses, ClassBuilder objectClass) {
ticker.logMs("Building class hierarchy");
ClassHierarchyBuilder classHierarchyBuilder =
@@ -935,6 +935,7 @@
classHierarchyBuilder.add(sourceClasses[i]);
}
ticker.logMs("Built class hierarchy");
+ return classHierarchyBuilder;
}
void createTypeInferenceEngine() {
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index eab5b94..02a8e3a 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -55,6 +55,12 @@
import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
+import 'package:front_end/src/fasta/kernel/class_hierarchy_builder.dart'
+ show ClassHierarchyNode;
+
+import 'package:front_end/src/fasta/kernel/kernel_builder.dart'
+ show ClassHierarchyBuilder;
+
import 'package:front_end/src/fasta/kernel/kernel_target.dart'
show KernelTarget;
@@ -173,6 +179,9 @@
if (kernelTextSerialization) {
steps.add(const KernelTextSerialization());
}
+ if (legacyMode && !fullCompile) {
+ steps.add(new MatchHierarchy());
+ }
if (fullCompile) {
steps.add(const Transform());
if (!ignoreExpectations) {
@@ -348,7 +357,7 @@
UriTranslator uriTranslator = new UriTranslator(
const TargetLibrariesSpecification('vm'),
context.uriTranslator.packages);
- KernelTarget sourceTarget = new KernelTarget(
+ KernelTarget sourceTarget = new KernelTestingTarget(
StandardFileSystem.instance, false, dillTarget, uriTranslator);
sourceTarget.setEntryPoints(<Uri>[description.uri]);
@@ -438,3 +447,32 @@
: fail(component, """Unexpected errors:\n$buffer""");
}
}
+
+class KernelTestingTarget extends KernelTarget {
+ @override
+ ClassHierarchyBuilder builderHierarchy;
+
+ KernelTestingTarget(StandardFileSystem fileSystem, bool includeComments,
+ DillTarget dillTarget, UriTranslator uriTranslator)
+ : super(fileSystem, includeComments, dillTarget, uriTranslator);
+}
+
+class MatchHierarchy extends Step<Component, Component, FastaContext> {
+ const MatchHierarchy();
+
+ String get name => "check hierarchy";
+
+ Future<Result<Component>> run(
+ Component component, FastaContext context) async {
+ Uri uri =
+ component.uriToSource.keys.firstWhere((uri) => uri?.scheme == "file");
+ KernelTestingTarget target = context.componentToTarget[component];
+ ClassHierarchyBuilder hierarchy = target.builderHierarchy;
+ StringBuffer sb = new StringBuffer();
+ for (ClassHierarchyNode node in hierarchy.nodes.values) {
+ node.toString(sb);
+ sb.writeln();
+ }
+ return context.match<Component>(".hierarchy.expect", "$sb", uri, component);
+ }
+}
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart b/pkg/front_end/testcases/complex_class_hierarchy.dart
new file mode 100644
index 0000000..86dba1e
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2019, 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.
+
+main() {}
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+class G<T extends A> {}
+
+class GB extends G<B> {}
+
+class GC extends G<C> {}
+
+class GD extends G<D> {}
+
+class X implements A {}
+
+class Y extends X {}
+
+class Z implements Y {}
+
+class W implements Z {}
+
+class GX implements G<A> {}
+
+class GY extends X implements GB {}
+
+class GZ implements Y, GC {}
+
+class GW implements Z, GD {}
+
+class GU extends GW {}
+
+class GV extends GU implements GW {}
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.hierarchy.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.hierarchy.expect
new file mode 100644
index 0000000..b3c7b13
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.hierarchy.expect
@@ -0,0 +1,459 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ -> A
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C:
+ superclasses:
+ Object
+ -> A
+ -> B
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+D:
+ superclasses:
+ Object
+ -> A
+ -> B
+ -> C
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+G:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+GB:
+ superclasses:
+ Object
+ -> G<B>
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+GC:
+ superclasses:
+ Object
+ -> G<C>
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+GD:
+ superclasses:
+ Object
+ -> G<D>
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+X:
+ superclasses:
+ Object
+ interfaces: A
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+Y:
+ superclasses:
+ Object
+ -> X
+ interfaces: A
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+Z:
+ superclasses:
+ Object
+ interfaces: Y, X, A
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+W:
+ superclasses:
+ Object
+ interfaces: Z, Y, X, A
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+GX:
+ superclasses:
+ Object
+ interfaces: G<A>
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+GY:
+ superclasses:
+ Object
+ -> X
+ interfaces: A, GB, G<B>
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+GZ:
+ superclasses:
+ Object
+ interfaces: Y, X, A, GC, G<C>
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+GW:
+ superclasses:
+ Object
+ interfaces: Z, Y, X, A, GD, G<D>
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+GU:
+ superclasses:
+ Object
+ -> GW
+ interfaces: Z, Y, X, A, GD, G<D>
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+GV:
+ superclasses:
+ Object
+ -> GW
+ -> GU
+ interfaces: Z, Y, X, A, GD, G<D>
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.expect
new file mode 100644
index 0000000..faa6b6d
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.expect
@@ -0,0 +1,95 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+}
+class D extends self::C {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+}
+class G<T extends self::A = dynamic> extends core::Object {
+ synthetic constructor •() → self::G<self::G::T>
+ : super core::Object::•()
+ ;
+}
+class GB extends self::G<self::B> {
+ synthetic constructor •() → self::GB
+ : super self::G::•()
+ ;
+}
+class GC extends self::G<self::C> {
+ synthetic constructor •() → self::GC
+ : super self::G::•()
+ ;
+}
+class GD extends self::G<self::D> {
+ synthetic constructor •() → self::GD
+ : super self::G::•()
+ ;
+}
+class X extends core::Object implements self::A {
+ synthetic constructor •() → self::X
+ : super core::Object::•()
+ ;
+}
+class Y extends self::X {
+ synthetic constructor •() → self::Y
+ : super self::X::•()
+ ;
+}
+class Z extends core::Object implements self::Y {
+ synthetic constructor •() → self::Z
+ : super core::Object::•()
+ ;
+}
+class W extends core::Object implements self::Z {
+ synthetic constructor •() → self::W
+ : super core::Object::•()
+ ;
+}
+class GX extends core::Object implements self::G<self::A> {
+ synthetic constructor •() → self::GX
+ : super core::Object::•()
+ ;
+}
+class GY extends self::X implements self::GB {
+ synthetic constructor •() → self::GY
+ : super self::X::•()
+ ;
+}
+class GZ extends core::Object implements self::Y, self::GC {
+ synthetic constructor •() → self::GZ
+ : super core::Object::•()
+ ;
+}
+class GW extends core::Object implements self::Z, self::GD {
+ synthetic constructor •() → self::GW
+ : super core::Object::•()
+ ;
+}
+class GU extends self::GW {
+ synthetic constructor •() → self::GU
+ : super self::GW::•()
+ ;
+}
+class GV extends self::GU implements self::GW {
+ synthetic constructor •() → self::GV
+ : super self::GU::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.transformed.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.transformed.expect
new file mode 100644
index 0000000..faa6b6d
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.transformed.expect
@@ -0,0 +1,95 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+}
+class D extends self::C {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+}
+class G<T extends self::A = dynamic> extends core::Object {
+ synthetic constructor •() → self::G<self::G::T>
+ : super core::Object::•()
+ ;
+}
+class GB extends self::G<self::B> {
+ synthetic constructor •() → self::GB
+ : super self::G::•()
+ ;
+}
+class GC extends self::G<self::C> {
+ synthetic constructor •() → self::GC
+ : super self::G::•()
+ ;
+}
+class GD extends self::G<self::D> {
+ synthetic constructor •() → self::GD
+ : super self::G::•()
+ ;
+}
+class X extends core::Object implements self::A {
+ synthetic constructor •() → self::X
+ : super core::Object::•()
+ ;
+}
+class Y extends self::X {
+ synthetic constructor •() → self::Y
+ : super self::X::•()
+ ;
+}
+class Z extends core::Object implements self::Y {
+ synthetic constructor •() → self::Z
+ : super core::Object::•()
+ ;
+}
+class W extends core::Object implements self::Z {
+ synthetic constructor •() → self::W
+ : super core::Object::•()
+ ;
+}
+class GX extends core::Object implements self::G<self::A> {
+ synthetic constructor •() → self::GX
+ : super core::Object::•()
+ ;
+}
+class GY extends self::X implements self::GB {
+ synthetic constructor •() → self::GY
+ : super self::X::•()
+ ;
+}
+class GZ extends core::Object implements self::Y, self::GC {
+ synthetic constructor •() → self::GZ
+ : super core::Object::•()
+ ;
+}
+class GW extends core::Object implements self::Z, self::GD {
+ synthetic constructor •() → self::GW
+ : super core::Object::•()
+ ;
+}
+class GU extends self::GW {
+ synthetic constructor •() → self::GU
+ : super self::GW::•()
+ ;
+}
+class GV extends self::GU implements self::GW {
+ synthetic constructor •() → self::GV
+ : super self::GU::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.outline.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.outline.expect
new file mode 100644
index 0000000..f1265b2
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.outline.expect
@@ -0,0 +1,78 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ ;
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ ;
+}
+class D extends self::C {
+ synthetic constructor •() → self::D
+ ;
+}
+class G<T extends self::A = dynamic> extends core::Object {
+ synthetic constructor •() → self::G<self::G::T>
+ ;
+}
+class GB extends self::G<self::B> {
+ synthetic constructor •() → self::GB
+ ;
+}
+class GC extends self::G<self::C> {
+ synthetic constructor •() → self::GC
+ ;
+}
+class GD extends self::G<self::D> {
+ synthetic constructor •() → self::GD
+ ;
+}
+class X extends core::Object implements self::A {
+ synthetic constructor •() → self::X
+ ;
+}
+class Y extends self::X {
+ synthetic constructor •() → self::Y
+ ;
+}
+class Z extends core::Object implements self::Y {
+ synthetic constructor •() → self::Z
+ ;
+}
+class W extends core::Object implements self::Z {
+ synthetic constructor •() → self::W
+ ;
+}
+class GX extends core::Object implements self::G<self::A> {
+ synthetic constructor •() → self::GX
+ ;
+}
+class GY extends self::X implements self::GB {
+ synthetic constructor •() → self::GY
+ ;
+}
+class GZ extends core::Object implements self::Y, self::GC {
+ synthetic constructor •() → self::GZ
+ ;
+}
+class GW extends core::Object implements self::Z, self::GD {
+ synthetic constructor •() → self::GW
+ ;
+}
+class GU extends self::GW {
+ synthetic constructor •() → self::GU
+ ;
+}
+class GV extends self::GU implements self::GW {
+ synthetic constructor •() → self::GV
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.expect
new file mode 100644
index 0000000..1bca20f
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.expect
@@ -0,0 +1,95 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+}
+class D extends self::C {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+}
+class G<T extends self::A = self::A> extends core::Object {
+ synthetic constructor •() → self::G<self::G::T>
+ : super core::Object::•()
+ ;
+}
+class GB extends self::G<self::B> {
+ synthetic constructor •() → self::GB
+ : super self::G::•()
+ ;
+}
+class GC extends self::G<self::C> {
+ synthetic constructor •() → self::GC
+ : super self::G::•()
+ ;
+}
+class GD extends self::G<self::D> {
+ synthetic constructor •() → self::GD
+ : super self::G::•()
+ ;
+}
+class X extends core::Object implements self::A {
+ synthetic constructor •() → self::X
+ : super core::Object::•()
+ ;
+}
+class Y extends self::X {
+ synthetic constructor •() → self::Y
+ : super self::X::•()
+ ;
+}
+class Z extends core::Object implements self::Y {
+ synthetic constructor •() → self::Z
+ : super core::Object::•()
+ ;
+}
+class W extends core::Object implements self::Z {
+ synthetic constructor •() → self::W
+ : super core::Object::•()
+ ;
+}
+class GX extends core::Object implements self::G<self::A> {
+ synthetic constructor •() → self::GX
+ : super core::Object::•()
+ ;
+}
+class GY extends self::X implements self::GB {
+ synthetic constructor •() → self::GY
+ : super self::X::•()
+ ;
+}
+class GZ extends core::Object implements self::Y, self::GC {
+ synthetic constructor •() → self::GZ
+ : super core::Object::•()
+ ;
+}
+class GW extends core::Object implements self::Z, self::GD {
+ synthetic constructor •() → self::GW
+ : super core::Object::•()
+ ;
+}
+class GU extends self::GW {
+ synthetic constructor •() → self::GU
+ : super self::GW::•()
+ ;
+}
+class GV extends self::GU implements self::GW {
+ synthetic constructor •() → self::GV
+ : super self::GU::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.transformed.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.transformed.expect
new file mode 100644
index 0000000..1bca20f
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.transformed.expect
@@ -0,0 +1,95 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+}
+class D extends self::C {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+}
+class G<T extends self::A = self::A> extends core::Object {
+ synthetic constructor •() → self::G<self::G::T>
+ : super core::Object::•()
+ ;
+}
+class GB extends self::G<self::B> {
+ synthetic constructor •() → self::GB
+ : super self::G::•()
+ ;
+}
+class GC extends self::G<self::C> {
+ synthetic constructor •() → self::GC
+ : super self::G::•()
+ ;
+}
+class GD extends self::G<self::D> {
+ synthetic constructor •() → self::GD
+ : super self::G::•()
+ ;
+}
+class X extends core::Object implements self::A {
+ synthetic constructor •() → self::X
+ : super core::Object::•()
+ ;
+}
+class Y extends self::X {
+ synthetic constructor •() → self::Y
+ : super self::X::•()
+ ;
+}
+class Z extends core::Object implements self::Y {
+ synthetic constructor •() → self::Z
+ : super core::Object::•()
+ ;
+}
+class W extends core::Object implements self::Z {
+ synthetic constructor •() → self::W
+ : super core::Object::•()
+ ;
+}
+class GX extends core::Object implements self::G<self::A> {
+ synthetic constructor •() → self::GX
+ : super core::Object::•()
+ ;
+}
+class GY extends self::X implements self::GB {
+ synthetic constructor •() → self::GY
+ : super self::X::•()
+ ;
+}
+class GZ extends core::Object implements self::Y, self::GC {
+ synthetic constructor •() → self::GZ
+ : super core::Object::•()
+ ;
+}
+class GW extends core::Object implements self::Z, self::GD {
+ synthetic constructor •() → self::GW
+ : super core::Object::•()
+ ;
+}
+class GU extends self::GW {
+ synthetic constructor •() → self::GU
+ : super self::GW::•()
+ ;
+}
+class GV extends self::GU implements self::GW {
+ synthetic constructor •() → self::GV
+ : super self::GU::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 669a0f6..aebb6da 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -59,6 +59,7 @@
clone_function_type: TextSerializationFailure # Was: Pass
closure: TextSerializationFailure # Was: Pass
co19_language_metadata_syntax_t04: TextSerializationFailure # Was: Pass
+complex_class_hierarchy: TextSerializationFailure
constructor_const_inference: TextSerializationFailure # Was: Pass
constructor_cycle: TextSerializationFailure # Was: Pass
constructor_function_types: TextSerializationFailure # Was: Pass