allow module to reserve slots for names that they export

This commit is contained in:
Vladimir Matveev
2015-04-28 18:51:29 -07:00
parent c057c0a22a
commit 3af5592243
3 changed files with 75 additions and 36 deletions
+35 -16
View File
@@ -4992,10 +4992,18 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
}
}
// storage has the following structure
// {
// <exported-name-from-current-module> : void 0,
// <exported-name-obtained-from star export in module 'm'>: 'm'
// }
// this allows to:
// - prevent star exports to overwrite locally exported names
// - bind star exported names to particular module so they won't be overwritten by other star exports
const exportedNamesStorageRef = makeUniqueName("exportedNames");
writeLine();
write(`var ${exportedNamesStorageRef} = { `);
write(`var ${exportedNamesStorageRef} = {`);
increaseIndent();
let started = false;
@@ -5036,7 +5044,26 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
writeLine();
write("};");
return exportedNamesStorageRef;
writeLine();
const exportStarFunction = makeUniqueName("exportStar");
// define an export star helper function
write(`function ${exportStarFunction}(m, name) {`);
writeLine();
write(` for(var n in m) {`);
writeLine();
// if name is not yet taken by either local names or names in other modules - reserve it
write(` if (!${exportedNamesStorageRef}.hasOwnProperty(n)) ${exportedNamesStorageRef}[n] = name;`);
writeLine();
// only export value if it was exported from the module with name 'name';
write(` if (${exportedNamesStorageRef}[n] === name) ${exportFunctionForFile}(n, m[n]);`);
writeLine();
write(" }");
writeLine();
write("}")
return exportStarFunction;
function writeExportedName(node: Identifier | Declaration): void {
if (started) {
@@ -5058,7 +5085,7 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
emitDeclarationName(<Declaration>node);
}
write("': true");
write("': void 0");
}
}
@@ -5234,12 +5261,12 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
emitVariableDeclarationsForImports();
writeLine();
var exportedDeclarations = processTopLevelVariableAndFunctionDeclarations(node);
let exportedLocalNames = emitLocalStorageForExportedNamesIfNecessary(exportedDeclarations)
let exportStarFunction = emitLocalStorageForExportedNamesIfNecessary(exportedDeclarations)
writeLine();
write("return {");
increaseIndent();
writeLine();
emitSetters(exportedLocalNames);
emitSetters(exportStarFunction);
writeLine();
emitExecute(node, startIndex);
emitTempDeclarations(/*newLine*/ true)
@@ -5248,7 +5275,7 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
write("}"); // return
}
function emitSetters(exportedLocalNamesRef: string) {
function emitSetters(exportStarFunction: string) {
write("setters:[");
for (let i = 0; i < externalImports.length; ++i) {
if (i !== 0) {
@@ -5341,16 +5368,8 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
writeLine();
// export * from 'foo'
// emit as:
// for (var n in _foo) exports(n, _foo[n]);
// NOTE: it is safe to use name 'n' since parameter name always starts with '_'
write(`for (var n in ${parameterName})`);
increaseIndent();
writeLine();
if (exportedLocalNamesRef) {
write(`if (!${exportedLocalNamesRef}.hasOwnProperty(n))`);
}
write(` ${exportFunctionForFile}(n, ${parameterName}[n]);`)
decreaseIndent();
// exportStar(_foo, 'foo');
write(`${exportStarFunction}(${parameterName}, ${getExternalModuleNameText(importNode)});`);
}
writeLine();
+30 -15
View File
@@ -39,15 +39,20 @@ System.register(['bar'], function(exports_1) {
var x;
function foo() { }
exports_1("foo", foo);
var exportedNames_1 = {
'x': true,
'foo': true
var exportedNames_1 = {
'x': void 0,
'foo': void 0
};
function exportStar_1(m, name) {
for(var n in m) {
if (!exportedNames_1.hasOwnProperty(n)) exportedNames_1[n] = name;
if (exportedNames_1[n] === name) exports_1(n, m[n]);
}
}
return {
setters:[
function (_bar_1) {
for (var n in _bar_1)
if (!exportedNames_1.hasOwnProperty(n)) exports_1(n, _bar_1[n]);
exportStar_1(_bar_1, 'bar');
}],
execute: function() {
exports_1("x", x);
@@ -57,15 +62,20 @@ System.register(['bar'], function(exports_1) {
//// [file2.js]
System.register(['bar'], function(exports_1) {
var x, y;
var exportedNames_1 = {
'x': true,
'y1': true
var exportedNames_1 = {
'x': void 0,
'y1': void 0
};
function exportStar_1(m, name) {
for(var n in m) {
if (!exportedNames_1.hasOwnProperty(n)) exportedNames_1[n] = name;
if (exportedNames_1[n] === name) exports_1(n, m[n]);
}
}
return {
setters:[
function (_bar_1) {
for (var n in _bar_1)
if (!exportedNames_1.hasOwnProperty(n)) exports_1(n, _bar_1[n]);
exportStar_1(_bar_1, 'bar');
}],
execute: function() {
exports_1("x", x);
@@ -75,10 +85,16 @@ System.register(['bar'], function(exports_1) {
});
//// [file3.js]
System.register(['a', 'bar'], function(exports_1) {
var exportedNames_1 = {
'x': true,
'z': true
var exportedNames_1 = {
'x': void 0,
'z': void 0
};
function exportStar_1(m, name) {
for(var n in m) {
if (!exportedNames_1.hasOwnProperty(n)) exportedNames_1[n] = name;
if (exportedNames_1[n] === name) exports_1(n, m[n]);
}
}
return {
setters:[
function (_a_1) {
@@ -86,8 +102,7 @@ System.register(['a', 'bar'], function(exports_1) {
exports_1("z", _a_1["y"]);
},
function (_bar_1) {
for (var n in _bar_1)
if (!exportedNames_1.hasOwnProperty(n)) exports_1(n, _bar_1[n]);
exportStar_1(_bar_1, 'bar');
}],
execute: function() {
}
+10 -5
View File
@@ -25,10 +25,16 @@ export {y as z};
System.register(['file1', 'file2', 'file3', 'file4', 'file5', 'file6', 'file7'], function(exports_1) {
var ns, file2_1, file3_1, file5_1, ns3;
var x, y;
var exportedNames_1 = {
'x': true,
'z': true
var exportedNames_1 = {
'x': void 0,
'z': void 0
};
function exportStar_1(m, name) {
for(var n in m) {
if (!exportedNames_1.hasOwnProperty(n)) exportedNames_1[n] = name;
if (exportedNames_1[n] === name) exports_1(n, m[n]);
}
}
return {
setters:[
function (_ns) {
@@ -48,8 +54,7 @@ System.register(['file1', 'file2', 'file3', 'file4', 'file5', 'file6', 'file7'],
ns3 = _ns3;
},
function (_file7_1) {
for (var n in _file7_1)
if (!exportedNames_1.hasOwnProperty(n)) exports_1(n, _file7_1[n]);
exportStar_1(_file7_1, 'file7');
}],
execute: function() {
ns.f();