OLD | NEW |
---|---|
(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 } | |
OLD | NEW |