| Index: pkg/front_end/lib/src/fasta/builder/class_builder.dart
|
| diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
|
| index 6cbecb53381ccacb3a42be09234794c967ab64c5..26f5db8f392436d42dba78be2b5b8c4514c089a8 100644
|
| --- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
|
| +++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
|
| @@ -56,8 +56,14 @@ abstract class ClassBuilder<T extends TypeBuilder, R>
|
| /// superclass.
|
| bool get isMixinApplication => mixedInType != null;
|
|
|
| + bool get isNamedMixinApplication {
|
| + return isMixinApplication && super.isNamedMixinApplication;
|
| + }
|
| +
|
| T get mixedInType;
|
|
|
| + void set mixedInType(T mixin);
|
| +
|
| List<ConstructorReferenceBuilder> get constructorReferences => null;
|
|
|
| LibraryBuilder get library {
|
| @@ -115,30 +121,52 @@ abstract class ClassBuilder<T extends TypeBuilder, R>
|
| List arguments;
|
| List variables;
|
| Builder builder;
|
| +
|
| + /// If [application] is mixing in [superclass] directly or via other named
|
| + /// mixin applications, return it.
|
| + NamedTypeBuilder findSuperclass(MixinApplicationBuilder application) {
|
| + for (TypeBuilder t in application.mixins) {
|
| + if (t is NamedTypeBuilder) {
|
| + if (t.builder == superclass) return t;
|
| + } else if (t is MixinApplicationBuilder) {
|
| + NamedTypeBuilder s = findSuperclass(t);
|
| + if (s != null) return s;
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + void handleNamedTypeBuilder(NamedTypeBuilder t) {
|
| + builder = t.builder;
|
| + arguments = t.arguments ?? const [];
|
| + if (builder is ClassBuilder) {
|
| + ClassBuilder cls = builder;
|
| + variables = cls.typeVariables;
|
| + supertype = cls.supertype;
|
| + }
|
| + }
|
| +
|
| while (builder != superclass) {
|
| + variables = null;
|
| if (supertype is NamedTypeBuilder) {
|
| - NamedTypeBuilder t = supertype;
|
| - builder = t.builder;
|
| - arguments = t.arguments;
|
| - if (builder is ClassBuilder) {
|
| - variables = builder.typeVariables;
|
| - if (builder != superclass) {
|
| - supertype = builder.supertype;
|
| - }
|
| - }
|
| + handleNamedTypeBuilder(supertype);
|
| } else if (supertype is MixinApplicationBuilder) {
|
| MixinApplicationBuilder t = supertype;
|
| + NamedTypeBuilder s = findSuperclass(t);
|
| + if (s != null) {
|
| + handleNamedTypeBuilder(s);
|
| + }
|
| supertype = t.supertype;
|
| } else {
|
| - internalError("Superclass not found.", fileUri, charOffset);
|
| + internalError("Superclass not found '${superclass.fullNameForErrors}'.",
|
| + fileUri, charOffset);
|
| }
|
| if (variables != null) {
|
| Map<TypeVariableBuilder, TypeBuilder> directSubstitutionMap =
|
| <TypeVariableBuilder, TypeBuilder>{};
|
| - arguments ??= const [];
|
| for (int i = 0; i < variables.length; i++) {
|
| TypeBuilder argument =
|
| - arguments.length < i ? arguments[i] : dynamicType;
|
| + i < arguments.length ? arguments[i] : dynamicType;
|
| if (substitutionMap != null) {
|
| argument = argument.subst(substitutionMap);
|
| }
|
|
|