Chromium Code Reviews| Index: lib/src/codegen/js_codegen.dart |
| diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart |
| index 28ba34dc6c3c6d2a8434e5793ad82e28ad425834..a4606a7653331c3c161ac242f828b798c3dcb044 100644 |
| --- a/lib/src/codegen/js_codegen.dart |
| +++ b/lib/src/codegen/js_codegen.dart |
| @@ -363,8 +363,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| jsPeerName = getConstantField(jsPeer, 'name', types.stringType); |
| } |
| - var body = _finishClassMembers( |
| - classElem, classExpr, ctors, fields, methods, jsPeerName); |
| + var body = _finishClassMembers(classElem, classExpr, ctors, fields, methods, |
| + node.metadata, jsPeerName); |
| var result = _finishClassDef(type, body); |
| @@ -541,13 +541,23 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| [_emitMemberName('iterator', type: t)])); |
| } |
| + JS.Expression _instantiateAnnotation(Annotation node) { |
| + var element = node.element; |
| + if (element is ConstructorElement) { |
| + return _emitInstanceCreationExpression( |
| + element, element.returnType, node.constructorName, node.arguments, true); |
|
Jennifer Messerly
2015/06/09 23:29:53
./tool/format.sh ? :)
vsm
2015/06/10 13:28:27
Done. Sorry - uploaded too early.
|
| + } else { |
| + return _visit(node.name); |
| + } |
| + } |
| + |
| /// Emit class members that need to come after the class declaration, such |
| /// as static fields. See [_emitClassMethods] for things that are emitted |
| /// inside the ES6 `class { ... }` node. |
| JS.Statement _finishClassMembers(ClassElement classElem, |
| JS.ClassExpression cls, List<ConstructorDeclaration> ctors, |
| List<FieldDeclaration> fields, List<MethodDeclaration> methods, |
| - String jsPeerName) { |
| + List<Annotation> metadata, String jsPeerName) { |
| var name = classElem.name; |
| var body = <JS.Statement>[]; |
| @@ -627,6 +637,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| } |
| } |
| } |
| + |
| var tCtors = []; |
| for (ConstructorDeclaration node in ctors) { |
| var memberName = _constructorName(node.element); |
| @@ -637,6 +648,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| new JS.Property(memberName, new JS.ArrayInitializer(parts)); |
| tCtors.add(property); |
| } |
| + |
| build(name, elements) { |
| var o = |
| new JS.ObjectInitializer(elements, multiline: elements.length > 1); |
| @@ -675,6 +687,14 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| ])); |
| } |
| + // Metadata |
| + if (metadata.isNotEmpty) { |
| + body.add(js.statement('#[dart.metadata] = () => #;', [ |
| + name, |
| + new JS.ArrayInitializer(metadata.map(_instantiateAnnotation).toList()) |
| + ])); |
| + } |
| + |
| return _statement(body); |
| } |
| @@ -1743,11 +1763,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| _properties.clear(); |
| } |
| - @override |
| - visitConstructorName(ConstructorName node) { |
| - var typeName = _visit(node.type); |
| - var element = node.staticElement; |
| - if (node.name != null || element.isFactory) { |
| + _emitConstructorName(ConstructorElement element, DartType type, SimpleIdentifier name) { |
|
Jennifer Messerly
2015/06/09 23:29:53
return type?
vsm
2015/06/10 13:28:27
Done.
|
| + var typeName = _emitTypeName(type); |
| + if (name != null || element.isFactory) { |
| var namedCtor = _constructorName(element); |
| return new JS.PropertyAccess(typeName, namedCtor); |
| } |
| @@ -1755,30 +1773,44 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| } |
| @override |
| - visitInstanceCreationExpression(InstanceCreationExpression node) { |
| + visitConstructorName(ConstructorName node) { |
| + return _emitConstructorName(node.staticElement, node.type.type, node.name); |
| + } |
| + |
| + _emitInstanceCreationExpression(ConstructorElement element, DartType type, SimpleIdentifier name, |
| + ArgumentList argumentList, bool isConst) { |
| emitNew() { |
| JS.Expression ctor; |
| bool isFactory = false; |
| - var element = node.staticElement; |
| + // var element = node.staticElement; |
| if (element == null) { |
| // TODO(jmesserly): this only happens if we had a static error. |
| // Should we generate a throw instead? |
| - ctor = _visit(node.constructorName.type); |
| - var ctorName = node.constructorName.name; |
| - if (ctorName != null) { |
| - ctor = new JS.PropertyAccess(ctor, _propertyName(ctorName.name)); |
| + ctor = _emitTypeName(type); |
| + if (name != null) { |
| + ctor = new JS.PropertyAccess(ctor, _propertyName(name.name)); |
| } |
| } else { |
| - ctor = _visit(node.constructorName); |
| + ctor = _emitConstructorName(element, type, name); |
| isFactory = element.isFactory; |
| } |
| - var args = _visit(node.argumentList); |
| + var args = _visit(argumentList); |
| return isFactory ? new JS.Call(ctor, args) : new JS.New(ctor, args); |
| } |
| - if (node.isConst) return _emitConst(node, emitNew); |
| + if (isConst) return _emitConst(emitNew); |
| return emitNew(); |
| } |
| + @override |
| + visitInstanceCreationExpression(InstanceCreationExpression node) { |
| + var element = node.staticElement; |
| + var constructor = node.constructorName; |
| + var name = constructor.name; |
| + var type = constructor.type.type; |
| + return _emitInstanceCreationExpression( |
| + element, type, name, node.argumentList, node.isConst); |
| + } |
| + |
| /// True if this type is built-in to JS, and we use the values unwrapped. |
| /// For these types we generate a calling convention via static |
| /// "extension methods". This allows types to be extended without adding |
| @@ -1876,6 +1908,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| var op = node.operator; |
| var left = node.leftOperand; |
| var right = node.rightOperand; |
| + |
| var leftType = getStaticType(left); |
| var rightType = getStaticType(right); |
| @@ -1945,7 +1978,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| return id; |
| } |
| - JS.Expression _emitConst(Expression node, JS.Expression expr()) { |
| + JS.Expression _emitConst(JS.Expression expr()) { |
| // TODO(jmesserly): emit the constants at top level if possible. |
| // This wasn't quite working, so disabled for now. |
| return js.call('dart.const(#)', expr()); |
| @@ -2436,7 +2469,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| var name = js.string(node.components.join('.'), "'"); |
| return new JS.New(_emitTypeName(types.symbolType), [name]); |
| } |
| - return _emitConst(node, emitSymbol); |
| + return _emitConst(emitSymbol); |
| } |
| @override |
| @@ -2450,7 +2483,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| } |
| return list; |
| } |
| - if (node.constKeyword != null) return _emitConst(node, emitList); |
| + if (node.constKeyword != null) return _emitConst(emitList); |
| return emitList(); |
| } |
| @@ -2482,7 +2515,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { |
| // TODO(jmesserly): add generic types args. |
| return js.call('dart.map(#)', [mapArguments]); |
| } |
| - if (node.constKeyword != null) return _emitConst(node, emitMap); |
| + if (node.constKeyword != null) return _emitConst(emitMap); |
| return emitMap(); |
| } |