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

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: 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
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 Modifiers finalModifiers =
floitsch 2014/11/10 16:08:32 final
Johnni Winther 2014/11/11 08:23:37 Done.
24 new Modifiers.withFlags(null, Modifiers.FLAG_FINAL);
25 Modifiers constModifiers =
26 new Modifiers.withFlags(null, Modifiers.FLAG_CONST);
27 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, // get/set.
86 null,
floitsch 2014/11/10 16:08:32 comment, what this one is.
Johnni Winther 2014/11/11 08:23:37 Done.
87 null // Async modifier.
88 );
89 }
90
91 EmptyStatement get emptyStatement => new EmptyStatement(symbolToken(COMMA_INFO ));
floitsch 2014/11/10 16:08:32 long line.
Johnni Winther 2014/11/11 08:23:37 Done.
92
93 LiteralInt literalInt(int value) {
94 return new LiteralInt(stringToken('$value'), null);
95 }
96
97 LiteralString literalString(String text,
98 {String prefix: '"',
99 String suffix: '"'}) {
100 return new LiteralString(stringToken('$prefix$text$suffix'),
101 new DartString.literal(text));
102 }
103
104 LiteralList listLiteral(List<Node> elements, {bool isConst: false}) {
105 return new LiteralList(
106 null,
107 new NodeList(symbolToken(OPEN_SQUARE_BRACKET_INFO),
108 linkedList(elements),
109 symbolToken(CLOSE_SQUARE_BRACKET_INFO),
110 ','),
111 isConst ? keywordToken('const') : null);
112 }
113
114 Node createDefinition(Identifier name, Expression initializer) {
115 if (initializer == null) return name;
116 return new SendSet(null, name, new Operator(symbolToken(EQ_INFO)),
117 new NodeList.singleton(initializer));
118 }
119
120 VariableDefinitions initializingFormal(String fieldName) {
121 return new VariableDefinitions.forParameter(
122 new NodeList.empty(),
123 null,
124 Modifiers.EMPTY,
125 new NodeList.singleton(
126 new Send(identifier('this'), identifier(fieldName))));
127 }
128
129 NewExpression newExpression(String typeName,
130 NodeList arguments,
131 {bool isConst: false}) {
132 return new NewExpression(keywordToken(isConst ? 'const' : 'new'),
133 new Send(null, identifier(typeName), arguments));
134 }
135
136 }
137
138 class EnumCreator {
139 final Compiler compiler;
140 final EnumClassElementX enumClass;
141
142 EnumCreator(this.compiler, this.enumClass);
143
144 void createMembers() {
145 Enum node = enumClass.node;
146 InterfaceType enumType = enumClass.thisType;
147 AstBuilder builder = new AstBuilder(enumClass.position);
148
149 InterfaceType intType = compiler.intClass.computeType(compiler);
150 InterfaceType stringType = compiler.stringClass.computeType(compiler);
151
152 EnumFieldElementX addInstanceMember(String name, InterfaceType type) {
153 Identifier identifier = builder.identifier(name);
154 VariableList variableList = new VariableList(builder.finalModifiers);
155 variableList.type = type;
156 EnumFieldElementX variable = new EnumFieldElementX(
157 identifier, enumClass, variableList, identifier);
158 enumClass.addMember(variable, compiler);
159 return variable;
160 }
161
162 EnumFieldElementX indexVariable = addInstanceMember('index', intType);
163 EnumFieldElementX nameVariable = addInstanceMember('_name', stringType);
164
165 VariableDefinitions indexDefinition = builder.initializingFormal('index');
166 VariableDefinitions nameDefinition = builder.initializingFormal('_name');
167
168 FunctionExpression constructorNode = builder.functionExpression(
169 builder.constModifiers,
170 enumClass.name,
171 builder.argumentList([indexDefinition, nameDefinition]),
172 builder.emptyStatement);
173
174 EnumConstructorElementX constructor = new EnumConstructorElementX(
175 enumClass,
176 builder.constModifiers,
177 constructorNode);
178
179 EnumFormalElementX indexFormal = new EnumFormalElementX(
180 constructor,
181 indexDefinition,
182 builder.identifier('index'),
183 indexVariable);
184
185 EnumFormalElementX nameFormal = new EnumFormalElementX(
186 constructor, nameDefinition,
floitsch 2014/11/10 16:08:32 keep nameDefinition on its own line.
Johnni Winther 2014/11/11 08:23:36 Done.
187 builder.identifier('_name'),
188 nameVariable);
189
190 FunctionSignatureX constructorSignature = new FunctionSignatureX(
191 builder.linkedList([indexFormal, nameFormal]),
192 const Link<Element>(),
floitsch 2014/11/10 16:08:32 what are all these arguments? either add comments
Johnni Winther 2014/11/11 08:23:36 Changed the constructor of FunctionSignatureX to t
193 2, 0, false, const <Element>[],
194 new FunctionType(constructor, const VoidType(),
195 <DartType>[intType, stringType]));
196 constructor.functionSignatureCache = constructorSignature;
197 enumClass.addMember(constructor, compiler);
198
199 VariableList variableList = new VariableList(builder.staticConstModifiers);
200 variableList.type = enumType;
201 int index = 0;
202 List<Node> valueReferences = <Node>[];
203 for (Link<Node> link = node.names.nodes;
204 !link.isEmpty;
205 link = link.tail) {
206 Identifier name = link.head;
207 AstBuilder valueBuilder = new AstBuilder(name.token);
208 valueReferences.add(new Send(null, name));
209
210 Expression initializer = valueBuilder.newExpression(
211 enumClass.name,
212 valueBuilder.argumentList([
213 valueBuilder.literalInt(index),
214 valueBuilder.literalString('${name.source}')
215 ]),
216 isConst: true);
217 SendSet definition = valueBuilder.createDefinition(name, initializer);
218
219 EnumFieldElementX field = new EnumFieldElementX(
220 name, enumClass, variableList, definition, initializer);
221 enumClass.addMember(field, compiler);
222 index++;
223 }
224
225 VariableList valuesVariableList =
226 new VariableList(builder.staticConstModifiers);
227 InterfaceType listType = compiler.listClass.computeType(compiler);
228 valuesVariableList.type = listType.createInstantiation([enumType]);
229
230 Identifier valuesIdentifier = builder.identifier('values');
231 // TODO(johnniwinther): Add type argument.
232 Expression initializer = builder.listLiteral(
233 valueReferences, isConst: true);
234
235 Node definition = builder.createDefinition(valuesIdentifier, initializer);
236
237 EnumFieldElementX valuesVariable = new EnumFieldElementX(
238 valuesIdentifier, enumClass, valuesVariableList,
239 definition, initializer);
240
241 enumClass.addMember(valuesVariable, compiler);
242
243 // TODO(johnniwinther): Support return type. Note `String` might be prefixed
244 // or not imported within the current library.
245 FunctionExpression toStringNode = builder.functionExpression(
246 Modifiers.EMPTY,
247 'toString',
248 builder.argumentList([]),
249 builder.returnStatement(
250 new StringInterpolation(
251 builder.literalString('${enumClass.name}.', suffix: ''),
252 new NodeList.singleton(new StringInterpolationPart(
253 new Send(null, builder.identifier('_name')),
254 builder.literalString('', prefix: '')))
255 ))
256 );
257
258 EnumMethodElementX toString = new EnumMethodElementX('toString',
259 enumClass, Modifiers.EMPTY, toStringNode);
260 FunctionSignatureX toStringSignature = new FunctionSignatureX(
261 const Link<Element>(), const Link<Element>(),
262 0, 0, false, const <Element>[],
263 new FunctionType(toString, stringType));
264 toString.functionSignatureCache = toStringSignature;
265 enumClass.addMember(toString, compiler);
266 }
267 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698