Index: lib/src/codegen/js_codegen.dart |
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart |
index 8104a628f51c1dbc5fe6dfcd8ab8ebd0563e8fa0..486eae63471dad8cf9bb8c8bcb62ea8295235ae3 100644 |
--- a/lib/src/codegen/js_codegen.dart |
+++ b/lib/src/codegen/js_codegen.dart |
@@ -25,7 +25,7 @@ import '../js/js_ast.dart' as JS; |
import '../js/js_ast.dart' show js; |
import '../closure/closure_annotator.dart' show ClosureAnnotator; |
-import '../compiler.dart' show AbstractCompiler; |
+import '../compiler.dart' show AbstractCompiler, corelibUriOrder; |
import '../info.dart'; |
import '../options.dart' show CodegenOptions; |
import '../utils.dart'; |
@@ -80,7 +80,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
/// Imported libraries, and the temporaries used to refer to them. |
final _imports = new Map<LibraryElement, JS.TemporaryId>(); |
- final _exports = new Set<String>(); |
+ final _exports = <String, String>{}; |
final _lazyFields = <VariableDeclaration>[]; |
final _properties = <FunctionDeclaration>[]; |
final _privateNames = new HashMap<String, JS.TemporaryId>(); |
@@ -179,16 +179,18 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
id.setQualified(!_loader.isLoaded(element)); |
} |
- var moduleBuilder = new ModuleBuilder( |
- compiler.getModuleName(currentLibrary.source.uri), |
- _jsModuleValue, |
- _exportsVar, |
- options.moduleFormat); |
- |
+ var moduleBuilder = new ModuleBuilder(options.moduleFormat); |
_exports.forEach(moduleBuilder.addExport); |
var items = <JS.ModuleItem>[]; |
if (!_isDartRuntime) { |
+ if (currentLibrary.source.isInSystemLibrary) { |
+ // Force the import order of runtime libs. |
+ // TODO(ochafik): Reduce this to a minimum. |
+ for (var lib in corelibUriOrder.reversed) { |
+ moduleBuilder.addImport(lib.replaceAll(':', '/'), null); |
+ } |
+ } |
moduleBuilder.addImport('dart/_runtime', _runtimeLibVar); |
var dartxImport = |
@@ -208,7 +210,11 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
// var jsBin = compiler.options.runnerOptions.v8Binary; |
// String scriptTag = null; |
// if (library.library.scriptTag != null) scriptTag = '/usr/bin/env $jsBin'; |
- return moduleBuilder.build(items); |
+ return moduleBuilder.build( |
+ compiler.getModuleName(currentLibrary.source.uri), |
+ _jsModuleValue, |
+ _exportsVar, |
+ items); |
} |
void _emitModuleItem(AstNode node) { |
@@ -266,8 +272,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
args.add(new JS.ArrayInitializer(hiddenNames)); |
} |
- // When we compile _runtime.js, we need to source export_ from _utils.js: |
- _moduleItems.add(js.statement('dart.export(#);', [args])); |
+ _moduleItems.add(js.statement('dart.export_(#);', [args])); |
} |
JS.Identifier _initSymbol(JS.Identifier id) { |
@@ -530,7 +535,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
if (genericDef != null) { |
var dynType = fillDynamicTypeArgs(type, types); |
var genericInst = _emitTypeName(dynType, lowerGeneric: true); |
- return js.statement('{ #; let # = #; }', [genericDef, name, genericInst]); |
+ return js |
+ .statement('{ #; const # = #; }', [genericDef, name, genericInst]); |
} |
return body; |
} |
@@ -539,7 +545,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var name = type.name; |
var genericName = '$name\$'; |
var typeParams = _boundTypeParametersOf(type).map((p) => p.name); |
- if (isPublic(name)) _exports.add(genericName); |
+ if (isPublic(name)) _addExport(genericName); |
return js.statement('const # = dart.generic(function(#) { #; return #; });', |
[genericName, typeParams, body, name]); |
} |
@@ -1285,7 +1291,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var body = <JS.Statement>[]; |
_flushLibraryProperties(body); |
- var name = _getJSExportName(node.element) ?? node.name.name; |
+ var name = node.name.name; |
var fn = _visit(node.functionExpression); |
@@ -1301,7 +1307,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
.toStatement()); |
} |
- if (isPublic(name)) _addExport(name); |
+ if (isPublic(name)) { |
+ _addExport(name, _getJSExportName(node.element) ?? name); |
+ } |
return _statement(body); |
} |
@@ -1735,7 +1743,6 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
JS.Expression _emitTopLevelName(Element e, {String suffix: ''}) { |
var libName = _libraryName(e.library); |
- var nameExpr = _propertyName((_getJSExportName(e) ?? e.name) + suffix); |
// Always qualify: |
// * mutable top-level fields |
@@ -1744,6 +1751,12 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
!e.isConst && |
!_isFinalJSDecl(e.computeNode()); |
bool fromAnotherLibrary = e.library != currentLibrary; |
+ var nameExpr; |
+ if (fromAnotherLibrary) { |
+ nameExpr = _propertyName((_getJSExportName(e) ?? e.name) + suffix); |
+ } else { |
+ nameExpr = _propertyName(e.name + suffix); |
+ } |
if (mutableTopLevel || fromAnotherLibrary) { |
return new JS.PropertyAccess(libName, nameExpr); |
} |
@@ -2136,8 +2149,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
} |
} |
- _addExport(String name) { |
- if (!_exports.add(name)) throw 'Duplicate top level name found: $name'; |
+ _addExport(String name, [String exportName]) { |
+ if (_exports.containsKey(name)) |
+ throw 'Duplicate top level name found: $name'; |
+ _exports[name] = exportName ?? name; |
} |
@override |
@@ -2199,8 +2214,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
if (isJSTopLevel) eagerInit = true; |
var fieldName = field.name.name; |
+ var exportName = fieldName; |
if (element is TopLevelVariableElement) { |
- fieldName = _getJSExportName(element) ?? fieldName; |
+ exportName = _getJSExportName(element) ?? fieldName; |
} |
if ((field.isConst && eagerInit && element is TopLevelVariableElement) || |
isJSTopLevel) { |
@@ -2208,7 +2224,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
// but add them to the module's exports. However, make sure we generate |
// anything they depend on first. |
- if (isPublic(fieldName)) _addExport(fieldName); |
+ if (isPublic(fieldName)) _addExport(fieldName, exportName); |
var declKeyword = field.isConst || field.isFinal ? 'const' : 'let'; |
return annotateVariable( |
js.statement( |