mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:33:53 -06:00
Wire up 'writing' parameter through protected derived class detection (#43455)
Fixes #43443
This commit is contained in:
parent
e4e96c3399
commit
b1ab2b98be
@ -19676,8 +19676,8 @@ namespace ts {
|
||||
|
||||
// Return true if the given class derives from each of the declaring classes of the protected
|
||||
// constituents of the given property.
|
||||
function isClassDerivedFromDeclaringClasses(checkClass: Type, prop: Symbol) {
|
||||
return forEachProperty(prop, p => getDeclarationModifierFlagsFromSymbol(p) & ModifierFlags.Protected ?
|
||||
function isClassDerivedFromDeclaringClasses(checkClass: Type, prop: Symbol, writing: boolean) {
|
||||
return forEachProperty(prop, p => getDeclarationModifierFlagsFromSymbol(p, writing) & ModifierFlags.Protected ?
|
||||
!hasBaseType(checkClass, getDeclaringClass(p)) : false) ? undefined : checkClass;
|
||||
}
|
||||
|
||||
@ -26907,7 +26907,7 @@ namespace ts {
|
||||
// of the property as base classes
|
||||
let enclosingClass = forEachEnclosingClass(node, enclosingDeclaration => {
|
||||
const enclosingClass = <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration)!);
|
||||
return isClassDerivedFromDeclaringClasses(enclosingClass, prop) ? enclosingClass : undefined;
|
||||
return isClassDerivedFromDeclaringClasses(enclosingClass, prop, writing) ? enclosingClass : undefined;
|
||||
});
|
||||
// A protected property is accessible if the property is within the declaring class or classes derived from it
|
||||
if (!enclosingClass) {
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts(33,7): error TS2446: Property 'q' is protected and only accessible through an instance of class 'A'. This is an instance of class 'B'.
|
||||
tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts(34,7): error TS2446: Property 'u' is protected and only accessible through an instance of class 'A'. This is an instance of class 'B'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts (2 errors) ====
|
||||
class A {
|
||||
get x() { return 0; }
|
||||
protected set x(v: number) { }
|
||||
|
||||
public get y() { return 0; }
|
||||
protected set y(v: number) { }
|
||||
}
|
||||
|
||||
class B {
|
||||
get q() { return 0; }
|
||||
protected set q(v: number) { }
|
||||
|
||||
protected get u() { return 0; }
|
||||
protected set u(v: number) { }
|
||||
|
||||
foo(this: A, a: A, b: B) {
|
||||
// Should have no errors in this block
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
a.x = 0;
|
||||
a.y = 0;
|
||||
b.q = 0;
|
||||
b.u = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function bar(this: A, a: A, b: B) {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
a.x = 0;
|
||||
a.y = 0;
|
||||
// These should error
|
||||
b.q = 0;
|
||||
~
|
||||
!!! error TS2446: Property 'q' is protected and only accessible through an instance of class 'A'. This is an instance of class 'B'.
|
||||
b.u = 0;
|
||||
~
|
||||
!!! error TS2446: Property 'u' is protected and only accessible through an instance of class 'A'. This is an instance of class 'B'.
|
||||
}
|
||||
|
||||
@ -0,0 +1,91 @@
|
||||
//// [publicGetterProtectedSetterFromThisParameter.ts]
|
||||
class A {
|
||||
get x() { return 0; }
|
||||
protected set x(v: number) { }
|
||||
|
||||
public get y() { return 0; }
|
||||
protected set y(v: number) { }
|
||||
}
|
||||
|
||||
class B {
|
||||
get q() { return 0; }
|
||||
protected set q(v: number) { }
|
||||
|
||||
protected get u() { return 0; }
|
||||
protected set u(v: number) { }
|
||||
|
||||
foo(this: A, a: A, b: B) {
|
||||
// Should have no errors in this block
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
a.x = 0;
|
||||
a.y = 0;
|
||||
b.q = 0;
|
||||
b.u = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function bar(this: A, a: A, b: B) {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
a.x = 0;
|
||||
a.y = 0;
|
||||
// These should error
|
||||
b.q = 0;
|
||||
b.u = 0;
|
||||
}
|
||||
|
||||
|
||||
//// [publicGetterProtectedSetterFromThisParameter.js]
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
}
|
||||
Object.defineProperty(A.prototype, "x", {
|
||||
get: function () { return 0; },
|
||||
set: function (v) { },
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(A.prototype, "y", {
|
||||
get: function () { return 0; },
|
||||
set: function (v) { },
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
return A;
|
||||
}());
|
||||
var B = /** @class */ (function () {
|
||||
function B() {
|
||||
}
|
||||
Object.defineProperty(B.prototype, "q", {
|
||||
get: function () { return 0; },
|
||||
set: function (v) { },
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(B.prototype, "u", {
|
||||
get: function () { return 0; },
|
||||
set: function (v) { },
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
B.prototype.foo = function (a, b) {
|
||||
// Should have no errors in this block
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
a.x = 0;
|
||||
a.y = 0;
|
||||
b.q = 0;
|
||||
b.u = 0;
|
||||
};
|
||||
return B;
|
||||
}());
|
||||
function bar(a, b) {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
a.x = 0;
|
||||
a.y = 0;
|
||||
// These should error
|
||||
b.q = 0;
|
||||
b.u = 0;
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
=== tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts ===
|
||||
class A {
|
||||
>A : Symbol(A, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 0))
|
||||
|
||||
get x() { return 0; }
|
||||
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
|
||||
|
||||
protected set x(v: number) { }
|
||||
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
|
||||
>v : Symbol(v, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 18))
|
||||
|
||||
public get y() { return 0; }
|
||||
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
|
||||
|
||||
protected set y(v: number) { }
|
||||
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
|
||||
>v : Symbol(v, Decl(publicGetterProtectedSetterFromThisParameter.ts, 5, 18))
|
||||
}
|
||||
|
||||
class B {
|
||||
>B : Symbol(B, Decl(publicGetterProtectedSetterFromThisParameter.ts, 6, 1))
|
||||
|
||||
get q() { return 0; }
|
||||
>q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
|
||||
|
||||
protected set q(v: number) { }
|
||||
>q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
|
||||
>v : Symbol(v, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 18))
|
||||
|
||||
protected get u() { return 0; }
|
||||
>u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
|
||||
|
||||
protected set u(v: number) { }
|
||||
>u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
|
||||
>v : Symbol(v, Decl(publicGetterProtectedSetterFromThisParameter.ts, 13, 18))
|
||||
|
||||
foo(this: A, a: A, b: B) {
|
||||
>foo : Symbol(B.foo, Decl(publicGetterProtectedSetterFromThisParameter.ts, 13, 32))
|
||||
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 6))
|
||||
>A : Symbol(A, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 0))
|
||||
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 14))
|
||||
>A : Symbol(A, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 0))
|
||||
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 20))
|
||||
>B : Symbol(B, Decl(publicGetterProtectedSetterFromThisParameter.ts, 6, 1))
|
||||
|
||||
// Should have no errors in this block
|
||||
this.x = 0;
|
||||
>this.x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
|
||||
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 6))
|
||||
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
|
||||
|
||||
this.y = 0;
|
||||
>this.y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
|
||||
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 6))
|
||||
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
|
||||
|
||||
a.x = 0;
|
||||
>a.x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
|
||||
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 14))
|
||||
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
|
||||
|
||||
a.y = 0;
|
||||
>a.y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
|
||||
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 14))
|
||||
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
|
||||
|
||||
b.q = 0;
|
||||
>b.q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
|
||||
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 20))
|
||||
>q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
|
||||
|
||||
b.u = 0;
|
||||
>b.u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
|
||||
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 20))
|
||||
>u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
|
||||
}
|
||||
}
|
||||
|
||||
function bar(this: A, a: A, b: B) {
|
||||
>bar : Symbol(bar, Decl(publicGetterProtectedSetterFromThisParameter.ts, 24, 1))
|
||||
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 13))
|
||||
>A : Symbol(A, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 0))
|
||||
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 21))
|
||||
>A : Symbol(A, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 0))
|
||||
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 27))
|
||||
>B : Symbol(B, Decl(publicGetterProtectedSetterFromThisParameter.ts, 6, 1))
|
||||
|
||||
this.x = 0;
|
||||
>this.x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
|
||||
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 13))
|
||||
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
|
||||
|
||||
this.y = 0;
|
||||
>this.y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
|
||||
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 13))
|
||||
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
|
||||
|
||||
a.x = 0;
|
||||
>a.x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
|
||||
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 21))
|
||||
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
|
||||
|
||||
a.y = 0;
|
||||
>a.y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
|
||||
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 21))
|
||||
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
|
||||
|
||||
// These should error
|
||||
b.q = 0;
|
||||
>b.q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
|
||||
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 27))
|
||||
>q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
|
||||
|
||||
b.u = 0;
|
||||
>b.u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
|
||||
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 27))
|
||||
>u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
|
||||
}
|
||||
|
||||
@ -0,0 +1,141 @@
|
||||
=== tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts ===
|
||||
class A {
|
||||
>A : A
|
||||
|
||||
get x() { return 0; }
|
||||
>x : number
|
||||
>0 : 0
|
||||
|
||||
protected set x(v: number) { }
|
||||
>x : number
|
||||
>v : number
|
||||
|
||||
public get y() { return 0; }
|
||||
>y : number
|
||||
>0 : 0
|
||||
|
||||
protected set y(v: number) { }
|
||||
>y : number
|
||||
>v : number
|
||||
}
|
||||
|
||||
class B {
|
||||
>B : B
|
||||
|
||||
get q() { return 0; }
|
||||
>q : number
|
||||
>0 : 0
|
||||
|
||||
protected set q(v: number) { }
|
||||
>q : number
|
||||
>v : number
|
||||
|
||||
protected get u() { return 0; }
|
||||
>u : number
|
||||
>0 : 0
|
||||
|
||||
protected set u(v: number) { }
|
||||
>u : number
|
||||
>v : number
|
||||
|
||||
foo(this: A, a: A, b: B) {
|
||||
>foo : (this: A, a: A, b: B) => void
|
||||
>this : A
|
||||
>a : A
|
||||
>b : B
|
||||
|
||||
// Should have no errors in this block
|
||||
this.x = 0;
|
||||
>this.x = 0 : 0
|
||||
>this.x : number
|
||||
>this : A
|
||||
>x : number
|
||||
>0 : 0
|
||||
|
||||
this.y = 0;
|
||||
>this.y = 0 : 0
|
||||
>this.y : number
|
||||
>this : A
|
||||
>y : number
|
||||
>0 : 0
|
||||
|
||||
a.x = 0;
|
||||
>a.x = 0 : 0
|
||||
>a.x : number
|
||||
>a : A
|
||||
>x : number
|
||||
>0 : 0
|
||||
|
||||
a.y = 0;
|
||||
>a.y = 0 : 0
|
||||
>a.y : number
|
||||
>a : A
|
||||
>y : number
|
||||
>0 : 0
|
||||
|
||||
b.q = 0;
|
||||
>b.q = 0 : 0
|
||||
>b.q : number
|
||||
>b : B
|
||||
>q : number
|
||||
>0 : 0
|
||||
|
||||
b.u = 0;
|
||||
>b.u = 0 : 0
|
||||
>b.u : number
|
||||
>b : B
|
||||
>u : number
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
|
||||
function bar(this: A, a: A, b: B) {
|
||||
>bar : (this: A, a: A, b: B) => void
|
||||
>this : A
|
||||
>a : A
|
||||
>b : B
|
||||
|
||||
this.x = 0;
|
||||
>this.x = 0 : 0
|
||||
>this.x : number
|
||||
>this : A
|
||||
>x : number
|
||||
>0 : 0
|
||||
|
||||
this.y = 0;
|
||||
>this.y = 0 : 0
|
||||
>this.y : number
|
||||
>this : A
|
||||
>y : number
|
||||
>0 : 0
|
||||
|
||||
a.x = 0;
|
||||
>a.x = 0 : 0
|
||||
>a.x : number
|
||||
>a : A
|
||||
>x : number
|
||||
>0 : 0
|
||||
|
||||
a.y = 0;
|
||||
>a.y = 0 : 0
|
||||
>a.y : number
|
||||
>a : A
|
||||
>y : number
|
||||
>0 : 0
|
||||
|
||||
// These should error
|
||||
b.q = 0;
|
||||
>b.q = 0 : 0
|
||||
>b.q : number
|
||||
>b : B
|
||||
>q : number
|
||||
>0 : 0
|
||||
|
||||
b.u = 0;
|
||||
>b.u = 0 : 0
|
||||
>b.u : number
|
||||
>b : B
|
||||
>u : number
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
// @target: ES5
|
||||
|
||||
class A {
|
||||
get x() { return 0; }
|
||||
protected set x(v: number) { }
|
||||
|
||||
public get y() { return 0; }
|
||||
protected set y(v: number) { }
|
||||
}
|
||||
|
||||
class B {
|
||||
get q() { return 0; }
|
||||
protected set q(v: number) { }
|
||||
|
||||
protected get u() { return 0; }
|
||||
protected set u(v: number) { }
|
||||
|
||||
foo(this: A, a: A, b: B) {
|
||||
// Should have no errors in this block
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
a.x = 0;
|
||||
a.y = 0;
|
||||
b.q = 0;
|
||||
b.u = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function bar(this: A, a: A, b: B) {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
a.x = 0;
|
||||
a.y = 0;
|
||||
// These should error
|
||||
b.q = 0;
|
||||
b.u = 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user