Skip to content

Commit

Permalink
Add support for Enums
Browse files Browse the repository at this point in the history
  • Loading branch information
vsmenon committed Jul 15, 2015
1 parent edf237c commit f50661a
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 2 deletions.
53 changes: 51 additions & 2 deletions pkg/dev_compiler/lib/src/codegen/js_codegen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -420,8 +420,57 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
}

@override
JS.Statement visitEnumDeclaration(EnumDeclaration node) =>
_unimplementedCall("Unimplemented enum: $node").toStatement();
JS.Statement visitEnumDeclaration(EnumDeclaration node) {
var element = node.element;
var type = element.type;
var name = js.string(type.name);
var id = new JS.Identifier(type.name);

// Generate a class per section 13 of the spec.
// TODO(vsm): Generate any accompanying metadata

// Create constructor and initialize index
var constructor =
new JS.Method(name, js.call('function(index) { this.index = index; }'));
var fields = new List<ConstFieldElementImpl>.from(
element.fields.where((f) => f.type == type));

// Create toString() method
var properties = new List<JS.Property>();
for (var i = 0; i < fields.length; ++i) {
properties.add(new JS.Property(
js.number(i), js.string('${type.name}.${fields[i].name}')));
}
var nameMap = new JS.ObjectInitializer(properties, multiline: true);
var toStringF = new JS.Method(js.string('toString'),
js.call('function () { return #[this.index]; }', nameMap));

// Create enum class
var classExpr = new JS.ClassExpression(
id, _classHeritage(element), [constructor, toStringF]);
var result = [js.statement('#', classExpr)];

// Create static fields for each enum value
for (var i = 0; i < fields.length; ++i) {
result.add(js.statement('#.# = dart.const(new #(#));', [
id,
fields[i].name,
id,
js.number(i)
]));
}

// Create static values list
var values = new JS.ArrayInitializer(
fields.map((f) => js.call('#.#', [id, f.name])).toList());
result.add(js.statement('#.values = dart.const(dart.list(#, #));', [
id,
values,
_emitTypeName(type)
]));

return _statement(result);
}

/// Given a class element and body, complete the class declaration.
/// This handles generic type parameters, laziness (in library-cycle cases),
Expand Down
19 changes: 19 additions & 0 deletions pkg/dev_compiler/test/codegen/expect/fieldtest.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,31 @@ dart_library.library('fieldtest', null, /* Imports */[
StaticFieldOrder2.c = dart.notNull(StaticFieldOrder2.d) + 2;
StaticFieldOrder2.b = dart.notNull(StaticFieldOrder2.c) + 3;
StaticFieldOrder2.a = dart.notNull(StaticFieldOrder2.b) + 1;
class MyEnum extends core.Object {
MyEnum(index) {
this.index = index;
}
toString() {
return {
0: "MyEnum.Val1",
1: "MyEnum.Val2",
2: "MyEnum.Val3",
3: "MyEnum.Val4"
}[this.index];
}
};
MyEnum.Val1 = dart.const(new MyEnum(0));
MyEnum.Val2 = dart.const(new MyEnum(1));
MyEnum.Val3 = dart.const(new MyEnum(2));
MyEnum.Val4 = dart.const(new MyEnum(3));
MyEnum.values = dart.const(dart.list([MyEnum.Val1, MyEnum.Val2, MyEnum.Val3, MyEnum.Val4], MyEnum));
function main() {
let a = new A();
foo(a);
bar(a);
core.print(baz(a));
core.print(new (Generic$(core.String))().foo(' world'));
core.print(MyEnum.values);
}
dart.fn(main, dart.void, []);
// Exports:
Expand Down
4 changes: 4 additions & 0 deletions pkg/dev_compiler/test/codegen/fieldtest.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,15 @@ class StaticFieldOrder2 {
static const d = 4;
}

enum MyEnum { Val1, Val2, Val3, Val4 }

void main() {
var a = new A();
foo(a);
bar(a);
print(baz(a));

print(new Generic<String>().foo(' world'));

print(MyEnum.values);
}

0 comments on commit f50661a

Please sign in to comment.