Skip to content

Commit b1ab2b9

Browse files
Wire up 'writing' parameter through protected derived class detection (microsoft#43455)
Fixes microsoft#43443
1 parent e4e96c3 commit b1ab2b9

6 files changed

+436
-3
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19676,8 +19676,8 @@ namespace ts {
1967619676

1967719677
// Return true if the given class derives from each of the declaring classes of the protected
1967819678
// constituents of the given property.
19679-
function isClassDerivedFromDeclaringClasses(checkClass: Type, prop: Symbol) {
19680-
return forEachProperty(prop, p => getDeclarationModifierFlagsFromSymbol(p) & ModifierFlags.Protected ?
19679+
function isClassDerivedFromDeclaringClasses(checkClass: Type, prop: Symbol, writing: boolean) {
19680+
return forEachProperty(prop, p => getDeclarationModifierFlagsFromSymbol(p, writing) & ModifierFlags.Protected ?
1968119681
!hasBaseType(checkClass, getDeclaringClass(p)) : false) ? undefined : checkClass;
1968219682
}
1968319683

@@ -26907,7 +26907,7 @@ namespace ts {
2690726907
// of the property as base classes
2690826908
let enclosingClass = forEachEnclosingClass(node, enclosingDeclaration => {
2690926909
const enclosingClass = <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration)!);
26910-
return isClassDerivedFromDeclaringClasses(enclosingClass, prop) ? enclosingClass : undefined;
26910+
return isClassDerivedFromDeclaringClasses(enclosingClass, prop, writing) ? enclosingClass : undefined;
2691126911
});
2691226912
// A protected property is accessible if the property is within the declaring class or classes derived from it
2691326913
if (!enclosingClass) {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
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'.
2+
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'.
3+
4+
5+
==== tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts (2 errors) ====
6+
class A {
7+
get x() { return 0; }
8+
protected set x(v: number) { }
9+
10+
public get y() { return 0; }
11+
protected set y(v: number) { }
12+
}
13+
14+
class B {
15+
get q() { return 0; }
16+
protected set q(v: number) { }
17+
18+
protected get u() { return 0; }
19+
protected set u(v: number) { }
20+
21+
foo(this: A, a: A, b: B) {
22+
// Should have no errors in this block
23+
this.x = 0;
24+
this.y = 0;
25+
a.x = 0;
26+
a.y = 0;
27+
b.q = 0;
28+
b.u = 0;
29+
}
30+
}
31+
32+
function bar(this: A, a: A, b: B) {
33+
this.x = 0;
34+
this.y = 0;
35+
a.x = 0;
36+
a.y = 0;
37+
// These should error
38+
b.q = 0;
39+
~
40+
!!! error TS2446: Property 'q' is protected and only accessible through an instance of class 'A'. This is an instance of class 'B'.
41+
b.u = 0;
42+
~
43+
!!! error TS2446: Property 'u' is protected and only accessible through an instance of class 'A'. This is an instance of class 'B'.
44+
}
45+
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//// [publicGetterProtectedSetterFromThisParameter.ts]
2+
class A {
3+
get x() { return 0; }
4+
protected set x(v: number) { }
5+
6+
public get y() { return 0; }
7+
protected set y(v: number) { }
8+
}
9+
10+
class B {
11+
get q() { return 0; }
12+
protected set q(v: number) { }
13+
14+
protected get u() { return 0; }
15+
protected set u(v: number) { }
16+
17+
foo(this: A, a: A, b: B) {
18+
// Should have no errors in this block
19+
this.x = 0;
20+
this.y = 0;
21+
a.x = 0;
22+
a.y = 0;
23+
b.q = 0;
24+
b.u = 0;
25+
}
26+
}
27+
28+
function bar(this: A, a: A, b: B) {
29+
this.x = 0;
30+
this.y = 0;
31+
a.x = 0;
32+
a.y = 0;
33+
// These should error
34+
b.q = 0;
35+
b.u = 0;
36+
}
37+
38+
39+
//// [publicGetterProtectedSetterFromThisParameter.js]
40+
var A = /** @class */ (function () {
41+
function A() {
42+
}
43+
Object.defineProperty(A.prototype, "x", {
44+
get: function () { return 0; },
45+
set: function (v) { },
46+
enumerable: false,
47+
configurable: true
48+
});
49+
Object.defineProperty(A.prototype, "y", {
50+
get: function () { return 0; },
51+
set: function (v) { },
52+
enumerable: false,
53+
configurable: true
54+
});
55+
return A;
56+
}());
57+
var B = /** @class */ (function () {
58+
function B() {
59+
}
60+
Object.defineProperty(B.prototype, "q", {
61+
get: function () { return 0; },
62+
set: function (v) { },
63+
enumerable: false,
64+
configurable: true
65+
});
66+
Object.defineProperty(B.prototype, "u", {
67+
get: function () { return 0; },
68+
set: function (v) { },
69+
enumerable: false,
70+
configurable: true
71+
});
72+
B.prototype.foo = function (a, b) {
73+
// Should have no errors in this block
74+
this.x = 0;
75+
this.y = 0;
76+
a.x = 0;
77+
a.y = 0;
78+
b.q = 0;
79+
b.u = 0;
80+
};
81+
return B;
82+
}());
83+
function bar(a, b) {
84+
this.x = 0;
85+
this.y = 0;
86+
a.x = 0;
87+
a.y = 0;
88+
// These should error
89+
b.q = 0;
90+
b.u = 0;
91+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
=== tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts ===
2+
class A {
3+
>A : Symbol(A, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 0))
4+
5+
get x() { return 0; }
6+
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
7+
8+
protected set x(v: number) { }
9+
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
10+
>v : Symbol(v, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 18))
11+
12+
public get y() { return 0; }
13+
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
14+
15+
protected set y(v: number) { }
16+
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
17+
>v : Symbol(v, Decl(publicGetterProtectedSetterFromThisParameter.ts, 5, 18))
18+
}
19+
20+
class B {
21+
>B : Symbol(B, Decl(publicGetterProtectedSetterFromThisParameter.ts, 6, 1))
22+
23+
get q() { return 0; }
24+
>q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
25+
26+
protected set q(v: number) { }
27+
>q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
28+
>v : Symbol(v, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 18))
29+
30+
protected get u() { return 0; }
31+
>u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
32+
33+
protected set u(v: number) { }
34+
>u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
35+
>v : Symbol(v, Decl(publicGetterProtectedSetterFromThisParameter.ts, 13, 18))
36+
37+
foo(this: A, a: A, b: B) {
38+
>foo : Symbol(B.foo, Decl(publicGetterProtectedSetterFromThisParameter.ts, 13, 32))
39+
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 6))
40+
>A : Symbol(A, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 0))
41+
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 14))
42+
>A : Symbol(A, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 0))
43+
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 20))
44+
>B : Symbol(B, Decl(publicGetterProtectedSetterFromThisParameter.ts, 6, 1))
45+
46+
// Should have no errors in this block
47+
this.x = 0;
48+
>this.x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
49+
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 6))
50+
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
51+
52+
this.y = 0;
53+
>this.y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
54+
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 6))
55+
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
56+
57+
a.x = 0;
58+
>a.x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
59+
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 14))
60+
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
61+
62+
a.y = 0;
63+
>a.y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
64+
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 14))
65+
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
66+
67+
b.q = 0;
68+
>b.q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
69+
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 20))
70+
>q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
71+
72+
b.u = 0;
73+
>b.u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
74+
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 15, 20))
75+
>u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
76+
}
77+
}
78+
79+
function bar(this: A, a: A, b: B) {
80+
>bar : Symbol(bar, Decl(publicGetterProtectedSetterFromThisParameter.ts, 24, 1))
81+
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 13))
82+
>A : Symbol(A, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 0))
83+
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 21))
84+
>A : Symbol(A, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 0))
85+
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 27))
86+
>B : Symbol(B, Decl(publicGetterProtectedSetterFromThisParameter.ts, 6, 1))
87+
88+
this.x = 0;
89+
>this.x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
90+
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 13))
91+
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
92+
93+
this.y = 0;
94+
>this.y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
95+
>this : Symbol(this, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 13))
96+
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
97+
98+
a.x = 0;
99+
>a.x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
100+
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 21))
101+
>x : Symbol(A.x, Decl(publicGetterProtectedSetterFromThisParameter.ts, 0, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 1, 23))
102+
103+
a.y = 0;
104+
>a.y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
105+
>a : Symbol(a, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 21))
106+
>y : Symbol(A.y, Decl(publicGetterProtectedSetterFromThisParameter.ts, 2, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 4, 30))
107+
108+
// These should error
109+
b.q = 0;
110+
>b.q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
111+
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 27))
112+
>q : Symbol(B.q, Decl(publicGetterProtectedSetterFromThisParameter.ts, 8, 9), Decl(publicGetterProtectedSetterFromThisParameter.ts, 9, 23))
113+
114+
b.u = 0;
115+
>b.u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
116+
>b : Symbol(b, Decl(publicGetterProtectedSetterFromThisParameter.ts, 26, 27))
117+
>u : Symbol(B.u, Decl(publicGetterProtectedSetterFromThisParameter.ts, 10, 32), Decl(publicGetterProtectedSetterFromThisParameter.ts, 12, 33))
118+
}
119+

0 commit comments

Comments
 (0)