mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Revert "Error when accessing abstract property in constructor #9230"
This reverts commit 9e00df590d.
This commit is contained in:
+5
-23
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 + "!";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user