More rigorous ASI prevention when emitting return/yield (#60304)

This commit is contained in:
Ron Buckton
2024-10-22 19:20:51 -04:00
committed by GitHub
parent a62ac67b50
commit 1679f4481d
7 changed files with 789 additions and 10 deletions
+83 -10
View File
@@ -3226,17 +3226,90 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
* Wraps an expression in parens if we would emit a leading comment that would introduce a line separator
* between the node and its parent.
*/
function parenthesizeExpressionForNoAsi(node: Expression) {
if (!commentsDisabled && isPartiallyEmittedExpression(node) && willEmitLeadingNewLine(node)) {
const parseNode = getParseTreeNode(node);
if (parseNode && isParenthesizedExpression(parseNode)) {
// If the original node was a parenthesized expression, restore it to preserve comment and source map emit
const parens = factory.createParenthesizedExpression(node.expression);
setOriginalNode(parens, node);
setTextRange(parens, parseNode);
return parens;
function parenthesizeExpressionForNoAsi(node: Expression): Expression {
if (!commentsDisabled) {
switch (node.kind) {
case SyntaxKind.PartiallyEmittedExpression:
if (willEmitLeadingNewLine(node)) {
const parseNode = getParseTreeNode(node);
if (parseNode && isParenthesizedExpression(parseNode)) {
// If the original node was a parenthesized expression, restore it to preserve comment and source map emit
const parens = factory.createParenthesizedExpression((node as PartiallyEmittedExpression).expression);
setOriginalNode(parens, node);
setTextRange(parens, parseNode);
return parens;
}
return factory.createParenthesizedExpression(node);
}
return factory.updatePartiallyEmittedExpression(
node as PartiallyEmittedExpression,
parenthesizeExpressionForNoAsi((node as PartiallyEmittedExpression).expression),
);
case SyntaxKind.PropertyAccessExpression:
return factory.updatePropertyAccessExpression(
node as PropertyAccessExpression,
parenthesizeExpressionForNoAsi((node as PropertyAccessExpression).expression),
(node as PropertyAccessExpression).name,
);
case SyntaxKind.ElementAccessExpression:
return factory.updateElementAccessExpression(
node as ElementAccessExpression,
parenthesizeExpressionForNoAsi((node as ElementAccessExpression).expression),
(node as ElementAccessExpression).argumentExpression,
);
case SyntaxKind.CallExpression:
return factory.updateCallExpression(
node as CallExpression,
parenthesizeExpressionForNoAsi((node as CallExpression).expression),
(node as CallExpression).typeArguments,
(node as CallExpression).arguments,
);
case SyntaxKind.TaggedTemplateExpression:
return factory.updateTaggedTemplateExpression(
node as TaggedTemplateExpression,
parenthesizeExpressionForNoAsi((node as TaggedTemplateExpression).tag),
(node as TaggedTemplateExpression).typeArguments,
(node as TaggedTemplateExpression).template,
);
case SyntaxKind.PostfixUnaryExpression:
return factory.updatePostfixUnaryExpression(
node as PostfixUnaryExpression,
parenthesizeExpressionForNoAsi((node as PostfixUnaryExpression).operand),
);
case SyntaxKind.BinaryExpression:
return factory.updateBinaryExpression(
node as BinaryExpression,
parenthesizeExpressionForNoAsi((node as BinaryExpression).left),
(node as BinaryExpression).operatorToken,
(node as BinaryExpression).right,
);
case SyntaxKind.ConditionalExpression:
return factory.updateConditionalExpression(
node as ConditionalExpression,
parenthesizeExpressionForNoAsi((node as ConditionalExpression).condition),
(node as ConditionalExpression).questionToken,
(node as ConditionalExpression).whenTrue,
(node as ConditionalExpression).colonToken,
(node as ConditionalExpression).whenFalse,
);
case SyntaxKind.AsExpression:
return factory.updateAsExpression(
node as AsExpression,
parenthesizeExpressionForNoAsi((node as AsExpression).expression),
(node as AsExpression).type,
);
case SyntaxKind.SatisfiesExpression:
return factory.updateSatisfiesExpression(
node as SatisfiesExpression,
parenthesizeExpressionForNoAsi((node as SatisfiesExpression).expression),
(node as SatisfiesExpression).type,
);
case SyntaxKind.NonNullExpression:
return factory.updateNonNullExpression(
node as NonNullExpression,
parenthesizeExpressionForNoAsi((node as NonNullExpression).expression),
);
}
return factory.createParenthesizedExpression(node);
}
return node;
}