Skip to content

Commit 3af5592

Browse files
committed
allow module to reserve slots for names that they export
1 parent c057c0a commit 3af5592

File tree

3 files changed

+75
-36
lines changed

3 files changed

+75
-36
lines changed

src/compiler/emitter.ts

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4992,10 +4992,18 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
49924992
}
49934993
}
49944994

4995+
// storage has the following structure
4996+
// {
4997+
// <exported-name-from-current-module> : void 0,
4998+
// <exported-name-obtained-from star export in module 'm'>: 'm'
4999+
// }
5000+
// this allows to:
5001+
// - prevent star exports to overwrite locally exported names
5002+
// - bind star exported names to particular module so they won't be overwritten by other star exports
49955003
const exportedNamesStorageRef = makeUniqueName("exportedNames");
49965004

49975005
writeLine();
4998-
write(`var ${exportedNamesStorageRef} = { `);
5006+
write(`var ${exportedNamesStorageRef} = {`);
49995007
increaseIndent();
50005008

50015009
let started = false;
@@ -5036,7 +5044,26 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
50365044
writeLine();
50375045
write("};");
50385046

5039-
return exportedNamesStorageRef;
5047+
writeLine();
5048+
5049+
const exportStarFunction = makeUniqueName("exportStar");
5050+
5051+
// define an export star helper function
5052+
write(`function ${exportStarFunction}(m, name) {`);
5053+
writeLine();
5054+
write(` for(var n in m) {`);
5055+
writeLine();
5056+
// if name is not yet taken by either local names or names in other modules - reserve it
5057+
write(` if (!${exportedNamesStorageRef}.hasOwnProperty(n)) ${exportedNamesStorageRef}[n] = name;`);
5058+
writeLine();
5059+
// only export value if it was exported from the module with name 'name';
5060+
write(` if (${exportedNamesStorageRef}[n] === name) ${exportFunctionForFile}(n, m[n]);`);
5061+
writeLine();
5062+
write(" }");
5063+
writeLine();
5064+
write("}")
5065+
5066+
return exportStarFunction;
50405067

50415068
function writeExportedName(node: Identifier | Declaration): void {
50425069
if (started) {
@@ -5058,7 +5085,7 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
50585085
emitDeclarationName(<Declaration>node);
50595086
}
50605087

5061-
write("': true");
5088+
write("': void 0");
50625089
}
50635090
}
50645091

@@ -5234,12 +5261,12 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
52345261
emitVariableDeclarationsForImports();
52355262
writeLine();
52365263
var exportedDeclarations = processTopLevelVariableAndFunctionDeclarations(node);
5237-
let exportedLocalNames = emitLocalStorageForExportedNamesIfNecessary(exportedDeclarations)
5264+
let exportStarFunction = emitLocalStorageForExportedNamesIfNecessary(exportedDeclarations)
52385265
writeLine();
52395266
write("return {");
52405267
increaseIndent();
52415268
writeLine();
5242-
emitSetters(exportedLocalNames);
5269+
emitSetters(exportStarFunction);
52435270
writeLine();
52445271
emitExecute(node, startIndex);
52455272
emitTempDeclarations(/*newLine*/ true)
@@ -5248,7 +5275,7 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
52485275
write("}"); // return
52495276
}
52505277

