Revert "Use ancestor walk to determine if property access is within constructor #9230"

This reverts commit 79f5d968a120e469dbaf432aaad101a708989a6d.
This commit is contained in:
Mohamed Hegazy 2017-10-12 17:25:13 -07:00
parent 5be9e429b4
commit 73ec738ed5
7 changed files with 32 additions and 123 deletions

View File

@ -14904,9 +14904,10 @@ 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 (declaringClassDeclaration && isNodeWithinConstructor(node, declaringClassDeclaration)) {
error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), typeToString(getDeclaringClass(prop)));
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;
}
}
@ -23221,16 +23222,8 @@ namespace ts {
return result;
}
function isNodeWithinConstructor(node: Node, classDeclaration: ClassLikeDeclaration) {
return findAncestor(node, element => {
if (isConstructorDeclaration(element) && nodeIsPresent(element.body)) {
return true;
} else if (element === classDeclaration || isFunctionLikeDeclaration(element)) {
return "quit";
}
return false;
});
function isNodeWithinFunction(node: Node, functionDeclaration: FunctionLike) {
return getContainingFunction(node) === functionDeclaration;
}
function isNodeWithinClass(node: Node, classDeclaration: ClassLikeDeclaration) {

View File

@ -2220,7 +2220,7 @@
"category": "Error",
"code": 2714
},
"Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.": {
"Abstract property '{0}' in class '{1}' cannot be accessed in constructor.": {
"category": "Error",
"code": 2715
},

View File

@ -1,32 +1,20 @@
tests/cases/compiler/abstractPropertyInConstructor.ts(4,24): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
tests/cases/compiler/abstractPropertyInConstructor.ts(7,18): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstract property 'cb' in class 'AbstractClass' cannot be accessed in the constructor.
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 (3 errors) ====
==== 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 the constructor.
if (!str) {
this.prop = "Hello World";
~~~~
!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
}
this.cb(str);
~~
!!! error TS2715: Abstract property 'cb' in class 'AbstractClass' cannot be accessed in the constructor.
const innerFunction = () => {
return this.prop;
}
!!! 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 cb: (s: string) => void;
abstract method(num: number): void;

View File

@ -3,19 +3,10 @@ abstract class AbstractClass {
constructor(str: string) {
this.method(parseInt(str));
let val = this.prop.toLowerCase();
if (!str) {
this.prop = "Hello World";
}
this.cb(str);
const innerFunction = () => {
return this.prop;
}
this.prop = "Hello World";
}
abstract prop: string;
abstract cb: (s: string) => void;
abstract method(num: number): void;
@ -28,16 +19,9 @@ abstract class AbstractClass {
//// [abstractPropertyInConstructor.js]
var AbstractClass = /** @class */ (function () {
function AbstractClass(str) {
var _this = this;
this.method(parseInt(str));
var val = this.prop.toLowerCase();
if (!str) {
this.prop = "Hello World";
}
this.cb(str);
var innerFunction = function () {
return _this.prop;
};
this.prop = "Hello World";
}
AbstractClass.prototype.method2 = function () {
this.prop = this.prop + "!";

View File

@ -6,65 +6,43 @@ abstract class AbstractClass {
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16))
this.method(parseInt(str));
>this.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37))
>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, 16, 37))
>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, 13, 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, 13, 5))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
>toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
if (!str) {
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16))
this.prop = "Hello World";
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
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, 13, 5))
}
this.cb(str);
>this.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26))
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16))
const innerFunction = () => {
>innerFunction : Symbol(innerFunction, Decl(abstractPropertyInConstructor.ts, 10, 13))
return this.prop;
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
}
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
}
abstract prop: string;
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
abstract cb: (s: string) => void;
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26))
>s : Symbol(s, Decl(abstractPropertyInConstructor.ts, 16, 18))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
abstract method(num: number): void;
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37))
>num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 18, 20))
>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, 18, 39))
>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 9, 39))
this.prop = this.prop + "!";
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 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, 13, 5))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5))
>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, 13, 5))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5))
}
}

View File

@ -23,42 +23,17 @@ abstract class AbstractClass {
>prop : string
>toLowerCase : () => string
if (!str) {
>!str : boolean
>str : string
this.prop = "Hello World";
this.prop = "Hello World";
>this.prop = "Hello World" : "Hello World"
>this.prop : string
>this : this
>prop : string
>"Hello World" : "Hello World"
}
this.cb(str);
>this.cb(str) : void
>this.cb : (s: string) => void
>this : this
>cb : (s: string) => void
>str : string
const innerFunction = () => {
>innerFunction : () => string
>() => { return this.prop; } : () => string
return this.prop;
>this.prop : string
>this : this
>prop : string
}
}
abstract prop: string;
>prop : string
abstract cb: (s: string) => void;
>cb : (s: string) => void
>s : string
abstract method(num: number): void;
>method : (num: number) => void
>num : number

View File

@ -2,19 +2,10 @@ abstract class AbstractClass {
constructor(str: string) {
this.method(parseInt(str));
let val = this.prop.toLowerCase();
if (!str) {
this.prop = "Hello World";
}
this.cb(str);
const innerFunction = () => {
return this.prop;
}
this.prop = "Hello World";
}
abstract prop: string;
abstract cb: (s: string) => void;
abstract method(num: number): void;