Revert "Error when accessing abstract property in constructor #9230"

This reverts commit 9e00df590d.
This commit is contained in:
Mohamed Hegazy
2017-10-12 17:27:06 -07:00
parent 73ec738ed5
commit 6b533a8f94
7 changed files with 5 additions and 201 deletions
+5 -23
View File
@@ -14886,7 +14886,11 @@ namespace ts {
// 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) {
if (symbolHasNonMethodDeclaration(prop)) {
const hasNonMethodDeclaration = forEachProperty(prop, p => {
const propKind = getDeclarationKindFromSymbol(p);
return propKind !== SyntaxKind.MethodDeclaration && propKind !== SyntaxKind.MethodSignature;
});
if (hasNonMethodDeclaration) {
error(errorNode, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
return false;
}
@@ -14901,17 +14905,6 @@ namespace ts {
}
}
// Referencing Abstract Properties within Constructors is not allowed
if ((flags & ModifierFlags.Abstract) && symbolHasNonMethodDeclaration(prop)) {
const declaringClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
const declaringClassConstructor = declaringClassDeclaration && findConstructorDeclaration(declaringClassDeclaration);
if (declaringClassConstructor && isNodeWithinFunction(node, declaringClassConstructor)) {
error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_constructor, symbolToString(prop), typeToString(getDeclaringClass(prop)));
return false;
}
}
// Public properties are otherwise accessible.
if (!(flags & ModifierFlags.NonPublicAccessibilityModifier)) {
return true;
@@ -14963,13 +14956,6 @@ namespace ts {
return true;
}
function symbolHasNonMethodDeclaration(symbol: Symbol) {
return forEachProperty(symbol, prop => {
const propKind = getDeclarationKindFromSymbol(prop);
return propKind !== SyntaxKind.MethodDeclaration && propKind !== SyntaxKind.MethodSignature;
});
}
function checkNonNullExpression(node: Expression | QualifiedName) {
return checkNonNullType(checkExpression(node), node);
}
@@ -23222,10 +23208,6 @@ namespace ts {
return result;
}
function isNodeWithinFunction(node: Node, functionDeclaration: FunctionLike) {
return getContainingFunction(node) === functionDeclaration;
}
function isNodeWithinClass(node: Node, classDeclaration: ClassLikeDeclaration) {
return !!forEachEnclosingClass(node, n => n === classDeclaration);
}
-4
View File
@@ -2220,10 +2220,6 @@
"category": "Error",
"code": 2714
},
"Abstract property '{0}' in class '{1}' cannot be accessed in constructor.": {
"category": "Error",
"code": 2715
},
"Type parameter '{0}' has a circular default.": {
"category": "Error",
"code": 2716
@@ -1,25 +0,0 @@
tests/cases/compiler/abstractPropertyInConstructor.ts(4,24): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor.
tests/cases/compiler/abstractPropertyInConstructor.ts(5,14): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor.
==== tests/cases/compiler/abstractPropertyInConstructor.ts (2 errors) ====
abstract class AbstractClass {
constructor(str: string) {
this.method(parseInt(str));
let val = this.prop.toLowerCase();
~~~~
!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor.
this.prop = "Hello World";
~~~~
!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor.
}
abstract prop: string;
abstract method(num: number): void;
method2() {
this.prop = this.prop + "!";
}
}
@@ -1,30 +0,0 @@
//// [abstractPropertyInConstructor.ts]
abstract class AbstractClass {
constructor(str: string) {
this.method(parseInt(str));
let val = this.prop.toLowerCase();
this.prop = "Hello World";
}
abstract prop: string;
abstract method(num: number): void;
method2() {
this.prop = this.prop + "!";
}
}
//// [abstractPropertyInConstructor.js]
var AbstractClass = /** @class */ (function () {
function AbstractClass(str) {
this.method(parseInt(str));
var val = this.prop.toLowerCase();
this.prop = "Hello World";
}
AbstractClass.prototype.method2 = function () {
this.prop = this.prop + "!";
};
return AbstractClass;
}());
@@ -1,48 +0,0 @@
=== tests/cases/compiler/abstractPropertyInConstructor.ts ===
abstract class AbstractClass {
>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
constructor(str: string) {
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16))
this.method(parseInt(str));
>this.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 7, 26))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 7, 26))
>parseInt : Symbol(parseInt, Decl(lib.d.ts, --, --))
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16))
let val = this.prop.toLowerCase();
>val : Symbol(val, Decl(abstractPropertyInConstructor.ts, 3, 11))
>this.prop.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
>toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
this.prop = "Hello World";
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
}
abstract prop: string;
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
abstract method(num: number): void;
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 7, 26))
>num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 9, 20))
method2() {
>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 9, 39))
this.prop = this.prop + "!";
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
}
}
@@ -1,56 +0,0 @@
=== tests/cases/compiler/abstractPropertyInConstructor.ts ===
abstract class AbstractClass {
>AbstractClass : AbstractClass
constructor(str: string) {
>str : string
this.method(parseInt(str));
>this.method(parseInt(str)) : void
>this.method : (num: number) => void
>this : this
>method : (num: number) => void
>parseInt(str) : number
>parseInt : (s: string, radix?: number) => number
>str : string
let val = this.prop.toLowerCase();
>val : string
>this.prop.toLowerCase() : string
>this.prop.toLowerCase : () => string
>this.prop : string
>this : this
>prop : string
>toLowerCase : () => string
this.prop = "Hello World";
>this.prop = "Hello World" : "Hello World"
>this.prop : string
>this : this
>prop : string
>"Hello World" : "Hello World"
}
abstract prop: string;
>prop : string
abstract method(num: number): void;
>method : (num: number) => void
>num : number
method2() {
>method2 : () => void
this.prop = this.prop + "!";
>this.prop = this.prop + "!" : string
>this.prop : string
>this : this
>prop : string
>this.prop + "!" : string
>this.prop : string
>this : this
>prop : string
>"!" : "!"
}
}
@@ -1,15 +0,0 @@
abstract class AbstractClass {
constructor(str: string) {
this.method(parseInt(str));
let val = this.prop.toLowerCase();
this.prop = "Hello World";
}
abstract prop: string;
abstract method(num: number): void;
method2() {
this.prop = this.prop + "!";
}
}