Chromium Code Reviews| 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 |