Chromium Code Reviews| 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 '../dart_types.dart'; | 7 import '../dart_types.dart'; |
| 8 import '../dart2jslib.dart'; | 8 import '../dart2jslib.dart'; |
| 9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
| 10 import '../elements/modelx.dart'; | 10 import '../elements/modelx.dart'; |
| 11 import '../scanner/scannerlib.dart'; | 11 import '../scanner/scannerlib.dart'; |
| 12 import '../tree/tree.dart'; | 12 import '../tree/tree.dart'; |
| 13 import '../util/util.dart'; | 13 import '../util/util.dart'; |
| 14 | 14 |
| 15 // TODO(johnniwinther): Merge functionality with the `TreePrinter`. | 15 // TODO(johnniwinther): Merge functionality with the `TreePrinter`. |
| 16 class AstBuilder { | 16 class AstBuilder { |
| 17 final Token position; | 17 final Token position; |
| 18 | 18 |
| 19 AstBuilder(this.position); | 19 AstBuilder(this.position); |
| 20 | 20 |
| 21 int get charOffset => position.charOffset; | 21 int get charOffset => position.charOffset; |
| 22 | 22 |
| 23 final Modifiers finalModifiers = | 23 Modifiers finalModifiers() { |
|
floitsch
2014/11/11 13:22:09
make getter or rename.
Johnni Winther
2014/11/12 10:16:29
Unified these methods to one [modifiers] method.
| |
| 24 new Modifiers.withFlags(null, Modifiers.FLAG_FINAL); | 24 return new Modifiers.withFlags( |
| 25 final Modifiers constModifiers = | 25 new NodeList.singleton(identifier('final')), |
| 26 new Modifiers.withFlags(null, Modifiers.FLAG_CONST); | 26 Modifiers.FLAG_FINAL); |
| 27 final Modifiers staticConstModifiers = | 27 } |
| 28 new Modifiers.withFlags(null, | 28 |
| 29 Modifiers.FLAG_STATIC | Modifiers.FLAG_CONST); | 29 Modifiers constModifiers() { |
| 30 return new Modifiers.withFlags( | |
| 31 new NodeList.singleton(identifier('const')), | |
| 32 Modifiers.FLAG_CONST); | |
| 33 } | |
| 34 | |
| 35 Modifiers staticConstModifiers() { | |
| 36 return new Modifiers.withFlags( | |
| 37 new NodeList(null, | |
| 38 linkedList([identifier('static'), identifier('const')]), | |
| 39 null, ''), | |
| 40 Modifiers.FLAG_STATIC | Modifiers.FLAG_CONST); | |
| 41 } | |
| 30 | 42 |
| 31 Token keywordToken(String text) { | 43 Token keywordToken(String text) { |
| 32 return new KeywordToken(Keyword.keywords[text], position.charOffset); | 44 return new KeywordToken(Keyword.keywords[text], position.charOffset); |
| 33 } | 45 } |
| 34 | 46 |
| 35 Token stringToken(String text) { | 47 Token stringToken(String text) { |
| 36 return new StringToken.fromString(IDENTIFIER_INFO, text, charOffset); | 48 return new StringToken.fromString(IDENTIFIER_INFO, text, charOffset); |
| 37 } | 49 } |
| 38 | 50 |
| 39 Token symbolToken(PrecedenceInfo info) { | 51 Token symbolToken(PrecedenceInfo info) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 new Send(identifier('this'), identifier(fieldName)))); | 140 new Send(identifier('this'), identifier(fieldName)))); |
| 129 } | 141 } |
| 130 | 142 |
| 131 NewExpression newExpression(String typeName, | 143 NewExpression newExpression(String typeName, |
| 132 NodeList arguments, | 144 NodeList arguments, |
| 133 {bool isConst: false}) { | 145 {bool isConst: false}) { |
| 134 return new NewExpression(keywordToken(isConst ? 'const' : 'new'), | 146 return new NewExpression(keywordToken(isConst ? 'const' : 'new'), |
| 135 new Send(null, identifier(typeName), arguments)); | 147 new Send(null, identifier(typeName), arguments)); |
| 136 } | 148 } |
| 137 | 149 |
| 150 Send reference(Identifier identifier) { | |
| 151 return new Send(null, identifier); | |
| 152 } | |
| 153 | |
| 154 Send indexGet(Expression receiver, Expression index) { | |
| 155 return new Send(receiver, | |
| 156 new Operator(symbolToken(INDEX_INFO)), | |
| 157 new NodeList.singleton(index)); | |
| 158 } | |
| 159 | |
| 160 LiteralMapEntry mapLiteralEntry(Expression key, Expression value) { | |
| 161 return new LiteralMapEntry(key, symbolToken(COLON_INFO), value); | |
| 162 } | |
| 163 | |
| 164 LiteralMap mapLiteral(List<LiteralMapEntry> entries, {bool isConst: false}) { | |
| 165 return new LiteralMap( | |
| 166 null, // Type arguments. | |
| 167 new NodeList(symbolToken(OPEN_CURLY_BRACKET_INFO), | |
| 168 linkedList(entries), | |
| 169 symbolToken(CLOSE_CURLY_BRACKET_INFO), | |
| 170 ','), | |
| 171 isConst ? keywordToken('const') : null); | |
| 172 } | |
| 138 } | 173 } |
| 139 | 174 |
| 140 class EnumCreator { | 175 class EnumCreator { |
| 141 final Compiler compiler; | 176 final Compiler compiler; |
| 142 final EnumClassElementX enumClass; | 177 final EnumClassElementX enumClass; |
| 143 | 178 |
| 144 EnumCreator(this.compiler, this.enumClass); | 179 EnumCreator(this.compiler, this.enumClass); |
| 145 | 180 |
| 146 void createMembers() { | 181 void createMembers() { |
| 147 Enum node = enumClass.node; | 182 Enum node = enumClass.node; |
| 148 InterfaceType enumType = enumClass.thisType; | 183 InterfaceType enumType = enumClass.thisType; |
| 149 AstBuilder builder = new AstBuilder(enumClass.position); | 184 AstBuilder builder = new AstBuilder(enumClass.position); |
| 150 | 185 |
| 151 InterfaceType intType = compiler.intClass.computeType(compiler); | 186 InterfaceType intType = compiler.intClass.computeType(compiler); |
| 152 InterfaceType stringType = compiler.stringClass.computeType(compiler); | 187 InterfaceType stringType = compiler.stringClass.computeType(compiler); |
| 153 | 188 |
| 154 EnumFieldElementX addInstanceMember(String name, InterfaceType type) { | 189 EnumFieldElementX addInstanceMember(String name, InterfaceType type) { |
| 155 Identifier identifier = builder.identifier(name); | 190 Identifier identifier = builder.identifier(name); |
| 156 VariableList variableList = new VariableList(builder.finalModifiers); | 191 VariableList variableList = new VariableList(builder.finalModifiers()); |
| 157 variableList.type = type; | 192 variableList.type = type; |
| 158 EnumFieldElementX variable = new EnumFieldElementX( | 193 EnumFieldElementX variable = new EnumFieldElementX( |
| 159 identifier, enumClass, variableList, identifier); | 194 identifier, enumClass, variableList, identifier); |
| 160 enumClass.addMember(variable, compiler); | 195 enumClass.addMember(variable, compiler); |
| 161 return variable; | 196 return variable; |
| 162 } | 197 } |
| 163 | 198 |
| 164 EnumFieldElementX indexVariable = addInstanceMember('index', intType); | 199 EnumFieldElementX indexVariable = addInstanceMember('index', intType); |
| 165 EnumFieldElementX nameVariable = addInstanceMember('_name', stringType); | |
| 166 | 200 |
| 167 VariableDefinitions indexDefinition = builder.initializingFormal('index'); | 201 VariableDefinitions indexDefinition = builder.initializingFormal('index'); |
| 168 VariableDefinitions nameDefinition = builder.initializingFormal('_name'); | |
| 169 | 202 |
| 170 FunctionExpression constructorNode = builder.functionExpression( | 203 FunctionExpression constructorNode = builder.functionExpression( |
| 171 builder.constModifiers, | 204 builder.constModifiers(), |
| 172 enumClass.name, | 205 enumClass.name, |
| 173 builder.argumentList([indexDefinition, nameDefinition]), | 206 builder.argumentList([indexDefinition]), |
| 174 builder.emptyStatement()); | 207 builder.emptyStatement()); |
| 175 | 208 |
| 176 EnumConstructorElementX constructor = new EnumConstructorElementX( | 209 EnumConstructorElementX constructor = new EnumConstructorElementX( |
| 177 enumClass, | 210 enumClass, |
| 178 builder.constModifiers, | 211 builder.constModifiers(), |
| 179 constructorNode); | 212 constructorNode); |
| 180 | 213 |
| 181 EnumFormalElementX indexFormal = new EnumFormalElementX( | 214 EnumFormalElementX indexFormal = new EnumFormalElementX( |
| 182 constructor, | 215 constructor, |
| 183 indexDefinition, | 216 indexDefinition, |
| 184 builder.identifier('index'), | 217 builder.identifier('index'), |
| 185 indexVariable); | 218 indexVariable); |
| 186 | 219 |
| 187 EnumFormalElementX nameFormal = new EnumFormalElementX( | |
| 188 constructor, | |
| 189 nameDefinition, | |
| 190 builder.identifier('_name'), | |
| 191 nameVariable); | |
| 192 | |
| 193 FunctionSignatureX constructorSignature = new FunctionSignatureX( | 220 FunctionSignatureX constructorSignature = new FunctionSignatureX( |
| 194 requiredParameters: builder.linkedList([indexFormal, nameFormal]), | 221 requiredParameters: builder.linkedList([indexFormal]), |
| 195 requiredParameterCount: 2, | 222 requiredParameterCount: 1, |
| 196 type: new FunctionType(constructor, const VoidType(), | 223 type: new FunctionType(constructor, const VoidType(), |
| 197 <DartType>[intType, stringType])); | 224 <DartType>[intType])); |
| 198 constructor.functionSignatureCache = constructorSignature; | 225 constructor.functionSignatureCache = constructorSignature; |
| 199 enumClass.addMember(constructor, compiler); | 226 enumClass.addMember(constructor, compiler); |
| 200 | 227 |
| 201 VariableList variableList = new VariableList(builder.staticConstModifiers); | 228 VariableList variableList = |
| 229 new VariableList(builder.staticConstModifiers()); | |
| 202 variableList.type = enumType; | 230 variableList.type = enumType; |
| 203 int index = 0; | 231 int index = 0; |
| 204 List<Node> valueReferences = <Node>[]; | 232 List<Node> valueReferences = <Node>[]; |
| 233 List<LiteralMapEntry> mapEntries = <LiteralMapEntry>[]; | |
| 205 for (Link<Node> link = node.names.nodes; | 234 for (Link<Node> link = node.names.nodes; |
| 206 !link.isEmpty; | 235 !link.isEmpty; |
| 207 link = link.tail) { | 236 link = link.tail) { |
| 208 Identifier name = link.head; | 237 Identifier name = link.head; |
| 209 AstBuilder valueBuilder = new AstBuilder(name.token); | 238 AstBuilder valueBuilder = new AstBuilder(name.token); |
| 210 valueReferences.add(new Send(null, name)); | 239 |
| 240 // Add reference for the `values` field. | |
| 241 valueReferences.add(valueBuilder.reference(name)); | |
| 242 | |
| 243 // Add map entry for `toString` implementation. | |
| 244 mapEntries.add(valueBuilder.mapLiteralEntry( | |
| 245 valueBuilder.literalInt(index), | |
| 246 valueBuilder.literalString('${enumClass.name}.${name.source}'))); | |
| 211 | 247 |
| 212 Expression initializer = valueBuilder.newExpression( | 248 Expression initializer = valueBuilder.newExpression( |
| 213 enumClass.name, | 249 enumClass.name, |
| 214 valueBuilder.argumentList([ | 250 valueBuilder.argumentList([valueBuilder.literalInt(index)]), |
| 215 valueBuilder.literalInt(index), | |
| 216 valueBuilder.literalString('${name.source}') | |
| 217 ]), | |
| 218 isConst: true); | 251 isConst: true); |
| 219 SendSet definition = valueBuilder.createDefinition(name, initializer); | 252 SendSet definition = valueBuilder.createDefinition(name, initializer); |
| 220 | 253 |
| 221 EnumFieldElementX field = new EnumFieldElementX( | 254 EnumFieldElementX field = new EnumFieldElementX( |
| 222 name, enumClass, variableList, definition, initializer); | 255 name, enumClass, variableList, definition, initializer); |
| 223 enumClass.addMember(field, compiler); | 256 enumClass.addMember(field, compiler); |
| 224 index++; | 257 index++; |
| 225 } | 258 } |
| 226 | 259 |
| 227 VariableList valuesVariableList = | 260 VariableList valuesVariableList = |
| 228 new VariableList(builder.staticConstModifiers); | 261 new VariableList(builder.staticConstModifiers()); |
| 229 InterfaceType listType = compiler.listClass.computeType(compiler); | 262 InterfaceType listType = compiler.listClass.computeType(compiler); |
| 230 valuesVariableList.type = listType.createInstantiation([enumType]); | 263 valuesVariableList.type = listType.createInstantiation([enumType]); |
| 231 | 264 |
| 232 Identifier valuesIdentifier = builder.identifier('values'); | 265 Identifier valuesIdentifier = builder.identifier('values'); |
| 233 // TODO(johnniwinther): Add type argument. | 266 // TODO(johnniwinther): Add type argument. |
| 234 Expression initializer = builder.listLiteral( | 267 Expression initializer = builder.listLiteral( |
| 235 valueReferences, isConst: true); | 268 valueReferences, isConst: true); |
| 236 | 269 |
| 237 Node definition = builder.createDefinition(valuesIdentifier, initializer); | 270 Node definition = builder.createDefinition(valuesIdentifier, initializer); |
| 238 | 271 |
| 239 EnumFieldElementX valuesVariable = new EnumFieldElementX( | 272 EnumFieldElementX valuesVariable = new EnumFieldElementX( |
| 240 valuesIdentifier, enumClass, valuesVariableList, | 273 valuesIdentifier, enumClass, valuesVariableList, |
| 241 definition, initializer); | 274 definition, initializer); |
| 242 | 275 |
| 243 enumClass.addMember(valuesVariable, compiler); | 276 enumClass.addMember(valuesVariable, compiler); |
| 244 | 277 |
| 245 // TODO(johnniwinther): Support return type. Note `String` might be prefixed | 278 // TODO(johnniwinther): Support return type. Note `String` might be prefixed |
| 246 // or not imported within the current library. | 279 // or not imported within the current library. |
| 247 FunctionExpression toStringNode = builder.functionExpression( | 280 FunctionExpression toStringNode = builder.functionExpression( |
| 248 Modifiers.EMPTY, | 281 Modifiers.EMPTY, |
| 249 'toString', | 282 'toString', |
| 250 builder.argumentList([]), | 283 builder.argumentList([]), |
| 251 builder.returnStatement( | 284 builder.returnStatement( |
| 252 new StringInterpolation( | 285 builder.indexGet( |
| 253 builder.literalString('${enumClass.name}.', suffix: ''), | 286 builder.mapLiteral(mapEntries, isConst: true), |
| 254 new NodeList.singleton(new StringInterpolationPart( | 287 builder.reference(builder.identifier('index'))) |
| 255 new Send(null, builder.identifier('_name')), | 288 ) |
| 256 builder.literalString('', prefix: ''))) | |
| 257 )) | |
| 258 ); | 289 ); |
| 259 | 290 |
| 260 EnumMethodElementX toString = new EnumMethodElementX('toString', | 291 EnumMethodElementX toString = new EnumMethodElementX('toString', |
| 261 enumClass, Modifiers.EMPTY, toStringNode); | 292 enumClass, Modifiers.EMPTY, toStringNode); |
| 262 FunctionSignatureX toStringSignature = new FunctionSignatureX( | 293 FunctionSignatureX toStringSignature = new FunctionSignatureX( |
| 263 type: new FunctionType(toString, stringType)); | 294 type: new FunctionType(toString, stringType)); |
| 264 toString.functionSignatureCache = toStringSignature; | 295 toString.functionSignatureCache = toStringSignature; |
| 265 enumClass.addMember(toString, compiler); | 296 enumClass.addMember(toString, compiler); |
| 266 } | 297 } |
| 267 } | 298 } |
| OLD | NEW |