| 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 '../core_types.dart' show CommonElements; | 8 import '../core_types.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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 /// This class generates the model for an enum class. | 174 /// This class generates the model for an enum class. |
| 175 /// | 175 /// |
| 176 /// For instance | 176 /// For instance |
| 177 /// | 177 /// |
| 178 /// enum A { b, c, } | 178 /// enum A { b, c, } |
| 179 /// | 179 /// |
| 180 /// is modelled as | 180 /// is modelled as |
| 181 /// | 181 /// |
| 182 /// class A { | 182 /// class A { |
| 183 /// final int index; | 183 /// final int index; |
| 184 /// final String _name; |
| 184 /// | 185 /// |
| 185 /// const A(this.index); | 186 /// const A(this.index); |
| 186 /// | 187 /// |
| 187 /// String toString() { | 188 /// String toString() { |
| 188 /// return const <int, A>{0: 'A.b', 1: 'A.c'}[index]; | 189 /// return _name; |
| 189 /// } | 190 /// } |
| 190 /// | 191 /// |
| 191 /// static const A b = const A(0); | 192 /// static const A b = const A(0, "A.b"); |
| 192 /// static const A c = const A(1); | 193 /// static const A c = const A(1, "A.v"); |
| 193 /// | 194 /// |
| 194 /// static const List<A> values = const <A>[b, c]; | 195 /// static const List<A> values = const <A>[b, c]; |
| 195 /// } | 196 /// } |
| 196 /// | 197 /// |
| 197 // TODO(johnniwinther): Avoid creating synthesized ASTs for enums when SSA is | 198 // TODO(johnniwinther): Avoid creating synthesized ASTs for enums when SSA is |
| 198 // removed. | 199 // removed. |
| 199 class EnumCreator { | 200 class EnumCreator { |
| 200 final DiagnosticReporter reporter; | 201 final DiagnosticReporter reporter; |
| 201 final CommonElements commonElements; | 202 final CommonElements commonElements; |
| 202 final EnumClassElementX enumClass; | 203 final EnumClassElementX enumClass; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 217 VariableList variableList = | 218 VariableList variableList = |
| 218 new VariableList(builder.modifiers(isFinal: true)); | 219 new VariableList(builder.modifiers(isFinal: true)); |
| 219 variableList.type = type; | 220 variableList.type = type; |
| 220 EnumFieldElementX variable = new EnumFieldElementX( | 221 EnumFieldElementX variable = new EnumFieldElementX( |
| 221 identifier, enumClass, variableList, identifier); | 222 identifier, enumClass, variableList, identifier); |
| 222 enumClass.addMember(variable, reporter); | 223 enumClass.addMember(variable, reporter); |
| 223 return variable; | 224 return variable; |
| 224 } | 225 } |
| 225 | 226 |
| 226 EnumFieldElementX indexVariable = addInstanceMember('index', intType); | 227 EnumFieldElementX indexVariable = addInstanceMember('index', intType); |
| 228 EnumFieldElementX nameVariable = addInstanceMember('_name', stringType); |
| 227 | 229 |
| 228 VariableDefinitions indexDefinition = builder.initializingFormal('index'); | 230 VariableDefinitions indexDefinition = builder.initializingFormal('index'); |
| 231 VariableDefinitions nameDefinition = builder.initializingFormal('_name'); |
| 229 | 232 |
| 230 FunctionExpression constructorNode = builder.functionExpression( | 233 FunctionExpression constructorNode = builder.functionExpression( |
| 231 builder.modifiers(isConst: true), | 234 builder.modifiers(isConst: true), |
| 232 enumClass.name, | 235 enumClass.name, |
| 233 null, // typeVariables | 236 null, // typeVariables |
| 234 builder.argumentList([indexDefinition]), | 237 builder.argumentList([indexDefinition, nameDefinition]), |
| 235 builder.emptyStatement()); | 238 builder.emptyStatement()); |
| 236 | 239 |
| 237 EnumConstructorElementX constructor = new EnumConstructorElementX( | 240 EnumConstructorElementX constructor = new EnumConstructorElementX( |
| 238 enumClass, builder.modifiers(isConst: true), constructorNode); | 241 enumClass, builder.modifiers(isConst: true), constructorNode); |
| 239 | 242 |
| 240 EnumFormalElementX indexFormal = new EnumFormalElementX(constructor, | 243 EnumFormalElementX indexFormal = new EnumFormalElementX(constructor, |
| 241 indexDefinition, builder.identifier('index'), indexVariable); | 244 indexDefinition, builder.identifier('index'), indexVariable); |
| 242 | 245 |
| 246 EnumFormalElementX nameFormal = new EnumFormalElementX( |
| 247 constructor, nameDefinition, builder.identifier('_name'), nameVariable); |
| 248 |
| 243 FunctionSignatureX constructorSignature = new FunctionSignatureX( | 249 FunctionSignatureX constructorSignature = new FunctionSignatureX( |
| 244 requiredParameters: [indexFormal], | 250 requiredParameters: [indexFormal, nameFormal], |
| 245 requiredParameterCount: 1, | 251 requiredParameterCount: 2, |
| 246 type: new ResolutionFunctionType(constructor, | 252 type: new ResolutionFunctionType( |
| 247 const ResolutionDynamicType(), <ResolutionDartType>[intType])); | 253 constructor, |
| 254 const ResolutionDynamicType(), |
| 255 <ResolutionDartType>[intType, stringType])); |
| 248 constructor.functionSignature = constructorSignature; | 256 constructor.functionSignature = constructorSignature; |
| 249 enumClass.addMember(constructor, reporter); | 257 enumClass.addMember(constructor, reporter); |
| 250 | 258 |
| 251 List<EnumConstantElement> enumValues = <EnumConstantElement>[]; | 259 List<EnumConstantElement> enumValues = <EnumConstantElement>[]; |
| 252 int index = 0; | 260 int index = 0; |
| 253 List<Node> valueReferences = <Node>[]; | 261 List<Node> valueReferences = <Node>[]; |
| 254 List<LiteralMapEntry> mapEntries = <LiteralMapEntry>[]; | |
| 255 for (Link<Node> link = node.names.nodes; !link.isEmpty; link = link.tail) { | 262 for (Link<Node> link = node.names.nodes; !link.isEmpty; link = link.tail) { |
| 256 Identifier name = link.head; | 263 Identifier name = link.head; |
| 257 AstBuilder valueBuilder = new AstBuilder(name.token.charOffset); | 264 AstBuilder valueBuilder = new AstBuilder(name.token.charOffset); |
| 258 VariableList variableList = new VariableList( | 265 VariableList variableList = new VariableList( |
| 259 valueBuilder.modifiers(isStatic: true, isConst: true)); | 266 valueBuilder.modifiers(isStatic: true, isConst: true)); |
| 260 variableList.type = enumType; | 267 variableList.type = enumType; |
| 261 | 268 |
| 262 // Add reference for the `values` field. | 269 // Add reference for the `values` field. |
| 263 valueReferences.add(valueBuilder.reference(name)); | 270 valueReferences.add(valueBuilder.reference(name)); |
| 264 | 271 |
| 265 // Add map entry for `toString` implementation. | 272 Expression initializer = valueBuilder.newExpression( |
| 266 mapEntries.add(valueBuilder.mapLiteralEntry( | 273 enumClass.name, |
| 267 valueBuilder.literalInt(index), | 274 valueBuilder.argumentList([ |
| 268 valueBuilder.literalString('${enumClass.name}.${name.source}'))); | 275 valueBuilder.literalInt(index), |
| 269 | 276 valueBuilder.literalString('${enumClass.name}.${name.source}') |
| 270 Expression initializer = valueBuilder.newExpression(enumClass.name, | 277 ]), |
| 271 valueBuilder.argumentList([valueBuilder.literalInt(index)]), | |
| 272 isConst: true); | 278 isConst: true); |
| 273 SendSet definition = valueBuilder.createDefinition(name, initializer); | 279 SendSet definition = valueBuilder.createDefinition(name, initializer); |
| 274 | 280 |
| 275 EnumConstantElementX field = new EnumConstantElementX( | 281 EnumConstantElementX field = new EnumConstantElementX( |
| 276 name, enumClass, variableList, definition, initializer, index); | 282 name, enumClass, variableList, definition, initializer, index); |
| 277 enumValues.add(field); | 283 enumValues.add(field); |
| 278 enumClass.addMember(field, reporter); | 284 enumClass.addMember(field, reporter); |
| 279 index++; | 285 index++; |
| 280 } | 286 } |
| 281 | 287 |
| 282 VariableList valuesVariableList = | 288 VariableList valuesVariableList = |
| 283 new VariableList(builder.modifiers(isStatic: true, isConst: true)); | 289 new VariableList(builder.modifiers(isStatic: true, isConst: true)); |
| 284 ResolutionInterfaceType valuesType = commonElements.listType(enumType); | 290 ResolutionInterfaceType valuesType = commonElements.listType(enumType); |
| 285 valuesVariableList.type = valuesType; | 291 valuesVariableList.type = valuesType; |
| 286 | 292 |
| 287 Identifier valuesIdentifier = builder.identifier('values'); | 293 Identifier valuesIdentifier = builder.identifier('values'); |
| 288 // TODO(johnniwinther): Add type argument. | 294 // TODO(28340): Add type argument. |
| 289 Expression initializer = | 295 Expression initializer = |
| 290 builder.listLiteral(valueReferences, isConst: true); | 296 builder.listLiteral(valueReferences, isConst: true); |
| 291 | 297 |
| 292 Node definition = builder.createDefinition(valuesIdentifier, initializer); | 298 Node definition = builder.createDefinition(valuesIdentifier, initializer); |
| 293 | 299 |
| 294 EnumFieldElementX valuesVariable = new EnumFieldElementX(valuesIdentifier, | 300 EnumFieldElementX valuesVariable = new EnumFieldElementX(valuesIdentifier, |
| 295 enumClass, valuesVariableList, definition, initializer); | 301 enumClass, valuesVariableList, definition, initializer); |
| 296 | 302 |
| 297 enumClass.addMember(valuesVariable, reporter); | 303 enumClass.addMember(valuesVariable, reporter); |
| 298 | 304 |
| 299 // TODO(johnniwinther): Support return type. Note `String` might be prefixed | |
| 300 // or not imported within the current library. | |
| 301 FunctionExpression toStringNode = builder.functionExpression( | 305 FunctionExpression toStringNode = builder.functionExpression( |
| 302 Modifiers.EMPTY, | 306 Modifiers.EMPTY, |
| 303 'toString', | 307 'toString', |
| 304 null, // typeVariables | 308 null, // typeVariables |
| 305 builder.argumentList([]), | 309 builder.argumentList([]), |
| 306 builder.returnStatement(builder.indexGet( | 310 builder |
| 307 builder.mapLiteral(mapEntries, isConst: true), | 311 .returnStatement(builder.reference(builder.identifier('_name')))); |
| 308 builder.reference(builder.identifier('index'))))); | |
| 309 | 312 |
| 310 EnumMethodElementX toString = new EnumMethodElementX( | 313 EnumMethodElementX toString = new EnumMethodElementX( |
| 311 'toString', enumClass, Modifiers.EMPTY, toStringNode); | 314 'toString', enumClass, Modifiers.EMPTY, toStringNode); |
| 312 FunctionSignatureX toStringSignature = new FunctionSignatureX( | 315 FunctionSignatureX toStringSignature = new FunctionSignatureX( |
| 313 type: new ResolutionFunctionType(toString, stringType)); | 316 type: new ResolutionFunctionType(toString, stringType)); |
| 314 toString.functionSignature = toStringSignature; | 317 toString.functionSignature = toStringSignature; |
| 315 enumClass.addMember(toString, reporter); | 318 enumClass.addMember(toString, reporter); |
| 316 | 319 |
| 317 enumClass.enumValues = enumValues; | 320 enumClass.enumValues = enumValues; |
| 318 } | 321 } |
| 319 } | 322 } |
| OLD | NEW |