Skip to content

Commit ecd6a7a

Browse files
committed
Merge pull request #3222 from Microsoft/port-3110
Port PR 3110 into release 1.5
2 parents 9d469c8 + c828bcb commit ecd6a7a

21 files changed

+648
-18
lines changed

src/compiler/emitter.ts

Lines changed: 62 additions & 18 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 exporter 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}("`);
@@ -4376,15 +4377,18 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
43764377
return;
43774378
}
43784379

4379-
if (!(node.flags & NodeFlags.Export) || isES6ExportedDeclaration(node)) {
4380-
emitStart(node);
4381-
if (isES6ExportedDeclaration(node)) {
4382-
write("export ");
4380+
if (!shouldHoistDeclarationInSystemJsModule(node)) {
4381+
// do not emit var if variable was already hoisted
4382+
if (!(node.flags & NodeFlags.Export) || isES6ExportedDeclaration(node)) {
4383+
emitStart(node);
4384+
if (isES6ExportedDeclaration(node)) {
4385+
write("export ");
4386+
}
4387+
write("var ");
4388+
emit(node.name);
4389+
emitEnd(node);
4390+
write(";");
43834391
}
4384-
write("var ");
4385-
emit(node.name);
4386-
emitEnd(node);
4387-
write(";");
43884392
}
43894393
writeLine();
43904394
emitStart(node);
@@ -4406,7 +4410,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
44064410
emitModuleMemberName(node);
44074411
write(" = {}));");
44084412
emitEnd(node);
4409-
if (!isES6ExportedDeclaration(node) && node.flags & NodeFlags.Export) {
4413+
if (!isES6ExportedDeclaration(node) && node.flags & NodeFlags.Export && !shouldHoistDeclarationInSystemJsModule(node)) {
4414+
// do not emit var if variable was already hoisted
44104415
writeLine();
44114416
emitStart(node);
44124417
write("var ");
@@ -4417,6 +4422,15 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
44174422
write(";");
44184423
}
44194424
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
4425+
if (compilerOptions.module === ModuleKind.System && (node.flags & NodeFlags.Export)) {
4426+
// write the call to exporter for enum
4427+
writeLine();
4428+
write(`${exportFunctionForFile}("`);
4429+
emitDeclarationName(node);
4430+
write(`", `);
4431+
emitDeclarationName(node);
4432+
write(")");
4433+
}
44204434
emitExportMemberAssignments(node.name);
44214435
}
44224436
}
@@ -5097,7 +5111,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
50975111
// in theory we should hoist only exported functions and its dependencies
50985112
// in practice to simplify things we'll hoist all source level functions and variable declaration
50995113
// including variables declarations for module and class declarations
5100-
let hoistedVars: (Identifier | ClassDeclaration | ModuleDeclaration)[];
5114+
let hoistedVars: (Identifier | ClassDeclaration | ModuleDeclaration | EnumDeclaration)[];
51015115
let hoistedFunctionDeclarations: FunctionDeclaration[];
51025116
let exportedDeclarations: (Identifier | Declaration)[];
51035117

@@ -5106,13 +5120,30 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
51065120
if (hoistedVars) {
51075121
writeLine();
51085122
write("var ");
5123+
let seen: Map<string> = {};
51095124
for (let i = 0; i < hoistedVars.length; ++i) {
51105125
let local = hoistedVars[i];
5126+
let name = local.kind === SyntaxKind.Identifier
5127+
? <Identifier>local
5128+
: <Identifier>(<ClassDeclaration | ModuleDeclaration | EnumDeclaration>local).name;
5129+
5130+
if (name) {
5131+
// do not emit duplicate entries (in case of declaration merging) in the list of hoisted variables
5132+
let text = unescapeIdentifier(name.text);
5133+
if (hasProperty(seen, text)) {
5134+
continue;
5135+
}
5136+
else {
5137+
seen[text] = text;
5138+
}
5139+
}
5140+
51115141
if (i !== 0) {
51125142
write(", ");
51135143
}
5114-
if (local.kind === SyntaxKind.ClassDeclaration || local.kind === SyntaxKind.ModuleDeclaration) {
5115-
emitDeclarationName(<ClassDeclaration | ModuleDeclaration>local);
5144+
5145+
if (local.kind === SyntaxKind.ClassDeclaration || local.kind === SyntaxKind.ModuleDeclaration || local.kind === SyntaxKind.EnumDeclaration) {
5146+
emitDeclarationName(<ClassDeclaration | ModuleDeclaration | EnumDeclaration>local);
51165147
}
51175148
else {
51185149
emit(local);
@@ -5156,7 +5187,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
51565187
}
51575188

51585189
if (node.kind === SyntaxKind.ClassDeclaration) {
5159-
// TODO: rename block scoped classes
51605190
if (!hoistedVars) {
51615191
hoistedVars = [];
51625192
}
@@ -5165,12 +5195,26 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
51655195
return;
51665196
}
51675197

5168-
if (node.kind === SyntaxKind.ModuleDeclaration && shouldEmitModuleDeclaration(<ModuleDeclaration>node)) {
5169-
if (!hoistedVars) {
5170-
hoistedVars = [];
5198+
if (node.kind === SyntaxKind.EnumDeclaration) {
5199+
if (shouldEmitEnumDeclaration(<EnumDeclaration>node)) {
5200+
if (!hoistedVars) {
5201+
hoistedVars = [];
5202+
}
5203+
5204+
hoistedVars.push(<ModuleDeclaration>node);
51715205
}
51725206

5173-
hoistedVars.push(<ModuleDeclaration>node);
5207+
return;
5208+
}
5209+
5210+
if (node.kind === SyntaxKind.ModuleDeclaration) {
5211+
if (shouldEmitModuleDeclaration(<ModuleDeclaration>node)) {
5212+
if (!hoistedVars) {
5213+
hoistedVars = [];
5214+
}
5215+
5216+
hoistedVars.push(<ModuleDeclaration>node);
5217+
}
51745218
return;
51755219
}
51765220

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//// [systemModuleConstEnums.ts]
2+
3+
declare function use(a: any);
4+
const enum TopLevelConstEnum { X }
5+
6+
export function foo() {
7+
use(TopLevelConstEnum.X);
8+
use(M.NonTopLevelConstEnum.X);
9+
}
10+
11+
module M {
12+
export const enum NonTopLevelConstEnum { X }
13+
}
14+
15+
//// [systemModuleConstEnums.js]
16+
System.register([], function(exports_1) {
17+
function foo() {
18+
use(0 /* X */);
19+
use(0 /* X */);
20+
}
21+
exports_1("foo", foo);
22+
return {
23+
setters:[],
24+
execute: function() {
25+
}
26+
}
27+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
=== tests/cases/compiler/systemModuleConstEnums.ts ===
2+
3+
declare function use(a: any);
4+
>use : Symbol(use, Decl(systemModuleConstEnums.ts, 0, 0))
5+
>a : Symbol(a, Decl(systemModuleConstEnums.ts, 1, 21))
6+
7+
const enum TopLevelConstEnum { X }
8+
>TopLevelConstEnum : Symbol(TopLevelConstEnum, Decl(systemModuleConstEnums.ts, 1, 29))
9+
>X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 2, 30))
10+
11+
export function foo() {
12+
>foo : Symbol(foo, Decl(systemModuleConstEnums.ts, 2, 34))
13+
14+
use(TopLevelConstEnum.X);
15+
>use : Symbol(use, Decl(systemModuleConstEnums.ts, 0, 0))
16+
>TopLevelConstEnum.X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 2, 30))
17+
>TopLevelConstEnum : Symbol(TopLevelConstEnum, Decl(systemModuleConstEnums.ts, 1, 29))
18+
>X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 2, 30))
19+
20+
use(M.NonTopLevelConstEnum.X);
21+
>use : Symbol(use, Decl(systemModuleConstEnums.ts, 0, 0))
22+
>M.NonTopLevelConstEnum.X : Symbol(M.NonTopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 10, 44))
23+
>M.NonTopLevelConstEnum : Symbol(M.NonTopLevelConstEnum, Decl(systemModuleConstEnums.ts, 9, 10))
24+
>M : Symbol(M, Decl(systemModuleConstEnums.ts, 7, 1))
25+
>NonTopLevelConstEnum : Symbol(M.NonTopLevelConstEnum, Decl(systemModuleConstEnums.ts, 9, 10))
26+
>X : Symbol(M.NonTopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 10, 44))
27+
}
28+
29+
module M {
30+
>M : Symbol(M, Decl(systemModuleConstEnums.ts, 7, 1))
31+
32+
export const enum NonTopLevelConstEnum { X }
33+
>NonTopLevelConstEnum : Symbol(NonTopLevelConstEnum, Decl(systemModuleConstEnums.ts, 9, 10))
34+
>X : Symbol(NonTopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 10, 44))
35+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
=== tests/cases/compiler/systemModuleConstEnums.ts ===
2+
3+
declare function use(a: any);
4+
>use : (a: any) => any
5+
>a : any
6+
7+
const enum TopLevelConstEnum { X }
8+
>TopLevelConstEnum : TopLevelConstEnum
9+
>X : TopLevelConstEnum
10+
11+
export function foo() {
12+
>foo : () => void
13+
14+
use(TopLevelConstEnum.X);
15+
>use(TopLevelConstEnum.X) : any
16+
>use : (a: any) => any
17+
>TopLevelConstEnum.X : TopLevelConstEnum
18+
>TopLevelConstEnum : typeof TopLevelConstEnum
19+
>X : TopLevelConstEnum
20+
21+
use(M.NonTopLevelConstEnum.X);
22+
>use(M.NonTopLevelConstEnum.X) : any
23+
>use : (a: any) => any
24+
>M.NonTopLevelConstEnum.X : M.NonTopLevelConstEnum
25+
>M.NonTopLevelConstEnum : typeof M.NonTopLevelConstEnum
26+
>M : typeof M
27+
>NonTopLevelConstEnum : typeof M.NonTopLevelConstEnum
28+
>X : M.NonTopLevelConstEnum
29+
}
30+
31+
module M {
32+
>M : typeof M
33+
34+
export const enum NonTopLevelConstEnum { X }
35+
>NonTopLevelConstEnum : NonTopLevelConstEnum
36+
>X : NonTopLevelConstEnum
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//// [systemModuleConstEnumsSeparateCompilation.ts]
2+
3+
declare function use(a: any);
4+
const enum TopLevelConstEnum { X }
5+
6+
export function foo() {
7+
use(TopLevelConstEnum.X);
8+
use(M.NonTopLevelConstEnum.X);
9+
}
10+
11+
module M {
12+
export const enum NonTopLevelConstEnum { X }
13+
}
14+
15+
//// [systemModuleConstEnumsSeparateCompilation.js]
16+
System.register([], function(exports_1) {
17+
var TopLevelConstEnum, M;
18+
function foo() {
19+
use(TopLevelConstEnum.X);
20+
use(M.NonTopLevelConstEnum.X);
21+
}
22+
exports_1("foo", foo);
23+
return {
24+
setters:[],
25+
execute: function() {
26+
(function (TopLevelConstEnum) {
27+
TopLevelConstEnum[TopLevelConstEnum["X"] = 0] = "X";
28+
})(TopLevelConstEnum || (TopLevelConstEnum = {}));
29+
(function (M) {
30+
(function (NonTopLevelConstEnum) {
31+
NonTopLevelConstEnum[NonTopLevelConstEnum["X"] = 0] = "X";
32+
})(M.NonTopLevelConstEnum || (M.NonTopLevelConstEnum = {}));
33+
var NonTopLevelConstEnum = M.NonTopLevelConstEnum;
34+
})(M || (M = {}));
35+
}
36+
}
37+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
=== tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts ===
2+
3+
declare function use(a: any);
4+
>use : Symbol(use, Decl(systemModuleConstEnumsSeparateCompilation.ts, 0, 0))
5+
>a : Symbol(a, Decl(systemModuleConstEnumsSeparateCompilation.ts, 1, 21))
6+
7+
const enum TopLevelConstEnum { X }
8+
>TopLevelConstEnum : Symbol(TopLevelConstEnum, Decl(systemModuleConstEnumsSeparateCompilation.ts, 1, 29))
9+
>X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 2, 30))
10+
11+
export function foo() {
12+
>foo : Symbol(foo, Decl(systemModuleConstEnumsSeparateCompilation.ts, 2, 34))
13+
14+
use(TopLevelConstEnum.X);
15+
>use : Symbol(use, Decl(systemModuleConstEnumsSeparateCompilation.ts, 0, 0))
16+
>TopLevelConstEnum.X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 2, 30))
17+
>TopLevelConstEnum : Symbol(TopLevelConstEnum, Decl(systemModuleConstEnumsSeparateCompilation.ts, 1, 29))
18+
>X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 2, 30))
19+
20+
use(M.NonTopLevelConstEnum.X);
21+
>use : Symbol(use, Decl(systemModuleConstEnumsSeparateCompilation.ts, 0, 0))
22+
>M.NonTopLevelConstEnum.X : Symbol(M.NonTopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 10, 44))
23+
>M.NonTopLevelConstEnum : Symbol(M.NonTopLevelConstEnum, Decl(systemModuleConstEnumsSeparateCompilation.ts, 9, 10))
24+
>M : Symbol(M, Decl(systemModuleConstEnumsSeparateCompilation.ts, 7, 1))
25+
>NonTopLevelConstEnum : Symbol(M.NonTopLevelConstEnum, Decl(systemModuleConstEnumsSeparateCompilation.ts, 9, 10))
26+
>X : Symbol(M.NonTopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 10, 44))
27+
}
28+
29+
module M {
30+
>M : Symbol(M, Decl(systemModuleConstEnumsSeparateCompilation.ts, 7, 1))
31+
32+
export const enum NonTopLevelConstEnum { X }
33+
>NonTopLevelConstEnum : Symbol(NonTopLevelConstEnum, Decl(systemModuleConstEnumsSeparateCompilation.ts, 9, 10))
34+
>X : Symbol(NonTopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 10, 44))
35+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
=== tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts ===
2+
3+
declare function use(a: any);
4+
>use : (a: any) => any
5+
>a : any
6+
7+
const enum TopLevelConstEnum { X }
8+
>TopLevelConstEnum : TopLevelConstEnum
9+
>X : TopLevelConstEnum
10+
11+
export function foo() {
12+
>foo : () => void
13+
14+
use(TopLevelConstEnum.X);
15+
>use(TopLevelConstEnum.X) : any
16+
>use : (a: any) => any
17+
>TopLevelConstEnum.X : TopLevelConstEnum
18+
>TopLevelConstEnum : typeof TopLevelConstEnum
19+
>X : TopLevelConstEnum
20+
21+
use(M.NonTopLevelConstEnum.X);
22+
>use(M.NonTopLevelConstEnum.X) : any
23+
>use : (a: any) => any
24+
>M.NonTopLevelConstEnum.X : M.NonTopLevelConstEnum
25+
>M.NonTopLevelConstEnum : typeof M.NonTopLevelConstEnum
26+
>M : typeof M
27+
>NonTopLevelConstEnum : typeof M.NonTopLevelConstEnum
28+
>X : M.NonTopLevelConstEnum
29+
}
30+
31+
module M {
32+
>M : typeof M
33+
34+
export const enum NonTopLevelConstEnum { X }
35+
>NonTopLevelConstEnum : NonTopLevelConstEnum
36+
>X : NonTopLevelConstEnum
37+
}

0 commit comments

Comments
 (0)