mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-22 07:25:55 -06:00
Port PR#6860 lexically check calling super before this
Update baselines add baselines Update baseline Port PR #6860 lexically check calling super before this Check using "super" before "this" lexically instead of using the NodeCheckFlags Remove "type-checking" way of checking if super is used before this. Instead check using whether super occurs before this syntactically Refactor the code Dive down to get super call Address PR Address PR about tests Add a flag so we don't repeatedly finding super call rename function Move tests into correct location Address PR: report error on super call instead of entire constructor node remove marge mark
This commit is contained in:
parent
20f7b18d99
commit
90c08c2201
@ -7328,6 +7328,50 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isSuperCallExpression(n: Node): boolean {
|
||||
return n.kind === SyntaxKind.CallExpression && (<CallExpression>n).expression.kind === SyntaxKind.SuperKeyword;
|
||||
}
|
||||
|
||||
function findFirstSuperCall(n: Node): Node {
|
||||
if (isSuperCallExpression(n)) {
|
||||
return n;
|
||||
}
|
||||
else if (isFunctionLike(n)) {
|
||||
return undefined;
|
||||
}
|
||||
return forEachChild(n, findFirstSuperCall);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a cached result if super-statement is already found.
|
||||
* Otherwise, find a super statement in a given constructor function and cache the result in the node-links of the constructor
|
||||
*
|
||||
* @param constructor constructor-function to look for super statement
|
||||
*/
|
||||
function getSuperCallInConstructor(constructor: ConstructorDeclaration): ExpressionStatement {
|
||||
const links = getNodeLinks(constructor);
|
||||
|
||||
// Only trying to find super-call if we haven't yet tried to find one. Once we try, we will record the result
|
||||
if (links.hasSuperCall === undefined) {
|
||||
links.superCall = <ExpressionStatement>findFirstSuperCall(constructor.body);
|
||||
links.hasSuperCall = links.superCall ? true : false;
|
||||
}
|
||||
return links.superCall;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given class-declaration extends null then return true.
|
||||
* Otherwise, return false
|
||||
* @param classDecl a class declaration to check if it extends null
|
||||
*/
|
||||
function classDeclarationExtendsNull(classDecl: ClassDeclaration): boolean {
|
||||
const classSymbol = getSymbolOfNode(classDecl);
|
||||
const classInstanceType = <InterfaceType>getDeclaredTypeOfSymbol(classSymbol);
|
||||
const baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType);
|
||||
|
||||
return baseConstructorType === nullType;
|
||||
}
|
||||
|
||||
function checkThisExpression(node: Node): Type {
|
||||
// Stop at the first arrow function so that we can
|
||||
// tell whether 'this' needs to be captured.
|
||||
@ -7335,10 +7379,25 @@ namespace ts {
|
||||
let needToCaptureLexicalThis = false;
|
||||
|
||||
if (container.kind === SyntaxKind.Constructor) {
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(<ClassLikeDeclaration>container.parent);
|
||||
if (baseTypeNode && !(getNodeCheckFlags(container) & NodeCheckFlags.HasSeenSuperCall)) {
|
||||
// In ES6, super inside constructor of class-declaration has to precede "this" accessing
|
||||
error(node, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
|
||||
const containingClassDecl = <ClassDeclaration>container.parent;
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(containingClassDecl);
|
||||
|
||||
// If a containing class does not have extends clause or the class extends null
|
||||
// skip checking whether super statement is called before "this" accessing.
|
||||
if (baseTypeNode && !classDeclarationExtendsNull(containingClassDecl)) {
|
||||
const superCall = getSuperCallInConstructor(<ConstructorDeclaration>container);
|
||||
|
||||
// We should give an error in the following cases:
|
||||
// - No super-call
|
||||
// - "this" is accessing before super-call.
|
||||
// i.e super(this)
|
||||
// this.x; super();
|
||||
// We want to make sure that super-call is done before accessing "this" so that
|
||||
// "this" is not accessed as a parameter of the super-call.
|
||||
if (!superCall || superCall.end > node.pos) {
|
||||
// In ES6, super inside constructor of class-declaration has to precede "this" accessing
|
||||
error(node, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10287,14 +10346,11 @@ namespace ts {
|
||||
checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node, node.arguments);
|
||||
|
||||
const signature = getResolvedSignature(node);
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const containingFunction = getContainingFunction(node.expression);
|
||||
|
||||
if (containingFunction && containingFunction.kind === SyntaxKind.Constructor) {
|
||||
getNodeLinks(containingFunction).flags |= NodeCheckFlags.HasSeenSuperCall;
|
||||
}
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return voidType;
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.NewExpression) {
|
||||
const declaration = signature.declaration;
|
||||
|
||||
@ -11875,17 +11931,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
// TS 1.0 spec (April 2014): 8.3.2
|
||||
// Constructors of classes with no extends clause may not contain super calls, whereas
|
||||
// constructors of derived classes must contain at least one super call somewhere in their function body.
|
||||
// Constructors of classes with no extends clause and constructors of classes that extends null may not contain super calls,
|
||||
// whereas constructors of derived classes must contain at least one super call somewhere in their function body.
|
||||
const containingClassDecl = <ClassDeclaration>node.parent;
|
||||
if (getClassExtendsHeritageClauseElement(containingClassDecl)) {
|
||||
const containingClassSymbol = getSymbolOfNode(containingClassDecl);
|
||||
const containingClassInstanceType = <InterfaceType>getDeclaredTypeOfSymbol(containingClassSymbol);
|
||||
const baseConstructorType = getBaseConstructorTypeOfClass(containingClassInstanceType);
|
||||
|
||||
if (containsSuperCall(node.body)) {
|
||||
if (baseConstructorType === nullType) {
|
||||
error(node, Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
|
||||
const classExtendsNull = classDeclarationExtendsNull(containingClassDecl);
|
||||
const superCall = getSuperCallInConstructor(node);
|
||||
if (superCall) {
|
||||
if (classExtendsNull) {
|
||||
error(superCall, Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
|
||||
}
|
||||
|
||||
// The first statement in the body of a constructor (excluding prologue directives) must be a super call
|
||||
@ -11902,6 +11956,7 @@ namespace ts {
|
||||
if (superCallShouldBeFirst) {
|
||||
const statements = (<Block>node.body).statements;
|
||||
let superCallStatement: ExpressionStatement;
|
||||
|
||||
for (const statement of statements) {
|
||||
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((<ExpressionStatement>statement).expression)) {
|
||||
superCallStatement = <ExpressionStatement>statement;
|
||||
@ -11916,7 +11971,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (baseConstructorType !== nullType) {
|
||||
else if (!classExtendsNull) {
|
||||
error(node, Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call);
|
||||
}
|
||||
}
|
||||
|
||||
@ -430,7 +430,6 @@ namespace ts {
|
||||
IntrinsicElement = IntrinsicNamedElement | IntrinsicIndexedElement,
|
||||
}
|
||||
|
||||
|
||||
/* @internal */
|
||||
export const enum RelationComparisonResult {
|
||||
Succeeded = 1, // Should be truthy
|
||||
@ -2041,10 +2040,9 @@ namespace ts {
|
||||
LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure
|
||||
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
|
||||
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
|
||||
HasSeenSuperCall = 0x00080000, // Set during the binding when encounter 'super'
|
||||
ClassWithBodyScopedClassBinding = 0x00100000, // Decorated class that contains a binding to itself inside of the class body.
|
||||
BodyScopedClassBinding = 0x00200000, // Binding to a decorated class inside of the class's body.
|
||||
NeedsLoopOutParameter = 0x00400000, // Block scoped binding whose value should be explicitly copied outside of the converted loop
|
||||
ClassWithBodyScopedClassBinding = 0x00080000, // Decorated class that contains a binding to itself inside of the class body.
|
||||
BodyScopedClassBinding = 0x00100000, // Binding to a decorated class inside of the class's body.
|
||||
NeedsLoopOutParameter = 0x00200000, // Block scoped binding whose value should be explicitly copied outside of the converted loop
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@ -2064,6 +2062,8 @@ namespace ts {
|
||||
importOnRightSide?: Symbol; // for import declarations - import that appear on the right side
|
||||
jsxFlags?: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with
|
||||
resolvedJsxType?: Type; // resolved element attributes type of a JSX openinglike element
|
||||
hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt.
|
||||
superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing
|
||||
}
|
||||
|
||||
export const enum TypeFlags {
|
||||
|
||||
@ -1,17 +1,14 @@
|
||||
tests/cases/compiler/classExtendsNull.ts(2,5): error TS17005: A constructor cannot contain a 'super' call when its class extends 'null'
|
||||
tests/cases/compiler/classExtendsNull.ts(3,9): error TS17005: A constructor cannot contain a 'super' call when its class extends 'null'
|
||||
|
||||
|
||||
==== tests/cases/compiler/classExtendsNull.ts (1 errors) ====
|
||||
class C extends null {
|
||||
constructor() {
|
||||
~~~~~~~~~~~~~~~
|
||||
super();
|
||||
~~~~~~~~~~~~~~~~
|
||||
return Object.create(null);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
~~~~~~~
|
||||
!!! error TS17005: A constructor cannot contain a 'super' call when its class extends 'null'
|
||||
return Object.create(null);
|
||||
}
|
||||
}
|
||||
|
||||
class D extends null {
|
||||
|
||||
40
tests/baselines/reference/superCallBeforeThisAccessing1.js
Normal file
40
tests/baselines/reference/superCallBeforeThisAccessing1.js
Normal file
@ -0,0 +1,40 @@
|
||||
//// [superCallBeforeThisAccessing1.ts]
|
||||
declare var Factory: any
|
||||
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
super(i);
|
||||
var s = {
|
||||
t: this._t
|
||||
}
|
||||
var i = Factory.create(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [superCallBeforeThisAccessing1.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var Base = (function () {
|
||||
function Base(c) {
|
||||
}
|
||||
return Base;
|
||||
}());
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
_super.call(this, i);
|
||||
var s = {
|
||||
t: this._t
|
||||
};
|
||||
var i = Factory.create(s);
|
||||
}
|
||||
return D;
|
||||
}(Base));
|
||||
@ -0,0 +1,38 @@
|
||||
=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing1.ts ===
|
||||
declare var Factory: any
|
||||
>Factory : Symbol(Factory, Decl(superCallBeforeThisAccessing1.ts, 0, 11))
|
||||
|
||||
class Base {
|
||||
>Base : Symbol(Base, Decl(superCallBeforeThisAccessing1.ts, 0, 24))
|
||||
|
||||
constructor(c) { }
|
||||
>c : Symbol(c, Decl(superCallBeforeThisAccessing1.ts, 3, 16))
|
||||
}
|
||||
class D extends Base {
|
||||
>D : Symbol(D, Decl(superCallBeforeThisAccessing1.ts, 4, 1))
|
||||
>Base : Symbol(Base, Decl(superCallBeforeThisAccessing1.ts, 0, 24))
|
||||
|
||||
private _t;
|
||||
>_t : Symbol(_t, Decl(superCallBeforeThisAccessing1.ts, 5, 22))
|
||||
|
||||
constructor() {
|
||||
super(i);
|
||||
>super : Symbol(Base, Decl(superCallBeforeThisAccessing1.ts, 0, 24))
|
||||
>i : Symbol(i, Decl(superCallBeforeThisAccessing1.ts, 12, 11))
|
||||
|
||||
var s = {
|
||||
>s : Symbol(s, Decl(superCallBeforeThisAccessing1.ts, 9, 11))
|
||||
|
||||
t: this._t
|
||||
>t : Symbol(t, Decl(superCallBeforeThisAccessing1.ts, 9, 17))
|
||||
>this._t : Symbol(_t, Decl(superCallBeforeThisAccessing1.ts, 5, 22))
|
||||
>this : Symbol(D, Decl(superCallBeforeThisAccessing1.ts, 4, 1))
|
||||
>_t : Symbol(_t, Decl(superCallBeforeThisAccessing1.ts, 5, 22))
|
||||
}
|
||||
var i = Factory.create(s);
|
||||
>i : Symbol(i, Decl(superCallBeforeThisAccessing1.ts, 12, 11))
|
||||
>Factory : Symbol(Factory, Decl(superCallBeforeThisAccessing1.ts, 0, 11))
|
||||
>s : Symbol(s, Decl(superCallBeforeThisAccessing1.ts, 9, 11))
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing1.ts ===
|
||||
declare var Factory: any
|
||||
>Factory : any
|
||||
|
||||
class Base {
|
||||
>Base : Base
|
||||
|
||||
constructor(c) { }
|
||||
>c : any
|
||||
}
|
||||
class D extends Base {
|
||||
>D : D
|
||||
>Base : Base
|
||||
|
||||
private _t;
|
||||
>_t : any
|
||||
|
||||
constructor() {
|
||||
super(i);
|
||||
>super(i) : void
|
||||
>super : typeof Base
|
||||
>i : any
|
||||
|
||||
var s = {
|
||||
>s : { t: any; }
|
||||
>{ t: this._t } : { t: any; }
|
||||
|
||||
t: this._t
|
||||
>t : any
|
||||
>this._t : any
|
||||
>this : this
|
||||
>_t : any
|
||||
}
|
||||
var i = Factory.create(s);
|
||||
>i : any
|
||||
>Factory.create(s) : any
|
||||
>Factory.create : any
|
||||
>Factory : any
|
||||
>create : any
|
||||
>s : { t: any; }
|
||||
}
|
||||
}
|
||||
|
||||
31
tests/baselines/reference/superCallBeforeThisAccessing2.js
Normal file
31
tests/baselines/reference/superCallBeforeThisAccessing2.js
Normal file
@ -0,0 +1,31 @@
|
||||
//// [superCallBeforeThisAccessing2.ts]
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
super(() => { this._t }); // no error. only check when this is directly accessing in constructor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [superCallBeforeThisAccessing2.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var Base = (function () {
|
||||
function Base(c) {
|
||||
}
|
||||
return Base;
|
||||
}());
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
var _this = this;
|
||||
_super.call(this, function () { _this._t; }); // no error. only check when this is directly accessing in constructor
|
||||
}
|
||||
return D;
|
||||
}(Base));
|
||||
@ -0,0 +1,23 @@
|
||||
=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing2.ts ===
|
||||
class Base {
|
||||
>Base : Symbol(Base, Decl(superCallBeforeThisAccessing2.ts, 0, 0))
|
||||
|
||||
constructor(c) { }
|
||||
>c : Symbol(c, Decl(superCallBeforeThisAccessing2.ts, 1, 16))
|
||||
}
|
||||
class D extends Base {
|
||||
>D : Symbol(D, Decl(superCallBeforeThisAccessing2.ts, 2, 1))
|
||||
>Base : Symbol(Base, Decl(superCallBeforeThisAccessing2.ts, 0, 0))
|
||||
|
||||
private _t;
|
||||
>_t : Symbol(_t, Decl(superCallBeforeThisAccessing2.ts, 3, 22))
|
||||
|
||||
constructor() {
|
||||
super(() => { this._t }); // no error. only check when this is directly accessing in constructor
|
||||
>super : Symbol(Base, Decl(superCallBeforeThisAccessing2.ts, 0, 0))
|
||||
>this._t : Symbol(_t, Decl(superCallBeforeThisAccessing2.ts, 3, 22))
|
||||
>this : Symbol(D, Decl(superCallBeforeThisAccessing2.ts, 2, 1))
|
||||
>_t : Symbol(_t, Decl(superCallBeforeThisAccessing2.ts, 3, 22))
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing2.ts ===
|
||||
class Base {
|
||||
>Base : Base
|
||||
|
||||
constructor(c) { }
|
||||
>c : any
|
||||
}
|
||||
class D extends Base {
|
||||
>D : D
|
||||
>Base : Base
|
||||
|
||||
private _t;
|
||||
>_t : any
|
||||
|
||||
constructor() {
|
||||
super(() => { this._t }); // no error. only check when this is directly accessing in constructor
|
||||
>super(() => { this._t }) : void
|
||||
>super : typeof Base
|
||||
>() => { this._t } : () => void
|
||||
>this._t : any
|
||||
>this : this
|
||||
>_t : any
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing3.ts(9,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing3.ts (1 errors) ====
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
let x = () => { this._t };
|
||||
x(); // no error; we only check super is called before this when the container is a constructor
|
||||
this._t; // error
|
||||
~~~~
|
||||
!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
|
||||
super(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
37
tests/baselines/reference/superCallBeforeThisAccessing3.js
Normal file
37
tests/baselines/reference/superCallBeforeThisAccessing3.js
Normal file
@ -0,0 +1,37 @@
|
||||
//// [superCallBeforeThisAccessing3.ts]
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
let x = () => { this._t };
|
||||
x(); // no error; we only check super is called before this when the container is a constructor
|
||||
this._t; // error
|
||||
super(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [superCallBeforeThisAccessing3.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var Base = (function () {
|
||||
function Base(c) {
|
||||
}
|
||||
return Base;
|
||||
}());
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
var _this = this;
|
||||
var x = function () { _this._t; };
|
||||
x(); // no error; we only check super is called before this when the container is a constructor
|
||||
this._t; // error
|
||||
_super.call(this, undefined);
|
||||
}
|
||||
return D;
|
||||
}(Base));
|
||||
@ -0,0 +1,24 @@
|
||||
tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing4.ts(5,9): error TS17005: A constructor cannot contain a 'super' call when its class extends 'null'
|
||||
tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing4.ts(12,9): error TS17005: A constructor cannot contain a 'super' call when its class extends 'null'
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing4.ts (2 errors) ====
|
||||
class D extends null {
|
||||
private _t;
|
||||
constructor() {
|
||||
this._t;
|
||||
super();
|
||||
~~~~~~~
|
||||
!!! error TS17005: A constructor cannot contain a 'super' call when its class extends 'null'
|
||||
}
|
||||
}
|
||||
|
||||
class E extends null {
|
||||
private _t;
|
||||
constructor() {
|
||||
super();
|
||||
~~~~~~~
|
||||
!!! error TS17005: A constructor cannot contain a 'super' call when its class extends 'null'
|
||||
this._t;
|
||||
}
|
||||
}
|
||||
39
tests/baselines/reference/superCallBeforeThisAccessing4.js
Normal file
39
tests/baselines/reference/superCallBeforeThisAccessing4.js
Normal file
@ -0,0 +1,39 @@
|
||||
//// [superCallBeforeThisAccessing4.ts]
|
||||
class D extends null {
|
||||
private _t;
|
||||
constructor() {
|
||||
this._t;
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
class E extends null {
|
||||
private _t;
|
||||
constructor() {
|
||||
super();
|
||||
this._t;
|
||||
}
|
||||
}
|
||||
|
||||
//// [superCallBeforeThisAccessing4.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
this._t;
|
||||
_super.call(this);
|
||||
}
|
||||
return D;
|
||||
}(null));
|
||||
var E = (function (_super) {
|
||||
__extends(E, _super);
|
||||
function E() {
|
||||
_super.call(this);
|
||||
this._t;
|
||||
}
|
||||
return E;
|
||||
}(null));
|
||||
22
tests/baselines/reference/superCallBeforeThisAccessing5.js
Normal file
22
tests/baselines/reference/superCallBeforeThisAccessing5.js
Normal file
@ -0,0 +1,22 @@
|
||||
//// [superCallBeforeThisAccessing5.ts]
|
||||
class D extends null {
|
||||
private _t;
|
||||
constructor() {
|
||||
this._t; // No error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [superCallBeforeThisAccessing5.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
this._t; // No error
|
||||
}
|
||||
return D;
|
||||
}(null));
|
||||
@ -0,0 +1,15 @@
|
||||
=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing5.ts ===
|
||||
class D extends null {
|
||||
>D : Symbol(D, Decl(superCallBeforeThisAccessing5.ts, 0, 0))
|
||||
|
||||
private _t;
|
||||
>_t : Symbol(_t, Decl(superCallBeforeThisAccessing5.ts, 0, 22))
|
||||
|
||||
constructor() {
|
||||
this._t; // No error
|
||||
>this._t : Symbol(_t, Decl(superCallBeforeThisAccessing5.ts, 0, 22))
|
||||
>this : Symbol(D, Decl(superCallBeforeThisAccessing5.ts, 0, 0))
|
||||
>_t : Symbol(_t, Decl(superCallBeforeThisAccessing5.ts, 0, 22))
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing5.ts ===
|
||||
class D extends null {
|
||||
>D : D
|
||||
>null : null
|
||||
|
||||
private _t;
|
||||
>_t : any
|
||||
|
||||
constructor() {
|
||||
this._t; // No error
|
||||
>this._t : any
|
||||
>this : this
|
||||
>_t : any
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing6.ts(7,15): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing6.ts (1 errors) ====
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
super(this);
|
||||
~~~~
|
||||
!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
|
||||
}
|
||||
}
|
||||
|
||||
30
tests/baselines/reference/superCallBeforeThisAccessing6.js
Normal file
30
tests/baselines/reference/superCallBeforeThisAccessing6.js
Normal file
@ -0,0 +1,30 @@
|
||||
//// [superCallBeforeThisAccessing6.ts]
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
super(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [superCallBeforeThisAccessing6.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var Base = (function () {
|
||||
function Base(c) {
|
||||
}
|
||||
return Base;
|
||||
}());
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
_super.call(this, this);
|
||||
}
|
||||
return D;
|
||||
}(Base));
|
||||
@ -0,0 +1,19 @@
|
||||
tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing7.ts(8,16): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing7.ts (1 errors) ====
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
let x = {
|
||||
j: this._t,
|
||||
~~~~
|
||||
!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
|
||||
}
|
||||
super(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
36
tests/baselines/reference/superCallBeforeThisAccessing7.js
Normal file
36
tests/baselines/reference/superCallBeforeThisAccessing7.js
Normal file
@ -0,0 +1,36 @@
|
||||
//// [superCallBeforeThisAccessing7.ts]
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
let x = {
|
||||
j: this._t,
|
||||
}
|
||||
super(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [superCallBeforeThisAccessing7.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var Base = (function () {
|
||||
function Base(c) {
|
||||
}
|
||||
return Base;
|
||||
}());
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
var x = {
|
||||
j: this._t
|
||||
};
|
||||
_super.call(this, undefined);
|
||||
}
|
||||
return D;
|
||||
}(Base));
|
||||
36
tests/baselines/reference/superCallBeforeThisAccessing8.js
Normal file
36
tests/baselines/reference/superCallBeforeThisAccessing8.js
Normal file
@ -0,0 +1,36 @@
|
||||
//// [superCallBeforeThisAccessing8.ts]
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
let x = {
|
||||
k: super(undefined),
|
||||
j: this._t, // no error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [superCallBeforeThisAccessing8.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var Base = (function () {
|
||||
function Base(c) {
|
||||
}
|
||||
return Base;
|
||||
}());
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
var x = {
|
||||
k: _super.call(this, undefined),
|
||||
j: this._t
|
||||
};
|
||||
}
|
||||
return D;
|
||||
}(Base));
|
||||
@ -0,0 +1,32 @@
|
||||
=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing8.ts ===
|
||||
class Base {
|
||||
>Base : Symbol(Base, Decl(superCallBeforeThisAccessing8.ts, 0, 0))
|
||||
|
||||
constructor(c) { }
|
||||
>c : Symbol(c, Decl(superCallBeforeThisAccessing8.ts, 1, 16))
|
||||
}
|
||||
class D extends Base {
|
||||
>D : Symbol(D, Decl(superCallBeforeThisAccessing8.ts, 2, 1))
|
||||
>Base : Symbol(Base, Decl(superCallBeforeThisAccessing8.ts, 0, 0))
|
||||
|
||||
private _t;
|
||||
>_t : Symbol(_t, Decl(superCallBeforeThisAccessing8.ts, 3, 22))
|
||||
|
||||
constructor() {
|
||||
let x = {
|
||||
>x : Symbol(x, Decl(superCallBeforeThisAccessing8.ts, 6, 11))
|
||||
|
||||
k: super(undefined),
|
||||
>k : Symbol(k, Decl(superCallBeforeThisAccessing8.ts, 6, 17))
|
||||
>super : Symbol(Base, Decl(superCallBeforeThisAccessing8.ts, 0, 0))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
j: this._t, // no error
|
||||
>j : Symbol(j, Decl(superCallBeforeThisAccessing8.ts, 7, 32))
|
||||
>this._t : Symbol(_t, Decl(superCallBeforeThisAccessing8.ts, 3, 22))
|
||||
>this : Symbol(D, Decl(superCallBeforeThisAccessing8.ts, 2, 1))
|
||||
>_t : Symbol(_t, Decl(superCallBeforeThisAccessing8.ts, 3, 22))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing8.ts ===
|
||||
class Base {
|
||||
>Base : Base
|
||||
|
||||
constructor(c) { }
|
||||
>c : any
|
||||
}
|
||||
class D extends Base {
|
||||
>D : D
|
||||
>Base : Base
|
||||
|
||||
private _t;
|
||||
>_t : any
|
||||
|
||||
constructor() {
|
||||
let x = {
|
||||
>x : { k: void; j: any; }
|
||||
>{ k: super(undefined), j: this._t, // no error } : { k: void; j: any; }
|
||||
|
||||
k: super(undefined),
|
||||
>k : void
|
||||
>super(undefined) : void
|
||||
>super : typeof Base
|
||||
>undefined : undefined
|
||||
|
||||
j: this._t, // no error
|
||||
>j : any
|
||||
>this._t : any
|
||||
>this : this
|
||||
>_t : any
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
declare var Factory: any
|
||||
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
super(i);
|
||||
var s = {
|
||||
t: this._t
|
||||
}
|
||||
var i = Factory.create(s);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
super(() => { this._t }); // no error. only check when this is directly accessing in constructor
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
let x = () => { this._t };
|
||||
x(); // no error; we only check super is called before this when the container is a constructor
|
||||
this._t; // error
|
||||
super(undefined);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
class D extends null {
|
||||
private _t;
|
||||
constructor() {
|
||||
this._t;
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
class E extends null {
|
||||
private _t;
|
||||
constructor() {
|
||||
super();
|
||||
this._t;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
class D extends null {
|
||||
private _t;
|
||||
constructor() {
|
||||
this._t; // No error
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
super(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
let x = {
|
||||
j: this._t,
|
||||
}
|
||||
super(undefined);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
class Base {
|
||||
constructor(c) { }
|
||||
}
|
||||
class D extends Base {
|
||||
private _t;
|
||||
constructor() {
|
||||
let x = {
|
||||
k: super(undefined),
|
||||
j: this._t, // no error
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user