Skip to content

Commit 7cc4a8d

Browse files
authored
Wrap classes with decorators or static properties in an IIFE, even for ES2015+ (microsoft#32011)
* Always wrap classes with decorators or static properties in an IIFE Currently only script targets less than or equal to ES5 will wrap classes. However, the wrapping is also crucial to file size optimizations for ES2015+ as well. Without the IIFE wrapper, minification tools do not elide the class. This is due to references to the class being present within the downlevelled decorator and static property code. This change represents the full completion of issue microsoft#15857 * Accept new baselines
1 parent 1d6bb8b commit 7cc4a8d

File tree

73 files changed

+1286
-967
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1286
-967
lines changed

src/compiler/transformers/ts.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@ namespace ts {
2323
IsNamedExternalExport = 1 << 4,
2424
IsDefaultExternalExport = 1 << 5,
2525
IsDerivedClass = 1 << 6,
26-
UseImmediatelyInvokedFunctionExpression = 1 << 7,
2726

2827
HasAnyDecorators = HasConstructorDecorators | HasMemberDecorators,
2928
NeedsName = HasStaticInitializedProperties | HasMemberDecorators,
30-
MayNeedImmediatelyInvokedFunctionExpression = HasAnyDecorators | HasStaticInitializedProperties,
29+
UseImmediatelyInvokedFunctionExpression = HasAnyDecorators | HasStaticInitializedProperties,
3130
IsExported = IsExportOfNamespace | IsDefaultExternalExport | IsNamedExternalExport,
3231
}
3332

@@ -590,7 +589,6 @@ namespace ts {
590589
if (isExportOfNamespace(node)) facts |= ClassFacts.IsExportOfNamespace;
591590
else if (isDefaultExternalModuleExport(node)) facts |= ClassFacts.IsDefaultExternalExport;
592591
else if (isNamedExternalModuleExport(node)) facts |= ClassFacts.IsNamedExternalExport;
593-
if (languageVersion <= ScriptTarget.ES5 && (facts & ClassFacts.MayNeedImmediatelyInvokedFunctionExpression)) facts |= ClassFacts.UseImmediatelyInvokedFunctionExpression;
594592
return facts;
595593
}
596594

@@ -661,6 +659,12 @@ namespace ts {
661659
const iife = createImmediatelyInvokedArrowFunction(statements);
662660
setEmitFlags(iife, EmitFlags.TypeScriptClassWrapper);
663661

662+
// Class comment is already added by the ES2015 transform when targeting ES5 or below.
663+
// Only add if targetting ES2015+ to prevent duplicates
664+
if (languageVersion > ScriptTarget.ES5) {
665+
addSyntheticLeadingComment(iife, SyntaxKind.MultiLineCommentTrivia, "* @class ");
666+
}
667+
664668
const varStatement = createVariableStatement(
665669
/*modifiers*/ undefined,
666670
createVariableDeclarationList([
@@ -669,7 +673,7 @@ namespace ts {
669673
/*type*/ undefined,
670674
iife
671675
)
672-
])
676+
], languageVersion > ScriptTarget.ES5 ? NodeFlags.Let : undefined)
673677
);
674678

675679
setOriginalNode(varStatement, node);

tests/baselines/reference/awaitAndYieldInProperty.js

