Skip to content

Commit 2c8ef42

Browse files
author
Joseph Watts
committed
Add/improve comments, fix double visiting constructor
Signed-off-by: Joseph Watts <[email protected]>
1 parent d5c0477 commit 2c8ef42

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

src/compiler/transformers/esnext.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ namespace ts {
33
const enum ESNextSubstitutionFlags {
44
/** Enables substitutions for async methods with `super` calls. */
55
AsyncMethodsWithSuper = 1 << 0,
6-
/** Enables substitutions for class expressions with static fields which have initializers that reference the class name. */
6+
/**
7+
* Enables substitutions for class expressions with static fields
8+
* which have initializers that reference the class name.
9+
*/
710
ClassAliases = 1 << 1,
811
}
912

@@ -140,9 +143,11 @@ namespace ts {
140143
function classElementVisitor(node: Node): VisitResult<Node> {
141144
switch (node.kind) {
142145
case SyntaxKind.Constructor:
143-
// TypeScript constructors are transformed in `visitClassDeclaration`.
144-
// We elide them here as `visitorWorker` checks transform flags, which could
145-
// erronously include an ES6 constructor without ESNext syntax.
146+
// Constructors for classes using ESNext syntax (like class properties)
147+
// are transformed in `visitClassDeclaration` or `visitClassExpression`.
148+
// We elide them here. The default visitor checks the transformFlags to
149+
// determine whether the node contains ESNext syntax, so it can skip over
150+
// constructors.
146151
return undefined;
147152

148153
case SyntaxKind.PropertyDeclaration:
@@ -164,9 +169,8 @@ namespace ts {
164169
* If the name is a computed property, this function transforms it, then either returns an expression which caches the
165170
* value of the result or the expression itself if the value is either unused or safe to inline into multiple locations
166171
* @param shouldHoist Does the expression need to be reused? (ie, for an initializer or a decorator)
167-
* @param omitSimple Should expressions with no observable side-effects be elided? (ie, the expression is not hoisted for a decorator or initializer and is a literal)
168172
*/
169-
function getPropertyNameExpressionIfNeeded(name: PropertyName, shouldHoist: boolean, omitSimple: boolean): Expression | undefined {
173+
function getPropertyNameExpressionIfNeeded(name: PropertyName, shouldHoist: boolean): Expression | undefined {
170174
if (isComputedPropertyName(name)) {
171175
const expression = visitNode(name.expression, visitor, isExpression);
172176
const innerExpression = skipPartiallyEmittedExpressions(expression);
@@ -177,7 +181,7 @@ namespace ts {
177181
hoistVariableDeclaration(generatedName);
178182
return createAssignment(generatedName, expression);
179183
}
180-
return (omitSimple && (inlinable || isIdentifier(innerExpression))) ? undefined : expression;
184+
return (inlinable || isIdentifier(innerExpression)) ? undefined : expression;
181185
}
182186
}
183187

@@ -197,7 +201,10 @@ namespace ts {
197201

198202
function visitPropertyDeclaration(node: PropertyDeclaration) {
199203
Debug.assert(!some(node.decorators));
200-
const expr = getPropertyNameExpressionIfNeeded(node.name, !!node.initializer, /*omitSimple*/ true);
204+
// Create a temporary variable to store a computed property name (if necessary).
205+
// If it's not inlineable, then we emit an expression after the class which assigns
206+
// the property name to the temporary variable.
207+
const expr = getPropertyNameExpressionIfNeeded(node.name, !!node.initializer);
201208
if (expr && !isSimpleInlineableExpression(expr)) {
202209
(pendingExpressions || (pendingExpressions = [])).push(expr);
203210
}
@@ -326,7 +333,7 @@ namespace ts {
326333
function transformConstructor(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) {
327334
const constructor = visitNode(getFirstConstructorWithBody(node), visitor, isConstructorDeclaration);
328335
if (!(node.transformFlags & TransformFlags.ContainsPropertyInitializer)) {
329-
return visitEachChild(constructor, visitor, context);
336+
return constructor;
330337
}
331338
const parameters = visitParameterList(constructor ? constructor.parameters : undefined, visitor, context);
332339
const body = transformConstructorBody(node, constructor, isDerivedClass);

0 commit comments

Comments
 (0)