Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(730)

Unified Diff: pkg/fasta/lib/src/kernel/kernel_library_builder.dart

Issue 2631693002: Fasta kernel builders. (Closed)
Patch Set: Address comments. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/fasta/lib/src/kernel/kernel_library_builder.dart
diff --git a/pkg/fasta/lib/src/kernel/kernel_library_builder.dart b/pkg/fasta/lib/src/kernel/kernel_library_builder.dart
new file mode 100644
index 0000000000000000000000000000000000000000..c4f6748e7b997bf362d01d2347fd3d445b48771a
--- /dev/null
+++ b/pkg/fasta/lib/src/kernel/kernel_library_builder.dart
@@ -0,0 +1,281 @@
+// Copyright (c) 2016, 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.
+
+library fasta.kernel_library_builder;
+
+import 'package:kernel/ast.dart';
+
+import 'package:kernel/clone.dart' show
+ CloneVisitor;
+
+import '../errors.dart' show
+ internalError;
+
+import '../loader.dart' show
+ Loader;
+
+import '../modifier.dart' show
+ staticMask;
+
+import '../source/source_library_builder.dart' show
+ SourceLibraryBuilder;
+
+import '../source/source_class_builder.dart' show
+ SourceClassBuilder;
+
+import 'kernel_builder.dart' show
+ Builder,
+ ClassBuilder,
+ ConstructorReferenceBuilder,
+ DynamicTypeBuilder,
+ EnumBuilder,
+ FieldBuilder,
+ FormalParameterBuilder,
+ FunctionTypeAliasBuilder,
+ KernelEnumBuilder,
+ KernelFieldBuilder,
+ KernelFormalParameterBuilder,
+ KernelFunctionTypeAliasBuilder,
+ KernelInterfaceTypeBuilder,
+ KernelInvalidTypeBuilder,
+ KernelMixinApplicationBuilder,
+ KernelNamedMixinApplicationBuilder,
+ KernelProcedureBuilder,
+ KernelTypeBuilder,
+ KernelTypeVariableBuilder,
+ MemberBuilder,
+ MetadataBuilder,
+ MixedAccessor,
+ NamedMixinApplicationBuilder,
+ PrefixBuilder,
+ ProcedureBuilder,
+ TypeVariableBuilder;
+
+class KernelLibraryBuilder
+ extends SourceLibraryBuilder<KernelTypeBuilder, Library> {
+ final Library library;
+
+ final List<Class> mixinApplicationClasses = <Class>[];
+
+ final List<List> argumentsWithMissingDefaultValues = <List>[];
+
+ KernelLibraryBuilder(Uri uri, Loader loader)
+ : library = new Library(uri),
+ super(loader);
+
+ Uri get uri => library.importUri;
+
+ KernelTypeBuilder addInterfaceType(String name,
+ List<KernelTypeBuilder> arguments) {
+ KernelInterfaceTypeBuilder type =
+ new KernelInterfaceTypeBuilder(name, arguments);
+ if (identical(name, "dynamic")) {
+ // TODO(ahe): Make const.
+ type.builder = new DynamicTypeBuilder(const DynamicType());
+ } else {
+ addType(type);
+ }
+ return type;
+ }
+
+ KernelTypeBuilder addMixinApplication(KernelTypeBuilder supertype,
+ List<KernelTypeBuilder> mixins) {
+ KernelTypeBuilder type =
+ new KernelMixinApplicationBuilder(supertype, mixins);
+ return addType(type);
+ }
+
+ KernelTypeBuilder addVoidType() {
+ return new KernelInterfaceTypeBuilder("void", null);
+ }
+
+ ClassBuilder addClass(List<MetadataBuilder> metadata,
+ int modifiers, String className,
+ List<TypeVariableBuilder> typeVariables, KernelTypeBuilder supertype,
+ List<KernelTypeBuilder> interfaces) {
+ ClassBuilder cls = new SourceClassBuilder(metadata, modifiers, className,
+ typeVariables, supertype, interfaces, classMembers, classTypes, this,
+ new List<ConstructorReferenceBuilder>.from(constructorReferences));
+ constructorReferences.clear();
+ classMembers.forEach((String name, MemberBuilder builder) {
+ while (builder != null) {
+ builder.parent = cls;
+ builder = builder.next;
+ }
+ });
+ // Nested scope began in `OutlineBuilder.beginClassDeclaration`.
+ endNestedScope();
+ return addBuilder(className, cls);
+ }
+
+ NamedMixinApplicationBuilder addNamedMixinApplication(
+ List<MetadataBuilder> metadata, String name,
+ List<TypeVariableBuilder> typeVariables, int modifiers,
+ KernelTypeBuilder mixinApplication, List<KernelTypeBuilder> interfaces) {
+ NamedMixinApplicationBuilder builder =
+ new KernelNamedMixinApplicationBuilder(metadata, name, typeVariables,
+ modifiers, mixinApplication, interfaces, classTypes, this);
+ // Nested scope began in `OutlineBuilder.beginNamedMixinApplication`.
+ endNestedScope();
+ return addBuilder(name, builder);
+ }
+
+ FieldBuilder addField(List<MetadataBuilder> metadata,
+ int modifiers, KernelTypeBuilder type, String name) {
+ return addBuilder(name,
+ new KernelFieldBuilder(metadata, type, name, modifiers));
+ }
+
+ ProcedureBuilder addProcedure(List<MetadataBuilder> metadata,
+ int modifiers, KernelTypeBuilder returnType, String name,
+ List<TypeVariableBuilder> typeVariables,
+ List<FormalParameterBuilder> formals, AsyncMarker asyncModifier,
+ ProcedureKind kind) {
+ return addBuilder(name,
+ new KernelProcedureBuilder(metadata, modifiers, returnType, name,
+ typeVariables, formals, asyncModifier, kind));
+ }
+
+ void addFactoryMethod(List<MetadataBuilder> metadata,
+ ConstructorReferenceBuilder constructorName,
+ List<FormalParameterBuilder> formals, AsyncMarker asyncModifier,
+ ConstructorReferenceBuilder redirectionTarget) {
+ String name = constructorName.name;
+ assert(constructorName.suffix == null);
+ addBuilder(name,
+ new KernelProcedureBuilder(metadata, staticMask, null, name, null,
+ formals, asyncModifier, ProcedureKind.Factory, redirectionTarget));
+ }
+
+ EnumBuilder addEnum(List<MetadataBuilder> metadata, String name,
+ List<String> constants) {
+ return addBuilder(name,
+ new KernelEnumBuilder(metadata, name, constants, this));
+ }
+
+ FunctionTypeAliasBuilder addFunctionTypeAlias(List<MetadataBuilder> metadata,
+ KernelTypeBuilder returnType, String name,
+ List<TypeVariableBuilder> typeVariables,
+ List<FormalParameterBuilder> formals) {
+ FunctionTypeAliasBuilder typedef = new KernelFunctionTypeAliasBuilder(
+ metadata, returnType, name, typeVariables, formals, classTypes, this);
+ // Nested scope began in `OutlineBuilder.beginFunctionTypeAlias`.
+ endNestedScope();
+ return addBuilder(name, typedef);
+ }
+
+ KernelFormalParameterBuilder addFormalParameter(
+ List<MetadataBuilder> metadata, int modifiers,
+ KernelTypeBuilder type, String name, bool hasThis) {
+ return new KernelFormalParameterBuilder(
+ metadata, modifiers, type, name, hasThis);
+ }
+
+ KernelTypeVariableBuilder addTypeVariable(String name,
+ KernelTypeBuilder bound) {
+ return new KernelTypeVariableBuilder(name, bound);
+ }
+
+ void buildBuilder(Builder builder) {
+ if (builder is SourceClassBuilder) {
+ Class cls = builder.build(this);
+ library.addClass(cls);
+ Class superclass = cls.superclass;
+ if (superclass != null && superclass.isMixinApplication) {
+ List<Class> mixinApplications = <Class>[];
+ mixinApplicationClasses.add(cls);
+ while (superclass != null && superclass.isMixinApplication) {
+ if (superclass.parent == null) {
+ mixinApplications.add(superclass);
+ }
+ superclass = superclass.superclass;
+ }
+ for (Class cls in mixinApplications.reversed) {
+ // TODO(ahe): Should be able to move this into the above loop as long
+ // as we don't care about matching dartk perfectly.
+ library.addClass(cls);
+ mixinApplicationClasses.add(cls);
+ }
+ }
+ } else if (builder is KernelFieldBuilder) {
+ library.addMember(builder.build(library)..isStatic = true);
+ } else if (builder is KernelProcedureBuilder) {
+ library.addMember(builder.build(library)..isStatic = true);
+ } else if (builder is FunctionTypeAliasBuilder) {
+ // Kernel discard typedefs and use their corresponding function types
+ // directly.
+ } else if (builder is KernelEnumBuilder) {
+ library.addClass(builder.build(this));
+ } else if (builder is PrefixBuilder) {
+ // Ignored. Kernel doesn't represent prefixes.
+ } else {
+ internalError("Unhandled builder: ${builder.runtimeType}");
+ }
+ }
+
+ Library build() {
+ super.build();
+ library.name = name;
+ // TODO(ahe): Set fileUri.
+ // library.fileUri = "${fileUri ?? uri}";
+ return library;
+ }
+
+ Builder buildAmbiguousBuilder(
+ String name, Builder builder, Builder other) {
+ if (builder.next == null && other.next == null) {
+ if (builder.isGetter && other.isSetter) {
+ return new MixedAccessor(builder, other);
+ } else if (builder.isSetter && other.isGetter) {
+ return new MixedAccessor(other, builder);
+ }
+ }
+ return new KernelInvalidTypeBuilder(name, this);
+ }
+
+ void addArgumentsWithMissingDefaultValues(Arguments arguments,
+ FunctionNode function) {
+ assert(partOfLibrary == null);
+ argumentsWithMissingDefaultValues.add([arguments, function]);
+ }
+
+ int finishStaticInvocations() {
+ CloneVisitor cloner;
+ for (var list in argumentsWithMissingDefaultValues) {
+ final Arguments arguments = list[0];
+ final FunctionNode function = list[1];
+
+ Expression defaultArgumentFrom(Expression expression) {
+ if (expression == null) {
+ return new NullLiteral();
+ }
+ cloner ??= new CloneVisitor();
+ return cloner.clone(expression);
+ }
+
+ for (int i = function.requiredParameterCount;
+ i < function.positionalParameters.length;
+ i++) {
+ arguments.positional[i] ??=
+ defaultArgumentFrom(function.positionalParameters[i].initializer)
+ ..parent = arguments;
+ }
+ Map<String, VariableDeclaration> names;
+ for (NamedExpression expression in arguments.named) {
+ if (expression.value == null) {
+ if (names == null) {
+ names = <String, VariableDeclaration>{};
+ for (VariableDeclaration parameter in function.namedParameters) {
+ names[parameter.name] = parameter;
+ }
+ }
+ expression.value =
+ defaultArgumentFrom(names[expression.name].initializer)
+ ..parent = expression;
+ }
+ }
+ }
+ return argumentsWithMissingDefaultValues.length;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698