Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Unified Diff: pkg/compiler/lib/src/resolution/enum_creator.dart

Issue 707463003: Support enums in dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/elements/modelx.dart ('k') | pkg/compiler/lib/src/resolution/members.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..fcc179682edea72902cb83327c827a339d076224
--- /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;
+
+ final Modifiers finalModifiers =
+ new Modifiers.withFlags(null, Modifiers.FLAG_FINAL);
+ final Modifiers constModifiers =
+ new Modifiers.withFlags(null, Modifiers.FLAG_CONST);
+ final 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, // Initializer.
+ null, // get/set.
+ null // Async modifier.
+ );
+ }
+
+ EmptyStatement emptyStatement() {
+ return new EmptyStatement(symbolToken(COMMA_INFO));
+ }
+
+ 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,
+ builder.identifier('_name'),
+ nameVariable);
+
+ FunctionSignatureX constructorSignature = new FunctionSignatureX(
+ requiredParameters: builder.linkedList([indexFormal, nameFormal]),
+ requiredParameterCount: 2,
+ type: 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(
+ type: new FunctionType(toString, stringType));
+ toString.functionSignatureCache = toStringSignature;
+ enumClass.addMember(toString, compiler);
+ }
+}
« no previous file with comments | « pkg/compiler/lib/src/elements/modelx.dart ('k') | pkg/compiler/lib/src/resolution/members.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698