Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -10405,33 +10405,37 @@ namespace ts {
return baseConstructorType === nullWideningType;
}

function checkThisBeforeSuper(node: Node, container: Node, diagnosticMessage: DiagnosticMessage) {
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, diagnosticMessage);
}
}
}

function checkThisExpression(node: Node): Type {
// Stop at the first arrow function so that we can
// tell whether 'this' needs to be captured.
let container = getThisContainer(node, /* includeArrowFunctions */ true);
let needToCaptureLexicalThis = false;

if (container.kind === SyntaxKind.Constructor) {
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);
}
}
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
}

// Now skip arrow functions to get the "real" owner of 'this'.
Expand DownExpand Up@@ -10579,6 +10583,10 @@ namespace ts {
return unknownType;
}

if (!isCallExpression && container.kind === SyntaxKind.Constructor) {
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
}

if ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) {
nodeCheckFlag = NodeCheckFlags.SuperStatic;
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -3165,6 +3165,10 @@
"category": "Error",
"code": 17010
},
"'super' must be called before accessing a property of 'super' in the constructor of a derived class.": {
"category": "Error",
"code": 17011
},

"Circularity detected while resolving configuration: {0}": {
"category": "Error",
Expand Down
1 change: 0 additions & 1 deletion src/compiler/transformers/es2015.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2837,7 +2837,6 @@ namespace ts {
// _super.call(this, a)
// _super.m.call(this, a)
// _super.prototype.m.call(this, a)

resultingCall = createFunctionCall(
visitNode(target, visitor, isExpression),
visitNode(thisArg, visitor, isExpression),
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/errorSuperCalls.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,14 +7,15 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error T
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(58,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(62,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(67,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.


==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (14 errors) ====
==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (15 errors) ====
//super call in class constructor with no base type
class NoBase {
constructor() {
Expand DownExpand Up@@ -79,6 +80,8 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error T
//super call with type arguments
constructor() {
super<string>();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
11 changes: 10 additions & 1 deletion tests/baselines/reference/superAccess2.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,18 +2,21 @@ tests/cases/compiler/superAccess2.ts(7,15): error TS1034: 'super' must be follow
tests/cases/compiler/superAccess2.ts(8,17): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.
tests/cases/compiler/superAccess2.ts(8,22): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,28): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,28): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,33): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,40): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,40): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,45): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,59): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,59): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,64): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(15,19): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(17,15): error TS2339: Property 'y' does not exist on type 'P'.
tests/cases/compiler/superAccess2.ts(20,26): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not exist on type 'typeof P'.


