Skip to content

Commit 21e2f6a

Browse files
committed
implement transforming private-named static fields
Implement transformation for private-named fields. This turned out to be as easy as ignoring whether a private-named field is static or not. Signed-off-by: Max Heiber <[email protected]>
1 parent e36e3aa commit 21e2f6a

33 files changed

+955
-199
lines changed

src/compiler/transformers/classProperties.ts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ namespace ts {
99
}
1010

1111
const enum PrivateNamePlacement {
12-
InstanceField,
12+
Field,
1313
InstanceMethod
1414
}
1515

16-
interface PrivateNamedInstanceField {
17-
placement: PrivateNamePlacement.InstanceField;
16+
interface PrivateNamedField {
17+
placement: PrivateNamePlacement.Field;
1818
accumulator: Identifier;
1919
}
2020

@@ -28,7 +28,7 @@ namespace ts {
2828
/**
2929
* A mapping of private names to information needed for transformation.
3030
*/
31-
type PrivateNameEnvironment = UnderscoreEscapedMap<PrivateNamedInstanceField | PrivateNamedInstanceMethod>;
31+
type PrivateNameEnvironment = UnderscoreEscapedMap<PrivateNamedField | PrivateNamedInstanceMethod>;
3232

3333
/**
3434
* Transforms ECMAScript Class Syntax.
@@ -181,7 +181,7 @@ namespace ts {
181181
const privateNameInfo = accessPrivateName(node.name);
182182
if (privateNameInfo) {
183183
switch (privateNameInfo.placement) {
184-
case PrivateNamePlacement.InstanceField:
184+
case PrivateNamePlacement.Field:
185185
return setOriginalNode(
186186
setTextRange(
187187
createClassPrivateFieldGetHelper(
@@ -359,16 +359,15 @@ namespace ts {
359359
const privateNameInfo = accessPrivateName(node.left.name);
360360
if (privateNameInfo) {
361361
switch (privateNameInfo.placement) {
362-
case PrivateNamePlacement.InstanceField: {
363-
return transformPrivateNamedInstanceFieldAssignment(privateNameInfo, node);
364-
}
362+
case PrivateNamePlacement.Field:
363+
return transformPrivateNamedFieldAssignment(privateNameInfo, node);
365364
}
366365
}
367366
}
368367
return visitEachChild(node, visitor, context);
369368
}
370369

371-
function transformPrivateNamedInstanceFieldAssignment(privateNameInfo: PrivateNamedInstanceField, node: PrivateNameAssignmentExpression) {
370+
function transformPrivateNamedFieldAssignment(privateNameInfo: PrivateNamedField, node: PrivateNameAssignmentExpression) {
372371
if (isCompoundAssignment(node.operatorToken.kind)) {
373372
const isReceiverInlineable = isSimpleInlineableExpression(node.left.expression);
374373
const getReceiver = isReceiverInlineable ? node.left.expression : createTempVariable(hoistVariableDeclaration);
@@ -532,7 +531,7 @@ namespace ts {
532531
pendingExpressions = pendingExpressions || [];
533532
last(privateNameEnvironmentStack).forEach(entry => {
534533
switch (entry.placement) {
535-
case PrivateNamePlacement.InstanceField:
534+
case PrivateNamePlacement.Field:
536535
break;
537536
case PrivateNamePlacement.InstanceMethod:
538537
const func = privateNamedMethodToFunction(entry.origFunc, entry.funcName);
@@ -625,7 +624,7 @@ namespace ts {
625624
if (classDeclaresPrivateNames) {
626625
last(privateNameEnvironmentStack).forEach(({ placement, accumulator }) => {
627626
switch (placement) {
628-
case PrivateNamePlacement.InstanceField:
627+
case PrivateNamePlacement.Field:
629628
// handled in addInitializedPropertyStatements
630629
break;
631630
case PrivateNamePlacement.InstanceMethod:
@@ -734,13 +733,12 @@ namespace ts {
734733
const privateNameInfo = accessPrivateName(propertyName);
735734
if (privateNameInfo) {
736735
switch (privateNameInfo.placement) {
737-
case PrivateNamePlacement.InstanceField: {
738-
return createPrivateInstanceFieldInitializer(
736+
case PrivateNamePlacement.Field:
737+
return createPrivateFieldInitializer(
739738
receiver,
740739
initializer,
741740
privateNameInfo.accumulator
742741
);
743-
}
744742
}
745743
}
746744
}
@@ -868,16 +866,16 @@ namespace ts {
868866

869867
let identifierName: string;
870868
let accumulator: Identifier;
871-
if (hasModifier(element, ModifierFlags.Static)) {
872-
// statics not supported yet
873-
return;
874-
}
875869
if (isPropertyDeclaration(element)) {
876870
identifierName = "WeakMap";
877871
accumulator = createUniqueName(`_${text.slice(1)}WeakMap`);
878-
env.set(escapedText, { placement: PrivateNamePlacement.InstanceField, accumulator });
872+
env.set(escapedText, { placement: PrivateNamePlacement.Field, accumulator });
879873
}
880874
else if (isMethodDeclaration(element)) {
875+
if (hasModifier(element, ModifierFlags.Static)) {
876+
// static methods not supported yet
877+
return;
878+
}
881879
identifierName = "WeakSet";
882880
accumulator = createUniqueName(`_${text.slice(1)}WeakSet`);
883881
const escapedText = element.name.escapedText;
@@ -990,7 +988,7 @@ namespace ts {
990988
}
991989
}
992990

993-
function createPrivateInstanceFieldInitializer(receiver: LeftHandSideExpression, initializer: Expression | undefined, weakMapName: Identifier) {
991+
function createPrivateFieldInitializer(receiver: LeftHandSideExpression, initializer: Expression | undefined, weakMapName: Identifier) {
994992
return createCall(
995993
createPropertyAccess(weakMapName, "set"),
996994
/*typeArguments*/ undefined,
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
//// [privateNameField.ts]
2-
// @target es6
3-
42
class A {
53
#name: string;
4+
static #staticName: string;
65
constructor(name: string) {
76
this.#name = name;
7+
A.#staticName = name;
88
}
99
}
1010

1111
//// [privateNameField.js]
12-
// @target es6
1312
var _classPrivateFieldSet = function (receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; };
14-
var _nameWeakMap_1;
15-
"use strict";
13+
var _nameWeakMap_1, _staticNameWeakMap_1;
1614
var A = /** @class */ (function () {
1715
function A(name) {
1816
_nameWeakMap_1.set(this, void 0);
1917
_classPrivateFieldSet(this, _nameWeakMap_1, name);
18+
_classPrivateFieldSet(A, _staticNameWeakMap_1, name);
2019
}
2120
return A;
2221
}());
23-
_nameWeakMap_1 = new WeakMap();
22+
_nameWeakMap_1 = new WeakMap(), _staticNameWeakMap_1 = new WeakMap();
Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
=== tests/cases/conformance/classes/members/privateNames/privateNameField.ts ===
2-
// @target es6
3-
42
class A {
53
>A : Symbol(A, Decl(privateNameField.ts, 0, 0))
64

75
#name: string;
8-
>#name : Symbol(A.#name, Decl(privateNameField.ts, 2, 9))
6+
>#name : Symbol(A.#name, Decl(privateNameField.ts, 0, 9))
7+
8+
static #staticName: string;
9+
>#staticName : Symbol(A.#staticName, Decl(privateNameField.ts, 1, 18))
910

1011
constructor(name: string) {
11-
>name : Symbol(name, Decl(privateNameField.ts, 4, 16))
12+
>name : Symbol(name, Decl(privateNameField.ts, 3, 16))
1213

1314
this.#name = name;
14-
>this.#name : Symbol(A.#name, Decl(privateNameField.ts, 2, 9))
15+
>this.#name : Symbol(A.#name, Decl(privateNameField.ts, 0, 9))
1516
>this : Symbol(A, Decl(privateNameField.ts, 0, 0))
16-
>name : Symbol(name, Decl(privateNameField.ts, 4, 16))
17+
>name : Symbol(name, Decl(privateNameField.ts, 3, 16))
18+
19+
A.#staticName = name;
20+
>A.#staticName : Symbol(A.#staticName, Decl(privateNameField.ts, 1, 18))
21+
>A : Symbol(A, Decl(privateNameField.ts, 0, 0))
22+
>name : Symbol(name, Decl(privateNameField.ts, 3, 16))
1723
}
1824
}
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
=== tests/cases/conformance/classes/members/privateNames/privateNameField.ts ===
2-
// @target es6
3-
42
class A {
53
>A : A
64

75
#name: string;
86
>#name : string
97

8+
static #staticName: string;
9+
>#staticName : string
10+
1011
constructor(name: string) {
1112
>name : string
1213

1314
this.#name = name;
1415
>this.#name = name : string
1516
>this.#name : string
1617
>this : this
18+
>name : string
19+
20+
A.#staticName = name;
21+
>A.#staticName = name : string
22+
>A.#staticName : string
23+
>A : typeof A
1724
>name : string
1825
}
1926
}

tests/baselines/reference/privateNameFieldAccess.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
//// [privateNameFieldAccess.ts]
22
class A {
33
#myField = "hello world";
4+
static #myStaticField = "hello world";
45
constructor() {
56
console.log(this.#myField);
7+
console.log(A.#myStaticField);
68
}
79
}
810

911

1012
//// [privateNameFieldAccess.js]
1113
var _classPrivateFieldGet = function (receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); };
12-
var _myFieldWeakMap_1;
1314
var A = /** @class */ (function () {
1415
function A() {
1516
_myFieldWeakMap_1.set(this, "hello world");
1617
console.log(_classPrivateFieldGet(this, _myFieldWeakMap_1));
18+
console.log(_classPrivateFieldGet(A, _myStaticFieldWeakMap_1));
1719
}
20+
var _myFieldWeakMap_1, _myStaticFieldWeakMap_1;
21+
_myFieldWeakMap_1 = new WeakMap(), _myStaticFieldWeakMap_1 = new WeakMap();
22+
_myStaticFieldWeakMap_1.set(A, "hello world");
1823
return A;
1924
}());
20-
_myFieldWeakMap_1 = new WeakMap();

tests/baselines/reference/privateNameFieldAccess.symbols

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,23 @@ class A {
55
#myField = "hello world";
66
>#myField : Symbol(A.#myField, Decl(privateNameFieldAccess.ts, 0, 9))
77

8+
static #myStaticField = "hello world";
9+
>#myStaticField : Symbol(A.#myStaticField, Decl(privateNameFieldAccess.ts, 1, 29))
10+
811
constructor() {
912
console.log(this.#myField);
1013
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
1114
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
1215
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
1316
>this.#myField : Symbol(A.#myField, Decl(privateNameFieldAccess.ts, 0, 9))
1417
>this : Symbol(A, Decl(privateNameFieldAccess.ts, 0, 0))
18+
19+
console.log(A.#myStaticField);
20+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
21+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
22+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
23+
>A.#myStaticField : Symbol(A.#myStaticField, Decl(privateNameFieldAccess.ts, 1, 29))
24+
>A : Symbol(A, Decl(privateNameFieldAccess.ts, 0, 0))
1525
}
1626
}
1727

tests/baselines/reference/privateNameFieldAccess.types

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ class A {
44

55
#myField = "hello world";
66
>#myField : string
7+
>"hello world" : "hello world"
8+
9+
static #myStaticField = "hello world";
10+
>#myStaticField : string
711
>"hello world" : "hello world"
812

913
constructor() {
@@ -14,6 +18,14 @@ class A {
1418
>log : (message?: any, ...optionalParams: any[]) => void
1519
>this.#myField : string
1620
>this : this
21+
22+
console.log(A.#myStaticField);
23+
>console.log(A.#myStaticField) : void
24+
>console.log : (message?: any, ...optionalParams: any[]) => void
25+
>console : Console
26+
>log : (message?: any, ...optionalParams: any[]) => void
27+
>A.#myStaticField : string
28+
>A : typeof A
1729
}
1830
}
1931

tests/baselines/reference/privateNameFieldAssignment.js

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//// [privateNameFieldAssignment.ts]
22
class A {
33
#field = 0;
4+
static #staticField = 0;
45
constructor() {
56
this.#field = 1;
67
this.#field += 2;
@@ -28,21 +29,49 @@ class A {
2829
A.getInstance().#field &= 11;
2930
A.getInstance().#field |= 12;
3031
A.getInstance().#field ^= 13;
32+
A.#staticField = 1;
33+
A.#staticField += 2;
34+
A.#staticField -= 3;
35+
A.#staticField /= 4;
36+
A.#staticField *= 5;
37+
A.#staticField **= 6;
38+
A.#staticField %= 7;
39+
A.#staticField <<= 8;
40+
A.#staticField >>= 9;
41+
A.#staticField >>>= 10;
42+
A.#staticField &= 11;
43+
A.#staticField |= 12;
44+
A.#staticField ^= 13;
45+
A.getClass().#staticField = 1;
46+
A.getClass().#staticField += 2;
47+
A.getClass().#staticField -= 3;
48+
A.getClass().#staticField /= 4;
49+
A.getClass().#staticField *= 5;
50+
A.getClass().#staticField **= 6;
51+
A.getClass().#staticField %= 7;
52+
A.getClass().#staticField <<= 8;
53+
A.getClass().#staticField >>= 9;
54+
A.getClass().#staticField >>>= 10;
55+
A.getClass().#staticField &= 11;
56+
A.getClass().#staticField |= 12;
57+
A.getClass().#staticField ^= 13;
3158
}
3259
static getInstance() {
3360
return new A();
3461
}
62+
static getClass() {
63+
return this;
64+
}
3565
}
3666

3767

3868
//// [privateNameFieldAssignment.js]
3969
var _classPrivateFieldSet = function (receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; };
4070
var _classPrivateFieldGet = function (receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); };
41-
var _fieldWeakMap_1;
4271
var A = /** @class */ (function () {
4372
function A() {
4473
_fieldWeakMap_1.set(this, 0);
45-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
74+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11;
4675
_classPrivateFieldSet(this, _fieldWeakMap_1, 1);
4776
_classPrivateFieldSet(this, _fieldWeakMap_1, _classPrivateFieldGet(this, _fieldWeakMap_1) + 2);
4877
_classPrivateFieldSet(this, _fieldWeakMap_1, _classPrivateFieldGet(this, _fieldWeakMap_1) - 3);
@@ -69,10 +98,41 @@ var A = /** @class */ (function () {
6998
_classPrivateFieldSet(_k = A.getInstance(), _fieldWeakMap_1, _classPrivateFieldGet(_k, _fieldWeakMap_1) & 11);
7099
_classPrivateFieldSet(_l = A.getInstance(), _fieldWeakMap_1, _classPrivateFieldGet(_l, _fieldWeakMap_1) | 12);
71100
_classPrivateFieldSet(_m = A.getInstance(), _fieldWeakMap_1, _classPrivateFieldGet(_m, _fieldWeakMap_1) ^ 13);
101+
_classPrivateFieldSet(A, _staticFieldWeakMap_1, 1);
102+
_classPrivateFieldSet(_o = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_o, _staticFieldWeakMap_1) + 2);
103+
_classPrivateFieldSet(_p = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_p, _staticFieldWeakMap_1) - 3);
104+
_classPrivateFieldSet(_q = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_q, _staticFieldWeakMap_1) / 4);
105+
_classPrivateFieldSet(_r = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_r, _staticFieldWeakMap_1) * 5);
106+
_classPrivateFieldSet(_s = A, _staticFieldWeakMap_1, Math.pow(_classPrivateFieldGet(_s, _staticFieldWeakMap_1), 6));
107+
_classPrivateFieldSet(_t = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_t, _staticFieldWeakMap_1) % 7);
108+
_classPrivateFieldSet(_u = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_u, _staticFieldWeakMap_1) << 8);
109+
_classPrivateFieldSet(_v = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_v, _staticFieldWeakMap_1) >> 9);
110+
_classPrivateFieldSet(_w = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_w, _staticFieldWeakMap_1) >>> 10);
111+
_classPrivateFieldSet(_x = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_x, _staticFieldWeakMap_1) & 11);
112+
_classPrivateFieldSet(_y = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_y, _staticFieldWeakMap_1) | 12);
113+
_classPrivateFieldSet(_z = A, _staticFieldWeakMap_1, _classPrivateFieldGet(_z, _staticFieldWeakMap_1) ^ 13);
114+
_classPrivateFieldSet(A.getClass(), _staticFieldWeakMap_1, 1);
115+
_classPrivateFieldSet(_0 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_0, _staticFieldWeakMap_1) + 2);
116+
_classPrivateFieldSet(_1 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_1, _staticFieldWeakMap_1) - 3);
117+
_classPrivateFieldSet(_2 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_2, _staticFieldWeakMap_1) / 4);
118+
_classPrivateFieldSet(_3 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_3, _staticFieldWeakMap_1) * 5);
119+
_classPrivateFieldSet(_4 = A.getClass(), _staticFieldWeakMap_1, Math.pow(_classPrivateFieldGet(_4, _staticFieldWeakMap_1), 6));
120+
_classPrivateFieldSet(_5 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_5, _staticFieldWeakMap_1) % 7);
121+
_classPrivateFieldSet(_6 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_6, _staticFieldWeakMap_1) << 8);
122+
_classPrivateFieldSet(_7 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_7, _staticFieldWeakMap_1) >> 9);
123+
_classPrivateFieldSet(_8 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_8, _staticFieldWeakMap_1) >>> 10);
124+
_classPrivateFieldSet(_9 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_9, _staticFieldWeakMap_1) & 11);
125+
_classPrivateFieldSet(_10 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_10, _staticFieldWeakMap_1) | 12);
126+
_classPrivateFieldSet(_11 = A.getClass(), _staticFieldWeakMap_1, _classPrivateFieldGet(_11, _staticFieldWeakMap_1) ^ 13);
72127
}
73128
A.getInstance = function () {
74129
return new A();
75130
};
131+
A.getClass = function () {
132+
return this;
133+
};
134+
var _fieldWeakMap_1, _staticFieldWeakMap_1;
135+
_fieldWeakMap_1 = new WeakMap(), _staticFieldWeakMap_1 = new WeakMap();
136+
_staticFieldWeakMap_1.set(A, 0);
76137
return A;
77138
}());
78-
_fieldWeakMap_1 = new WeakMap();

0 commit comments

Comments
 (0)