OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.resolution.enum_creator; | 5 library dart2js.resolution.enum_creator; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common_elements.dart' show CommonElements; | 8 import '../common_elements.dart' show CommonElements; |
9 import '../elements/resolution_types.dart'; | 9 import '../elements/resolution_types.dart'; |
10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 /// | 192 /// |
193 // TODO(johnniwinther): Avoid creating synthesized ASTs for enums when SSA is | 193 // TODO(johnniwinther): Avoid creating synthesized ASTs for enums when SSA is |
194 // removed. | 194 // removed. |
195 class EnumCreator { | 195 class EnumCreator { |
196 final DiagnosticReporter reporter; | 196 final DiagnosticReporter reporter; |
197 final CommonElements commonElements; | 197 final CommonElements commonElements; |
198 final EnumClassElementX enumClass; | 198 final EnumClassElementX enumClass; |
199 | 199 |
200 EnumCreator(this.reporter, this.commonElements, this.enumClass); | 200 EnumCreator(this.reporter, this.commonElements, this.enumClass); |
201 | 201 |
202 /// Flag to re-enable the spec-based encoding of the `toString` method. This | |
203 /// is used for equivalence testing with kernel based input. | |
204 static bool USE_CONSTANT_MAP_IN_TO_STRING = false; | |
Siggi Cherem (dart-lang)
2017/05/15 17:05:50
a few nits:
- just use the common camelCaseNotatio
Johnni Winther
2017/05/16 08:29:54
Done.
| |
205 | |
202 void createMembers() { | 206 void createMembers() { |
203 Enum node = enumClass.node; | 207 Enum node = enumClass.node; |
204 ResolutionInterfaceType enumType = enumClass.thisType; | 208 ResolutionInterfaceType enumType = enumClass.thisType; |
205 AstBuilder builder = new AstBuilder(enumClass.position.charOffset); | 209 AstBuilder builder = new AstBuilder(enumClass.position.charOffset); |
206 | 210 |
207 ResolutionInterfaceType intType = commonElements.intType; | 211 ResolutionInterfaceType intType = commonElements.intType; |
208 ResolutionInterfaceType stringType = commonElements.stringType; | 212 ResolutionInterfaceType stringType = commonElements.stringType; |
209 | 213 |
210 EnumFieldElementX addInstanceMember( | 214 EnumFieldElementX addInstanceMember( |
211 String name, ResolutionInterfaceType type) { | 215 String name, ResolutionInterfaceType type) { |
212 Identifier identifier = builder.identifier(name); | 216 Identifier identifier = builder.identifier(name); |
213 VariableList variableList = | 217 VariableList variableList = |
214 new VariableList(builder.modifiers(isFinal: true)); | 218 new VariableList(builder.modifiers(isFinal: true)); |
215 variableList.type = type; | 219 variableList.type = type; |
216 EnumFieldElementX variable = new EnumFieldElementX( | 220 EnumFieldElementX variable = new EnumFieldElementX( |
217 identifier, enumClass, variableList, identifier); | 221 identifier, enumClass, variableList, identifier); |
218 enumClass.addMember(variable, reporter); | 222 enumClass.addMember(variable, reporter); |
219 return variable; | 223 return variable; |
220 } | 224 } |
221 | 225 |
222 EnumFieldElementX indexVariable = addInstanceMember('index', intType); | 226 EnumFieldElementX indexVariable = addInstanceMember('index', intType); |
223 EnumFieldElementX nameVariable = addInstanceMember('_name', stringType); | 227 EnumFieldElementX nameVariable; |
224 | 228 |
225 VariableDefinitions indexDefinition = builder.initializingFormal('index'); | 229 VariableDefinitions indexDefinition = builder.initializingFormal('index'); |
226 VariableDefinitions nameDefinition = builder.initializingFormal('_name'); | 230 VariableDefinitions nameDefinition; |
227 | 231 |
232 List<Node> constructorInitializers = <Node>[indexDefinition]; | |
233 if (!USE_CONSTANT_MAP_IN_TO_STRING) { | |
234 nameVariable = addInstanceMember('_name', stringType); | |
235 nameDefinition = builder.initializingFormal('_name'); | |
236 constructorInitializers.add(nameDefinition); | |
237 } | |
228 FunctionExpression constructorNode = builder.functionExpression( | 238 FunctionExpression constructorNode = builder.functionExpression( |
229 builder.modifiers(isConst: true), | 239 builder.modifiers(isConst: true), |
230 enumClass.name, | 240 enumClass.name, |
231 null, // typeVariables | 241 null, // typeVariables |
232 builder.argumentList([indexDefinition, nameDefinition]), | 242 builder.argumentList(constructorInitializers), |
233 builder.emptyStatement()); | 243 builder.emptyStatement()); |
234 | 244 |
235 EnumConstructorElementX constructor = new EnumConstructorElementX( | 245 EnumConstructorElementX constructor = new EnumConstructorElementX( |
236 enumClass, builder.modifiers(isConst: true), constructorNode); | 246 enumClass, builder.modifiers(isConst: true), constructorNode); |
237 | 247 |
238 EnumFormalElementX indexFormal = new EnumFormalElementX(constructor, | 248 EnumFormalElementX indexFormal = new EnumFormalElementX(constructor, |
239 indexDefinition, builder.identifier('index'), indexVariable); | 249 indexDefinition, builder.identifier('index'), indexVariable); |
240 | 250 |
241 EnumFormalElementX nameFormal = new EnumFormalElementX( | 251 EnumFormalElementX nameFormal; |
242 constructor, nameDefinition, builder.identifier('_name'), nameVariable); | |
243 | 252 |
253 List<Element> parameters = <Element>[indexFormal]; | |
254 List<ResolutionDartType> parameterTypes = <ResolutionDartType>[intType]; | |
255 if (!USE_CONSTANT_MAP_IN_TO_STRING) { | |
256 nameFormal = new EnumFormalElementX(constructor, nameDefinition, | |
257 builder.identifier('_name'), nameVariable); | |
258 parameters.add(nameFormal); | |
259 parameterTypes.add(stringType); | |
260 } | |
244 FunctionSignatureX constructorSignature = new FunctionSignatureX( | 261 FunctionSignatureX constructorSignature = new FunctionSignatureX( |
245 requiredParameters: [indexFormal, nameFormal], | 262 requiredParameters: parameters, |
246 requiredParameterCount: 2, | 263 requiredParameterCount: parameters.length, |
247 type: new ResolutionFunctionType( | 264 type: new ResolutionFunctionType( |
248 constructor, | 265 constructor, const ResolutionDynamicType(), parameterTypes)); |
249 const ResolutionDynamicType(), | |
250 <ResolutionDartType>[intType, stringType])); | |
251 constructor.functionSignature = constructorSignature; | 266 constructor.functionSignature = constructorSignature; |
252 enumClass.addMember(constructor, reporter); | 267 enumClass.addMember(constructor, reporter); |
253 | 268 |
254 List<EnumConstantElement> enumValues = <EnumConstantElement>[]; | 269 List<EnumConstantElement> enumValues = <EnumConstantElement>[]; |
255 int index = 0; | 270 int index = 0; |
256 List<Node> valueReferences = <Node>[]; | 271 List<Node> valueReferences = <Node>[]; |
272 List<LiteralMapEntry> mapEntries; | |
273 if (USE_CONSTANT_MAP_IN_TO_STRING) { | |
274 mapEntries = <LiteralMapEntry>[]; | |
275 } | |
257 for (Link<Node> link = node.names.nodes; !link.isEmpty; link = link.tail) { | 276 for (Link<Node> link = node.names.nodes; !link.isEmpty; link = link.tail) { |
258 Identifier name = link.head; | 277 Identifier name = link.head; |
259 AstBuilder valueBuilder = new AstBuilder(name.token.charOffset); | 278 AstBuilder valueBuilder = new AstBuilder(name.token.charOffset); |
260 VariableList variableList = new VariableList( | 279 VariableList variableList = new VariableList( |
261 valueBuilder.modifiers(isStatic: true, isConst: true)); | 280 valueBuilder.modifiers(isStatic: true, isConst: true)); |
262 variableList.type = enumType; | 281 variableList.type = enumType; |
263 | 282 |
264 // Add reference for the `values` field. | 283 // Add reference for the `values` field. |
265 valueReferences.add(valueBuilder.reference(name)); | 284 valueReferences.add(valueBuilder.reference(name)); |
266 | 285 |
267 Expression initializer = valueBuilder.newExpression( | 286 Node indexValue = valueBuilder.literalInt(index); |
268 enumClass.name, | 287 Node nameValue = |
269 valueBuilder.argumentList([ | 288 valueBuilder.literalString('${enumClass.name}.${name.source}'); |
270 valueBuilder.literalInt(index), | 289 Expression initializer; |
271 valueBuilder.literalString('${enumClass.name}.${name.source}') | 290 if (USE_CONSTANT_MAP_IN_TO_STRING) { |
272 ]), | 291 // Add map entry for `toString` implementation. |
273 isConst: true); | 292 mapEntries.add(valueBuilder.mapLiteralEntry(indexValue, nameValue)); |
293 | |
294 initializer = valueBuilder.newExpression(enumClass.name, | |
295 valueBuilder.argumentList([valueBuilder.literalInt(index)]), | |
Siggi Cherem (dart-lang)
2017/05/15 17:05:50
reuse indexValue
Johnni Winther
2017/05/16 08:29:54
Done.
| |
296 isConst: true); | |
297 } else { | |
298 initializer = valueBuilder.newExpression( | |
299 enumClass.name, valueBuilder.argumentList([indexValue, nameValue]), | |
300 isConst: true); | |
301 } | |
274 SendSet definition = valueBuilder.createDefinition(name, initializer); | 302 SendSet definition = valueBuilder.createDefinition(name, initializer); |
275 | 303 |
276 EnumConstantElementX field = new EnumConstantElementX( | 304 EnumConstantElementX field = new EnumConstantElementX( |
277 name, enumClass, variableList, definition, initializer, index); | 305 name, enumClass, variableList, definition, initializer, index); |
278 enumValues.add(field); | 306 enumValues.add(field); |
279 enumClass.addMember(field, reporter); | 307 enumClass.addMember(field, reporter); |
280 index++; | 308 index++; |
281 } | 309 } |
282 | 310 |
283 VariableList valuesVariableList = | 311 VariableList valuesVariableList = |
284 new VariableList(builder.modifiers(isStatic: true, isConst: true)); | 312 new VariableList(builder.modifiers(isStatic: true, isConst: true)); |
285 ResolutionInterfaceType valuesType = commonElements.listType(enumType); | 313 ResolutionInterfaceType valuesType = commonElements.listType(enumType); |
286 valuesVariableList.type = valuesType; | 314 valuesVariableList.type = valuesType; |
287 | 315 |
288 Identifier valuesIdentifier = builder.identifier('values'); | 316 Identifier valuesIdentifier = builder.identifier('values'); |
289 // TODO(28340): Add type argument. | 317 // TODO(28340): Add type argument. |
290 Expression initializer = | 318 Expression initializer = |
291 builder.listLiteral(valueReferences, isConst: true); | 319 builder.listLiteral(valueReferences, isConst: true); |
292 | 320 |
293 Node definition = builder.createDefinition(valuesIdentifier, initializer); | 321 Node definition = builder.createDefinition(valuesIdentifier, initializer); |
294 | 322 |
295 EnumFieldElementX valuesVariable = new EnumFieldElementX(valuesIdentifier, | 323 EnumFieldElementX valuesVariable = new EnumFieldElementX(valuesIdentifier, |
296 enumClass, valuesVariableList, definition, initializer); | 324 enumClass, valuesVariableList, definition, initializer); |
297 | 325 |
298 enumClass.addMember(valuesVariable, reporter); | 326 enumClass.addMember(valuesVariable, reporter); |
299 | 327 |
328 Node toStringValue; | |
329 if (USE_CONSTANT_MAP_IN_TO_STRING) { | |
330 toStringValue = builder.indexGet( | |
331 builder.mapLiteral(mapEntries, isConst: true), | |
332 builder.reference(builder.identifier('index'))); | |
333 } else { | |
334 toStringValue = builder.reference(builder.identifier('_name')); | |
335 } | |
300 FunctionExpression toStringNode = builder.functionExpression( | 336 FunctionExpression toStringNode = builder.functionExpression( |
301 Modifiers.EMPTY, | 337 Modifiers.EMPTY, |
302 'toString', | 338 'toString', |
303 null, // typeVariables | 339 null, // typeVariables |
304 builder.argumentList([]), | 340 builder.argumentList([]), |
305 builder | 341 builder.returnStatement(toStringValue)); |
306 .returnStatement(builder.reference(builder.identifier('_name')))); | |
307 | 342 |
308 EnumMethodElementX toString = new EnumMethodElementX( | 343 EnumMethodElementX toString = new EnumMethodElementX( |
309 'toString', enumClass, Modifiers.EMPTY, toStringNode); | 344 'toString', enumClass, Modifiers.EMPTY, toStringNode); |
310 FunctionSignatureX toStringSignature = new FunctionSignatureX( | 345 FunctionSignatureX toStringSignature = new FunctionSignatureX( |
311 type: new ResolutionFunctionType(toString, stringType)); | 346 type: new ResolutionFunctionType(toString, stringType)); |
312 toString.functionSignature = toStringSignature; | 347 toString.functionSignature = toStringSignature; |
313 enumClass.addMember(toString, reporter); | 348 enumClass.addMember(toString, reporter); |
314 | 349 |
315 enumClass.enumValues = enumValues; | 350 enumClass.enumValues = enumValues; |
316 } | 351 } |
317 } | 352 } |
OLD | NEW |