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

Side by Side Diff: pkg/fasta/lib/src/kernel/kernel_enum_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 unified diff | Download patch
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library fasta.kernel_enum_builder;
6
7 import 'package:kernel/ast.dart' show
8 Arguments,
9 AsyncMarker,
10 Class,
11 Constructor,
12 ConstructorInvocation,
13 DirectPropertyGet,
14 Expression,
15 Field,
16 FieldInitializer,
17 IntLiteral,
18 InterfaceType,
19 ListLiteral,
20 MapEntry,
21 MapLiteral,
22 MethodInvocation,
23 Name,
24 ProcedureKind,
25 ReturnStatement,
26 StaticGet,
27 StringLiteral,
28 ThisExpression,
29 VariableGet;
30
31 import '../errors.dart' show
32 inputError;
33
34 import '../modifier.dart' show
35 constMask,
36 finalMask,
37 staticMask;
38
39 import "../source/source_class_builder.dart" show
40 SourceClassBuilder;
41
42 import 'kernel_builder.dart' show
43 Builder,
44 EnumBuilder,
45 FormalParameterBuilder,
46 KernelConstructorBuilder,
47 KernelFieldBuilder,
48 KernelFormalParameterBuilder,
49 KernelInterfaceTypeBuilder,
50 KernelLibraryBuilder,
51 KernelProcedureBuilder,
52 KernelTypeBuilder,
53 LibraryBuilder,
54 MemberBuilder,
55 MetadataBuilder;
56
57 class KernelEnumBuilder extends SourceClassBuilder
58 implements EnumBuilder<KernelTypeBuilder, InterfaceType> {
59 final List<String> constants;
60
61 final MapLiteral toStringMap;
62
63 final KernelTypeBuilder intType;
64
65 final KernelTypeBuilder stringType;
66
67 KernelEnumBuilder.internal(List<MetadataBuilder> metadata, String name,
68 Map<String, Builder> members, List<KernelTypeBuilder> types, Class cls,
69 this.constants, this.toStringMap, this.intType, this.stringType,
70 LibraryBuilder parent)
71 : super(metadata, 0, name, null, null, null, members, types, parent, null,
72 cls);
73
74 factory KernelEnumBuilder(List<MetadataBuilder> metadata, String name,
75 List<String> constants, LibraryBuilder parent) {
76 constants ??= const <String>[];
77 // TODO(ahe): These types shouldn't be looked up in scope, they come
78 // directly from dart:core.
79 KernelTypeBuilder objectType =
80 new KernelInterfaceTypeBuilder("Object", null);
81 KernelTypeBuilder intType =
82 new KernelInterfaceTypeBuilder("int", null);
83 KernelTypeBuilder stringType =
84 new KernelInterfaceTypeBuilder("String", null);
85 List<KernelTypeBuilder> types = <KernelTypeBuilder>[
86 objectType,
87 intType,
88 stringType];
89 Class cls = new Class(name: name);
90 Map<String, Builder> members = <String, Builder>{};
91 KernelInterfaceTypeBuilder selfType = new KernelInterfaceTypeBuilder(
92 name, null);
93 KernelTypeBuilder listType =
94 new KernelInterfaceTypeBuilder("List", <KernelTypeBuilder>[selfType]);
95 types.add(listType);
96
97 /// From Dart Programming Language Specification 4th Edition/December 2015:
98 /// metadata class E {
99 /// final int index;
100 /// const E(this.index);
101 /// static const E id0 = const E(0);
102 /// ...
103 /// static const E idn-1 = const E(n - 1);
104 /// static const List<E> values = const <E>[id0, ..., idn-1];
105 /// String toString() => { 0: ‘E.id0’, . . ., n-1: ‘E.idn-1’}[index]
106 /// }
107 members["index"] =
108 new KernelFieldBuilder(null, intType, "index", finalMask);
109 KernelConstructorBuilder constructorBuilder = new KernelConstructorBuilder(
110 null, constMask, null, "", null, <FormalParameterBuilder>[
111 new KernelFormalParameterBuilder(null, 0, intType, "index", true)]);
112 members[""] = constructorBuilder;
113 int index = 0;
114 List<MapEntry> toStringEntries = <MapEntry>[];
115 KernelFieldBuilder valuesBuilder = new KernelFieldBuilder(null, listType,
116 "values", constMask | staticMask);
117 members["values"] = valuesBuilder;
118 KernelProcedureBuilder toStringBuilder = new KernelProcedureBuilder(null, 0,
119 stringType, "toString", null, null, AsyncMarker.Sync,
120 ProcedureKind.Method);
121 members["toString"] = toStringBuilder;
122 String className = name;
123 for (String name in constants) {
124 if (members.containsKey(name)) {
125 inputError(null, null, "Duplicated name: $name");
126 continue;
127 }
128 KernelFieldBuilder fieldBuilder =
129 new KernelFieldBuilder(null, selfType, name, constMask | staticMask);
130 members[name] = fieldBuilder;
131 toStringEntries.add(new MapEntry(
132 new IntLiteral(index), new StringLiteral("$className.$name")));
133 index++;
134 }
135 MapLiteral toStringMap = new MapLiteral(toStringEntries, isConst: true);
136 KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal(metadata,
137 name, members, types, cls, constants, toStringMap, intType, stringType,
138 parent);
139 members.forEach((String name, MemberBuilder builder) {
140 builder.parent = enumBuilder;
141 });
142 selfType.builder = enumBuilder;
143 return enumBuilder;
144 }
145
146 InterfaceType buildType(List<KernelTypeBuilder> arguments) {
147 return cls.rawType;
148 }
149
150 Class build(KernelLibraryBuilder libraryBuilder) {
151 if (constants.isEmpty) {
152 libraryBuilder.addCompileTimeError(
153 -1, "An enum declaration can't be empty.");
154 }
155 toStringMap.keyType = intType.build();
156 toStringMap.valueType = stringType.build();
157 KernelFieldBuilder indexFieldBuilder = members["index"];
158 Field indexField = indexFieldBuilder.build(libraryBuilder.library);
159 KernelProcedureBuilder toStringBuilder = members["toString"];
160 toStringBuilder.body = new ReturnStatement(
161 new MethodInvocation(toStringMap, new Name("[]"),
162 new Arguments(<Expression>[
163 new DirectPropertyGet(new ThisExpression(), indexField)])));
164 List<Expression> values = <Expression>[];
165 for (String name in constants) {
166 KernelFieldBuilder builder = members[name];
167 values.add(new StaticGet(builder.build(libraryBuilder.library)));
168 }
169 KernelFieldBuilder valuesBuilder = members["values"];
170 valuesBuilder.build(libraryBuilder.library);
171 valuesBuilder.initializer =
172 new ListLiteral(values, typeArgument: cls.rawType, isConst: true);
173 KernelConstructorBuilder constructorBuilder = members[""];
174 Constructor constructor = constructorBuilder.build(libraryBuilder.library);
175 constructor.initializers.insert(0, new FieldInitializer(indexField,
176 new VariableGet(constructor.function.positionalParameters.single))
177 ..parent = constructor);
178 int index = 0;
179 for (String constant in constants) {
180 KernelFieldBuilder field = members[constant];
181 field.build(libraryBuilder.library);
182 Arguments arguments =
183 new Arguments(<Expression>[new IntLiteral(index++)]);
184 field.initializer =
185 new ConstructorInvocation(constructor, arguments, isConst: true);
186 }
187 return super.build(libraryBuilder);
188 }
189
190 Builder findConstructorOrFactory(String name) => null;
191 }
OLDNEW
« no previous file with comments | « pkg/fasta/lib/src/kernel/kernel_class_builder.dart ('k') | pkg/fasta/lib/src/kernel/kernel_field_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698