Skip to content

Commit e3ff684

Browse files
author
Joseph Watts
committed
Generate WeakMaps for private fields in class expressions
1 parent 5ec6a98 commit e3ff684

File tree

1 file changed

+19
-29
lines changed

1 file changed

+19
-29
lines changed

src/compiler/transformers/esnext.ts

+19-29
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,9 @@ namespace ts {
254254
if (some(pendingExpressions)) {
255255
statements.push(createExpressionStatement(inlineExpressions(pendingExpressions!)));
256256
}
257+
endPrivateNameEnvironment();
257258
pendingExpressions = savedPendingExpressions;
258259

259-
const privateNameExpressions = endPrivateNameEnvironment();
260-
if (some(privateNameExpressions)) {
261-
statements.push(createExpressionStatement(inlineExpressions(privateNameExpressions)));
262-
}
263-
264260
// Emit static property assignment. Because classDeclaration is lexically evaluated,
265261
// it is safe to emit static property assignment after classDeclaration
266262
// From ES6 specification:
@@ -277,6 +273,7 @@ namespace ts {
277273
function visitClassExpression(node: ClassExpression): Expression {
278274
const savedPendingExpressions = pendingExpressions;
279275
pendingExpressions = undefined;
276+
startPrivateNameEnvironment();
280277

281278
// If this class expression is a transformation of a decorated class declaration,
282279
// then we want to output the pendingExpressions as statements, not as inlined
@@ -304,7 +301,7 @@ namespace ts {
304301
if (isDecoratedClassDeclaration) {
305302
Debug.assertDefined(pendingStatements, "Decorated classes transformed by TypeScript are expected to be within a variable declaration.");
306303

307-
// Write any pending expressions from elided or moved computed property names
304+
// Write any pending expressions from elided or moved computed property names or private names
308305
if (some(pendingExpressions)) {
309306
pendingStatements!.push(createExpressionStatement(inlineExpressions(pendingExpressions!)));
310307
}
@@ -313,6 +310,7 @@ namespace ts {
313310
if (some(staticProperties)) {
314311
addInitializedPropertyStatements(pendingStatements!, staticProperties, getInternalName(node));
315312
}
313+
endPrivateNameEnvironment();
316314
return classExpression;
317315
}
318316
else {
@@ -337,11 +335,13 @@ namespace ts {
337335
expressions.push(startOnNewLine(temp));
338336

339337
pendingExpressions = savedPendingExpressions;
338+
endPrivateNameEnvironment();
340339
return inlineExpressions(expressions);
341340
}
342341
}
343342

344343
pendingExpressions = savedPendingExpressions;
344+
endPrivateNameEnvironment();
345345
return classExpression;
346346
}
347347

@@ -508,36 +508,26 @@ namespace ts {
508508
return env;
509509
}
510510

511-
function endPrivateNameEnvironment(): Expression[] {
512-
const env = privateNameEnvironmentStack.pop();
513-
Debug.assertDefined(env, "Tried to end private name environment that does not exist.");
514-
const initializers: Expression[] = [];
515-
forEachEntry(env!, (privateName) => {
516-
switch (privateName.type) {
517-
case PrivateNameType.InstanceField: {
518-
hoistVariableDeclaration(privateName.weakMapName);
519-
initializers.push(
520-
createAssignment(
521-
privateName.weakMapName,
522-
createNew(
523-
createIdentifier("WeakMap"),
524-
/*typeArguments*/ undefined,
525-
[]
526-
)
527-
)
528-
);
529-
break;
530-
}
531-
}
532-
});
533-
return initializers;
511+
function endPrivateNameEnvironment() {
512+
privateNameEnvironmentStack.pop();
534513
}
535514

536515
function addPrivateNameToEnvironment(name: PrivateName) {
537516
const env = last(privateNameEnvironmentStack);
538517
const text = getTextOfPropertyName(name) as string;
539518
const weakMapName = createFileLevelUniqueName("_" + text.substring(1));
519+
hoistVariableDeclaration(weakMapName);
540520
env.set(name.escapedText, { type: PrivateNameType.InstanceField, weakMapName });
521+
(pendingExpressions || (pendingExpressions = [])).push(
522+
createAssignment(
523+
weakMapName,
524+
createNew(
525+
createIdentifier("WeakMap"),
526+
/*typeArguments*/ undefined,
527+
[]
528+
)
529+
)
530+
);
541531
}
542532

543533
function enableSubstitutionForClassAliases() {

0 commit comments

Comments
 (0)