Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a15030f

Browse filesBrowse files
a-tarasyukrbuckton
andauthored
fix(35050): Decorator emit incorrect within try block (microsoft#41951)
* fix(35050): fix decorated block-scoped class emit * Only use internal name when targeting ES5/3 Co-authored-by: Ron Buckton <ron.buckton@microsoft.com>
1 parent e881a69 commit a15030f
Copy full SHA for a15030f

13 files changed

+455-2Lines changed: 455 additions & 2 deletions
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/transformers/ts.ts‎

Copy file name to clipboardExpand all lines: src/compiler/transformers/ts.ts
+12-2Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,12 @@ namespace ts {
823823

824824
const location = moveRangePastDecorators(node);
825825
const classAlias = getClassAliasIfNeeded(node);
826-
const declName = factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
826+
827+
// When we transform to ES5/3 this will be moved inside an IIFE and should reference the name
828+
// without any block-scoped variable collision handling
829+
const declName = languageVersion <= ScriptTarget.ES2015 ?
830+
factory.getInternalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true) :
831+
factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
827832

828833
// ... = class ${name} ${heritageClauses} {
829834
// ${members}
@@ -1233,7 +1238,12 @@ namespace ts {
12331238
}
12341239

12351240
const classAlias = classAliases && classAliases[getOriginalNodeId(node)];
1236-
const localName = factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
1241+
1242+
// When we transform to ES5/3 this will be moved inside an IIFE and should reference the name
1243+
// without any block-scoped variable collision handling
1244+
const localName = languageVersion <= ScriptTarget.ES2015 ?
1245+
factory.getInternalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true) :
1246+
factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
12371247
const decorate = emitHelpers().createDecorateHelper(decoratorExpressions, localName);
12381248
const expression = factory.createAssignment(localName, classAlias ? factory.createAssignment(classAlias, decorate) : decorate);
12391249
setEmitFlags(expression, EmitFlags.NoComments);
Collapse file
+38Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//// [a.ts]
2+
function decorator() {
3+
return (target: new (...args: any[]) => any) => {}
4+
}
5+
6+
@decorator()
7+
class Foo {
8+
public static func(): Foo {
9+
return new Foo();
10+
}
11+
}
12+
Foo.func();
13+
14+
15+
//// [a.js]
16+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
17+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
18+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
19+
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;
20+
return c > 3 && r && Object.defineProperty(target, key, r), r;
21+
};
22+
function decorator() {
23+
return function (target) { };
24+
}
25+
var Foo = /** @class */ (function () {
26+
function Foo() {
27+
}
28+
Foo_1 = Foo;
29+
Foo.func = function () {
30+
return new Foo_1();
31+
};
32+
var Foo_1;
33+
Foo = Foo_1 = __decorate([
34+
decorator()
35+
], Foo);
36+
return Foo;
37+
}());
38+
Foo.func();
Collapse file
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
=== tests/cases/conformance/decorators/class/a.ts ===
2+
function decorator() {
3+
>decorator : Symbol(decorator, Decl(a.ts, 0, 0))
4+
5+
return (target: new (...args: any[]) => any) => {}
6+
>target : Symbol(target, Decl(a.ts, 1, 12))
7+
>args : Symbol(args, Decl(a.ts, 1, 25))
8+
}
9+
10+
@decorator()
11+
>decorator : Symbol(decorator, Decl(a.ts, 0, 0))
12+
13+
class Foo {
14+
>Foo : Symbol(Foo, Decl(a.ts, 2, 1))
15+
16+
public static func(): Foo {
17+
>func : Symbol(Foo.func, Decl(a.ts, 5, 11))
18+
>Foo : Symbol(Foo, Decl(a.ts, 2, 1))
19+
20+
return new Foo();
21+
>Foo : Symbol(Foo, Decl(a.ts, 2, 1))
22+
}
23+
}
24+
Foo.func();
25+
>Foo.func : Symbol(Foo.func, Decl(a.ts, 5, 11))
26+
>Foo : Symbol(Foo, Decl(a.ts, 2, 1))
27+
>func : Symbol(Foo.func, Decl(a.ts, 5, 11))
28+
Collapse file
+31Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
=== tests/cases/conformance/decorators/class/a.ts ===
2+
function decorator() {
3+
>decorator : () => (target: new (...args: any[]) => any) => void
4+
5+
return (target: new (...args: any[]) => any) => {}
6+
>(target: new (...args: any[]) => any) => {} : (target: new (...args: any[]) => any) => void
7+
>target : new (...args: any[]) => any
8+
>args : any[]
9+
}
10+
11+
@decorator()
12+
>decorator() : (target: new (...args: any[]) => any) => void
13+
>decorator : () => (target: new (...args: any[]) => any) => void
14+
15+
class Foo {
16+
>Foo : Foo
17+
18+
public static func(): Foo {
19+
>func : () => Foo
20+
21+
return new Foo();
22+
>new Foo() : Foo
23+
>Foo : typeof Foo
24+
}
25+
}
26+
Foo.func();
27+
>Foo.func() : Foo
28+
>Foo.func : () => Foo
29+
>Foo : typeof Foo
30+
>func : () => Foo
31+
Collapse file
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//// [a.ts]
2+
function decorator() {
3+
return (target: new (...args: any[]) => any) => {}
4+
}
5+
6+
try {
7+
@decorator()
8+
class Foo {
9+
public static func(): Foo {
10+
return new Foo();
11+
}
12+
}
13+
Foo.func();
14+
}
15+
catch (e) {}
16+
17+
18+
//// [a.js]
19+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
20+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
21+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22+
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;
23+
return c > 3 && r && Object.defineProperty(target, key, r), r;
24+
};
25+
function decorator() {
26+
return function (target) { };
27+
}
28+
try {
29+
var Foo_1 = /** @class */ (function () {
30+
function Foo() {
31+
}
32+
Foo_2 = Foo;
33+
Foo.func = function () {
34+
return new Foo_2();
35+
};
36+
var Foo_2;
37+
Foo = Foo_2 = __decorate([
38+
decorator()
39+
], Foo);
40+
return Foo;
41+
}());
42+
Foo_1.func();
43+
}
44+
catch (e) { }
Collapse file
+32Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/conformance/decorators/class/a.ts ===
2+
function decorator() {
3+
>decorator : Symbol(decorator, Decl(a.ts, 0, 0))
4+
5+
return (target: new (...args: any[]) => any) => {}
6+
>target : Symbol(target, Decl(a.ts, 1, 12))
7+
>args : Symbol(args, Decl(a.ts, 1, 25))
8+
}
9+
10+
try {
11+
@decorator()
12+
>decorator : Symbol(decorator, Decl(a.ts, 0, 0))
13+
14+
class Foo {
15+
>Foo : Symbol(Foo, Decl(a.ts, 4, 5))
16+
17+
public static func(): Foo {
18+
>func : Symbol(Foo.func, Decl(a.ts, 6, 15))
19+
>Foo : Symbol(Foo, Decl(a.ts, 4, 5))
20+
21+
return new Foo();
22+
>Foo : Symbol(Foo, Decl(a.ts, 4, 5))
23+
}
24+
}
25+
Foo.func();
26+
>Foo.func : Symbol(Foo.func, Decl(a.ts, 6, 15))
27+
>Foo : Symbol(Foo, Decl(a.ts, 4, 5))
28+
>func : Symbol(Foo.func, Decl(a.ts, 6, 15))
29+
}
30+
catch (e) {}
31+
>e : Symbol(e, Decl(a.ts, 13, 7))
32+
Collapse file
+35Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
=== tests/cases/conformance/decorators/class/a.ts ===
2+
function decorator() {
3+
>decorator : () => (target: new (...args: any[]) => any) => void
4+
5+
return (target: new (...args: any[]) => any) => {}
6+
>(target: new (...args: any[]) => any) => {} : (target: new (...args: any[]) => any) => void
7+
>target : new (...args: any[]) => any
8+
>args : any[]
9+
}
10+
11+
try {
12+
@decorator()
13+
>decorator() : (target: new (...args: any[]) => any) => void
14+
>decorator : () => (target: new (...args: any[]) => any) => void
15+
16+
class Foo {
17+
>Foo : Foo
18+
19+
public static func(): Foo {
20+
>func : () => Foo
21+
22+
return new Foo();
23+
>new Foo() : Foo
24+
>Foo : typeof Foo
25+
}
26+
}
27+
Foo.func();
28+
>Foo.func() : Foo
29+
>Foo.func : () => Foo
30+
>Foo : typeof Foo
31+
>func : () => Foo
32+
}
33+
catch (e) {}
34+
>e : any
35+
Collapse file
+66Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//// [a.ts]
2+
function decorator() {
3+
return (target: new (...args: any[]) => any) => {}
4+
}
5+
6+
@decorator()
7+
class Foo {
8+
public static func(): Foo {
9+
return new Foo();
10+
}
11+
}
12+
Foo.func();
13+
14+
try {
15+
@decorator()
16+
class Foo {
17+
public static func(): Foo {
18+
return new Foo();
19+
}
20+
}
21+
Foo.func();
22+
}
23+
catch (e) {}
24+
25+
26+
//// [a.js]
27+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
28+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
29+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
30+
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;
31+
return c > 3 && r && Object.defineProperty(target, key, r), r;
32+
};
33+
function decorator() {
34+
return function (target) { };
35+
}
36+
var Foo = /** @class */ (function () {
37+
function Foo() {
38+
}
39+
Foo_1 = Foo;
40+
Foo.func = function () {
41+
return new Foo_1();
42+
};
43+
var Foo_1;
44+
Foo = Foo_1 = __decorate([
45+
decorator()
46+
], Foo);
47+
return Foo;
48+
}());
49+
Foo.func();
50+
try {
51+
var Foo_2 = /** @class */ (function () {
52+
function Foo() {
53+
}
54+
Foo_3 = Foo;
55+
Foo.func = function () {
56+
return new Foo_3();
57+
};
58+
var Foo_3;
59+
Foo = Foo_3 = __decorate([
60+
decorator()
61+
], Foo);
62+
return Foo;
63+
}());
64+
Foo_2.func();
65+
}
66+
catch (e) { }
Collapse file
+51Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
=== tests/cases/conformance/decorators/class/a.ts ===
2+
function decorator() {
3+
>decorator : Symbol(decorator, Decl(a.ts, 0, 0))
4+
5+
return (target: new (...args: any[]) => any) => {}
6+
>target : Symbol(target, Decl(a.ts, 1, 12))
7+
>args : Symbol(args, Decl(a.ts, 1, 25))
8+
}
9+
10+
@decorator()
11+
>decorator : Symbol(decorator, Decl(a.ts, 0, 0))
12+
13+
class Foo {
14+
>Foo : Symbol(Foo, Decl(a.ts, 2, 1))
15+
16+
public static func(): Foo {
17+
>func : Symbol(Foo.func, Decl(a.ts, 5, 11))
18+
>Foo : Symbol(Foo, Decl(a.ts, 2, 1))
19+
20+
return new Foo();
21+
>Foo : Symbol(Foo, Decl(a.ts, 2, 1))
22+
}
23+
}
24+
Foo.func();
25+
>Foo.func : Symbol(Foo.func, Decl(a.ts, 5, 11))
26+
>Foo : Symbol(Foo, Decl(a.ts, 2, 1))
27+
>func : Symbol(Foo.func, Decl(a.ts, 5, 11))
28+
29+
try {
30+
@decorator()
31+
>decorator : Symbol(decorator, Decl(a.ts, 0, 0))
32+
33+
class Foo {
34+
>Foo : Symbol(Foo, Decl(a.ts, 12, 5))
35+
36+
public static func(): Foo {
37+
>func : Symbol(Foo.func, Decl(a.ts, 14, 15))
38+
>Foo : Symbol(Foo, Decl(a.ts, 12, 5))
39+
40+
return new Foo();
41+
>Foo : Symbol(Foo, Decl(a.ts, 12, 5))
42+
}
43+
}
44+
Foo.func();
45+
>Foo.func : Symbol(Foo.func, Decl(a.ts, 14, 15))
46+
>Foo : Symbol(Foo, Decl(a.ts, 12, 5))
47+
>func : Symbol(Foo.func, Decl(a.ts, 14, 15))
48+
}
49+
catch (e) {}
50+
>e : Symbol(e, Decl(a.ts, 21, 7))
51+

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.