Chromium Code Reviews| Index: pkg/compiler/lib/src/resolution/enum_creator.dart |
| diff --git a/pkg/compiler/lib/src/resolution/enum_creator.dart b/pkg/compiler/lib/src/resolution/enum_creator.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..85f64f2299a7690a66518da4d6c4a149b4167786 |
| --- /dev/null |
| +++ b/pkg/compiler/lib/src/resolution/enum_creator.dart |
| @@ -0,0 +1,267 @@ |
| +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +library dart2js.resolution.enum_creator; |
| + |
| +import '../dart_types.dart'; |
| +import '../dart2jslib.dart'; |
| +import '../elements/elements.dart'; |
| +import '../elements/modelx.dart'; |
| +import '../scanner/scannerlib.dart'; |
| +import '../tree/tree.dart'; |
| +import '../util/util.dart'; |
| + |
| +// TODO(johnniwinther): Merge functionality with the `TreePrinter`. |
| +class AstBuilder { |
| + final Token position; |
| + |
| + AstBuilder(this.position); |
| + |
| + int get charOffset => position.charOffset; |
| + |
| + Modifiers finalModifiers = |
|
floitsch
2014/11/10 16:08:32
final
Johnni Winther
2014/11/11 08:23:37
Done.
|
| + new Modifiers.withFlags(null, Modifiers.FLAG_FINAL); |
| + Modifiers constModifiers = |
| + new Modifiers.withFlags(null, Modifiers.FLAG_CONST); |
| + Modifiers staticConstModifiers = |
| + new Modifiers.withFlags(null, |
| + Modifiers.FLAG_STATIC | Modifiers.FLAG_CONST); |
| + |
| + Token keywordToken(String text) { |
| + return new KeywordToken(Keyword.keywords[text], position.charOffset); |
| + } |
| + |
| + Token stringToken(String text) { |
| + return new StringToken.fromString(IDENTIFIER_INFO, text, charOffset); |
| + } |
| + |
| + Token symbolToken(PrecedenceInfo info) { |
| + return new SymbolToken(info, charOffset); |
| + } |
| + |
| + Identifier identifier(String text) { |
| + Keyword keyword = Keyword.keywords[text]; |
| + Token token; |
| + if (keyword != null) { |
| + token = new KeywordToken(Keyword.keywords[text], charOffset); |
| + } else { |
| + token = stringToken(text); |
| + } |
| + return new Identifier(token); |
| + } |
| + |
| + Link linkedList(List elements) { |
| + LinkBuilder builder = new LinkBuilder(); |
| + elements.forEach((e) => builder.addLast(e)); |
| + return builder.toLink(); |
| + } |
| + |
| + NodeList argumentList(List<Node> nodes) { |
| + return new NodeList(symbolToken(OPEN_PAREN_INFO), |
| + linkedList(nodes), |
| + symbolToken(CLOSE_PAREN_INFO), |
| + ','); |
| + } |
| + |
| + Return returnStatement(Expression expression) { |
| + return new Return( |
| + keywordToken('return'), |
| + symbolToken(SEMICOLON_INFO), |
| + expression); |
| + } |
| + |
| + FunctionExpression functionExpression(Modifiers modifiers, |
| + String name, |
| + NodeList argumentList, |
| + Statement body, |
| + [TypeAnnotation returnType]) { |
| + return new FunctionExpression( |
| + identifier(name), |
| + argumentList, |
| + body, |
| + returnType, |
| + modifiers, |
| + null, // get/set. |
| + null, |
|
floitsch
2014/11/10 16:08:32
comment, what this one is.
Johnni Winther
2014/11/11 08:23:37
Done.
|
| + null // Async modifier. |
| + ); |
| + } |
| + |
| + 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.
|
| + |
| + LiteralInt literalInt(int value) { |
| + return new LiteralInt(stringToken('$value'), null); |
| + } |
| + |
| + LiteralString literalString(String text, |
| + {String prefix: '"', |
| + String suffix: '"'}) { |
| + return new LiteralString(stringToken('$prefix$text$suffix'), |
| + new DartString.literal(text)); |
| + } |
| + |
| + LiteralList listLiteral(List<Node> elements, {bool isConst: false}) { |
| + return new LiteralList( |
| + null, |
| + new NodeList(symbolToken(OPEN_SQUARE_BRACKET_INFO), |
| + linkedList(elements), |
| + symbolToken(CLOSE_SQUARE_BRACKET_INFO), |
| + ','), |
| + isConst ? keywordToken('const') : null); |
| + } |
| + |
| + Node createDefinition(Identifier name, Expression initializer) { |
| + if (initializer == null) return name; |
| + return new SendSet(null, name, new Operator(symbolToken(EQ_INFO)), |
| + new NodeList.singleton(initializer)); |
| + } |
| + |
| + VariableDefinitions initializingFormal(String fieldName) { |
| + return new VariableDefinitions.forParameter( |
| + new NodeList.empty(), |
| + null, |
| + Modifiers.EMPTY, |
| + new NodeList.singleton( |
| + new Send(identifier('this'), identifier(fieldName)))); |
| + } |
| + |
| + NewExpression newExpression(String typeName, |
| + NodeList arguments, |
| + {bool isConst: false}) { |
| + return new NewExpression(keywordToken(isConst ? 'const' : 'new'), |
| + new Send(null, identifier(typeName), arguments)); |
| + } |
| + |
| +} |
| + |
| +class EnumCreator { |
| + final Compiler compiler; |
| + final EnumClassElementX enumClass; |
| + |
| + EnumCreator(this.compiler, this.enumClass); |
| + |
| + void createMembers() { |
| + Enum node = enumClass.node; |
| + InterfaceType enumType = enumClass.thisType; |
| + AstBuilder builder = new AstBuilder(enumClass.position); |
| + |
| + InterfaceType intType = compiler.intClass.computeType(compiler); |
| + InterfaceType stringType = compiler.stringClass.computeType(compiler); |
| + |
| + EnumFieldElementX addInstanceMember(String name, InterfaceType type) { |
| + Identifier identifier = builder.identifier(name); |
| + VariableList variableList = new VariableList(builder.finalModifiers); |
| + variableList.type = type; |
| + EnumFieldElementX variable = new EnumFieldElementX( |
| + identifier, enumClass, variableList, identifier); |
| + enumClass.addMember(variable, compiler); |
| + return variable; |
| + } |
| + |
| + EnumFieldElementX indexVariable = addInstanceMember('index', intType); |
| + EnumFieldElementX nameVariable = addInstanceMember('_name', stringType); |
| + |
| + VariableDefinitions indexDefinition = builder.initializingFormal('index'); |
| + VariableDefinitions nameDefinition = builder.initializingFormal('_name'); |
| + |
| + FunctionExpression constructorNode = builder.functionExpression( |
| + builder.constModifiers, |
| + enumClass.name, |
| + builder.argumentList([indexDefinition, nameDefinition]), |
| + builder.emptyStatement); |
| + |
| + EnumConstructorElementX constructor = new EnumConstructorElementX( |
| + enumClass, |
| + builder.constModifiers, |
| + constructorNode); |
| + |
| + EnumFormalElementX indexFormal = new EnumFormalElementX( |
| + constructor, |
| + indexDefinition, |
| + builder.identifier('index'), |
| + indexVariable); |
| + |
| + EnumFormalElementX nameFormal = new EnumFormalElementX( |
| + constructor, nameDefinition, |
|
floitsch
2014/11/10 16:08:32
keep nameDefinition on its own line.
Johnni Winther
2014/11/11 08:23:36
Done.
|
| + builder.identifier('_name'), |
| + nameVariable); |
| + |
| + FunctionSignatureX constructorSignature = new FunctionSignatureX( |
| + builder.linkedList([indexFormal, nameFormal]), |
| + 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
|
| + 2, 0, false, const <Element>[], |
| + new FunctionType(constructor, const VoidType(), |
| + <DartType>[intType, stringType])); |
| + constructor.functionSignatureCache = constructorSignature; |
| + enumClass.addMember(constructor, compiler); |
| + |
| + VariableList variableList = new VariableList(builder.staticConstModifiers); |
| + variableList.type = enumType; |
| + int index = 0; |
| + List<Node> valueReferences = <Node>[]; |
| + for (Link<Node> link = node.names.nodes; |
| + !link.isEmpty; |
| + link = link.tail) { |
| + Identifier name = link.head; |
| + AstBuilder valueBuilder = new AstBuilder(name.token); |
| + valueReferences.add(new Send(null, name)); |
| + |
| + Expression initializer = valueBuilder.newExpression( |
| + enumClass.name, |
| + valueBuilder.argumentList([ |
| + valueBuilder.literalInt(index), |
| + valueBuilder.literalString('${name.source}') |
| + ]), |
| + isConst: true); |
| + SendSet definition = valueBuilder.createDefinition(name, initializer); |
| + |
| + EnumFieldElementX field = new EnumFieldElementX( |
| + name, enumClass, variableList, definition, initializer); |
| + enumClass.addMember(field, compiler); |
| + index++; |
| + } |
| + |
| + VariableList valuesVariableList = |
| + new VariableList(builder.staticConstModifiers); |
| + InterfaceType listType = compiler.listClass.computeType(compiler); |
| + valuesVariableList.type = listType.createInstantiation([enumType]); |
| + |
| + Identifier valuesIdentifier = builder.identifier('values'); |
| + // TODO(johnniwinther): Add type argument. |
| + Expression initializer = builder.listLiteral( |
| + valueReferences, isConst: true); |
| + |
| + Node definition = builder.createDefinition(valuesIdentifier, initializer); |
| + |
| + EnumFieldElementX valuesVariable = new EnumFieldElementX( |
| + valuesIdentifier, enumClass, valuesVariableList, |
| + definition, initializer); |
| + |
| + enumClass.addMember(valuesVariable, compiler); |
| + |
| + // TODO(johnniwinther): Support return type. Note `String` might be prefixed |
| + // or not imported within the current library. |
| + FunctionExpression toStringNode = builder.functionExpression( |
| + Modifiers.EMPTY, |
| + 'toString', |
| + builder.argumentList([]), |
| + builder.returnStatement( |
| + new StringInterpolation( |
| + builder.literalString('${enumClass.name}.', suffix: ''), |
| + new NodeList.singleton(new StringInterpolationPart( |
| + new Send(null, builder.identifier('_name')), |
| + builder.literalString('', prefix: ''))) |
| + )) |
| + ); |
| + |
| + EnumMethodElementX toString = new EnumMethodElementX('toString', |
| + enumClass, Modifiers.EMPTY, toStringNode); |
| + FunctionSignatureX toStringSignature = new FunctionSignatureX( |
| + const Link<Element>(), const Link<Element>(), |
| + 0, 0, false, const <Element>[], |
| + new FunctionType(toString, stringType)); |
| + toString.functionSignatureCache = toStringSignature; |
| + enumClass.addMember(toString, compiler); |
| + } |
| +} |