Skip to content

Commit 87ed20b

Browse files
committed
system: fix emit for exports of non-top level entities, fix emit for enums
1 parent c8dd04b commit 87ed20b

9 files changed

+289
-10
lines changed

src/compiler/emitter.ts

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2642,7 +2642,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
26422642
writeLine();
26432643
emitStart(node);
26442644

2645-
if (compilerOptions.module === ModuleKind.System) {
2645+
// emit call to exported only for top level nodes
2646+
if (compilerOptions.module === ModuleKind.System && node.parent === currentSourceFile) {
26462647
// emit export default <smth> as
26472648
// export("default", <smth>)
26482649
write(`${exportFunctionForFile}("`);
@@ -4406,7 +4407,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
44064407
emitModuleMemberName(node);
44074408
write(" = {}));");
44084409
emitEnd(node);
4409-
if (!isES6ExportedDeclaration(node) && node.flags & NodeFlags.Export) {
4410+
if (!isES6ExportedDeclaration(node) && node.flags & NodeFlags.Export && !shouldHoistDeclarationInSystemJsModule(node)) {
4411+
// do not emit var if variable was already hoisted
44104412
writeLine();
44114413
emitStart(node);
44124414
write("var ");
@@ -4417,6 +4419,15 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
44174419
write(";");
44184420
}
44194421
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
4422+
if (compilerOptions.module === ModuleKind.System && (node.flags & NodeFlags.Export)) {
4423+
// write the call to exported for enum
4424+
writeLine();
4425+
write(`${exportFunctionForFile}("`);
4426+
emitDeclarationName(node);
4427+
write(`", `);
4428+
emitDeclarationName(node);
4429+
write(")");
4430+
}
44204431
emitExportMemberAssignments(node.name);
44214432
}
44224433
}
@@ -5097,7 +5108,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
50975108
// in theory we should hoist only exported functions and its dependencies
50985109
// in practice to simplify things we'll hoist all source level functions and variable declaration
50995110
// including variables declarations for module and class declarations
5100-
let hoistedVars: (Identifier | ClassDeclaration | ModuleDeclaration)[];
5111+
let hoistedVars: (Identifier | ClassDeclaration | ModuleDeclaration | EnumDeclaration)[];
51015112
let hoistedFunctionDeclarations: FunctionDeclaration[];
51025113
let exportedDeclarations: (Identifier | Declaration)[];
51035114

@@ -5106,13 +5117,30 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
51065117
if (hoistedVars) {
51075118
writeLine();
51085119
write("var ");
5120+
let seen: Map<string> = {};
51095121
for (let i = 0; i < hoistedVars.length; ++i) {
51105122
let local = hoistedVars[i];
5123+
let name = local.kind === SyntaxKind.Identifier
5124+
? <Identifier>local
5125+
: <Identifier>(<ClassDeclaration | ModuleDeclaration | EnumDeclaration>local).name;
5126+
5127+
if (name) {
5128+
// do not emit duplicate entries (in case of declaration merging) in the list of hoisted variables
5129+
let text = unescapeIdentifier(name.text);
5130+
if (hasProperty(seen, text)) {
5131+
continue;
5132+
}
5133+
else {
5134+
seen[text] = text;
5135+
}
5136+
}
5137+
51115138
if (i !== 0) {
51125139
write(", ");
51135140
}
5114-
if (local.kind === SyntaxKind.ClassDeclaration || local.kind === SyntaxKind.ModuleDeclaration) {
5115-
emitDeclarationName(<ClassDeclaration | ModuleDeclaration>local);
5141+
5142+
if (local.kind === SyntaxKind.ClassDeclaration || local.kind === SyntaxKind.ModuleDeclaration || local.kind === SyntaxKind.EnumDeclaration) {
5143+
emitDeclarationName(<ClassDeclaration | ModuleDeclaration | EnumDeclaration>local);
51165144
}
51175145
else {
51185146
emit(local);
@@ -5156,7 +5184,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
51565184
}
51575185

51585186
if (node.kind === SyntaxKind.ClassDeclaration) {
5159-
// TODO: rename block scoped classes
51605187
if (!hoistedVars) {
51615188
hoistedVars = [];
51625189
}
@@ -5165,12 +5192,26 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
51655192
return;
51665193
}
51675194

5168-
if (node.kind === SyntaxKind.ModuleDeclaration && shouldEmitModuleDeclaration(<ModuleDeclaration>node)) {
5169-
if (!hoistedVars) {
5170-
hoistedVars = [];
5195+
if (node.kind === SyntaxKind.EnumDeclaration) {
5196+
if (shouldEmitEnumDeclaration(<EnumDeclaration>node)) {
5197+
if (!hoistedVars) {
5198+
hoistedVars = [];
5199+
}
5200+
5201+
hoistedVars.push(<ModuleDeclaration>node);
51715202
}
51725203

5173-
hoistedVars.push(<ModuleDeclaration>node);
5204+
return;
5205+
}
5206+
5207+
if (node.kind === SyntaxKind.ModuleDeclaration) {
5208+
if (shouldEmitModuleDeclaration(<ModuleDeclaration>node)) {
5209+
if (!hoistedVars) {
5210+
hoistedVars = [];
5211+
}
5212+
5213+
hoistedVars.push(<ModuleDeclaration>node);
5214+
}
51745215
return;
51755216
}
51765217

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//// [systemModuleDeclarationMerging.ts]
2+
3+
export function F() {}
4+
export module F { var x; }
5+
6+
export class C {}
7+
export module C { var x; }
8+
9+
export enum E {}
10+
export module E { var x; }
11+
12+
//// [systemModuleDeclarationMerging.js]
13+
System.register([], function(exports_1) {
14+
var F, C, E;
15+
function F() { }
16+
exports_1("F", F);
17+
return {
18+
setters:[],
19+
execute: function() {
20+
(function (F) {
21+
var x;
22+
})(F = F || (F = {}));
23+
exports_1("F", F)
24+
C = (function () {
25+
function C() {
26+
}
27+
return C;
28+
})();
29+
exports_1("C", C);
30+
(function (C) {
31+
var x;
32+
})(C = C || (C = {}));
33+
exports_1("C", C)
34+
(function (E) {
35+
})(E || (E = {}));
36+
exports_1("E", E)
37+
(function (E) {
38+
var x;
39+
})(E = E || (E = {}));
40+
exports_1("E", E)
41+
}
42+
}
43+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/compiler/systemModuleDeclarationMerging.ts ===
2+
3+
export function F() {}
4+
>F : Symbol(F, Decl(systemModuleDeclarationMerging.ts, 0, 0), Decl(systemModuleDeclarationMerging.ts, 1, 22))
5+
6+
export module F { var x; }
7+
>F : Symbol(F, Decl(systemModuleDeclarationMerging.ts, 0, 0), Decl(systemModuleDeclarationMerging.ts, 1, 22))
8+
>x : Symbol(x, Decl(systemModuleDeclarationMerging.ts, 2, 21))
9+
10+
export class C {}
11+
>C : Symbol(C, Decl(systemModuleDeclarationMerging.ts, 2, 26), Decl(systemModuleDeclarationMerging.ts, 4, 17))
12+
13+
export module C { var x; }
14+
>C : Symbol(C, Decl(systemModuleDeclarationMerging.ts, 2, 26), Decl(systemModuleDeclarationMerging.ts, 4, 17))
15+
>x : Symbol(x, Decl(systemModuleDeclarationMerging.ts, 5, 21))
16+
17+
export enum E {}
18+
>E : Symbol(E, Decl(systemModuleDeclarationMerging.ts, 5, 26), Decl(systemModuleDeclarationMerging.ts, 7, 16))
19+
20+
export module E { var x; }
21+
>E : Symbol(E, Decl(systemModuleDeclarationMerging.ts, 5, 26), Decl(systemModuleDeclarationMerging.ts, 7, 16))
22+
>x : Symbol(x, Decl(systemModuleDeclarationMerging.ts, 8, 21))
23+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/compiler/systemModuleDeclarationMerging.ts ===
2+
3+
export function F() {}
4+
>F : typeof F
5+
6+
export module F { var x; }
7+
>F : typeof F
8+
>x : any
9+
10+
export class C {}
11+
>C : C
12+
13+
export module C { var x; }
14+
>C : typeof C
15+
>x : any
16+
17+
export enum E {}
18+
>E : E
19+
20+
export module E { var x; }
21+
>E : typeof E
22+
>x : any
23+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//// [systemModuleNonTopLevelModuleMembers.ts]
2+
3+
export class TopLevelClass {}
4+
export module TopLevelModule {var v;}
5+
export function TopLevelFunction(): void {}
6+
export enum TopLevelEnum {E}
7+
8+
export module TopLevelModule2 {
9+
export class NonTopLevelClass {}
10+
export module NonTopLevelModule {var v;}
11+
export function NonTopLevelFunction(): void {}
12+
export enum NonTopLevelEnum {E}
13+
}
14+
15+
//// [systemModuleNonTopLevelModuleMembers.js]
16+
System.register([], function(exports_1) {
17+
var TopLevelClass, TopLevelModule, TopLevelEnum, TopLevelModule2;
18+
function TopLevelFunction() { }
19+
exports_1("TopLevelFunction", TopLevelFunction);
20+
return {
21+
setters:[],
22+
execute: function() {
23+
TopLevelClass = (function () {
24+
function TopLevelClass() {
25+
}
26+
return TopLevelClass;
27+
})();
28+
exports_1("TopLevelClass", TopLevelClass);
29+
(function (TopLevelModule) {
30+
var v;
31+
})(TopLevelModule = TopLevelModule || (TopLevelModule = {}));
32+
exports_1("TopLevelModule", TopLevelModule)
33+
(function (TopLevelEnum) {
34+
TopLevelEnum[TopLevelEnum["E"] = 0] = "E";
35+
})(TopLevelEnum || (TopLevelEnum = {}));
36+
exports_1("TopLevelEnum", TopLevelEnum)
37+
(function (TopLevelModule2) {
38+
var NonTopLevelClass = (function () {
39+
function NonTopLevelClass() {
40+
}
41+
return NonTopLevelClass;
42+
})();
43+
TopLevelModule2.NonTopLevelClass = NonTopLevelClass;
44+
var NonTopLevelModule;
45+
(function (NonTopLevelModule) {
46+
var v;
47+
})(NonTopLevelModule = TopLevelModule2.NonTopLevelModule || (TopLevelModule2.NonTopLevelModule = {}));
48+
function NonTopLevelFunction() { }
49+
TopLevelModule2.NonTopLevelFunction = NonTopLevelFunction;
50+
(function (NonTopLevelEnum) {
51+
NonTopLevelEnum[NonTopLevelEnum["E"] = 0] = "E";
52+
})(TopLevelModule2.NonTopLevelEnum || (TopLevelModule2.NonTopLevelEnum = {}));
53+
var NonTopLevelEnum = TopLevelModule2.NonTopLevelEnum;
54+
})(TopLevelModule2 = TopLevelModule2 || (TopLevelModule2 = {}));
55+
exports_1("TopLevelModule2", TopLevelModule2)
56+
}
57+
}
58+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts ===
2+
3+
export class TopLevelClass {}
4+
>TopLevelClass : Symbol(TopLevelClass, Decl(systemModuleNonTopLevelModuleMembers.ts, 0, 0))
5+
6+
export module TopLevelModule {var v;}
7+
>TopLevelModule : Symbol(TopLevelModule, Decl(systemModuleNonTopLevelModuleMembers.ts, 1, 29))
8+
>v : Symbol(v, Decl(systemModuleNonTopLevelModuleMembers.ts, 2, 33))
9+
10+
export function TopLevelFunction(): void {}
11+
>TopLevelFunction : Symbol(TopLevelFunction, Decl(systemModuleNonTopLevelModuleMembers.ts, 2, 37))
12+
13+
export enum TopLevelEnum {E}
14+
>TopLevelEnum : Symbol(TopLevelEnum, Decl(systemModuleNonTopLevelModuleMembers.ts, 3, 43))
15+
>E : Symbol(TopLevelEnum.E, Decl(systemModuleNonTopLevelModuleMembers.ts, 4, 26))
16+
17+
export module TopLevelModule2 {
18+
>TopLevelModule2 : Symbol(TopLevelModule2, Decl(systemModuleNonTopLevelModuleMembers.ts, 4, 28))
19+
20+
export class NonTopLevelClass {}
21+
>NonTopLevelClass : Symbol(NonTopLevelClass, Decl(systemModuleNonTopLevelModuleMembers.ts, 6, 31))
22+
23+
export module NonTopLevelModule {var v;}
24+
>NonTopLevelModule : Symbol(NonTopLevelModule, Decl(systemModuleNonTopLevelModuleMembers.ts, 7, 36))
25+
>v : Symbol(v, Decl(systemModuleNonTopLevelModuleMembers.ts, 8, 40))
26+
27+
export function NonTopLevelFunction(): void {}
28+
>NonTopLevelFunction : Symbol(NonTopLevelFunction, Decl(systemModuleNonTopLevelModuleMembers.ts, 8, 44))
29+
30+
export enum NonTopLevelEnum {E}
31+
>NonTopLevelEnum : Symbol(NonTopLevelEnum, Decl(systemModuleNonTopLevelModuleMembers.ts, 9, 50))
32+
>E : Symbol(NonTopLevelEnum.E, Decl(systemModuleNonTopLevelModuleMembers.ts, 10, 33))
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts ===
2+
3+
export class TopLevelClass {}
4+
>TopLevelClass : TopLevelClass
5+
6+
export module TopLevelModule {var v;}
7+
>TopLevelModule : typeof TopLevelModule
8+
>v : any
9+
10+
export function TopLevelFunction(): void {}
11+
>TopLevelFunction : () => void
12+
13+
export enum TopLevelEnum {E}
14+
>TopLevelEnum : TopLevelEnum
15+
>E : TopLevelEnum
16+
17+
export module TopLevelModule2 {
18+
>TopLevelModule2 : typeof TopLevelModule2
19+
20+
export class NonTopLevelClass {}
21+
>NonTopLevelClass : NonTopLevelClass
22+
23+
export module NonTopLevelModule {var v;}
24+
>NonTopLevelModule : typeof NonTopLevelModule
25+
>v : any
26+
27+
export function NonTopLevelFunction(): void {}
28+
>NonTopLevelFunction : () => void
29+
30+
export enum NonTopLevelEnum {E}
31+
>NonTopLevelEnum : NonTopLevelEnum
32+
>E : NonTopLevelEnum
33+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @module: system
2+
// @separateCompilation: true
3+
4+
export function F() {}
5+
export module F { var x; }
6+
7+
export class C {}
8+
export module C { var x; }
9+
10+
export enum E {}
11+
export module E { var x; }
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @module: system
2+
// @separateCompilation: true
3+
4+
export class TopLevelClass {}
5+
export module TopLevelModule {var v;}
6+
export function TopLevelFunction(): void {}
7+
export enum TopLevelEnum {E}
8+
9+
export module TopLevelModule2 {
10+
export class NonTopLevelClass {}
11+
export module NonTopLevelModule {var v;}
12+
export function NonTopLevelFunction(): void {}
13+
export enum NonTopLevelEnum {E}
14+
}

0 commit comments

Comments
 (0)