Skip to content

Commit aaea852

Browse files
committed
Merge pull request #6911 from Microsoft/fix6901
Fix emitting super-call when using prologue directives
2 parents 252aada + c02816f commit aaea852

File tree

28 files changed

+630
-18
lines changed

28 files changed

+630
-18
lines changed

src/compiler/checker.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11813,10 +11813,6 @@ namespace ts {
1181311813
return;
1181411814
}
1181511815

11816-
function isSuperCallExpression(n: Node): boolean {
11817-
return n.kind === SyntaxKind.CallExpression && (<CallExpression>n).expression.kind === SyntaxKind.SuperKeyword;
11818-
}
11819-
1182011816
function containsSuperCallAsComputedPropertyName(n: Declaration): boolean {
1182111817
return n.name && containsSuperCall(n.name);
1182211818
}

src/compiler/emitter.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4871,18 +4871,24 @@ const _super = (function (geti, seti) {
48714871
emitToken(SyntaxKind.CloseBraceToken, body.statements.end);
48724872
}
48734873

4874-
function findInitialSuperCall(ctor: ConstructorDeclaration): ExpressionStatement {
4875-
if (ctor.body) {
4876-
const statement = (<Block>ctor.body).statements[0];
4877-
if (statement && statement.kind === SyntaxKind.ExpressionStatement) {
4878-
const expr = (<ExpressionStatement>statement).expression;
4879-
if (expr && expr.kind === SyntaxKind.CallExpression) {
4880-
const func = (<CallExpression>expr).expression;
4881-
if (func && func.kind === SyntaxKind.SuperKeyword) {
4882-
return <ExpressionStatement>statement;
4883-
}
4884-
}
4885-
}
4874+
/**
4875+
* Return the statement at a given index if it is a super-call statement
4876+
* @param ctor a constructor declaration
4877+
* @param index an index to constructor's body to check
4878+
*/
4879+
function getSuperCallAtGivenIndex(ctor: ConstructorDeclaration, index: number): ExpressionStatement {
4880+
if (!ctor.body) {
4881+
return undefined;
4882+
}
4883+
const statements = ctor.body.statements;
4884+
4885+
if (!statements || index >= statements.length) {
4886+
return undefined;
4887+
}
4888+
4889+
const statement = statements[index];
4890+
if (statement.kind === SyntaxKind.ExpressionStatement) {
4891+
return isSuperCallExpression((<ExpressionStatement>statement).expression) ? <ExpressionStatement>statement : undefined;
48864892
}
48874893
}
48884894

@@ -5166,13 +5172,15 @@ const _super = (function (geti, seti) {
51665172
if (ctor) {
51675173
emitDefaultValueAssignments(ctor);
51685174
emitRestParameter(ctor);
5175+
51695176
if (baseTypeElement) {
5170-
superCall = findInitialSuperCall(ctor);
5177+
superCall = getSuperCallAtGivenIndex(ctor, startIndex);
51715178
if (superCall) {
51725179
writeLine();
51735180
emit(superCall);
51745181
}
51755182
}
5183+
51765184
emitParameterPropertyAssignments(ctor);
51775185
}
51785186
else {

src/compiler/utilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,10 @@ namespace ts {
464464
return !!(getCombinedNodeFlags(node) & NodeFlags.Let);
465465
}
466466

467+
export function isSuperCallExpression(n: Node): boolean {
468+
return n.kind === SyntaxKind.CallExpression && (<CallExpression>n).expression.kind === SyntaxKind.SuperKeyword;
469+
}
470+
467471
export function isPrologueDirective(node: Node): boolean {
468472
return node.kind === SyntaxKind.ExpressionStatement && (<ExpressionStatement>node).expression.kind === SyntaxKind.StringLiteral;
469473
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//// [emitSuperCallBeforeEmitParameterPropertyDeclaration1.ts]
2+
class A {
3+
blub = 6;
4+
}
5+
6+
7+
class B extends A {
8+
constructor(public x: number) {
9+
"use strict";
10+
'someStringForEgngInject';
11+
super()
12+
}
13+
}
14+
15+
16+
//// [emitSuperCallBeforeEmitParameterPropertyDeclaration1.js]
17+
var __extends = (this && this.__extends) || function (d, b) {
18+
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
19+
function __() { this.constructor = d; }
20+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
21+
};
22+
var A = (function () {
23+
function A() {
24+
this.blub = 6;
25+
}
26+
return A;
27+
}());
28+
var B = (function (_super) {
29+
__extends(B, _super);
30+
function B(x) {
31+
"use strict";
32+
'someStringForEgngInject';
33+
_super.call(this);
34+
this.x = x;
35+
}
36+
return B;
37+
}(A));
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/compiler/emitSuperCallBeforeEmitParameterPropertyDeclaration1.ts ===
2+
class A {
3+
>A : Symbol(A, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1.ts, 0, 0))
4+
5+
blub = 6;
6+
>blub : Symbol(blub, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1.ts, 0, 9))
7+
}
8+
9+
10+
class B extends A {
11+
>B : Symbol(B, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1.ts, 2, 1))
12+
>A : Symbol(A, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1.ts, 0, 0))
13+
14+
constructor(public x: number) {
15+
>x : Symbol(x, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1.ts, 6, 16))
16+
17+
"use strict";
18+
'someStringForEgngInject';
19+
super()
20+
>super : Symbol(A, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1.ts, 0, 0))
21+
}
22+
}
23+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=== tests/cases/compiler/emitSuperCallBeforeEmitParameterPropertyDeclaration1.ts ===
2+
class A {
3+
>A : A
4+
5+
blub = 6;
6+
>blub : number
7+
>6 : number
8+
}
9+
10+
11+
class B extends A {
12+
>B : B
13+
>A : A
14+
15+
constructor(public x: number) {
16+
>x : number
17+
18+
"use strict";
19+
>"use strict" : string
20+
21+
'someStringForEgngInject';
22+
>'someStringForEgngInject' : string
23+
24+
super()
25+
>super() : void
26+
>super : typeof A
27+
}
28+
}
29+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//// [emitSuperCallBeforeEmitParameterPropertyDeclaration1ES6.ts]
2+
class A {
3+
blub = 6;
4+
}
5+
6+
7+
class B extends A {
8+
constructor(public x: number) {
9+
"use strict";
10+
'someStringForEgngInject';
11+
super()
12+
}
13+
}
14+
15+
16+
//// [emitSuperCallBeforeEmitParameterPropertyDeclaration1ES6.js]
17+
class A {
18+
constructor() {
19+
this.blub = 6;
20+
}
21+
}
22+
class B extends A {
23+
constructor(x) {
24+
"use strict";
25+
'someStringForEgngInject';
26+
super();
27+
this.x = x;
28+
}
29+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/compiler/emitSuperCallBeforeEmitParameterPropertyDeclaration1ES6.ts ===
2+
class A {
3+
>A : Symbol(A, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1ES6.ts, 0, 0))
4+
5+
blub = 6;
6+
>blub : Symbol(blub, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1ES6.ts, 0, 9))
7+
}
8+
9+
10+
class B extends A {
11+
>B : Symbol(B, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1ES6.ts, 2, 1))
12+
>A : Symbol(A, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1ES6.ts, 0, 0))
13+
14+
constructor(public x: number) {
15+
>x : Symbol(x, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1ES6.ts, 6, 16))
16+
17+
"use strict";
18+
'someStringForEgngInject';
19+
super()
20+
>super : Symbol(A, Decl(emitSuperCallBeforeEmitParameterPropertyDeclaration1ES6.ts, 0, 0))
21+
}
22+
}
23+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=== tests/cases/compiler/emitSuperCallBeforeEmitParameterPropertyDeclaration1ES6.ts ===
2+
class A {
3+
>A : A
4+
5+
blub = 6;
6+
>blub : number
7+
>6 : number
8+
}
9+
10+
11+
class B extends A {
12+
>B : B
13+
>A : A
14+
15+
constructor(public x: number) {
16+
>x : number
17+
18+
"use strict";
19+
>"use strict" : string
20+
21+
'someStringForEgngInject';
22+
>'someStringForEgngInject' : string
23+
24+
super()
25+
>super() : void
26+
>super : typeof A
27+
}
28+
}
29+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//// [emitSuperCallBeforeEmitPropertyDeclaration1.ts]
2+
class A {
3+
blub = 6;
4+
}
5+
6+
7+
class B extends A {
8+
9+
blub = 12;
10+
11+
constructor() {
12+
"use strict";
13+
'someStringForEgngInject';
14+
super()
15+
}
16+
}
17+
18+
//// [emitSuperCallBeforeEmitPropertyDeclaration1.js]
19+
var __extends = (this && this.__extends) || function (d, b) {
20+
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
21+
function __() { this.constructor = d; }
22+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
23+
};
24+
var A = (function () {
25+
function A() {
26+
this.blub = 6;
27+
}
28+
return A;
29+
}());
30+
var B = (function (_super) {
31+
__extends(B, _super);
32+
function B() {
33+
"use strict";
34+
'someStringForEgngInject';
35+
_super.call(this);
36+
this.blub = 12;
37+
}
38+
return B;
39+
}(A));

0 commit comments

Comments
 (0)