5251-
function emitSetters(exportedLocalNamesRef: string) {
5278+
function emitSetters(exportStarFunction: string) {
52525279
write("setters:[");
52535280
for (let i = 0; i < externalImports.length; ++i) {
52545281
if (i !== 0) {
@@ -5341,16 +5368,8 @@ if (typeof __param !== "function") __param = function (paramIndex, decorator) {
53415368
writeLine();
53425369
// export * from 'foo'
53435370
// emit as:
5344-
// for (var n in _foo) exports(n, _foo[n]);
5345-
// NOTE: it is safe to use name 'n' since parameter name always starts with '_'
5346-
write(`for (var n in ${parameterName})`);
5347-
increaseIndent();
5348-
writeLine();
5349-
if (exportedLocalNamesRef) {
5350-
write(`if (!${exportedLocalNamesRef}.hasOwnProperty(n))`);
5351-
}
5352-
write(` ${exportFunctionForFile}(n, ${parameterName}[n]);`)
5353-
decreaseIndent();
5371+
// exportStar(_foo, 'foo');
5372+
write(`${exportStarFunction}(${parameterName}, ${getExternalModuleNameText(importNode)});`);
53545373
}
53555374

53565375
writeLine();

tests/baselines/reference/systemModule11.js

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,20 @@ System.register(['bar'], function(exports_1) {
3939
var x;
4040
function foo() { }
4141
exports_1("foo", foo);
42-
var exportedNames_1 = {
43-
'x': true,
44-
'foo': true
42+
var exportedNames_1 = {
43+
'x': void 0,
44+
'foo': void 0
4545
};
46+
function exportStar_1(m, name) {
47+
for(var n in m) {
48+
if (!exportedNames_1.hasOwnProperty(n)) exportedNames_1[n] = name;
49+
if (exportedNames_1[n] === name) exports_1(n, m[n]);
50+
}
51+
}
4652
return {
4753
setters:[
4854
function (_bar_1) {
49-
for (var n in _bar_1)
50-
if (!exportedNames_1.hasOwnProperty(n)) exports_1(n, _bar_1[n]);
55+
exportStar_1(_bar_1, 'bar');
5156
}],
5257
execute: function() {
5358
exports_1("x", x);
@@ -57,15 +62,20 @@ System.register(['bar'], function(exports_1) {
5762
//// [file2.js]
5863
System.register(['bar'], function(exports_1) {
5964
var x, y;
60-
var exportedNames_1 = {
61-
'x': true,
62-
'y1': true
65+
var exportedNames_1 = {
66+
'x': void 0,
67+
'y1': void 0
6368
};
69+
function exportStar_1(m, name) {
70+
for(var n in m) {
71+
if (!exportedNames_1.hasOwnProperty(n)) exportedNames_1[n] = name;
72+
if (exportedNames_1[n] === name) exports_1(n, m[n]);
73+
}
74+
}
6475
return {
6576
setters:[
6677
function (_bar_1) {
67-
for (var n in _bar_1)
68-
if (!exportedNames_1.hasOwnProperty(n)) exports_1(n, _bar_1[n]);
78+
exportStar_1(_bar_1, 'bar');
6979
}],
7080
execute: function() {
7181
exports_1("x", x);
@@ -75,19 +85,24 @@ System.register(['bar'], function(exports_1) {
7585
});
7686
//// [file3.js]
7787
System.register(['a', 'bar'], function(exports_1) {
78-
var exportedNames_1 = {
79-
'x': true,
80-
'z': true
88+
var exportedNames_1 = {
89+
'x': void 0,
90+
'z': void 0
8191
};
92+
function exportStar_1(m, name) {
93+
for(var n in m) {
94+
if (!exportedNames_1.hasOwnProperty(n)) exportedNames_1[n] = name;
95+
if (exportedNames_1[n] === name) exports_1(n, m[n]);
96+
}
97+
}
8298
return {
8399
setters:[
84100
function (_a_1) {
85101
exports_1("x", _a_1["x"]);
86102
exports_1("z", _a_1["y"]);
87103
},
88104
function (_bar_1) {
89-
for (var n in _bar_1)
90-
if (!exportedNames_1.hasOwnProperty(n)) exports_1(n, _bar_1[n]);
105+
exportStar_1(_bar_1, 'bar');
91106
}],
92107
execute: function() {
93108
}

tests/baselines/reference/systemModule9.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,16 @@ export {y as z};
2525
System.register(['file1', 'file2', 'file3', 'file4', 'file5', 'file6', 'file7'], function(exports_1) {
2626
var ns, file2_1, file3_1, file5_1, ns3;
2727
var x, y;
28-
var exportedNames_1 = {
29-
'x': true,
30-
'z': true
28+
var exportedNames_1 = {
29+
'x': void 0,
30+
'z': void 0
3131
};
32+
function exportStar_1(m, name) {
33+
for(var n in m) {
34+
if (!exportedNames_1.hasOwnProperty(n)) exportedNames_1[n] = name;
35+
if (exportedNames_1[n] === name) exports_1(n, m[n]);
36+
}
37+
}
3238
return {
3339
setters:[
3440
function (_ns) {
@@ -48,8 +54,7 @@ System.register(['file1', 'file2', 'file3', 'file4', 'file5', 'file6', 'file7'],
4854
ns3 = _ns3;
4955
},
5056
function (_file7_1) {
51-
for (var n in _file7_1)
52-
if (!exportedNames_1.hasOwnProperty(n)) exports_1(n, _file7_1[n]);
57+
exportStar_1(_file7_1, 'file7');
5358
}],
5459
execute: function() {
5560
ns.f();

0 commit comments

Comments
 (0)