Skip to content

Commit b5d2106

Browse files
author
Josh Goldberg
committed
Added error for accessing private statics via derived classes
Fixes microsoft#8624
1 parent 9f19c06 commit b5d2106

7 files changed

+1211
-1
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18908,13 +18908,24 @@ namespace ts {
1890818908

1890918909
// Property is known to be private or protected at this point
1891018910

18911-
// Private property is accessible if the property is within the declaring class
1891218911
if (flags & ModifierFlags.Private) {
1891318912
const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!)!;
18913+
18914+
// Private property is accessible if the property is within the declaring class
1891418915
if (!isNodeWithinClass(node, declaringClassDeclaration)) {
1891518916
error(errorNode, Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(getDeclaringClass(prop)!));
1891618917
return false;
1891718918
}
18919+
18920+
// Accessing a private static property via a child class is also disallowed (GH #8624)
18921+
if (isPropertyAccessExpression(node) && hasModifier(prop.valueDeclaration, ModifierFlags.Private) && hasStaticModifier(prop.valueDeclaration)) {
18922+
const accessingSymbol = getSymbolAtLocation(node.expression);
18923+
if (accessingSymbol !== undefined && accessingSymbol.valueDeclaration !== declaringClassDeclaration) {
18924+
error(errorNode, Diagnostics.Static_property_0_is_private_and_only_accessible_via_class_1_not_via_2, symbolToString(prop), typeToString(getDeclaringClass(prop)!), typeToString(getDeclaredTypeOfClassOrInterface(accessingSymbol)));
18925+
return false;
18926+
}
18927+
}
18928+
1891818929
return true;
1891918930
}
1892018931

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2541,6 +2541,10 @@
25412541
"category": "Error",
25422542
"code": 2744
25432543
},
2544+
"Static property '{0}' is private and only accessible via class '{1}' (not via '{2}').": {
2545+
"category": "Error",
2546+
"code": 2745
2547+
},
25442548