+22-18
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,31 @@ async function* test(x: Promise<string>) {
1919

2020
//// [awaitAndYieldInProperty.js]
2121
async function* test(x) {
22-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
23-
class C {
24-
constructor() {
25-
this[_a] = await x;
26-
this[_c] = yield 2;
27-
}
28-
}
29-
_a = await x, _b = await x, _c = yield 1, _d = yield 3;
30-
C[_b] = await x;
31-
C[_d] = yield 4;
32-
return _j = class {
22+
var _a, _b, _c, _d, _e;
23+
let C = /** @class */ (() => {
24+
var _e, _f, _g, _h;
25+
class C {
3326
constructor() {
3427
this[_e] = await x;
3528
this[_g] = yield 2;
3629
}
30+
}
31+
_e = await x, _f = await x, _g = yield 1, _h = yield 3;
32+
C[_f] = await x;
33+
C[_h] = yield 4;
34+
return C;
35+
})();
36+
return _e = class {
37+
constructor() {
38+
this[_a] = await x;
39+
this[_c] = yield 2;
40+
}
3741
},
38-
_e = await x,
39-
_f = await x,
40-
_g = yield 1,
41-
_h = yield 3,
42-
_j[_f] = await x,
43-
_j[_h] = yield 4,
44-
_j;
42+
_a = await x,
43+
_b = await x,
44+
_c = yield 1,
45+
_d = yield 3,
46+
_e[_b] = await x,
47+
_e[_d] = yield 4,
48+
_e;
4549
}

tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ class C3 {
44
}
55

66
//// [classDeclarationCheckUsedBeforeDefinitionInItself.js]
7-
class C3 {
8-
}
9-
C3.intance = new C3(); // ok
7+
let C3 = /** @class */ (() => {
8+
class C3 {
9+
}
10+
C3.intance = new C3(); // ok
11+
return C3;
12+
})();

tests/baselines/reference/computedPropertyNames12_ES6.js

+12-9
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,19 @@ class C {
1717
}
1818

1919
//// [computedPropertyNames12_ES6.js]
20-
var _a, _b, _c;
2120
var s;
2221
var n;
2322
var a;
24-
class C {
25-
constructor() {
26-
this[_a] = n;
27-
this[_b] = 2;
28-
this[`hello bye`] = 0;
23+
let C = /** @class */ (() => {
24+
var _a, _b, _c;
25+
class C {
26+
constructor() {
27+
this[_a] = n;
28+
this[_b] = 2;
29+
this[`hello bye`] = 0;
30+
}
2931
}
30-
}
31-
_a = n, s + s, _b = s + n, +s, _c = `hello ${a} bye`;
32-
C[_c] = 0;
32+
_a = n, s + s, _b = s + n, +s, _c = `hello ${a} bye`;
33+
C[_c] = 0;
34+
return C;
35+
})();

tests/baselines/reference/computedPropertyNamesWithStaticProperty.js

+12-9
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ class C {
1111
}
1212

1313
//// [computedPropertyNamesWithStaticProperty.js]
14-
class C {
15-
get [C.staticProp]() {
16-
return "hello";
14+
let C = /** @class */ (() => {
15+
class C {
16+
get [C.staticProp]() {
17+
return "hello";
18+
}
19+
set [C.staticProp](x) {
20+
var y = x;
21+
}
22+
[C.staticProp]() { }
1723
}
18-
set [C.staticProp](x) {
19-
var y = x;
20-
}
21-
[C.staticProp]() { }
22-
}
23-
C.staticProp = 10;
24+
C.staticProp = 10;
25+
return C;
26+
})();

tests/baselines/reference/decoratedClassExportsCommonJS1.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
1414
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1515
return c > 3 && r && Object.defineProperty(target, key, r), r;
1616
};
17-
var Testing123_1;
1817
Object.defineProperty(exports, "__esModule", { value: true });
19-
let Testing123 = Testing123_1 = class Testing123 {
20-
};
21-
Testing123.prop1 = Testing123_1.prop0;
22-
Testing123 = Testing123_1 = __decorate([
23-
Something({ v: () => Testing123_1 })
24-
], Testing123);
18+
let Testing123 = /** @class */ (() => {
19+
var Testing123_1;
20+
let Testing123 = Testing123_1 = class Testing123 {
21+
};
22+
Testing123.prop1 = Testing123_1.prop0;
23+
Testing123 = Testing123_1 = __decorate([
24+
Something({ v: () => Testing123_1 })
25+
], Testing123);
26+
return Testing123;
27+
})();
2528
exports.Testing123 = Testing123;

tests/baselines/reference/decoratedClassExportsCommonJS2.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
1212
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1313
return c > 3 && r && Object.defineProperty(target, key, r), r;
1414
};
15-
var Testing123_1;
1615
Object.defineProperty(exports, "__esModule", { value: true });
17-
let Testing123 = Testing123_1 = class Testing123 {
18-
};
19-
Testing123 = Testing123_1 = __decorate([
20-
Something({ v: () => Testing123_1 })
21-
], Testing123);
16+
let Testing123 = /** @class */ (() => {
17+
var Testing123_1;
18+
let Testing123 = Testing123_1 = class Testing123 {
19+
};
20+
Testing123 = Testing123_1 = __decorate([
21+
Something({ v: () => Testing123_1 })
22+
], Testing123);
23+
return Testing123;
24+
})();
2225
exports.Testing123 = Testing123;

tests/baselines/reference/decoratedClassExportsSystem1.js

+11-7
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,21 @@ System.register([], function (exports_1, context_1) {
1616
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1717
return c > 3 && r && Object.defineProperty(target, key, r), r;
1818
};
19-
var Testing123_1, Testing123;
19+
var Testing123;
2020
var __moduleName = context_1 && context_1.id;
2121
return {
2222
setters: [],
2323
execute: function () {
24-
Testing123 = Testing123_1 = class Testing123 {
25-
};
26-
Testing123.prop1 = Testing123_1.prop0;
27-
Testing123 = Testing123_1 = __decorate([
28-
Something({ v: () => Testing123_1 })
29-
], Testing123);
24+
Testing123 = /** @class */ (() => {
25+
var Testing123_1;
26+
let Testing123 = Testing123_1 = class Testing123 {
27+
};
28+
Testing123.prop1 = Testing123_1.prop0;
29+
Testing123 = Testing123_1 = __decorate([
30+
Something({ v: () => Testing123_1 })
31+
], Testing123);
32+
return Testing123;
33+
})();
3034
exports_1("Testing123", Testing123);
3135
}
3236
};

tests/baselines/reference/decoratedClassExportsSystem2.js

+10-6
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@ System.register([], function (exports_1, context_1) {
1313
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1414
return c > 3 && r && Object.defineProperty(target, key, r), r;
1515
};
16-
var Testing123_1, Testing123;
16+
var Testing123;
1717
var __moduleName = context_1 && context_1.id;
1818
return {
1919
setters: [],
2020
execute: function () {
21-
Testing123 = Testing123_1 = class Testing123 {
22-
};
23-
Testing123 = Testing123_1 = __decorate([
24-
Something({ v: () => Testing123_1 })
25-
], Testing123);
21+
Testing123 = /** @class */ (() => {
22+
var Testing123_1;
23+
let Testing123 = Testing123_1 = class Testing123 {
24+
};
25+
Testing123 = Testing123_1 = __decorate([
26+
Something({ v: () => Testing123_1 })
27+
], Testing123);
28+
return Testing123;
29+
})();
2630
exports_1("Testing123", Testing123);
2731
}
2832
};

tests/baselines/reference/decoratedClassFromExternalModule.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
1717
return c > 3 && r && Object.defineProperty(target, key, r), r;
1818
};
1919
function decorate(target) { }
20-
let Decorated = class Decorated {
21-
};
22-
Decorated = __decorate([
23-
decorate
24-
], Decorated);
20+
let Decorated = /** @class */ (() => {
21+
let Decorated = class Decorated {
22+
};
23+
Decorated = __decorate([
24+
decorate
25+
], Decorated);
26+
return Decorated;
27+
})();
2528
export default Decorated;
2629
//// [undecorated.js]

tests/baselines/reference/decoratedDefaultExportsGetExportedAmd.js

+16-10
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@ define(["require", "exports"], function (require, exports) {
2424
"use strict";
2525
Object.defineProperty(exports, "__esModule", { value: true });
2626
var decorator;
27-
let Foo = class Foo {
28-
};
29-
Foo = __decorate([
30-
decorator
31-
], Foo);
27+
let Foo = /** @class */ (() => {
28+
let Foo = class Foo {
29+
};
30+
Foo = __decorate([
31+
decorator
32+
], Foo);
33+
return Foo;
34+
})();
3235
exports.default = Foo;
3336
});
3437
//// [b.js]
@@ -42,10 +45,13 @@ define(["require", "exports"], function (require, exports) {
4245
"use strict";
4346
Object.defineProperty(exports, "__esModule", { value: true });
4447
var decorator;
45-
let default_1 = class {
46-
};
47-
default_1 = __decorate([
48-
decorator
49-
], default_1);
48+
let default_1 = /** @class */ (() => {
49+
let default_1 = class {
50+
};
51+
default_1 = __decorate([
52+
decorator
53+
], default_1);
54+
return default_1;
55+
})();
5056
exports.default = default_1;
5157
});

tests/baselines/reference/decoratedDefaultExportsGetExportedCommonjs.js

+16-10
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
2323
};
2424
Object.defineProperty(exports, "__esModule", { value: true });
2525
var decorator;
26-
let Foo = class Foo {
27-
};
28-
Foo = __decorate([
29-
decorator
30-
], Foo);
26+
let Foo = /** @class */ (() => {
27+
let Foo = class Foo {
28+
};
29+
Foo = __decorate([
30+
decorator
31+
], Foo);
32+
return Foo;
33+
})();
3134
exports.default = Foo;
3235
//// [b.js]
3336
"use strict";
@@ -39,9 +42,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
3942
};
4043
Object.defineProperty(exports, "__esModule", { value: true });
4144
var decorator;
42-
let default_1 = class {
43-
};
44-
default_1 = __decorate([
45-
decorator
46-
], default_1);
45+
let default_1 = /** @class */ (() => {
46+
let default_1 = class {
47+
};
48+
default_1 = __decorate([
49+
decorator
50+
], default_1);
51+
return default_1;
52+
})();
4753
exports.default = default_1;

tests/baselines/reference/decoratedDefaultExportsGetExportedSystem.js

+16-10
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,14 @@ System.register([], function (exports_1, context_1) {
2626
return {
2727
setters: [],
2828
execute: function () {
29-
Foo = class Foo {
30-
};
31-
Foo = __decorate([
32-
decorator
33-
], Foo);
29+
Foo = /** @class */ (() => {
30+
let Foo = class Foo {
31+
};
32+
Foo = __decorate([
33+
decorator
34+
], Foo);
35+
return Foo;
36+
})();
3437
exports_1("default", Foo);
3538
}
3639
};
@@ -49,11 +52,14 @@ System.register([], function (exports_1, context_1) {
4952
return {
5053
setters: [],
5154
execute: function () {
52-
default_1 = class {
53-
};
54-
default_1 = __decorate([
55-
decorator
56-
], default_1);
55+
default_1 = /** @class */ (() => {
56+
let default_1 = class {
57+
};
58+
default_1 = __decorate([
59+
decorator
60+
], default_1);
61+
return default_1;
62+
})();
5763
exports_1("default", default_1);
5864
}
5965
};

0 commit comments

Comments
 (0)