Skip to content

Commit b362de1

Browse files
author
Joseph Watts
committed
Generate WeakMaps for private fields in class expressions
1 parent a156d31 commit b362de1

File tree

1 file changed

+19
-29
lines changed

1 file changed

+19
-29
lines changed

src/compiler/transformers/esnext.ts

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,9 @@ namespace ts {
270270
if (some(pendingExpressions)) {
271271
statements.push(createExpressionStatement(inlineExpressions(pendingExpressions!)));
272272
}
273+
endPrivateNameEnvironment();
273274
pendingExpressions = savedPendingExpressions;
274275

275-
const privateNameExpressions = endPrivateNameEnvironment();
276-
if (some(privateNameExpressions)) {
277-
statements.push(createExpressionStatement(inlineExpressions(privateNameExpressions)));
278-
}
279-
280276
// Emit static property assignment. Because classDeclaration is lexically evaluated,
281277
// it is safe to emit static property assignment after classDeclaration
282278
// From ES6 specification:
@@ -293,6 +289,7 @@ namespace ts {
293289
function visitClassExpression(node: ClassExpression): Expression {
294290
const savedPendingExpressions = pendingExpressions;
295291
pendingExpressions = undefined;
292+
startPrivateNameEnvironment();
296293

297294
// If this class expression is a transformation of a decorated class declaration,
298295
// then we want to output the pendingExpressions as statements, not as inlined
@@ -320,7 +317,7 @@ namespace ts {
320317
if (isDecoratedClassDeclaration) {
321318
Debug.assertDefined(pendingStatements, "Decorated classes transformed by TypeScript are expected to be within a variable declaration.");
322319

323-
// Write any pending expressions from elided or moved computed property names
320+
// Write any pending expressions from elided or moved computed property names or private names
324321
if (some(pendingExpressions)) {
325322
pendingStatements!.push(createExpressionStatement(inlineExpressions(pendingExpressions!)));
326323
}
@@ -329,6 +326,7 @@ namespace ts {
329326
if (some(staticProperties)) {
330327
addInitializedPropertyStatements(pendingStatements!, staticProperties, getInternalName(node));
331328
}
329+
endPrivateNameEnvironment();
332330
return classExpression;
333331
}
334332
else {
@@ -353,11 +351,13 @@ namespace ts {
353351
expressions.push(startOnNewLine(temp));
354352

355353
pendingExpressions = savedPendingExpressions;
354+
endPrivateNameEnvironment();
356355
return inlineExpressions(expressions);
357356
}
358357
}
359358

360359
pendingExpressions = savedPendingExpressions;
360+
endPrivateNameEnvironment();
361361
return classExpression;
362362
}
363363

@@ -525,36 +525,26 @@ namespace ts {
525525
return env;
526526
}
527527

528-
function endPrivateNameEnvironment(): Expression[] {
529-
const env = privateNameEnvironmentStack.pop();
530-
Debug.assertDefined(env, "Tried to end private name environment that does not exist.");
531-
const initializers: Expression[] = [];
532-
forEachEntry(env!, (privateName) => {
533-
switch (privateName.type) {
534-
case PrivateNameType.InstanceField: {
535-
hoistVariableDeclaration(privateName.weakMapName);
536-
initializers.push(
537-
createAssignment(
538-
privateName.weakMapName,
539-
createNew(
540-
createIdentifier("WeakMap"),
541-
/*typeArguments*/ undefined,
542-
[]
543-
)
544-
)
545-
);
546-
break;
547-
}
548-
}
549-
});
550-
return initializers;
528+
function endPrivateNameEnvironment() {
529+
privateNameEnvironmentStack.pop();
551530
}
552531

553532
function addPrivateNameToEnvironment(name: PrivateName) {
554533
const env = last(privateNameEnvironmentStack);
555534
const text = getTextOfPropertyName(name) as string;
556535
const weakMapName = createFileLevelUniqueName("_" + text.substring(1));
536+
hoistVariableDeclaration(weakMapName);
557537
env.set(name.escapedText, { type: PrivateNameType.InstanceField, weakMapName });
538+
(pendingExpressions || (pendingExpressions = [])).push(
539+
createAssignment(
540+
weakMapName,
541+
createNew(
542+
createIdentifier("WeakMap"),
543+
/*typeArguments*/ undefined,
544+
[]
545+
)
546+
)
547+
);
558548
}
559549

560550
function enableSubstitutionForClassAliases() {

0 commit comments

Comments
 (0)