25452549
"Import declaration '{0}' is using private name '{1}'.": {
25462550
"category": "Error",
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(11,16): error TS2745: Static property 'privateStaticGrandParent' is private and only accessible via class 'GrandParent' (not via 'Parent').
2+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(14,16): error TS2341: Property 'privateStaticParent' is private and only accessible within class 'Parent'.
3+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(15,16): error TS2445: Property 'protectedStaticParent' is protected and only accessible within class 'Parent' and its subclasses.
4+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(18,15): error TS2745: Static property 'privateStaticGrandParent' is private and only accessible via class 'GrandParent' (not via 'Child').
5+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(21,15): error TS2341: Property 'privateStaticParent' is private and only accessible within class 'Parent'.
6+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(22,15): error TS2445: Property 'protectedStaticParent' is protected and only accessible within class 'Parent' and its subclasses.
7+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(24,15): error TS2341: Property 'privateStaticChild' is private and only accessible within class 'Child'.
8+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(25,15): error TS2445: Property 'protectedStaticChild' is protected and only accessible within class 'Child' and its subclasses.
9+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(26,15): error TS2445: Property 'publicStaticChild' is protected and only accessible within class 'Child' and its subclasses.
10+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(36,21): error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
11+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(40,16): error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
12+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(47,15): error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
13+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(50,15): error TS2745: Static property 'privateStaticParent' is private and only accessible via class 'Parent' (not via 'Child').
14+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(53,15): error TS2341: Property 'privateStaticChild' is private and only accessible within class 'Child'.
15+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(54,15): error TS2445: Property 'protectedStaticChild' is protected and only accessible within class 'Child' and its subclasses.
16+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(55,15): error TS2445: Property 'publicStaticChild' is protected and only accessible within class 'Child' and its subclasses.
17+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(65,21): error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
18+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(69,16): error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
19+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(72,16): error TS2341: Property 'privateStaticParent' is private and only accessible within class 'Parent'.
20+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(76,15): error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
21+
tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts(79,15): error TS2341: Property 'privateStaticParent' is private and only accessible within class 'Parent'.
22+
23+
24+
==== tests/cases/conformance/types/members/classWithPrivateStaticProperty.ts (21 errors) ====
25+
class GrandParent {
26+
private static privateStaticGrandParent = "unset";
27+
protected static protectedStaticGrandParent = "unset";
28+
public static publicStaticGrandParent = "unset";
29+
30+
testGrandparent() {
31+
GrandParent.privateStaticGrandParent = "set";
32+
GrandParent.protectedStaticGrandParent = "set";
33+
GrandParent.publicStaticGrandParent = "set";
34+
35+
Parent.privateStaticGrandParent = "set";
36+
~~~~~~~~~~~~~~~~~~~~~~~~
37+
!!! error TS2745: Static property 'privateStaticGrandParent' is private and only accessible via class 'GrandParent' (not via 'Parent').
38+
Parent.protectedStaticGrandParent = "set";
39+
Parent.publicStaticGrandParent = "set";
40+
Parent.privateStaticParent = "set";
41+
~~~~~~~~~~~~~~~~~~~
42+
!!! error TS2341: Property 'privateStaticParent' is private and only accessible within class 'Parent'.
43+
Parent.protectedStaticParent = "set";
44+
~~~~~~~~~~~~~~~~~~~~~
45+
!!! error TS2445: Property 'protectedStaticParent' is protected and only accessible within class 'Parent' and its subclasses.
46+
Parent.publicStaticParent = "set";
47+
48+
Child.privateStaticGrandParent = "set";
49+
~~~~~~~~~~~~~~~~~~~~~~~~
50+
!!! error TS2745: Static property 'privateStaticGrandParent' is private and only accessible via class 'GrandParent' (not via 'Child').
51+
Child.protectedStaticGrandParent = "set";
52+
Child.publicStaticGrandParent = "set";
53+
Child.privateStaticParent = "set";
54+
~~~~~~~~~~~~~~~~~~~
55+
!!! error TS2341: Property 'privateStaticParent' is private and only accessible within class 'Parent'.
56+
Child.protectedStaticParent = "set";
57+
~~~~~~~~~~~~~~~~~~~~~
58+
!!! error TS2445: Property 'protectedStaticParent' is protected and only accessible within class 'Parent' and its subclasses.
59+
Child.publicStaticParent = "set";
60+
Child.privateStaticChild = "set";
61+
~~~~~~~~~~~~~~~~~~
62+
!!! error TS2341: Property 'privateStaticChild' is private and only accessible within class 'Child'.
63+
Child.protectedStaticChild = "set";
64+
~~~~~~~~~~~~~~~~~~~~
65+
!!! error TS2445: Property 'protectedStaticChild' is protected and only accessible within class 'Child' and its subclasses.
66+
Child.publicStaticChild = "set";
67+
~~~~~~~~~~~~~~~~~
68+
!!! error TS2445: Property 'publicStaticChild' is protected and only accessible within class 'Child' and its subclasses.
69+
}
70+
}
71+
72+
class Parent extends GrandParent {
73+
private static privateStaticParent = "unset";
74+
protected static protectedStaticParent = "unset";
75+
public static publicStaticParent = "unset";
76+
77+
testParent() {
78+
GrandParent.privateStaticGrandParent = "set";
79+
~~~~~~~~~~~~~~~~~~~~~~~~
80+
!!! error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
81+
GrandParent.protectedStaticGrandParent = "set";
82+
GrandParent.publicStaticGrandParent = "set";
83+
84+
Parent.privateStaticGrandParent = "set";
85+
~~~~~~~~~~~~~~~~~~~~~~~~
86+
!!! error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
87+
Parent.protectedStaticGrandParent = "set";
88+
Parent.publicStaticGrandParent = "set";
89+
Parent.privateStaticParent = "set";
90+
Parent.protectedStaticParent = "set";
91+
Parent.publicStaticParent = "set";
92+
93+
Child.privateStaticGrandParent = "set";
94+
~~~~~~~~~~~~~~~~~~~~~~~~
95+
!!! error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
96+
Child.protectedStaticGrandParent = "set";
97+
Child.publicStaticGrandParent = "set";
98+
Child.privateStaticParent = "set";
99+
~~~~~~~~~~~~~~~~~~~
100+
!!! error TS2745: Static property 'privateStaticParent' is private and only accessible via class 'Parent' (not via 'Child').
101+
Child.protectedStaticParent = "set";
102+
Child.publicStaticParent = "set";
103+
Child.privateStaticChild = "set";
104+
~~~~~~~~~~~~~~~~~~
105+
!!! error TS2341: Property 'privateStaticChild' is private and only accessible within class 'Child'.
106+
Child.protectedStaticChild = "set";
107+
~~~~~~~~~~~~~~~~~~~~
108+
!!! error TS2445: Property 'protectedStaticChild' is protected and only accessible within class 'Child' and its subclasses.
109+
Child.publicStaticChild = "set";
110+
~~~~~~~~~~~~~~~~~
111+
!!! error TS2445: Property 'publicStaticChild' is protected and only accessible within class 'Child' and its subclasses.
112+
}
113+
}
114+
115+
class Child extends Parent {
116+
private static privateStaticChild = "unset";
117+
protected static protectedStaticChild = "unset";
118+
protected static publicStaticChild = "unset";
119+
120+
testChild() {
121+
GrandParent.privateStaticGrandParent = "set";
122+
~~~~~~~~~~~~~~~~~~~~~~~~
123+
!!! error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
124+
GrandParent.protectedStaticGrandParent = "set";
125+
GrandParent.publicStaticGrandParent = "set";
126+
127+
Parent.privateStaticGrandParent = "set";
128+
~~~~~~~~~~~~~~~~~~~~~~~~
129+
!!! error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
130+
Parent.protectedStaticGrandParent = "set";
131+
Parent.publicStaticGrandParent = "set";
132+
Parent.privateStaticParent = "set";
133+
~~~~~~~~~~~~~~~~~~~
134+
!!! error TS2341: Property 'privateStaticParent' is private and only accessible within class 'Parent'.
135+
Parent.protectedStaticParent = "set";
136+
Parent.publicStaticParent = "set";
137+
138+
Child.privateStaticGrandParent = "set";
139+
~~~~~~~~~~~~~~~~~~~~~~~~
140+
!!! error TS2341: Property 'privateStaticGrandParent' is private and only accessible within class 'GrandParent'.
141+
Child.protectedStaticGrandParent = "set";
142+
Child.publicStaticGrandParent = "set";
143+
Child.privateStaticParent = "set";
144+
~~~~~~~~~~~~~~~~~~~
145+
!!! error TS2341: Property 'privateStaticParent' is private and only accessible within class 'Parent'.
146+
Child.protectedStaticParent = "set";
147+
Child.publicStaticParent = "set";
148+
Child.privateStaticChild = "set";
149+
Child.protectedStaticChild = "set";
150+
Child.publicStaticChild = "set";
151+
}
152+
}
153+

0 commit comments

Comments
 (0)