==== tests/cases/compiler/superAccess2.ts (13 errors) ====
==== tests/cases/compiler/superAccess2.ts (16 errors) ====
class P {
x() { }
static y() { }
Expand All@@ -33,14 +36,20 @@ tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not
constructor(public z = super, zz = super, zzz = () => super) {
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superInConstructorParam1.ts(8,3): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superInConstructorParam1.ts (2 errors) ====
==== tests/cases/compiler/superInConstructorParam1.ts (3 errors) ====
class B {
public foo(): number {
return 0;
Expand All@@ -14,6 +15,8 @@ tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' ca
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/superNewCall1.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superNewCall1.ts(9,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/superNewCall1.ts(10,13): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superNewCall1.ts (2 errors) ====
==== tests/cases/compiler/superNewCall1.ts (3 errors) ====

class A<T1, T2> {
constructor(private map: (value: T1) => T2) {
Expand All@@ -17,6 +18,8 @@ tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(13,15): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts (2 errors) ====
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
//// [superPropertyInConstructorBeforeSuperCall.ts]
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}

//// [superPropertyInConstructorBeforeSuperCall.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 B = (function () {
function B(x) {
}
B.prototype.x = function () { return ""; };
return B;
}());
var C1 = (function (_super) {
__extends(C1, _super);
function C1() {
var _this;
_super.prototype.x.call(_this);
_this = _super.call(this) || this;
return _this;
}
return C1;
}(B));
var C2 = (function (_super) {
__extends(C2, _super);
function C2() {
return _super.call(this, _super.x.call(_this)) || this;
}
return C2;
}(B));
5 changes: 4 additions & 1 deletion tests/baselines/reference/superWithTypeArgument.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument.ts (3 errors) ====
class C {

}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument2.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument2.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument2.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument2.ts (3 errors) ====
class C<T> {
foo: T;
}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~~
super<T>(x);
~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument3.ts(7,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument3.ts(8,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument3.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument3.ts (3 errors) ====
class C<T> {
foo: T;
bar<U>(x: U) { }
Expand All@@ -13,6 +14,8 @@ tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -10405,33 +10405,37 @@ namespace ts {
return baseConstructorType === nullWideningType;
}

function checkThisBeforeSuper(node: Node, container: Node, diagnosticMessage: DiagnosticMessage) {
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, diagnosticMessage);
}
}
}

function checkThisExpression(node: Node): Type {
// Stop at the first arrow function so that we can
// tell whether 'this' needs to be captured.
let container = getThisContainer(node, /* includeArrowFunctions */ true);
let needToCaptureLexicalThis = false;

if (container.kind === SyntaxKind.Constructor) {
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);
}
}
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
}

// Now skip arrow functions to get the "real" owner of 'this'.
Expand DownExpand Up@@ -10579,6 +10583,10 @@ namespace ts {
return unknownType;
}

if (!isCallExpression && container.kind === SyntaxKind.Constructor) {
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
}

if ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) {
nodeCheckFlag = NodeCheckFlags.SuperStatic;
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -3165,6 +3165,10 @@
"category": "Error",
"code": 17010
},
"'super' must be called before accessing a property of 'super' in the constructor of a derived class.": {
"category": "Error",
"code": 17011
},

"Circularity detected while resolving configuration: {0}": {
"category": "Error",
Expand Down
1 change: 0 additions & 1 deletion src/compiler/transformers/es2015.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2837,7 +2837,6 @@ namespace ts {
// _super.call(this, a)
// _super.m.call(this, a)
// _super.prototype.m.call(this, a)

resultingCall = createFunctionCall(
visitNode(target, visitor, isExpression),
visitNode(thisArg, visitor, isExpression),
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/errorSuperCalls.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,14 +7,15 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error T
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(58,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(62,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(67,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.


==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (14 errors) ====
==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (15 errors) ====
//super call in class constructor with no base type
class NoBase {
constructor() {
Expand DownExpand Up@@ -79,6 +80,8 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error T
//super call with type arguments
constructor() {
super<string>();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
11 changes: 10 additions & 1 deletion tests/baselines/reference/superAccess2.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,18 +2,21 @@ tests/cases/compiler/superAccess2.ts(7,15): error TS1034: 'super' must be follow
tests/cases/compiler/superAccess2.ts(8,17): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.
tests/cases/compiler/superAccess2.ts(8,22): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,28): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,28): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,33): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,40): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,40): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,45): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,59): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,59): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,64): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(15,19): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(17,15): error TS2339: Property 'y' does not exist on type 'P'.
tests/cases/compiler/superAccess2.ts(20,26): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not exist on type 'typeof P'.


==== tests/cases/compiler/superAccess2.ts (13 errors) ====
==== tests/cases/compiler/superAccess2.ts (16 errors) ====
class P {
x() { }
static y() { }
Expand All@@ -33,14 +36,20 @@ tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not
constructor(public z = super, zz = super, zzz = () => super) {
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superInConstructorParam1.ts(8,3): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superInConstructorParam1.ts (2 errors) ====
==== tests/cases/compiler/superInConstructorParam1.ts (3 errors) ====
class B {
public foo(): number {
return 0;
Expand All@@ -14,6 +15,8 @@ tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' ca
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/superNewCall1.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superNewCall1.ts(9,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/superNewCall1.ts(10,13): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superNewCall1.ts (2 errors) ====
==== tests/cases/compiler/superNewCall1.ts (3 errors) ====

class A<T1, T2> {
constructor(private map: (value: T1) => T2) {
Expand All@@ -17,6 +18,8 @@ tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(13,15): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts (2 errors) ====
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
//// [superPropertyInConstructorBeforeSuperCall.ts]
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}

//// [superPropertyInConstructorBeforeSuperCall.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 B = (function () {
function B(x) {
}
B.prototype.x = function () { return ""; };
return B;
}());
var C1 = (function (_super) {
__extends(C1, _super);
function C1() {
var _this;
_super.prototype.x.call(_this);
_this = _super.call(this) || this;
return _this;
}
return C1;
}(B));
var C2 = (function (_super) {
__extends(C2, _super);
function C2() {
return _super.call(this, _super.x.call(_this)) || this;
}
return C2;
}(B));
5 changes: 4 additions & 1 deletion tests/baselines/reference/superWithTypeArgument.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument.ts (3 errors) ====
class C {

}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument2.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument2.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument2.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument2.ts (3 errors) ====
class C<T> {
foo: T;
}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~~
super<T>(x);
~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument3.ts(7,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument3.ts(8,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument3.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument3.ts (3 errors) ====
class C<T> {
foo: T;
bar<U>(x: U) { }
Expand All@@ -13,6 +14,8 @@ tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -10405,33 +10405,37 @@ namespace ts {
return baseConstructorType === nullWideningType;
}

function checkThisBeforeSuper(node: Node, container: Node, diagnosticMessage: DiagnosticMessage) {
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, diagnosticMessage);
}
}
}

function checkThisExpression(node: Node): Type {
// Stop at the first arrow function so that we can
// tell whether 'this' needs to be captured.
let container = getThisContainer(node, /* includeArrowFunctions */ true);
let needToCaptureLexicalThis = false;

if (container.kind === SyntaxKind.Constructor) {
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);
}
}
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
}

// Now skip arrow functions to get the "real" owner of 'this'.
Expand DownExpand Up@@ -10579,6 +10583,10 @@ namespace ts {
return unknownType;
}

if (!isCallExpression && container.kind === SyntaxKind.Constructor) {
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
}

if ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) {
nodeCheckFlag = NodeCheckFlags.SuperStatic;
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -3165,6 +3165,10 @@
"category": "Error",
"code": 17010
},
"'super' must be called before accessing a property of 'super' in the constructor of a derived class.": {
"category": "Error",
"code": 17011
},

"Circularity detected while resolving configuration: {0}": {
"category": "Error",
Expand Down
1 change: 0 additions & 1 deletion src/compiler/transformers/es2015.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2837,7 +2837,6 @@ namespace ts {
// _super.call(this, a)
// _super.m.call(this, a)
// _super.prototype.m.call(this, a)

resultingCall = createFunctionCall(
visitNode(target, visitor, isExpression),
visitNode(thisArg, visitor, isExpression),
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/errorSuperCalls.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,14 +7,15 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error T
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(58,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(62,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(67,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.


==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (14 errors) ====
==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (15 errors) ====
//super call in class constructor with no base type
class NoBase {
constructor() {
Expand DownExpand Up@@ -79,6 +80,8 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error T
//super call with type arguments
constructor() {
super<string>();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
11 changes: 10 additions & 1 deletion tests/baselines/reference/superAccess2.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,18 +2,21 @@ tests/cases/compiler/superAccess2.ts(7,15): error TS1034: 'super' must be follow
tests/cases/compiler/superAccess2.ts(8,17): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.
tests/cases/compiler/superAccess2.ts(8,22): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,28): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,28): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,33): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,40): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,40): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,45): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,59): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,59): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,64): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(15,19): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(17,15): error TS2339: Property 'y' does not exist on type 'P'.
tests/cases/compiler/superAccess2.ts(20,26): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not exist on type 'typeof P'.


==== tests/cases/compiler/superAccess2.ts (13 errors) ====
==== tests/cases/compiler/superAccess2.ts (16 errors) ====
class P {
x() { }
static y() { }
Expand All@@ -33,14 +36,20 @@ tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not
constructor(public z = super, zz = super, zzz = () => super) {
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superInConstructorParam1.ts(8,3): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superInConstructorParam1.ts (2 errors) ====
==== tests/cases/compiler/superInConstructorParam1.ts (3 errors) ====
class B {
public foo(): number {
return 0;
Expand All@@ -14,6 +15,8 @@ tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' ca
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/superNewCall1.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superNewCall1.ts(9,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/superNewCall1.ts(10,13): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superNewCall1.ts (2 errors) ====
==== tests/cases/compiler/superNewCall1.ts (3 errors) ====

class A<T1, T2> {
constructor(private map: (value: T1) => T2) {
Expand All@@ -17,6 +18,8 @@ tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(13,15): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts (2 errors) ====
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
//// [superPropertyInConstructorBeforeSuperCall.ts]
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}

//// [superPropertyInConstructorBeforeSuperCall.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 B = (function () {
function B(x) {
}
B.prototype.x = function () { return ""; };
return B;
}());
var C1 = (function (_super) {
__extends(C1, _super);
function C1() {
var _this;
_super.prototype.x.call(_this);
_this = _super.call(this) || this;
return _this;
}
return C1;
}(B));
var C2 = (function (_super) {
__extends(C2, _super);
function C2() {
return _super.call(this, _super.x.call(_this)) || this;
}
return C2;
}(B));
5 changes: 4 additions & 1 deletion tests/baselines/reference/superWithTypeArgument.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument.ts (3 errors) ====
class C {

}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument2.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument2.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument2.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument2.ts (3 errors) ====
class C<T> {
foo: T;
}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~~
super<T>(x);
~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument3.ts(7,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument3.ts(8,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument3.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument3.ts (3 errors) ====
class C<T> {
foo: T;
bar<U>(x: U) { }
Expand All@@ -13,6 +14,8 @@ tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -10405,33 +10405,37 @@ namespace ts {
return baseConstructorType === nullWideningType;
}

function checkThisBeforeSuper(node: Node, container: Node, diagnosticMessage: DiagnosticMessage) {
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, diagnosticMessage);
}
}
}

function checkThisExpression(node: Node): Type {
// Stop at the first arrow function so that we can
// tell whether 'this' needs to be captured.
let container = getThisContainer(node, /* includeArrowFunctions */ true);
let needToCaptureLexicalThis = false;

if (container.kind === SyntaxKind.Constructor) {
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);
}
}
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
}

// Now skip arrow functions to get the "real" owner of 'this'.
Expand DownExpand Up@@ -10579,6 +10583,10 @@ namespace ts {
return unknownType;
}

if (!isCallExpression && container.kind === SyntaxKind.Constructor) {
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
}

if ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) {
nodeCheckFlag = NodeCheckFlags.SuperStatic;
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -3165,6 +3165,10 @@
"category": "Error",
"code": 17010
},
"'super' must be called before accessing a property of 'super' in the constructor of a derived class.": {
"category": "Error",
"code": 17011
},

"Circularity detected while resolving configuration: {0}": {
"category": "Error",
Expand Down
1 change: 0 additions & 1 deletion src/compiler/transformers/es2015.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2837,7 +2837,6 @@ namespace ts {
// _super.call(this, a)
// _super.m.call(this, a)
// _super.prototype.m.call(this, a)

resultingCall = createFunctionCall(
visitNode(target, visitor, isExpression),
visitNode(thisArg, visitor, isExpression),
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/errorSuperCalls.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,14 +7,15 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error T
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(58,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(62,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(67,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.


==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (14 errors) ====
==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (15 errors) ====
//super call in class constructor with no base type
class NoBase {
constructor() {
Expand DownExpand Up@@ -79,6 +80,8 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error T
//super call with type arguments
constructor() {
super<string>();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
11 changes: 10 additions & 1 deletion tests/baselines/reference/superAccess2.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,18 +2,21 @@ tests/cases/compiler/superAccess2.ts(7,15): error TS1034: 'super' must be follow
tests/cases/compiler/superAccess2.ts(8,17): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.
tests/cases/compiler/superAccess2.ts(8,22): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,28): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,28): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,33): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,40): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,40): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,45): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,59): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,59): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,64): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(15,19): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(17,15): error TS2339: Property 'y' does not exist on type 'P'.
tests/cases/compiler/superAccess2.ts(20,26): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not exist on type 'typeof P'.


==== tests/cases/compiler/superAccess2.ts (13 errors) ====
==== tests/cases/compiler/superAccess2.ts (16 errors) ====
class P {
x() { }
static y() { }
Expand All@@ -33,14 +36,20 @@ tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not
constructor(public z = super, zz = super, zzz = () => super) {
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superInConstructorParam1.ts(8,3): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superInConstructorParam1.ts (2 errors) ====
==== tests/cases/compiler/superInConstructorParam1.ts (3 errors) ====
class B {
public foo(): number {
return 0;
Expand All@@ -14,6 +15,8 @@ tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' ca
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/superNewCall1.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superNewCall1.ts(9,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/superNewCall1.ts(10,13): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superNewCall1.ts (2 errors) ====
==== tests/cases/compiler/superNewCall1.ts (3 errors) ====

class A<T1, T2> {
constructor(private map: (value: T1) => T2) {
Expand All@@ -17,6 +18,8 @@ tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(13,15): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts (2 errors) ====
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
//// [superPropertyInConstructorBeforeSuperCall.ts]
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}

//// [superPropertyInConstructorBeforeSuperCall.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 B = (function () {
function B(x) {
}
B.prototype.x = function () { return ""; };
return B;
}());
var C1 = (function (_super) {
__extends(C1, _super);
function C1() {
var _this;
_super.prototype.x.call(_this);
_this = _super.call(this) || this;
return _this;
}
return C1;
}(B));
var C2 = (function (_super) {
__extends(C2, _super);
function C2() {
return _super.call(this, _super.x.call(_this)) || this;
}
return C2;
}(B));
5 changes: 4 additions & 1 deletion tests/baselines/reference/superWithTypeArgument.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument.ts (3 errors) ====
class C {

}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument2.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument2.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument2.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument2.ts (3 errors) ====
class C<T> {
foo: T;
}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~~
super<T>(x);
~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument3.ts(7,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument3.ts(8,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument3.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument3.ts (3 errors) ====
class C<T> {
foo: T;
bar<U>(x: U) { }
Expand All@@ -13,6 +14,8 @@ tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -10405,33 +10405,37 @@ namespace ts {
return baseConstructorType === nullWideningType;
}

function checkThisBeforeSuper(node: Node, container: Node, diagnosticMessage: DiagnosticMessage) {
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, diagnosticMessage);
}
}
}

function checkThisExpression(node: Node): Type {
// Stop at the first arrow function so that we can
// tell whether 'this' needs to be captured.
let container = getThisContainer(node, /* includeArrowFunctions */ true);
let needToCaptureLexicalThis = false;

if (container.kind === SyntaxKind.Constructor) {
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);
}
}
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
}

// Now skip arrow functions to get the "real" owner of 'this'.
Expand DownExpand Up@@ -10579,6 +10583,10 @@ namespace ts {
return unknownType;
}

if (!isCallExpression && container.kind === SyntaxKind.Constructor) {
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
}

if ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) {
nodeCheckFlag = NodeCheckFlags.SuperStatic;
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -3165,6 +3165,10 @@
"category": "Error",
"code": 17010
},
"'super' must be called before accessing a property of 'super' in the constructor of a derived class.": {
"category": "Error",
"code": 17011
},

"Circularity detected while resolving configuration: {0}": {
"category": "Error",
Expand Down
1 change: 0 additions & 1 deletion src/compiler/transformers/es2015.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2837,7 +2837,6 @@ namespace ts {
// _super.call(this, a)
// _super.m.call(this, a)
// _super.prototype.m.call(this, a)

resultingCall = createFunctionCall(
visitNode(target, visitor, isExpression),
visitNode(thisArg, visitor, isExpression),
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/errorSuperCalls.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,14 +7,15 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error T
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(58,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(62,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(67,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.


==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (14 errors) ====
==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (15 errors) ====
//super call in class constructor with no base type
class NoBase {
constructor() {
Expand DownExpand Up@@ -79,6 +80,8 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error T
//super call with type arguments
constructor() {
super<string>();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
11 changes: 10 additions & 1 deletion tests/baselines/reference/superAccess2.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,18 +2,21 @@ tests/cases/compiler/superAccess2.ts(7,15): error TS1034: 'super' must be follow
tests/cases/compiler/superAccess2.ts(8,17): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.
tests/cases/compiler/superAccess2.ts(8,22): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,28): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,28): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,33): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,40): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,40): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,45): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,59): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,59): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,64): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(15,19): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(17,15): error TS2339: Property 'y' does not exist on type 'P'.
tests/cases/compiler/superAccess2.ts(20,26): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not exist on type 'typeof P'.


==== tests/cases/compiler/superAccess2.ts (13 errors) ====
==== tests/cases/compiler/superAccess2.ts (16 errors) ====
class P {
x() { }
static y() { }
Expand All@@ -33,14 +36,20 @@ tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not
constructor(public z = super, zz = super, zzz = () => super) {
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superInConstructorParam1.ts(8,3): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superInConstructorParam1.ts (2 errors) ====
==== tests/cases/compiler/superInConstructorParam1.ts (3 errors) ====
class B {
public foo(): number {
return 0;
Expand All@@ -14,6 +15,8 @@ tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' ca
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/superNewCall1.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superNewCall1.ts(9,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/superNewCall1.ts(10,13): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superNewCall1.ts (2 errors) ====
==== tests/cases/compiler/superNewCall1.ts (3 errors) ====

class A<T1, T2> {
constructor(private map: (value: T1) => T2) {
Expand All@@ -17,6 +18,8 @@ tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(13,15): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts (2 errors) ====
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
//// [superPropertyInConstructorBeforeSuperCall.ts]
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}

//// [superPropertyInConstructorBeforeSuperCall.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 B = (function () {
function B(x) {
}
B.prototype.x = function () { return ""; };
return B;
}());
var C1 = (function (_super) {
__extends(C1, _super);
function C1() {
var _this;
_super.prototype.x.call(_this);
_this = _super.call(this) || this;
return _this;
}
return C1;
}(B));
var C2 = (function (_super) {
__extends(C2, _super);
function C2() {
return _super.call(this, _super.x.call(_this)) || this;
}
return C2;
}(B));
5 changes: 4 additions & 1 deletion tests/baselines/reference/superWithTypeArgument.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument.ts (3 errors) ====
class C {

}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument2.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument2.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument2.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument2.ts (3 errors) ====
class C<T> {
foo: T;
}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~~
super<T>(x);
~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument3.ts(7,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument3.ts(8,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument3.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument3.ts (3 errors) ====
class C<T> {
foo: T;
bar<U>(x: U) { }
Expand All@@ -13,6 +14,8 @@ tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -10405,33 +10405,37 @@ namespace ts {
return baseConstructorType === nullWideningType;
}

function checkThisBeforeSuper(node: Node, container: Node, diagnosticMessage: DiagnosticMessage) {
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, diagnosticMessage);
}
}
}

function checkThisExpression(node: Node): Type {
// Stop at the first arrow function so that we can
// tell whether 'this' needs to be captured.
let container = getThisContainer(node, /* includeArrowFunctions */ true);
let needToCaptureLexicalThis = false;

if (container.kind === SyntaxKind.Constructor) {
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);
}
}
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
}

// Now skip arrow functions to get the "real" owner of 'this'.
Expand DownExpand Up@@ -10579,6 +10583,10 @@ namespace ts {
return unknownType;
}

if (!isCallExpression && container.kind === SyntaxKind.Constructor) {
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
}

if ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) {
nodeCheckFlag = NodeCheckFlags.SuperStatic;
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -3165,6 +3165,10 @@
"category": "Error",
"code": 17010
},
"'super' must be called before accessing a property of 'super' in the constructor of a derived class.": {
"category": "Error",
"code": 17011
},

"Circularity detected while resolving configuration: {0}": {
"category": "Error",
Expand Down
1 change: 0 additions & 1 deletion src/compiler/transformers/es2015.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2837,7 +2837,6 @@ namespace ts {
// _super.call(this, a)
// _super.m.call(this, a)
// _super.prototype.m.call(this, a)

resultingCall = createFunctionCall(
visitNode(target, visitor, isExpression),
visitNode(thisArg, visitor, isExpression),
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/errorSuperCalls.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,14 +7,15 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error T
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(58,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(62,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(67,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.


==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (14 errors) ====
==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (15 errors) ====
//super call in class constructor with no base type
class NoBase {
constructor() {
Expand DownExpand Up@@ -79,6 +80,8 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error T
//super call with type arguments
constructor() {
super<string>();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
11 changes: 10 additions & 1 deletion tests/baselines/reference/superAccess2.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,18 +2,21 @@ tests/cases/compiler/superAccess2.ts(7,15): error TS1034: 'super' must be follow
tests/cases/compiler/superAccess2.ts(8,17): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.
tests/cases/compiler/superAccess2.ts(8,22): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,28): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,28): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,33): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,40): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,40): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,45): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,59): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,59): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,64): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(15,19): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(17,15): error TS2339: Property 'y' does not exist on type 'P'.
tests/cases/compiler/superAccess2.ts(20,26): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not exist on type 'typeof P'.


==== tests/cases/compiler/superAccess2.ts (13 errors) ====
==== tests/cases/compiler/superAccess2.ts (16 errors) ====
class P {
x() { }
static y() { }
Expand All@@ -33,14 +36,20 @@ tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not
constructor(public z = super, zz = super, zzz = () => super) {
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superInConstructorParam1.ts(8,3): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superInConstructorParam1.ts (2 errors) ====
==== tests/cases/compiler/superInConstructorParam1.ts (3 errors) ====
class B {
public foo(): number {
return 0;
Expand All@@ -14,6 +15,8 @@ tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' ca
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/superNewCall1.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superNewCall1.ts(9,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/superNewCall1.ts(10,13): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superNewCall1.ts (2 errors) ====
==== tests/cases/compiler/superNewCall1.ts (3 errors) ====

class A<T1, T2> {
constructor(private map: (value: T1) => T2) {
Expand All@@ -17,6 +18,8 @@ tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(13,15): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts (2 errors) ====
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
//// [superPropertyInConstructorBeforeSuperCall.ts]
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}

//// [superPropertyInConstructorBeforeSuperCall.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 B = (function () {
function B(x) {
}
B.prototype.x = function () { return ""; };
return B;
}());
var C1 = (function (_super) {
__extends(C1, _super);
function C1() {
var _this;
_super.prototype.x.call(_this);
_this = _super.call(this) || this;
return _this;
}
return C1;
}(B));
var C2 = (function (_super) {
__extends(C2, _super);
function C2() {
return _super.call(this, _super.x.call(_this)) || this;
}
return C2;
}(B));
5 changes: 4 additions & 1 deletion tests/baselines/reference/superWithTypeArgument.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument.ts (3 errors) ====
class C {

}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument2.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument2.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument2.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument2.ts (3 errors) ====
class C<T> {
foo: T;
}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~~
super<T>(x);
~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument3.ts(7,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument3.ts(8,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument3.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument3.ts (3 errors) ====
class C<T> {
foo: T;
bar<U>(x: U) { }
Expand All@@ -13,6 +14,8 @@ tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -10405,33 +10405,37 @@ namespace ts {
return baseConstructorType === nullWideningType;
}

function checkThisBeforeSuper(node: Node, container: Node, diagnosticMessage: DiagnosticMessage) {
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, diagnosticMessage);
}
}
}

function checkThisExpression(node: Node): Type {
// Stop at the first arrow function so that we can
// tell whether 'this' needs to be captured.
let container = getThisContainer(node, /* includeArrowFunctions */ true);
let needToCaptureLexicalThis = false;

if (container.kind === SyntaxKind.Constructor) {
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);
}
}
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
}

// Now skip arrow functions to get the "real" owner of 'this'.
Expand DownExpand Up@@ -10579,6 +10583,10 @@ namespace ts {
return unknownType;
}

if (!isCallExpression && container.kind === SyntaxKind.Constructor) {
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
}

if ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) {
nodeCheckFlag = NodeCheckFlags.SuperStatic;
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -3165,6 +3165,10 @@
"category": "Error",
"code": 17010
},
"'super' must be called before accessing a property of 'super' in the constructor of a derived class.": {
"category": "Error",
"code": 17011
},

"Circularity detected while resolving configuration: {0}": {
"category": "Error",
Expand Down
1 change: 0 additions & 1 deletion src/compiler/transformers/es2015.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2837,7 +2837,6 @@ namespace ts {
// _super.call(this, a)
// _super.m.call(this, a)
// _super.prototype.m.call(this, a)

resultingCall = createFunctionCall(
visitNode(target, visitor, isExpression),
visitNode(thisArg, visitor, isExpression),
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/errorSuperCalls.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,14 +7,15 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error T
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(58,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(62,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(67,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.


==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (14 errors) ====
==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (15 errors) ====
//super call in class constructor with no base type
class NoBase {
constructor() {
Expand DownExpand Up@@ -79,6 +80,8 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error T
//super call with type arguments
constructor() {
super<string>();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
11 changes: 10 additions & 1 deletion tests/baselines/reference/superAccess2.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,18 +2,21 @@ tests/cases/compiler/superAccess2.ts(7,15): error TS1034: 'super' must be follow
tests/cases/compiler/superAccess2.ts(8,17): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.
tests/cases/compiler/superAccess2.ts(8,22): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,28): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,28): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,33): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,40): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,40): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,45): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,59): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,59): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,64): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(15,19): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(17,15): error TS2339: Property 'y' does not exist on type 'P'.
tests/cases/compiler/superAccess2.ts(20,26): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not exist on type 'typeof P'.


==== tests/cases/compiler/superAccess2.ts (13 errors) ====
==== tests/cases/compiler/superAccess2.ts (16 errors) ====
class P {
x() { }
static y() { }
Expand All@@ -33,14 +36,20 @@ tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not
constructor(public z = super, zz = super, zzz = () => super) {
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superInConstructorParam1.ts(8,3): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superInConstructorParam1.ts (2 errors) ====
==== tests/cases/compiler/superInConstructorParam1.ts (3 errors) ====
class B {
public foo(): number {
return 0;
Expand All@@ -14,6 +15,8 @@ tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' ca
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/superNewCall1.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superNewCall1.ts(9,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/superNewCall1.ts(10,13): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superNewCall1.ts (2 errors) ====
==== tests/cases/compiler/superNewCall1.ts (3 errors) ====

class A<T1, T2> {
constructor(private map: (value: T1) => T2) {
Expand All@@ -17,6 +18,8 @@ tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(13,15): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts (2 errors) ====
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
//// [superPropertyInConstructorBeforeSuperCall.ts]
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}

//// [superPropertyInConstructorBeforeSuperCall.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 B = (function () {
function B(x) {
}
B.prototype.x = function () { return ""; };
return B;
}());
var C1 = (function (_super) {
__extends(C1, _super);
function C1() {
var _this;
_super.prototype.x.call(_this);
_this = _super.call(this) || this;
return _this;
}
return C1;
}(B));
var C2 = (function (_super) {
__extends(C2, _super);
function C2() {
return _super.call(this, _super.x.call(_this)) || this;
}
return C2;
}(B));
5 changes: 4 additions & 1 deletion tests/baselines/reference/superWithTypeArgument.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument.ts (3 errors) ====
class C {

}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument2.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument2.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument2.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument2.ts (3 errors) ====
class C<T> {
foo: T;
}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~~
super<T>(x);
~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument3.ts(7,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument3.ts(8,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument3.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument3.ts (3 errors) ====
class C<T> {
foo: T;
bar<U>(x: U) { }
Expand All@@ -13,6 +14,8 @@ tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -10405,33 +10405,37 @@ namespace ts {
return baseConstructorType === nullWideningType;
}

function checkThisBeforeSuper(node: Node, container: Node, diagnosticMessage: DiagnosticMessage) {
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, diagnosticMessage);
}
}
}

function checkThisExpression(node: Node): Type {
// Stop at the first arrow function so that we can
// tell whether 'this' needs to be captured.
let container = getThisContainer(node, /* includeArrowFunctions */ true);
let needToCaptureLexicalThis = false;

if (container.kind === SyntaxKind.Constructor) {
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);
}
}
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
}

// Now skip arrow functions to get the "real" owner of 'this'.
Expand DownExpand Up@@ -10579,6 +10583,10 @@ namespace ts {
return unknownType;
}

if (!isCallExpression && container.kind === SyntaxKind.Constructor) {
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
}

if ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) {
nodeCheckFlag = NodeCheckFlags.SuperStatic;
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -3165,6 +3165,10 @@
"category": "Error",
"code": 17010
},
"'super' must be called before accessing a property of 'super' in the constructor of a derived class.": {
"category": "Error",
"code": 17011
},

"Circularity detected while resolving configuration: {0}": {
"category": "Error",
Expand Down
1 change: 0 additions & 1 deletion src/compiler/transformers/es2015.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2837,7 +2837,6 @@ namespace ts {
// _super.call(this, a)
// _super.m.call(this, a)
// _super.prototype.m.call(this, a)

resultingCall = createFunctionCall(
visitNode(target, visitor, isExpression),
visitNode(thisArg, visitor, isExpression),
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/errorSuperCalls.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,14 +7,15 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error T
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(58,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(62,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(67,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.


==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (14 errors) ====
==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (15 errors) ====
//super call in class constructor with no base type
class NoBase {
constructor() {
Expand DownExpand Up@@ -79,6 +80,8 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error T
//super call with type arguments
constructor() {
super<string>();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
11 changes: 10 additions & 1 deletion tests/baselines/reference/superAccess2.errors.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,18 +2,21 @@ tests/cases/compiler/superAccess2.ts(7,15): error TS1034: 'super' must be follow
tests/cases/compiler/superAccess2.ts(8,17): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.
tests/cases/compiler/superAccess2.ts(8,22): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,28): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,28): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,33): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,40): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,40): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,45): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(11,59): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superAccess2.ts(11,59): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superAccess2.ts(11,64): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(15,19): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(17,15): error TS2339: Property 'y' does not exist on type 'P'.
tests/cases/compiler/superAccess2.ts(20,26): error TS1034: 'super' must be followed by an argument list or member access.
tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not exist on type 'typeof P'.


==== tests/cases/compiler/superAccess2.ts (13 errors) ====
==== tests/cases/compiler/superAccess2.ts (16 errors) ====
class P {
x() { }
static y() { }
Expand All@@ -33,14 +36,20 @@ tests/cases/compiler/superAccess2.ts(21,15): error TS2339: Property 'x' does not
constructor(public z = super, zz = super, zzz = () => super) {
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
super();
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superInConstructorParam1.ts(8,3): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' cannot be referenced in constructor arguments.
tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superInConstructorParam1.ts (2 errors) ====
==== tests/cases/compiler/superInConstructorParam1.ts (3 errors) ====
class B {
public foo(): number {
return 0;
Expand All@@ -14,6 +15,8 @@ tests/cases/compiler/superInConstructorParam1.ts(8,19): error TS2336: 'super' ca
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS2336: 'super' cannot be referenced in constructor arguments.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/superNewCall1.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superNewCall1.ts(9,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
tests/cases/compiler/superNewCall1.ts(10,13): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/compiler/superNewCall1.ts (2 errors) ====
==== tests/cases/compiler/superNewCall1.ts (3 errors) ====

class A<T1, T2> {
constructor(private map: (value: T1) => T2) {
Expand All@@ -17,6 +18,8 @@ tests/cases/compiler/superNewCall1.ts(10,9): error TS2351: Cannot use 'new' with
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
~~~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts(13,15): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.


==== tests/cases/conformance/classes/constructorDeclarations/superCalls/superPropertyInConstructorBeforeSuperCall.ts (2 errors) ====
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
//// [superPropertyInConstructorBeforeSuperCall.ts]
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}

//// [superPropertyInConstructorBeforeSuperCall.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 B = (function () {
function B(x) {
}
B.prototype.x = function () { return ""; };
return B;
}());
var C1 = (function (_super) {
__extends(C1, _super);
function C1() {
var _this;
_super.prototype.x.call(_this);
_this = _super.call(this) || this;
return _this;
}
return C1;
}(B));
var C2 = (function (_super) {
__extends(C2, _super);
function C2() {
return _super.call(this, _super.x.call(_this)) || this;
}
return C2;
}(B));
5 changes: 4 additions & 1 deletion tests/baselines/reference/superWithTypeArgument.errors.txt
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument.ts (3 errors) ====
class C {

}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument2.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument2.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument2.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument2.ts (3 errors) ====
class C<T> {
foo: T;
}
Expand All@@ -12,6 +13,8 @@ tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~~
super<T>(x);
~~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
tests/cases/compiler/superWithTypeArgument3.ts(7,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/superWithTypeArgument3.ts(8,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must be followed by an argument list or member access.


==== tests/cases/compiler/superWithTypeArgument3.ts (2 errors) ====
==== tests/cases/compiler/superWithTypeArgument3.ts (3 errors) ====
class C<T> {
foo: T;
bar<U>(x: U) { }
Expand All@@ -13,6 +14,8 @@ tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must
~~~~~~~~~~~~~~~
super<T>();
~~~~~~~~~~~~~~~~~~~
~~~~~
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
~
!!! error TS1034: 'super' must be followed by an argument list or member access.
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
class B {
constructor(x?: string) {}
x(): string { return ""; }
}
class C1 extends B {
constructor() {
super.x();
super();
}
}
class C2 extends B {
constructor() {
super(super.x());
}
}