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

Side by Side Diff: pkg/compiler/lib/src/resolution/enum_creator.dart

Issue 707463003: Support enums in dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « pkg/compiler/lib/src/elements/modelx.dart ('k') | pkg/compiler/lib/src/resolution/members.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2014, 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 dart2js.resolution.enum_creator;
6
7 import '../dart_types.dart';
8 import '../dart2jslib.dart';
9 import '../elements/elements.dart';
10 import '../elements/modelx.dart';
11 import '../scanner/scannerlib.dart';
12 import '../tree/tree.dart';
13 import '../util/util.dart';
14
15 // TODO(johnniwinther): Merge functionality with the `TreePrinter`.
16 class AstBuilder {
17 final Token position;
18
19 AstBuilder(this.position);
20
21 int get charOffset => position.charOffset;
22
23 final Modifiers finalModifiers =
24 new Modifiers.withFlags(null, Modifiers.FLAG_FINAL);
25 final Modifiers constModifiers =
26 new Modifiers.withFlags(null, Modifiers.FLAG_CONST);
27 final Modifiers staticConstModifiers =
28 new Modifiers.withFlags(null,
29 Modifiers.FLAG_STATIC | Modifiers.FLAG_CONST);
30
31 Token keywordToken(String text) {
32 return new KeywordToken(Keyword.keywords[text], position.charOffset);
33 }
34
35 Token stringToken(String text) {
36 return new StringToken.fromString(IDENTIFIER_INFO, text, charOffset);
37 }
38
39 Token symbolToken(PrecedenceInfo info) {
40 return new SymbolToken(info, charOffset);
41 }
42
43 Identifier identifier(String text) {
44 Keyword keyword = Keyword.keywords[text];
45 Token token;
46 if (keyword != null) {
47 token = new KeywordToken(Keyword.keywords[text], charOffset);
48 } else {
49 token = stringToken(text);
50 }
51 return new Identifier(token);
52 }
53
54 Link linkedList(List elements) {
55 LinkBuilder builder = new LinkBuilder();
56 elements.forEach((e) => builder.addLast(e));
57 return builder.toLink();
58 }
59
60 NodeList argumentList(List<Node> nodes) {
61 return new NodeList(symbolToken(OPEN_PAREN_INFO),
62 linkedList(nodes),
63 symbolToken(CLOSE_PAREN_INFO),
64 ',');
65 }
66
67 Return returnStatement(Expression expression) {
68 return new Return(
69 keywordToken('return'),
70 symbolToken(SEMICOLON_INFO),
71 expression);
72 }
73
74 FunctionExpression functionExpression(Modifiers modifiers,
75 String name,
76 NodeList argumentList,
77 Statement body,
78 [TypeAnnotation returnType]) {
79 return new FunctionExpression(
80 identifier(name),
81 argumentList,
82 body,
83 returnType,
84 modifiers,
85 null, // Initializer.
86 null, // get/set.
87 null // Async modifier.
88 );
89 }
90
91 EmptyStatement emptyStatement() {
92 return new EmptyStatement(symbolToken(COMMA_INFO));
93 }
94
95 LiteralInt literalInt(int value) {
96 return new LiteralInt(stringToken('$value'), null);
97 }
98
99 LiteralString literalString(String text,
100 {String prefix: '"',
101 String suffix: '"'}) {
102 return new LiteralString(stringToken('$prefix$text$suffix'),
103 new DartString.literal(text));
104 }
105
106 LiteralList listLiteral(List<Node> elements, {bool isConst: false}) {
107 return new LiteralList(
108 null,
109 new NodeList(symbolToken(OPEN_SQUARE_BRACKET_INFO),
110 linkedList(elements),
111 symbolToken(CLOSE_SQUARE_BRACKET_INFO),
112 ','),
113 isConst ? keywordToken('const') : null);
114 }
115
116 Node createDefinition(Identifier name, Expression initializer) {
117 if (initializer == null) return name;
118 return new SendSet(null, name, new Operator(symbolToken(EQ_INFO)),
119 new NodeList.singleton(initializer));
120 }
121
122 VariableDefinitions initializingFormal(String fieldName) {
123 return new VariableDefinitions.forParameter(
124 new NodeList.empty(),
125 null,
126 Modifiers.EMPTY,
127 new NodeList.singleton(
128 new Send(identifier('this'), identifier(fieldName))));
129 }
130
131 NewExpression newExpression(String typeName,
132 NodeList arguments,
133 {bool isConst: false}) {
134 return new NewExpression(keywordToken(isConst ? 'const' : 'new'),
135 new Send(null, identifier(typeName), arguments));
136 }
137
138 }
139
140 class EnumCreator {
141 final Compiler compiler;
142 final EnumClassElementX enumClass;
143
144 EnumCreator(this.compiler, this.enumClass);
145
146 void createMembers() {
147 Enum node = enumClass.node;
148 InterfaceType enumType = enumClass.thisType;
149 AstBuilder builder = new AstBuilder(enumClass.position);
150
151 InterfaceType intType = compiler.intClass.computeType(compiler);
152 InterfaceType stringType = compiler.stringClass.computeType(compiler);
153
154 EnumFieldElementX addInstanceMember(String name, InterfaceType type) {
155 Identifier identifier = builder.identifier(name);
156 VariableList variableList = new VariableList(builder.finalModifiers);
157 variableList.type = type;
158 EnumFieldElementX variable = new EnumFieldElementX(
159 identifier, enumClass, variableList, identifier);
160 enumClass.addMember(variable, compiler);
161 return variable;
162 }
163
164 EnumFieldElementX indexVariable = addInstanceMember('index', intType);
165 EnumFieldElementX nameVariable = addInstanceMember('_name', stringType);
166
167 VariableDefinitions indexDefinition = builder.initializingFormal('index');
168 VariableDefinitions nameDefinition = builder.initializingFormal('_name');
169
170 FunctionExpression constructorNode = builder.functionExpression(
171 builder.constModifiers,
172 enumClass.name,
173 builder.argumentList([indexDefinition, nameDefinition]),
174 builder.emptyStatement());
175
176 EnumConstructorElementX constructor = new EnumConstructorElementX(
177 enumClass,
178 builder.constModifiers,
179 constructorNode);
180
181 EnumFormalElementX indexFormal = new EnumFormalElementX(
182 constructor,
183 indexDefinition,
184 builder.identifier('index'),
185 indexVariable);
186
187 EnumFormalElementX nameFormal = new EnumFormalElementX(
188 constructor,
189 nameDefinition,
190 builder.identifier('_name'),
191 nameVariable);
192
193 FunctionSignatureX constructorSignature = new FunctionSignatureX(
194 requiredParameters: builder.linkedList([indexFormal, nameFormal]),
195 requiredParameterCount: 2,
196 type: new FunctionType(constructor, const VoidType(),
197 <DartType>[intType, stringType]));
198 constructor.functionSignatureCache = constructorSignature;
199 enumClass.addMember(constructor, compiler);
200
201 VariableList variableList = new VariableList(builder.staticConstModifiers);
202 variableList.type = enumType;
203 int index = 0;
204 List<Node> valueReferences = <Node>[];
205 for (Link<Node> link = node.names.nodes;
206 !link.isEmpty;
207 link = link.tail) {
208 Identifier name = link.head;
209 AstBuilder valueBuilder = new AstBuilder(name.token);
210 valueReferences.add(new Send(null, name));
211
212 Expression initializer = valueBuilder.newExpression(
213 enumClass.name,
214 valueBuilder.argumentList([
215 valueBuilder.literalInt(index),
216 valueBuilder.literalString('${name.source}')
217 ]),
218 isConst: true);
219 SendSet definition = valueBuilder.createDefinition(name, initializer);
220
221 EnumFieldElementX field = new EnumFieldElementX(
222 name, enumClass, variableList, definition, initializer);
223 enumClass.addMember(field, compiler);
224 index++;
225 }
226
227 VariableList valuesVariableList =
228 new VariableList(builder.staticConstModifiers);
229 InterfaceType listType = compiler.listClass.computeType(compiler);
230 valuesVariableList.type = listType.createInstantiation([enumType]);
231
232 Identifier valuesIdentifier = builder.identifier('values');
233 // TODO(johnniwinther): Add type argument.
234 Expression initializer = builder.listLiteral(
235 valueReferences, isConst: true);
236
237 Node definition = builder.createDefinition(valuesIdentifier, initializer);
238
239 EnumFieldElementX valuesVariable = new EnumFieldElementX(
240 valuesIdentifier, enumClass, valuesVariableList,
241 definition, initializer);
242
243 enumClass.addMember(valuesVariable, compiler);
244
245 // TODO(johnniwinther): Support return type. Note `String` might be prefixed
246 // or not imported within the current library.
247 FunctionExpression toStringNode = builder.functionExpression(
248 Modifiers.EMPTY,
249 'toString',
250 builder.argumentList([]),
251 builder.returnStatement(
252 new StringInterpolation(
253 builder.literalString('${enumClass.name}.', suffix: ''),
254 new NodeList.singleton(new StringInterpolationPart(
255 new Send(null, builder.identifier('_name')),
256 builder.literalString('', prefix: '')))
257 ))
258 );
259
260 EnumMethodElementX toString = new EnumMethodElementX('toString',
261 enumClass, Modifiers.EMPTY, toStringNode);
262 FunctionSignatureX toStringSignature = new FunctionSignatureX(
263 type: new FunctionType(toString, stringType));
264 toString.functionSignatureCache = toStringSignature;
265 enumClass.addMember(toString, compiler);
266 }
267 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/elements/modelx.dart ('k') | pkg/compiler/lib/src/resolution/members.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698