Allow super to access method signatures

Previously, super was only allowed to access method *declarations*. But
method signatures can come from interfaces that merge with classes, and
should also be accessible as methods on super.
This commit is contained in:
Nathan Shively-Sanders 2017-01-27 09:53:57 -08:00
parent 71d1a3f051
commit 4d67b0c2b6
5 changed files with 99 additions and 5 deletions

View file

@ -12337,12 +12337,15 @@ namespace ts {
// - In a static member function or static member accessor
// where this references the constructor function object of a derived class,
// a super property access is permitted and must specify a public static member function of the base class.
if (languageVersion < ScriptTarget.ES2015 && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) {
// `prop` refers to a *property* declared in the super class
// rather than a *method*, so it does not satisfy the above criteria.
if (languageVersion < ScriptTarget.ES2015) {
const propKind = getDeclarationKindFromSymbol(prop);
if (propKind !== SyntaxKind.MethodDeclaration && propKind !== SyntaxKind.MethodSignature) {
// `prop` refers to a *property* declared in the super class
// rather than a *method*, so it does not satisfy the above criteria.
error(errorNode, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
return false;
error(errorNode, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
return false;
}
}
if (flags & ModifierFlags.Abstract) {

View file

@ -0,0 +1,37 @@
//// [superHasMethodsFromMergedInterface.ts]
class C { m1() { } }
interface C { m2(): void }
class Sub extends C {
m3() {
super.m2();
}
}
//// [superHasMethodsFromMergedInterface.js]
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var C = (function () {
function C() {
}
C.prototype.m1 = function () { };
return C;
}());
var Sub = (function (_super) {
__extends(Sub, _super);
function Sub() {
return _super !== null && _super.apply(this, arguments) || this;
}
Sub.prototype.m3 = function () {
_super.prototype.m2.call(this);
};
return Sub;
}(C));

View file

@ -0,0 +1,23 @@
=== tests/cases/compiler/superHasMethodsFromMergedInterface.ts ===
class C { m1() { } }
>C : Symbol(C, Decl(superHasMethodsFromMergedInterface.ts, 0, 0), Decl(superHasMethodsFromMergedInterface.ts, 0, 20))
>m1 : Symbol(C.m1, Decl(superHasMethodsFromMergedInterface.ts, 0, 9))
interface C { m2(): void }
>C : Symbol(C, Decl(superHasMethodsFromMergedInterface.ts, 0, 0), Decl(superHasMethodsFromMergedInterface.ts, 0, 20))
>m2 : Symbol(C.m2, Decl(superHasMethodsFromMergedInterface.ts, 1, 13))
class Sub extends C {
>Sub : Symbol(Sub, Decl(superHasMethodsFromMergedInterface.ts, 1, 26))
>C : Symbol(C, Decl(superHasMethodsFromMergedInterface.ts, 0, 0), Decl(superHasMethodsFromMergedInterface.ts, 0, 20))
m3() {
>m3 : Symbol(Sub.m3, Decl(superHasMethodsFromMergedInterface.ts, 2, 21))
super.m2();
>super.m2 : Symbol(C.m2, Decl(superHasMethodsFromMergedInterface.ts, 1, 13))
>super : Symbol(C, Decl(superHasMethodsFromMergedInterface.ts, 0, 0), Decl(superHasMethodsFromMergedInterface.ts, 0, 20))
>m2 : Symbol(C.m2, Decl(superHasMethodsFromMergedInterface.ts, 1, 13))
}
}

View file

@ -0,0 +1,24 @@
=== tests/cases/compiler/superHasMethodsFromMergedInterface.ts ===
class C { m1() { } }
>C : C
>m1 : () => void
interface C { m2(): void }
>C : C
>m2 : () => void
class Sub extends C {
>Sub : Sub
>C : C
m3() {
>m3 : () => void
super.m2();
>super.m2() : void
>super.m2 : () => void
>super : C
>m2 : () => void
}
}

View file

@ -0,0 +1,7 @@
class C { m1() { } }
interface C { m2(): void }
class Sub extends C {
m3() {
super.m2();
}
}