@@ -363,8 +363,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
363
363
jsPeerName = getConstantField (jsPeer, 'name' , types.stringType);
364
364
}
365
365
366
- var body = _finishClassMembers (
367
- classElem, classExpr, ctors, fields, methods , jsPeerName);
366
+ var body = _finishClassMembers (classElem, classExpr, ctors, fields, methods,
367
+ node.metadata , jsPeerName);
368
368
369
369
var result = _finishClassDef (type, body);
370
370
@@ -541,13 +541,23 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
541
541
[_emitMemberName ('iterator' , type: t)]));
542
542
}
543
543
544
+ JS .Expression _instantiateAnnotation (Annotation node) {
545
+ var element = node.element;
546
+ if (element is ConstructorElement ) {
547
+ return _emitInstanceCreationExpression (element, element.returnType,
548
+ node.constructorName, node.arguments, true );
549
+ } else {
550
+ return _visit (node.name);
551
+ }
552
+ }
553
+
544
554
/// Emit class members that need to come after the class declaration, such
545
555
/// as static fields. See [_emitClassMethods] for things that are emitted
546
556
/// inside the ES6 `class { ... }` node.
547
557
JS .Statement _finishClassMembers (ClassElement classElem,
548
558
JS .ClassExpression cls, List <ConstructorDeclaration > ctors,
549
559
List <FieldDeclaration > fields, List <MethodDeclaration > methods,
550
- String jsPeerName) {
560
+ List < Annotation > metadata, String jsPeerName) {
551
561
var name = classElem.name;
552
562
var body = < JS .Statement > [];
553
563
@@ -627,6 +637,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
627
637
}
628
638
}
629
639
}
640
+
630
641
var tCtors = [];
631
642
for (ConstructorDeclaration node in ctors) {
632
643
var memberName = _constructorName (node.element);
@@ -637,6 +648,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
637
648
new JS .Property (memberName, new JS .ArrayInitializer (parts));
638
649
tCtors.add (property);
639
650
}
651
+
640
652
build (name, elements) {
641
653
var o =
642
654
new JS .ObjectInitializer (elements, multiline: elements.length > 1 );
@@ -675,6 +687,14 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
675
687
]));
676
688
}
677
689
690
+ // Metadata
691
+ if (metadata.isNotEmpty) {
692
+ body.add (js.statement ('#[dart.metadata] = () => #;' , [
693
+ name,
694
+ new JS .ArrayInitializer (metadata.map (_instantiateAnnotation).toList ())
695
+ ]));
696
+ }
697
+
678
698
return _statement (body);
679
699
}
680
700
@@ -1743,42 +1763,56 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
1743
1763
_properties.clear ();
1744
1764
}
1745
1765
1746
- @override
1747
- visitConstructorName (ConstructorName node) {
1748
- var typeName = _visit (node.type);
1749
- var element = node.staticElement;
1750
- if (node.name != null || element.isFactory) {
1766
+ JS .Expression _emitConstructorName (
1767
+ ConstructorElement element, DartType type, SimpleIdentifier name) {
1768
+ var typeName = _emitTypeName (type);
1769
+ if (name != null || element.isFactory) {
1751
1770
var namedCtor = _constructorName (element);
1752
1771
return new JS .PropertyAccess (typeName, namedCtor);
1753
1772
}
1754
1773
return typeName;
1755
1774
}
1756
1775
1757
1776
@override
1758
- visitInstanceCreationExpression (InstanceCreationExpression node) {
1777
+ visitConstructorName (ConstructorName node) {
1778
+ return _emitConstructorName (node.staticElement, node.type.type, node.name);
1779
+ }
1780
+
1781
+ JS .Expression _emitInstanceCreationExpression (ConstructorElement element,
1782
+ DartType type, SimpleIdentifier name, ArgumentList argumentList,
1783
+ bool isConst) {
1759
1784
emitNew () {
1760
1785
JS .Expression ctor;
1761
1786
bool isFactory = false ;
1762
- var element = node.staticElement;
1787
+ // var element = node.staticElement;
1763
1788
if (element == null ) {
1764
1789
// TODO(jmesserly): this only happens if we had a static error.
1765
1790
// Should we generate a throw instead?
1766
- ctor = _visit (node.constructorName.type);
1767
- var ctorName = node.constructorName.name;
1768
- if (ctorName != null ) {
1769
- ctor = new JS .PropertyAccess (ctor, _propertyName (ctorName.name));
1791
+ ctor = _emitTypeName (type);
1792
+ if (name != null ) {
1793
+ ctor = new JS .PropertyAccess (ctor, _propertyName (name.name));
1770
1794
}
1771
1795
} else {
1772
- ctor = _visit (node.constructorName );
1796
+ ctor = _emitConstructorName (element, type, name );
1773
1797
isFactory = element.isFactory;
1774
1798
}
1775
- var args = _visit (node. argumentList);
1799
+ var args = _visit (argumentList);
1776
1800
return isFactory ? new JS .Call (ctor, args) : new JS .New (ctor, args);
1777
1801
}
1778
- if (node. isConst) return _emitConst (node, emitNew);
1802
+ if (isConst) return _emitConst (emitNew);
1779
1803
return emitNew ();
1780
1804
}
1781
1805
1806
+ @override
1807
+ visitInstanceCreationExpression (InstanceCreationExpression node) {
1808
+ var element = node.staticElement;
1809
+ var constructor = node.constructorName;
1810
+ var name = constructor.name;
1811
+ var type = constructor.type.type;
1812
+ return _emitInstanceCreationExpression (
1813
+ element, type, name, node.argumentList, node.isConst);
1814
+ }
1815
+
1782
1816
/// True if this type is built-in to JS, and we use the values unwrapped.
1783
1817
/// For these types we generate a calling convention via static
1784
1818
/// "extension methods". This allows types to be extended without adding
@@ -1876,6 +1910,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
1876
1910
var op = node.operator ;
1877
1911
var left = node.leftOperand;
1878
1912
var right = node.rightOperand;
1913
+
1879
1914
var leftType = getStaticType (left);
1880
1915
var rightType = getStaticType (right);
1881
1916
@@ -1945,7 +1980,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
1945
1980
return id;
1946
1981
}
1947
1982
1948
- JS .Expression _emitConst (Expression node, JS .Expression expr ()) {
1983
+ JS .Expression _emitConst (JS .Expression expr ()) {
1949
1984
// TODO(jmesserly): emit the constants at top level if possible.
1950
1985
// This wasn't quite working, so disabled for now.
1951
1986
return js.call ('dart.const(#)' , expr ());
@@ -2436,7 +2471,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
2436
2471
var name = js.string (node.components.join ('.' ), "'" );
2437
2472
return new JS .New (_emitTypeName (types.symbolType), [name]);
2438
2473
}
2439
- return _emitConst (node, emitSymbol);
2474
+ return _emitConst (emitSymbol);
2440
2475
}
2441
2476
2442
2477
@override
@@ -2450,7 +2485,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
2450
2485
}
2451
2486
return list;
2452
2487
}
2453
- if (node.constKeyword != null ) return _emitConst (node, emitList);
2488
+ if (node.constKeyword != null ) return _emitConst (emitList);
2454
2489
return emitList ();
2455
2490
}
2456
2491
@@ -2482,7 +2517,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor {
2482
2517
// TODO(jmesserly): add generic types args.
2483
2518
return js.call ('dart.map(#)' , [mapArguments]);
2484
2519
}
2485
- if (node.constKeyword != null ) return _emitConst (node, emitMap);
2520
+ if (node.constKeyword != null ) return _emitConst (emitMap);
2486
2521
return emitMap ();
2487
2522
}
2488
2523
0 commit comments