| Index: pkg/fasta/lib/src/kernel/kernel_enum_builder.dart
|
| diff --git a/pkg/fasta/lib/src/kernel/kernel_enum_builder.dart b/pkg/fasta/lib/src/kernel/kernel_enum_builder.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..851c4563e4c8d55f155f8ff96119c15a2a2a7082
|
| --- /dev/null
|
| +++ b/pkg/fasta/lib/src/kernel/kernel_enum_builder.dart
|
| @@ -0,0 +1,191 @@
|
| +// 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_enum_builder;
|
| +
|
| +import 'package:kernel/ast.dart' show
|
| + Arguments,
|
| + AsyncMarker,
|
| + Class,
|
| + Constructor,
|
| + ConstructorInvocation,
|
| + DirectPropertyGet,
|
| + Expression,
|
| + Field,
|
| + FieldInitializer,
|
| + IntLiteral,
|
| + InterfaceType,
|
| + ListLiteral,
|
| + MapEntry,
|
| + MapLiteral,
|
| + MethodInvocation,
|
| + Name,
|
| + ProcedureKind,
|
| + ReturnStatement,
|
| + StaticGet,
|
| + StringLiteral,
|
| + ThisExpression,
|
| + VariableGet;
|
| +
|
| +import '../errors.dart' show
|
| + inputError;
|
| +
|
| +import '../modifier.dart' show
|
| + constMask,
|
| + finalMask,
|
| + staticMask;
|
| +
|
| +import "../source/source_class_builder.dart" show
|
| + SourceClassBuilder;
|
| +
|
| +import 'kernel_builder.dart' show
|
| + Builder,
|
| + EnumBuilder,
|
| + FormalParameterBuilder,
|
| + KernelConstructorBuilder,
|
| + KernelFieldBuilder,
|
| + KernelFormalParameterBuilder,
|
| + KernelInterfaceTypeBuilder,
|
| + KernelLibraryBuilder,
|
| + KernelProcedureBuilder,
|
| + KernelTypeBuilder,
|
| + LibraryBuilder,
|
| + MemberBuilder,
|
| + MetadataBuilder;
|
| +
|
| +class KernelEnumBuilder extends SourceClassBuilder
|
| + implements EnumBuilder<KernelTypeBuilder, InterfaceType> {
|
| + final List<String> constants;
|
| +
|
| + final MapLiteral toStringMap;
|
| +
|
| + final KernelTypeBuilder intType;
|
| +
|
| + final KernelTypeBuilder stringType;
|
| +
|
| + KernelEnumBuilder.internal(List<MetadataBuilder> metadata, String name,
|
| + Map<String, Builder> members, List<KernelTypeBuilder> types, Class cls,
|
| + this.constants, this.toStringMap, this.intType, this.stringType,
|
| + LibraryBuilder parent)
|
| + : super(metadata, 0, name, null, null, null, members, types, parent, null,
|
| + cls);
|
| +
|
| + factory KernelEnumBuilder(List<MetadataBuilder> metadata, String name,
|
| + List<String> constants, LibraryBuilder parent) {
|
| + constants ??= const <String>[];
|
| + // TODO(ahe): These types shouldn't be looked up in scope, they come
|
| + // directly from dart:core.
|
| + KernelTypeBuilder objectType =
|
| + new KernelInterfaceTypeBuilder("Object", null);
|
| + KernelTypeBuilder intType =
|
| + new KernelInterfaceTypeBuilder("int", null);
|
| + KernelTypeBuilder stringType =
|
| + new KernelInterfaceTypeBuilder("String", null);
|
| + List<KernelTypeBuilder> types = <KernelTypeBuilder>[
|
| + objectType,
|
| + intType,
|
| + stringType];
|
| + Class cls = new Class(name: name);
|
| + Map<String, Builder> members = <String, Builder>{};
|
| + KernelInterfaceTypeBuilder selfType = new KernelInterfaceTypeBuilder(
|
| + name, null);
|
| + KernelTypeBuilder listType =
|
| + new KernelInterfaceTypeBuilder("List", <KernelTypeBuilder>[selfType]);
|
| + types.add(listType);
|
| +
|
| + /// From Dart Programming Language Specification 4th Edition/December 2015:
|
| + /// metadata class E {
|
| + /// final int index;
|
| + /// const E(this.index);
|
| + /// static const E id0 = const E(0);
|
| + /// ...
|
| + /// static const E idn-1 = const E(n - 1);
|
| + /// static const List<E> values = const <E>[id0, ..., idn-1];
|
| + /// String toString() => { 0: ‘E.id0’, . . ., n-1: ‘E.idn-1’}[index]
|
| + /// }
|
| + members["index"] =
|
| + new KernelFieldBuilder(null, intType, "index", finalMask);
|
| + KernelConstructorBuilder constructorBuilder = new KernelConstructorBuilder(
|
| + null, constMask, null, "", null, <FormalParameterBuilder>[
|
| + new KernelFormalParameterBuilder(null, 0, intType, "index", true)]);
|
| + members[""] = constructorBuilder;
|
| + int index = 0;
|
| + List<MapEntry> toStringEntries = <MapEntry>[];
|
| + KernelFieldBuilder valuesBuilder = new KernelFieldBuilder(null, listType,
|
| + "values", constMask | staticMask);
|
| + members["values"] = valuesBuilder;
|
| + KernelProcedureBuilder toStringBuilder = new KernelProcedureBuilder(null, 0,
|
| + stringType, "toString", null, null, AsyncMarker.Sync,
|
| + ProcedureKind.Method);
|
| + members["toString"] = toStringBuilder;
|
| + String className = name;
|
| + for (String name in constants) {
|
| + if (members.containsKey(name)) {
|
| + inputError(null, null, "Duplicated name: $name");
|
| + continue;
|
| + }
|
| + KernelFieldBuilder fieldBuilder =
|
| + new KernelFieldBuilder(null, selfType, name, constMask | staticMask);
|
| + members[name] = fieldBuilder;
|
| + toStringEntries.add(new MapEntry(
|
| + new IntLiteral(index), new StringLiteral("$className.$name")));
|
| + index++;
|
| + }
|
| + MapLiteral toStringMap = new MapLiteral(toStringEntries, isConst: true);
|
| + KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal(metadata,
|
| + name, members, types, cls, constants, toStringMap, intType, stringType,
|
| + parent);
|
| + members.forEach((String name, MemberBuilder builder) {
|
| + builder.parent = enumBuilder;
|
| + });
|
| + selfType.builder = enumBuilder;
|
| + return enumBuilder;
|
| + }
|
| +
|
| + InterfaceType buildType(List<KernelTypeBuilder> arguments) {
|
| + return cls.rawType;
|
| + }
|
| +
|
| + Class build(KernelLibraryBuilder libraryBuilder) {
|
| + if (constants.isEmpty) {
|
| + libraryBuilder.addCompileTimeError(
|
| + -1, "An enum declaration can't be empty.");
|
| + }
|
| + toStringMap.keyType = intType.build();
|
| + toStringMap.valueType = stringType.build();
|
| + KernelFieldBuilder indexFieldBuilder = members["index"];
|
| + Field indexField = indexFieldBuilder.build(libraryBuilder.library);
|
| + KernelProcedureBuilder toStringBuilder = members["toString"];
|
| + toStringBuilder.body = new ReturnStatement(
|
| + new MethodInvocation(toStringMap, new Name("[]"),
|
| + new Arguments(<Expression>[
|
| + new DirectPropertyGet(new ThisExpression(), indexField)])));
|
| + List<Expression> values = <Expression>[];
|
| + for (String name in constants) {
|
| + KernelFieldBuilder builder = members[name];
|
| + values.add(new StaticGet(builder.build(libraryBuilder.library)));
|
| + }
|
| + KernelFieldBuilder valuesBuilder = members["values"];
|
| + valuesBuilder.build(libraryBuilder.library);
|
| + valuesBuilder.initializer =
|
| + new ListLiteral(values, typeArgument: cls.rawType, isConst: true);
|
| + KernelConstructorBuilder constructorBuilder = members[""];
|
| + Constructor constructor = constructorBuilder.build(libraryBuilder.library);
|
| + constructor.initializers.insert(0, new FieldInitializer(indexField,
|
| + new VariableGet(constructor.function.positionalParameters.single))
|
| + ..parent = constructor);
|
| + int index = 0;
|
| + for (String constant in constants) {
|
| + KernelFieldBuilder field = members[constant];
|
| + field.build(libraryBuilder.library);
|
| + Arguments arguments =
|
| + new Arguments(<Expression>[new IntLiteral(index++)]);
|
| + field.initializer =
|
| + new ConstructorInvocation(constructor, arguments, isConst: true);
|
| + }
|
| + return super.build(libraryBuilder);
|
| + }
|
| +
|
| + Builder findConstructorOrFactory(String name) => null;
|
| +}
|
|
|