Chromium Code Reviews| Index: pkg/front_end/lib/src/fasta/kernel/kernel_mixin_application_builder.dart |
| diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_mixin_application_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_mixin_application_builder.dart |
| index 34a3f8d68a4e1ddcb6dee86a108c5370b67e7acb..a58c1909b6e695fb63ef0e8ca646a697ca474056 100644 |
| --- a/pkg/front_end/lib/src/fasta/kernel/kernel_mixin_application_builder.dart |
| +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_mixin_application_builder.dart |
| @@ -5,17 +5,30 @@ |
| library fasta.kernel_mixin_application_builder; |
| import 'package:kernel/ast.dart' show |
| - Class, |
| InterfaceType, |
| - Supertype; |
| + Supertype, |
| + setParents; |
| + |
| +import '../modifier.dart' show |
| + abstractMask; |
| import 'kernel_builder.dart' show |
| + Builder, |
| + ConstructorReferenceBuilder, |
| + KernelLibraryBuilder, |
| + KernelNamedTypeBuilder, |
| KernelTypeBuilder, |
| - MixinApplicationBuilder; |
| + KernelTypeVariableBuilder, |
| + MixinApplicationBuilder, |
| + TypeBuilder, |
| + TypeVariableBuilder; |
| import '../util/relativize.dart' show |
| relativizeUri; |
| +import '../source/source_class_builder.dart' show |
| + SourceClassBuilder; |
| + |
| class KernelMixinApplicationBuilder |
| extends MixinApplicationBuilder<KernelTypeBuilder> |
| implements KernelTypeBuilder { |
| @@ -23,10 +36,21 @@ class KernelMixinApplicationBuilder |
| final String relativeFileUri; |
| + final KernelLibraryBuilder library; |
| + |
| Supertype builtType; |
| + List<TypeVariableBuilder> typeVariables; |
| + |
| + /// If this mixin application uses type variables, it needs a unique name |
| + /// based on its subclass. |
| + // |
| + // TODO(ahe): This is to reduce diff against dartk. Consider if this is |
| + // necessary. |
| + String subclassName; |
|
karlklose
2017/02/15 09:09:30
Could you move (or copy) this documentation to `Mi
ahe
2017/02/15 09:36:50
Done.
|
| + |
| KernelMixinApplicationBuilder(KernelTypeBuilder supertype, |
| - List<KernelTypeBuilder> mixins, int charOffset, Uri fileUri) |
| + List<KernelTypeBuilder> mixins, this.library, int charOffset, Uri fileUri) |
| : charOffset = charOffset, |
| relativeFileUri = relativizeUri(fileUri), |
| super(supertype, mixins, charOffset, fileUri); |
| @@ -35,28 +59,45 @@ class KernelMixinApplicationBuilder |
| Supertype buildSupertype() { |
| if (builtType != null) return builtType; |
| - Supertype supertype = |
| - this.supertype.buildSupertype()?.classNode?.asRawSupertype; |
| - if (supertype == null) { |
| - return null; |
| - } |
| + KernelTypeBuilder s = this.supertype; |
| for (KernelTypeBuilder builder in mixins) { |
| - Supertype mixin = builder.buildSupertype()?.classNode?.asRawSupertype; |
| - if (mixin == null) { |
| - return null; |
| - } |
| - Class application = new Class( |
| - name: "${supertype.classNode.name}&${mixin.classNode.name}", |
| - isAbstract: true, |
| - supertype: supertype, |
| - mixedInType: mixin, |
| - typeParameters: null, // TODO(ahe): Compute these. |
| - fileUri: relativeFileUri); |
| - application.fileOffset = charOffset; |
| - // TODO(ahe): Use asThisSupertype instead and translate type variables. |
| - supertype = application.asRawSupertype; |
| + s = applyMixin(s, builder); |
| } |
| - builtType = supertype; |
| + builtType = s.buildSupertype(); |
| return builtType; |
| } |
| + |
| + TypeBuilder applyMixin(TypeBuilder supertype, TypeBuilder mixin) { |
| + KernelLibraryBuilder library = this.library.partOfLibrary ?? this.library; |
| + List<TypeVariableBuilder> newTypeVariables; |
| + List<KernelTypeBuilder> typeArguments; |
| + if (typeVariables != null) { |
| + newTypeVariables = library.copyTypeVariables(typeVariables); |
| + Map<TypeVariableBuilder, TypeBuilder> substitution = |
| + <TypeVariableBuilder, TypeBuilder>{}; |
| + typeArguments = <KernelTypeBuilder>[]; |
| + for (int i = 0; i < typeVariables.length; i++) { |
| + substitution[typeVariables[i]] = newTypeVariables[i].asTypeBuilder(); |
| + typeArguments.add(typeVariables[i].asTypeBuilder()); |
| + } |
| + supertype = supertype.subst(substitution); |
| + mixin = mixin.subst(substitution); |
| + } |
| + String name = subclassName != null |
|
karlklose
2017/02/15 09:09:30
Could you add a comment on when these cases happen
ahe
2017/02/15 09:36:50
Done.
|
| + ? "${subclassName}^${mixin.name}" |
| + : "${supertype.name}&${mixin.name}"; |
| + SourceClassBuilder cls = new SourceClassBuilder(null, abstractMask, name, |
| + newTypeVariables, supertype, null, <String, Builder>{}, library, |
| + <ConstructorReferenceBuilder>[], charOffset, null, mixin); |
| + library.addImplementationBuilder(name, cls, charOffset); |
| + if (newTypeVariables != null) { |
| + for (KernelTypeVariableBuilder t in newTypeVariables) { |
| + cls.cls.typeParameters.add(t.parameter); |
| + } |
| + setParents(cls.cls.typeParameters, cls.cls); |
| + } |
| + return new KernelNamedTypeBuilder(name, typeArguments, charOffset, |
| + library.fileUri) |
| + ..builder = cls; |
| + } |
| } |