Skip to content

Commit 81f1e5f

Browse files
Fixed multiple prologue directives with parameter properties (#48687) (#48782)
Co-authored-by: Josh Goldberg <me@joshuakgoldberg.com>
1 parent 79b02a6 commit 81f1e5f

6 files changed

+353
-8
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34839,7 +34839,7 @@ namespace ts {
3483934839
superCallStatement = statement;
3484034840
break;
3484134841
}
34842-
if (!isPrologueDirective(statement) && nodeImmediatelyReferencesSuperOrThis(statement)) {
34842+
if (nodeImmediatelyReferencesSuperOrThis(statement)) {
3484334843
break;
3484434844
}
3484534845
}

src/compiler/transformers/ts.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -1936,14 +1936,14 @@ namespace ts {
19361936

19371937
resumeLexicalEnvironment();
19381938

1939-
const indexAfterLastPrologueStatement = factory.copyPrologue(body.statements, statements, /*ensureUseStrict*/ false, visitor);
1940-
const superStatementIndex = findSuperStatementIndex(body.statements, indexAfterLastPrologueStatement);
1939+
const prologueStatementCount = factory.copyPrologue(body.statements, statements, /*ensureUseStrict*/ false, visitor);
1940+
const superStatementIndex = findSuperStatementIndex(body.statements, prologueStatementCount);
19411941

19421942
// If there was a super call, visit existing statements up to and including it
19431943
if (superStatementIndex >= 0) {
19441944
addRange(
19451945
statements,
1946-
visitNodes(body.statements, visitor, isStatement, indexAfterLastPrologueStatement, superStatementIndex + 1 - indexAfterLastPrologueStatement),
1946+
visitNodes(body.statements, visitor, isStatement, prologueStatementCount, superStatementIndex + 1 - prologueStatementCount),
19471947
);
19481948
}
19491949

@@ -1965,13 +1965,17 @@ namespace ts {
19651965
if (superStatementIndex >= 0) {
19661966
addRange(statements, parameterPropertyAssignments);
19671967
}
1968-
// Since there was no super() call, parameter properties are the first statements in the constructor
1968+
// Since there was no super() call, parameter properties are the first statements in the constructor after any prologue statements
19691969
else {
1970-
statements = addRange(parameterPropertyAssignments, statements);
1970+
statements = [
1971+
...statements.slice(0, prologueStatementCount),
1972+
...parameterPropertyAssignments,
1973+
...statements.slice(prologueStatementCount),
1974+
];
19711975
}
19721976

1973-
// Add remaining statements from the body, skipping the super() call if it was found
1974-
addRange(statements, visitNodes(body.statements, visitor, isStatement, superStatementIndex + 1));
1977+
// Add remaining statements from the body, skipping the super() call if it was found and any (already added) prologue statements
1978+
addRange(statements, visitNodes(body.statements, visitor, isStatement, superStatementIndex + 1 + prologueStatementCount));
19751979

19761980
// End the lexical environment.
19771981
statements = factory.mergeLexicalEnvironment(statements, endLexicalEnvironment());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
//// [parameterPropertyInConstructorWithPrologues.ts]
2+
// https://github.com/microsoft/TypeScript/issues/48671
3+
4+
class Foo1 {
5+
constructor(private A: string) {
6+
"ngInject1";
7+
}
8+
}
9+
10+
class Foo2 {
11+
constructor(private A: string, private B: string) {
12+
"ngInject1";
13+
"ngInject2";
14+
}
15+
}
16+
17+
class Foo3 {
18+
constructor(private A: string, private B: string, private C: string) {
19+
"ngInject1";
20+
"ngInject2";
21+
}
22+
}
23+
24+
class Foo4 {
25+
constructor(private A: string) {
26+
"ngInject1";
27+
console.log("hi");
28+
}
29+
}
30+
31+
class Foo5 {
32+
constructor(private A: string, private B: string) {
33+
"ngInject1";
34+
"ngInject2";
35+
console.log("hi");
36+
}
37+
}
38+
39+
class Foo6 {
40+
constructor(private A: string, private B: string, private C: string) {
41+
"ngInject1";
42+
"ngInject2";
43+
console.log("hi");
44+
}
45+
}
46+
47+
48+
//// [parameterPropertyInConstructorWithPrologues.js]
49+
// https://github.com/microsoft/TypeScript/issues/48671
50+
var Foo1 = /** @class */ (function () {
51+
function Foo1(A) {
52+
"ngInject1";
53+
this.A = A;
54+
}
55+
return Foo1;
56+
}());
57+
var Foo2 = /** @class */ (function () {
58+
function Foo2(A, B) {
59+
"ngInject1";
60+
"ngInject2";
61+
this.A = A;
62+
this.B = B;
63+
}
64+
return Foo2;
65+
}());
66+
var Foo3 = /** @class */ (function () {
67+
function Foo3(A, B, C) {
68+
"ngInject1";
69+
"ngInject2";
70+
this.A = A;
71+
this.B = B;
72+
this.C = C;
73+
}
74+
return Foo3;
75+
}());
76+
var Foo4 = /** @class */ (function () {
77+
function Foo4(A) {
78+
"ngInject1";
79+
this.A = A;
80+
console.log("hi");
81+
}
82+
return Foo4;
83+
}());
84+
var Foo5 = /** @class */ (function () {
85+
function Foo5(A, B) {
86+
"ngInject1";
87+
"ngInject2";
88+
this.A = A;
89+
this.B = B;
90+
console.log("hi");
91+
}
92+
return Foo5;
93+
}());
94+
var Foo6 = /** @class */ (function () {
95+
function Foo6(A, B, C) {
96+
"ngInject1";
97+
"ngInject2";
98+
this.A = A;
99+
this.B = B;
100+
this.C = C;
101+
console.log("hi");
102+
}
103+
return Foo6;
104+
}());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
=== tests/cases/compiler/parameterPropertyInConstructorWithPrologues.ts ===
2+
// https://github.com/microsoft/TypeScript/issues/48671
3+
4+
class Foo1 {
5+
>Foo1 : Symbol(Foo1, Decl(parameterPropertyInConstructorWithPrologues.ts, 0, 0))
6+
7+
constructor(private A: string) {
8+
>A : Symbol(Foo1.A, Decl(parameterPropertyInConstructorWithPrologues.ts, 3, 14))
9+
10+
"ngInject1";
11+
}
12+
}
13+
14+
class Foo2 {
15+
>Foo2 : Symbol(Foo2, Decl(parameterPropertyInConstructorWithPrologues.ts, 6, 1))
16+
17+
constructor(private A: string, private B: string) {
18+
>A : Symbol(Foo2.A, Decl(parameterPropertyInConstructorWithPrologues.ts, 9, 14))
19+
>B : Symbol(Foo2.B, Decl(parameterPropertyInConstructorWithPrologues.ts, 9, 32))
20+
21+
"ngInject1";
22+
"ngInject2";
23+
}
24+
}
25+
26+
class Foo3 {
27+
>Foo3 : Symbol(Foo3, Decl(parameterPropertyInConstructorWithPrologues.ts, 13, 1))
28+
29+
constructor(private A: string, private B: string, private C: string) {
30+
>A : Symbol(Foo3.A, Decl(parameterPropertyInConstructorWithPrologues.ts, 16, 14))
31+
>B : Symbol(Foo3.B, Decl(parameterPropertyInConstructorWithPrologues.ts, 16, 32))
32+
>C : Symbol(Foo3.C, Decl(parameterPropertyInConstructorWithPrologues.ts, 16, 51))
33+
34+
"ngInject1";
35+
"ngInject2";
36+
}
37+
}
38+
39+
class Foo4 {
40+
>Foo4 : Symbol(Foo4, Decl(parameterPropertyInConstructorWithPrologues.ts, 20, 1))
41+
42+
constructor(private A: string) {
43+
>A : Symbol(Foo4.A, Decl(parameterPropertyInConstructorWithPrologues.ts, 23, 14))
44+
45+
"ngInject1";
46+
console.log("hi");
47+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
48+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
49+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
50+
}
51+
}
52+
53+
class Foo5 {
54+
>Foo5 : Symbol(Foo5, Decl(parameterPropertyInConstructorWithPrologues.ts, 27, 1))
55+
56+
constructor(private A: string, private B: string) {
57+
>A : Symbol(Foo5.A, Decl(parameterPropertyInConstructorWithPrologues.ts, 30, 14))
58+
>B : Symbol(Foo5.B, Decl(parameterPropertyInConstructorWithPrologues.ts, 30, 32))
59+
60+
"ngInject1";
61+
"ngInject2";
62+
console.log("hi");
63+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
64+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
65+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
66+
}
67+
}
68+
69+
class Foo6 {
70+
>Foo6 : Symbol(Foo6, Decl(parameterPropertyInConstructorWithPrologues.ts, 35, 1))
71+
72+
constructor(private A: string, private B: string, private C: string) {
73+
>A : Symbol(Foo6.A, Decl(parameterPropertyInConstructorWithPrologues.ts, 38, 14))
74+
>B : Symbol(Foo6.B, Decl(parameterPropertyInConstructorWithPrologues.ts, 38, 32))
75+
>C : Symbol(Foo6.C, Decl(parameterPropertyInConstructorWithPrologues.ts, 38, 51))
76+
77+
"ngInject1";
78+
"ngInject2";
79+
console.log("hi");
80+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
81+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
82+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
83+
}
84+
}
85+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
=== tests/cases/compiler/parameterPropertyInConstructorWithPrologues.ts ===
2+
// https://github.com/microsoft/TypeScript/issues/48671
3+
4+
class Foo1 {
5+
>Foo1 : Foo1
6+
7+
constructor(private A: string) {
8+
>A : string
9+
10+
"ngInject1";
11+
>"ngInject1" : "ngInject1"
12+
}
13+
}
14+
15+
class Foo2 {
16+
>Foo2 : Foo2
17+
18+
constructor(private A: string, private B: string) {
19+
>A : string
20+
>B : string
21+
22+
"ngInject1";
23+
>"ngInject1" : "ngInject1"
24+
25+
"ngInject2";
26+
>"ngInject2" : "ngInject2"
27+
}
28+
}
29+
30+
class Foo3 {
31+
>Foo3 : Foo3
32+
33+
constructor(private A: string, private B: string, private C: string) {
34+
>A : string
35+
>B : string
36+
>C : string
37+
38+
"ngInject1";
39+
>"ngInject1" : "ngInject1"
40+
41+
"ngInject2";
42+
>"ngInject2" : "ngInject2"
43+
}
44+
}
45+
46+
class Foo4 {
47+
>Foo4 : Foo4
48+
49+
constructor(private A: string) {
50+
>A : string
51+
52+
"ngInject1";
53+
>"ngInject1" : "ngInject1"
54+
55+
console.log("hi");
56+
>console.log("hi") : void
57+
>console.log : (...data: any[]) => void
58+
>console : Console
59+
>log : (...data: any[]) => void
60+
>"hi" : "hi"
61+
}
62+
}
63+
64+
class Foo5 {
65+
>Foo5 : Foo5
66+
67+
constructor(private A: string, private B: string) {
68+
>A : string
69+
>B : string
70+
71+
"ngInject1";
72+
>"ngInject1" : "ngInject1"
73+
74+
"ngInject2";
75+
>"ngInject2" : "ngInject2"
76+
77+
console.log("hi");
78+
>console.log("hi") : void
79+
>console.log : (...data: any[]) => void
80+
>console : Console
81+
>log : (...data: any[]) => void
82+
>"hi" : "hi"
83+
}
84+
}
85+
86+
class Foo6 {
87+
>Foo6 : Foo6
88+
89+
constructor(private A: string, private B: string, private C: string) {
90+
>A : string
91+
>B : string
92+
>C : string
93+
94+
"ngInject1";
95+
>"ngInject1" : "ngInject1"
96+
97+
"ngInject2";
98+
>"ngInject2" : "ngInject2"
99+
100+
console.log("hi");
101+
>console.log("hi") : void
102+
>console.log : (...data: any[]) => void
103+
>console : Console
104+
>log : (...data: any[]) => void
105+
>"hi" : "hi"
106+
}
107+
}
108+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// https://github.com/microsoft/TypeScript/issues/48671
2+
3+
class Foo1 {
4+
constructor(private A: string) {
5+
"ngInject1";
6+
}
7+
}
8+
9+
class Foo2 {
10+
constructor(private A: string, private B: string) {
11+
"ngInject1";
12+
"ngInject2";
13+
}
14+
}
15+
16+
class Foo3 {
17+
constructor(private A: string, private B: string, private C: string) {
18+
"ngInject1";
19+
"ngInject2";
20+
}
21+
}
22+
23+
class Foo4 {
24+
constructor(private A: string) {
25+
"ngInject1";
26+
console.log("hi");
27+
}
28+
}
29+
30+
class Foo5 {
31+
constructor(private A: string, private B: string) {
32+
"ngInject1";
33+
"ngInject2";
34+
console.log("hi");
35+
}
36+
}
37+
38+
class Foo6 {
39+
constructor(private A: string, private B: string, private C: string) {
40+
"ngInject1";
41+
"ngInject2";
42+
console.log("hi");
43+
}
44+
}

0 commit comments

Comments
 (0)