| Index: lib/src/codegen/js_codegen.dart
|
| diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
|
| index 31821af5f895a04fd914475a411d13eaade00062..6635ad69c937c2e70a19e52c9a9c449c6e9a6c8c 100644
|
| --- a/lib/src/codegen/js_codegen.dart
|
| +++ b/lib/src/codegen/js_codegen.dart
|
| @@ -73,7 +73,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
| final _properties = <FunctionDeclaration>[];
|
| final _privateNames = new HashMap<String, JSTemporary>();
|
| final _extensionMethodNames = new HashSet<String>();
|
| - final _pendingSymbols = <JS.Identifier>[];
|
| + final _pendingStatements = <JS.Statement>[];
|
| final _temps = new HashMap<Element, JSTemporary>();
|
|
|
| /// The name for the library's exports inside itself.
|
| @@ -156,8 +156,11 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
| ]);
|
| }
|
|
|
| - JS.Statement _initSymbol(JS.Identifier id) =>
|
| - js.statement('let # = $_SYMBOL(#);', [id, js.string(id.name, "'")]);
|
| + JS.Identifier _initSymbol(JS.Identifier id) {
|
| + var s = js.statement('let # = $_SYMBOL(#);', [id, js.string(id.name, "'")]);
|
| + _pendingStatements.add(s);
|
| + return id;
|
| + }
|
|
|
| // TODO(jmesserly): this is a temporary workaround for `Symbol` in core,
|
| // until we have better name tracking.
|
| @@ -182,9 +185,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
|
|
| var code = _visit(child);
|
| if (code != null) {
|
| - if (_pendingSymbols.isNotEmpty) {
|
| - body.addAll(_pendingSymbols.map(_initSymbol));
|
| - _pendingSymbols.clear();
|
| + if (_pendingStatements.isNotEmpty) {
|
| + body.addAll(_pendingStatements);
|
| + _pendingStatements.clear();
|
| }
|
| body.add(code);
|
| }
|
| @@ -194,7 +197,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
| _flushLazyFields(body);
|
| _flushLibraryProperties(body);
|
|
|
| - assert(_pendingSymbols.isEmpty);
|
| + assert(_pendingStatements.isEmpty);
|
| return _statement(body);
|
| }
|
|
|
| @@ -1478,8 +1481,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
|
|
| @override
|
| visitInstanceCreationExpression(InstanceCreationExpression node) {
|
| - return js.call(
|
| + var newExpr = js.call(
|
| 'new #(#)', [_visit(node.constructorName), _visit(node.argumentList)]);
|
| + if (node.isConst) return _const(node, newExpr);
|
| + return newExpr;
|
| }
|
|
|
| /// True if this type is built-in to JS, and we use the values unwrapped.
|
| @@ -1640,6 +1645,28 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
| return id;
|
| }
|
|
|
| + JS.Expression _const(Expression node, JS.Expression expr, [String nameHint]) {
|
| + var value = js.call('dart.const(#)', expr);
|
| +
|
| + // If we're inside a method or function, capture the value into a
|
| + // global temporary, so we don't do the expensive canonicalization step.
|
| + var ancestor = node.getAncestor((n) => n is FunctionBody ||
|
| + (n is FieldDeclaration && n.staticKeyword == null));
|
| + if (ancestor == null) return value;
|
| +
|
| + if (nameHint == null) {
|
| + nameHint = 'const_' + getStaticType(node).name;
|
| + }
|
| +
|
| + // TODO(jmesserly): enable this once we fix
|
| + // https://github.com/dart-lang/dev_compiler/issues/131
|
| + /*var temp = new JSTemporary(nameHint);
|
| + _pendingStatements.add(js.statement('let # = #;', [temp, value]));
|
| + return temp;*/
|
| + assert(nameHint != null); // so it's not marked unused
|
| + return value;
|
| + }
|
| +
|
| bool _isTemporary(Element node) => node.nameOffset == -1;
|
|
|
| /// Returns a new expression, which can be be used safely *once* on the
|
| @@ -2099,10 +2126,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
| visitSymbolLiteral(SymbolLiteral node) {
|
| // TODO(vsm): When we canonicalize, we need to treat private symbols
|
| // correctly.
|
| - // TODO(vsm): Make this core.Symbol instead.
|
| - var name = js.escapedString(node.components.join('.'));
|
| - var symbol = js.call('new _internal.Symbol(#)', name);
|
| - return js.commentExpression('Unimplemented const', symbol);
|
| + var name = js.string(node.components.join('.'), "'");
|
| + var nameHint = 'symbol_' + node.components.join('_');
|
| + return _const(node, js.call('new core.Symbol(#)', name), nameHint);
|
| }
|
|
|
| @override
|
| @@ -2113,9 +2139,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
| if (type.typeArguments.any((a) => a != types.dynamicType)) {
|
| list = js.call('dart.setType(#, #)', [list, _emitTypeName(type)]);
|
| }
|
| - if (node.constKeyword != null) {
|
| - list = js.commentExpression('Unimplemented const', list);
|
| - }
|
| + if (node.constKeyword != null) return _const(node, list);
|
| return list;
|
| }
|
|
|
| @@ -2145,9 +2169,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
| }
|
| // TODO(jmesserly): add generic types args.
|
| var map = js.call('dart.map(#)', [mapArguments]);
|
| - if (node.constKeyword != null) {
|
| - map = js.commentExpression('Unimplemented const', map);
|
| - }
|
| + if (node.constKeyword != null) return _const(node, map);
|
| return map;
|
| }
|
|
|
| @@ -2286,11 +2308,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
| JS.Expression _emitMemberName(String name,
|
| {DartType type, bool unary: false, bool isStatic: false}) {
|
| if (name.startsWith('_')) {
|
| - return _privateNames.putIfAbsent(name, () {
|
| - var t = new JSTemporary(name);
|
| - _pendingSymbols.add(t);
|
| - return t;
|
| - });
|
| + return _privateNames.putIfAbsent(
|
| + name, () => _initSymbol(new JSTemporary(name)));
|
| }
|
|
|
| // Check for extension method:
|
| @@ -2345,7 +2364,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
| // name symbols do not conflict with other symbols before we can let
|
| // user defined libraries define extension methods.
|
| if (_extensionMethodNames.add(extName)) {
|
| - _pendingSymbols.add(new JS.Identifier(extName));
|
| + _initSymbol(new JS.Identifier(extName));
|
| _addExport(extName);
|
| }
|
| return new JS.Identifier(extName);
|
|
|