Index: lib/src/codegen/js_codegen.dart |
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart |
index 048bb5c8508f6633a0b5a295e4f98eedc4740c58..87db3c5e1cc0cf239380317713201323b7610651 100644 |
--- a/lib/src/codegen/js_codegen.dart |
+++ b/lib/src/codegen/js_codegen.dart |
@@ -291,19 +291,11 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
} |
JS.Identifier _initSymbol(JS.Identifier id) { |
- var s = js.statement('let # = $_SYMBOL(#);', [id, js.string(id.name, "'")]); |
+ var s = js.statement('let # = Symbol(#);', [id, js.string(id.name, "'")]); |
_moduleItems.add(s); |
return id; |
} |
- // TODO(jmesserly): this is a temporary workaround for `Symbol` in core, |
- // until we have better name tracking. |
- String get _SYMBOL { |
- var name = currentLibrary.name; |
- if (name == 'dart.core' || name == 'dart._internal') return 'dart.JsSymbol'; |
- return 'Symbol'; |
- } |
- |
bool isPublic(String name) => !name.startsWith('_'); |
@override |
@@ -551,13 +543,34 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
[_exportsVar, _propertyName(name), body, name]); |
} |
- if (isPublic(name)) _addExport(name); |
- |
if (genericDef != null) { |
var dynType = fillDynamicTypeArgs(type, types); |
var genericInst = _emitTypeName(dynType, lowerGeneric: true); |
- return js.statement('{ #; let # = #; }', [genericDef, name, genericInst]); |
+ |
+ if (_isJsBuiltinName(name)) { |
ochafik
2015/09/15 18:05:17
nit: store as a var above for reuse below?
|
+ genericInst = js.statement('#.# = #;', |
+ [_libraryName(type.element.library), name, genericInst]); |
ochafik
2015/09/15 18:05:17
nit: isn't this guaranteed to be currentLibrary?
|
+ } else { |
+ if (isPublic(name)) _addExport(name); |
+ genericInst = js.statement('let # = #;', [name, genericInst]); |
+ } |
+ |
+ return new JS.Block([genericDef, genericInst]); |
} |
+ |
+ if (_isJsBuiltinName(name)) { |
+ var typeName = _emitTypeName(type) as JS.PropertyAccess; |
+ |
+ // TODO(jmesserly): we could generate something cleaner, but since it only |
+ // affects 3 types, doesn't seem like a big concern. |
+ var classExpr = new JS.Call( |
+ new JS.ArrowFun([], js.statement('{ #; return #; }', [body, name])), |
+ []); |
+ return new JS.Assignment(typeName, classExpr).toStatement(); |
+ } else if (isPublic(name)) { |
+ _addExport(name); |
+ } |
+ |
return body; |
} |
@@ -655,7 +668,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
// Otherwise, emit the adapter method, which wraps the Dart iterator in |
// an ES6 iterator. |
return new JS.Method( |
- js.call('$_SYMBOL.iterator'), |
+ js.call('Symbol.iterator'), |
js.call('function() { return new dart.JsIterator(this.#); }', |
[_emitMemberName('iterator', type: t)]) as JS.Fun); |
} |
@@ -1655,13 +1668,30 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
// Mutable top-level fields should always be qualified. |
bool mutableTopLevel = e is TopLevelVariableElement && !e.isConst; |
- if (e.library != currentLibrary || mutableTopLevel) { |
+ if (e.library != currentLibrary || |
+ mutableTopLevel || |
+ _isJsBuiltinName(e.name)) { |
ochafik
2015/09/15 18:05:17
I think that check alone (in the context of "exten
|
return new JS.PropertyAccess(libName, name); |
} |
return idTable.putIfAbsent(e, () => new JS.MaybeQualifiedId(libName, name)); |
} |
+ /// Returns true if this name is Object, Error, or Symbol. |
+ /// |
+ /// We avoid using those names as locals so we don't shadow the global JS |
+ /// names. While we could technically deal with this, it confuses other tools |
+ /// like JS Compiler. |
+ bool _isJsBuiltinName(String name) { |
+ switch (name) { |
+ case 'Object': |
+ case 'Error': |
+ case 'Symbol': |
ochafik
2015/09/15 16:58:33
Presumably also Map, Set, TypeError, RangeError, R
Jennifer Messerly
2015/09/15 17:06:09
Maybe I need to step back, I honestly don't have a
ochafik
2015/09/15 18:05:17
Right now it's just to avoid errors in Closure wit
Jennifer Messerly
2015/09/15 18:34:23
ah, we try and qualify the minimum possible. In fa
|
+ return true; |
+ } |
+ return false; |
+ } |
+ |
@override |
JS.Expression visitAssignmentExpression(AssignmentExpression node) { |
var left = node.leftHandSide; |