fix DDC ES6 module export names, part of #32272

We use renamable variables for Dart libraries, this ensures we still
export it with the correct name.

Change-Id: I96dc161e33d265c0ffbd07f8d642629504dffe62
Reviewed-on: https://dart-review.googlesource.com/42892
Commit-Queue: Jenny Messerly <jmesserly@google.com>
Reviewed-by: Vijay Menon <vsm@google.com>
This commit is contained in:
Jenny Messerly 2018-03-07 01:03:01 +00:00 committed by commit-bot@chromium.org
parent 69f8d4ef0d
commit 1b9b3453de
4 changed files with 54 additions and 36 deletions

View file

@ -329,8 +329,9 @@ class CodeGenerator extends Object
var root = new JS.Identifier('_root');
items.add(js.statement('const # = Object.create(null)', [root]));
if (compilationUnits.any((u) => isSdkInternalRuntime(
resolutionMap.elementDeclaredByCompilationUnit(u).library))) {
var isBuildingSdk =
compilationUnits.any((u) => isSdkInternalRuntime(u.element.library));
if (isBuildingSdk) {
// Don't allow these to be renamed when we're building the SDK.
// There is JS code in dart:* that depends on their names.
_runtimeModule = new JS.Identifier('dart');
@ -343,28 +344,29 @@ class CodeGenerator extends Object
_typeTable = new TypeTable(_runtimeModule);
// Initialize our library variables.
var isBuildingSdk = false;
var exports = <JS.NameSpecifier>[];
void emitLibrary(JS.Identifier id) {
items.add(js.statement('const # = Object.create(#)', [id, root]));
exports.add(new JS.NameSpecifier(id));
}
for (var unit in compilationUnits) {
var library =
resolutionMap.elementDeclaredByCompilationUnit(unit).library;
var library = unit.element.library;
if (unit.element != library.definingCompilationUnit) continue;
var libraryTemp = isSdkInternalRuntime(library)
? _runtimeModule
: new JS.TemporaryId(jsLibraryName(_libraryRoot, library));
_libraries[library] = libraryTemp;
items.add(new JS.ExportDeclaration(
js.call('const # = Object.create(#)', [libraryTemp, root])));
// dart:_runtime has a magic module that holds extension method symbols.
// TODO(jmesserly): find a cleaner design for this.
if (isSdkInternalRuntime(library)) {
isBuildingSdk = true;
items.add(new JS.ExportDeclaration(js.call(
'const # = Object.create(#)', [_extensionSymbolsModule, root])));
}
emitLibrary(libraryTemp);
}
// dart:_runtime has a magic module that holds extension method symbols.
// TODO(jmesserly): find a cleaner design for this.
if (isBuildingSdk) emitLibrary(_extensionSymbolsModule);
items.add(new JS.ExportDeclaration(new JS.ExportClause(exports)));
// Collect all class/type Element -> Node mappings
// in case we need to forward declare any classes.
_declarationNodes = new HashMap<TypeDefiningElement, AstNode>.identity();

View file

@ -134,7 +134,10 @@ abstract class _ModuleBuilder {
visitExportDeclaration(ExportDeclaration node) {
exports.add(node);
statements.add(node.exported.toStatement());
var exported = node.exported;
if (exported is! ExportClause) {
statements.add(exported.toStatement());
}
}
visitStatement(Statement node) {

View file

@ -1233,7 +1233,7 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor {
spaceOut();
}
}
nameSpecifierListOut(node.namedImports);
nameSpecifierListOut(node.namedImports, false);
fromClauseOut(node.from);
outSemicolonLn();
}
@ -1248,15 +1248,15 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor {
}
visitExportClause(ExportClause node) {
nameSpecifierListOut(node.exports);
nameSpecifierListOut(node.exports, true);
fromClauseOut(node.from);
}
nameSpecifierListOut(List<NameSpecifier> names) {
nameSpecifierListOut(List<NameSpecifier> names, bool export) {
if (names == null) return;
if (names.length == 1 && names[0].name == '*') {
visit(names[0]);
nameSpecifierOut(names[0], export);
return;
}
@ -1267,7 +1267,7 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor {
out(',');
spaceOut();
}
visit(names[i]);
nameSpecifierOut(names[i], export);
}
spaceOut();
out('}');
@ -1281,22 +1281,28 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor {
}
}
/// This is unused, see [nameSpecifierOut].
visitNameSpecifier(NameSpecifier node) {
throw new UnsupportedError('visitNameSpecifier');
}
nameSpecifierOut(NameSpecifier node, bool export) {
if (node.isStar) {
out('*');
} else {
var importName = node.name.name;
out(importName);
var name = node.name.name;
if (node.asName == null) {
// If our local was renamed, generate an implicit "as".
// This is a convenience feature so imports can be renamed.
// This is a convenience feature so imports and exports can be renamed.
var localName = localNamer.getName(node.name);
if (localName != importName) {
if (localName != name) {
out(export ? localName : name);
out(' as ');
out(localName);
out(export ? name : localName);
return;
}
}
out(name);
}
if (node.asName != null) {
out(' as ');

View file

@ -280,22 +280,29 @@ class ProgramCompiler
// Initialize our library variables.
var items = <JS.ModuleItem>[];
var exports = <JS.NameSpecifier>[];
var root = new JS.Identifier('_root');
items.add(js.statement('const # = Object.create(null)', [root]));
void emitLibrary(JS.Identifier id) {
items.add(js.statement('const # = Object.create(#)', [id, root]));
exports.add(new JS.NameSpecifier(id));
}
for (var library in libraries) {
var libraryTemp = library == ddcRuntime
? _runtimeModule
: new JS.TemporaryId(jsLibraryName(library));
_libraries[library] = libraryTemp;
items.add(new JS.ExportDeclaration(
js.call('const # = Object.create(null)', [libraryTemp])));
// dart:_runtime has a magic module that holds extension method symbols.
// TODO(jmesserly): find a cleaner design for this.
if (library == ddcRuntime) {
items.add(new JS.ExportDeclaration(js
.call('const # = Object.create(null)', [_extensionSymbolsModule])));
}
emitLibrary(libraryTemp);
}
// dart:_runtime has a magic module that holds extension method symbols.
// TODO(jmesserly): find a cleaner design for this.
if (ddcRuntime != null) emitLibrary(_extensionSymbolsModule);
items.add(new JS.ExportDeclaration(new JS.ExportClause(exports)));
// Collect all class/type Element -> Node mappings
// in case we need to forward declare any classes.
_pendingClasses = new HashSet.identity();