| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library fasta.kernel_mixin_application_builder; | 5 library fasta.kernel_mixin_application_builder; |
| 6 | 6 |
| 7 import 'package:kernel/ast.dart' show | 7 import 'package:kernel/ast.dart' show |
| 8 Class, | |
| 9 InterfaceType, | 8 InterfaceType, |
| 10 Supertype; | 9 Supertype, |
| 10 setParents; |
| 11 |
| 12 import '../modifier.dart' show |
| 13 abstractMask; |
| 11 | 14 |
| 12 import 'kernel_builder.dart' show | 15 import 'kernel_builder.dart' show |
| 16 Builder, |
| 17 ConstructorReferenceBuilder, |
| 18 KernelLibraryBuilder, |
| 19 KernelNamedTypeBuilder, |
| 13 KernelTypeBuilder, | 20 KernelTypeBuilder, |
| 14 MixinApplicationBuilder; | 21 KernelTypeVariableBuilder, |
| 22 MixinApplicationBuilder, |
| 23 TypeBuilder, |
| 24 TypeVariableBuilder; |
| 15 | 25 |
| 16 import '../util/relativize.dart' show | 26 import '../util/relativize.dart' show |
| 17 relativizeUri; | 27 relativizeUri; |
| 18 | 28 |
| 29 import '../source/source_class_builder.dart' show |
| 30 SourceClassBuilder; |
| 31 |
| 19 class KernelMixinApplicationBuilder | 32 class KernelMixinApplicationBuilder |
| 20 extends MixinApplicationBuilder<KernelTypeBuilder> | 33 extends MixinApplicationBuilder<KernelTypeBuilder> |
| 21 implements KernelTypeBuilder { | 34 implements KernelTypeBuilder { |
| 22 final int charOffset; | 35 final int charOffset; |
| 23 | 36 |
| 24 final String relativeFileUri; | 37 final String relativeFileUri; |
| 25 | 38 |
| 39 final KernelLibraryBuilder library; |
| 40 |
| 26 Supertype builtType; | 41 Supertype builtType; |
| 27 | 42 |
| 43 List<TypeVariableBuilder> typeVariables; |
| 44 |
| 45 String subclassName; |
| 46 |
| 28 KernelMixinApplicationBuilder(KernelTypeBuilder supertype, | 47 KernelMixinApplicationBuilder(KernelTypeBuilder supertype, |
| 29 List<KernelTypeBuilder> mixins, int charOffset, Uri fileUri) | 48 List<KernelTypeBuilder> mixins, this.library, int charOffset, Uri fileUri) |
| 30 : charOffset = charOffset, | 49 : charOffset = charOffset, |
| 31 relativeFileUri = relativizeUri(fileUri), | 50 relativeFileUri = relativizeUri(fileUri), |
| 32 super(supertype, mixins, charOffset, fileUri); | 51 super(supertype, mixins, charOffset, fileUri); |
| 33 | 52 |
| 34 InterfaceType build() => buildSupertype().asInterfaceType; | 53 InterfaceType build() => buildSupertype().asInterfaceType; |
| 35 | 54 |
| 36 Supertype buildSupertype() { | 55 Supertype buildSupertype() { |
| 37 if (builtType != null) return builtType; | 56 if (builtType != null) return builtType; |
| 38 Supertype supertype = | 57 KernelTypeBuilder s = this.supertype; |
| 39 this.supertype.buildSupertype()?.classNode?.asRawSupertype; | 58 for (KernelTypeBuilder builder in mixins) { |
| 40 if (supertype == null) { | 59 s = applyMixin(s, builder); |
| 41 return null; | |
| 42 } | 60 } |
| 43 for (KernelTypeBuilder builder in mixins) { | 61 builtType = s.buildSupertype(); |
| 44 Supertype mixin = builder.buildSupertype()?.classNode?.asRawSupertype; | |
| 45 if (mixin == null) { | |
| 46 return null; | |
| 47 } | |
| 48 Class application = new Class( | |
| 49 name: "${supertype.classNode.name}&${mixin.classNode.name}", | |
| 50 isAbstract: true, | |
| 51 supertype: supertype, | |
| 52 mixedInType: mixin, | |
| 53 typeParameters: null, // TODO(ahe): Compute these. | |
| 54 fileUri: relativeFileUri); | |
| 55 application.fileOffset = charOffset; | |
| 56 // TODO(ahe): Use asThisSupertype instead and translate type variables. | |
| 57 supertype = application.asRawSupertype; | |
| 58 } | |
| 59 builtType = supertype; | |
| 60 return builtType; | 62 return builtType; |
| 61 } | 63 } |
| 64 |
| 65 TypeBuilder applyMixin(TypeBuilder supertype, TypeBuilder mixin) { |
| 66 KernelLibraryBuilder library = this.library.partOfLibrary ?? this.library; |
| 67 List<TypeVariableBuilder> newTypeVariables; |
| 68 List<KernelTypeBuilder> typeArguments; |
| 69 if (typeVariables != null) { |
| 70 newTypeVariables = library.copyTypeVariables(typeVariables); |
| 71 Map<TypeVariableBuilder, TypeBuilder> substitution = |
| 72 <TypeVariableBuilder, TypeBuilder>{}; |
| 73 typeArguments = <KernelTypeBuilder>[]; |
| 74 for (int i = 0; i < typeVariables.length; i++) { |
| 75 substitution[typeVariables[i]] = newTypeVariables[i].asTypeBuilder(); |
| 76 typeArguments.add(typeVariables[i].asTypeBuilder()); |
| 77 } |
| 78 supertype = supertype.subst(substitution); |
| 79 mixin = mixin.subst(substitution); |
| 80 } |
| 81 // To reduce diff against dartk, we create a different name for mixin |
| 82 // applications that have free type variables. We do this by setting |
| 83 // [subclassName] when setting typeVariables. |
| 84 String name = subclassName != null |
| 85 ? "${subclassName}^${mixin.name}" |
| 86 : "${supertype.name}&${mixin.name}"; |
| 87 SourceClassBuilder cls = new SourceClassBuilder(null, abstractMask, name, |
| 88 newTypeVariables, supertype, null, <String, Builder>{}, library, |
| 89 <ConstructorReferenceBuilder>[], charOffset, null, mixin); |
| 90 library.addImplementationBuilder(name, cls, charOffset); |
| 91 if (newTypeVariables != null) { |
| 92 for (KernelTypeVariableBuilder t in newTypeVariables) { |
| 93 cls.cls.typeParameters.add(t.parameter); |
| 94 } |
| 95 setParents(cls.cls.typeParameters, cls.cls); |
| 96 } |
| 97 return new KernelNamedTypeBuilder(name, typeArguments, charOffset, |
| 98 library.fileUri) |
| 99 ..builder = cls; |
| 100 } |
| 62 } | 101 } |
| OLD | NEW |