Skip to content

Commit 7e1088b

Browse files
author
Kanchalai Tanglertsampan
committed
Address PR
1 parent ed09628 commit 7e1088b

File tree

2 files changed

+26
-18
lines changed

2 files changed

+26
-18
lines changed

src/compiler/checker.ts

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7266,28 +7266,28 @@ namespace ts {
72667266
return n.kind === SyntaxKind.CallExpression && (<CallExpression>n).expression.kind === SyntaxKind.SuperKeyword;
72677267
}
72687268

7269+
function findFirstSuperCall(n: Node): Node {
7270+
if (isSuperCallExpression(n)) {
7271+
return n;
7272+
}
7273+
else if (isFunctionLike(n)) {
7274+
return undefined;
7275+
}
7276+
return forEachChild(n, findFirstSuperCall);
7277+
}
7278+
72697279
/**
72707280
* Return a cached result if super-statement is already found.
72717281
* Otherwise, find a super statement in a given constructor function and cache the result in the node-links of the constructor
72727282
*
72737283
* @param constructor constructor-function to look for super statement
72747284
*/
7275-
function getSuperStatementInConstructor(constructor: ConstructorDeclaration): ExpressionStatement {
7276-
function getContainingSuperCall(n: Node): Node {
7277-
if (isSuperCallExpression(n)) {
7278-
return n;
7279-
}
7280-
else if (isFunctionLike(n)) {
7281-
return undefined;
7282-
}
7283-
return forEachChild(n, getContainingSuperCall);
7284-
}
7285-
7285+
function getSuperCallInConstructor(constructor: ConstructorDeclaration): ExpressionStatement {
72867286
const links = getNodeLinks(constructor);
7287-
if (!links.superStatement) {
7288-
links.superStatement = <ExpressionStatement>getContainingSuperCall(constructor.body);
7287+
if (!links.superCall) {
7288+
links.superCall = <ExpressionStatement>findFirstSuperCall(constructor.body);
72897289
}
7290-
return links.superStatement;
7290+
return links.superCall;
72917291
}
72927292

72937293
/**
@@ -7316,8 +7316,16 @@ namespace ts {
73167316
// If a containing class does not have extends clause or the class extends null
73177317
// skip checking whether super statement is called before "this" accessing.
73187318
if (baseTypeNode && !isClassDeclarationExtendNull(containingClassDecl)) {
7319-
const superStatement = getSuperStatementInConstructor(<ConstructorDeclaration>container);
7320-
if (!superStatement || (superStatement && superStatement.pos > node.pos || superStatement.end > node.pos)) {
7319+
const superCall = getSuperCallInConstructor(<ConstructorDeclaration>container);
7320+
7321+
// We should give an error in the following cases:
7322+
// - No super-call
7323+
// - "this" is accessing before super-call.
7324+
// i.e super(this)
7325+
// this.x; super();
7326+
// We want to make sure that super-call is done before accessing "this" so that
7327+
// "this" is not accessed as a parameter of the super-call.
7328+
if (!superCall || superCall.end > node.pos) {
73217329
// In ES6, super inside constructor of class-declaration has to precede "this" accessing
73227330
error(node, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
73237331
}
@@ -11833,7 +11841,7 @@ namespace ts {
1183311841
if (getClassExtendsHeritageClauseElement(containingClassDecl)) {
1183411842
const isClassExtendNull = isClassDeclarationExtendNull(containingClassDecl);
1183511843

11836-
if (getSuperStatementInConstructor(node)) {
11844+
if (getSuperCallInConstructor(node)) {
1183711845
if (isClassExtendNull) {
1183811846
error(node, Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
1183911847
}

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2088,7 +2088,7 @@ namespace ts {
20882088
importOnRightSide?: Symbol; // for import declarations - import that appear on the right side
20892089
jsxFlags?: JsxFlags; // flags for knowning what kind of element/attributes we're dealing with
20902090
resolvedJsxType?: Type; // resolved element attributes type of a JSX openinglike element
2091-
superStatement?: ExpressionStatement; // Cached super-statement found in the constructor. Used in checking whether super is called before this-accessing
2091+
superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing
20922092
}
20932093

20942094
export const enum TypeFlags {

0 commit comments

Comments
 (0)