mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 11:24:29 -05:00
Fix emit for nested object rest in assignment pattern (#52922)
This commit is contained in:
@@ -58,6 +58,7 @@ import {
|
||||
ConstructorDeclaration,
|
||||
ConstructorTypeNode,
|
||||
ConstructSignatureDeclaration,
|
||||
containsObjectRestOrSpread,
|
||||
ContinueStatement,
|
||||
createBaseNodeFactory,
|
||||
createNodeConverters,
|
||||
@@ -114,7 +115,6 @@ import {
|
||||
getAllUnscopedEmitHelpers,
|
||||
getBuildInfo,
|
||||
getCommentRange,
|
||||
getElementsOfBindingOrAssignmentPattern,
|
||||
getEmitFlags,
|
||||
getIdentifierTypeArguments,
|
||||
getJSDocTypeAliasName,
|
||||
@@ -124,7 +124,6 @@ import {
|
||||
getSourceMapRange,
|
||||
getSyntheticLeadingComments,
|
||||
getSyntheticTrailingComments,
|
||||
getTargetOfBindingOrAssignmentElement,
|
||||
getTextOfIdentifierOrLiteral,
|
||||
hasInvalidEscape,
|
||||
HasModifiers,
|
||||
@@ -150,7 +149,6 @@ import {
|
||||
isArray,
|
||||
isArrayLiteralExpression,
|
||||
isArrowFunction,
|
||||
isAssignmentPattern,
|
||||
isBinaryExpression,
|
||||
isCallChain,
|
||||
isClassDeclaration,
|
||||
@@ -3326,24 +3324,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
|
||||
}
|
||||
|
||||
function propagateAssignmentPatternFlags(node: AssignmentPattern): TransformFlags {
|
||||
if (node.transformFlags & TransformFlags.ContainsObjectRestOrSpread) return TransformFlags.ContainsObjectRestOrSpread;
|
||||
if (node.transformFlags & TransformFlags.ContainsES2018) {
|
||||
// check for nested spread assignments, otherwise '{ x: { a, ...b } = foo } = c'
|
||||
// will not be correctly interpreted by the ES2018 transformer
|
||||
for (const element of getElementsOfBindingOrAssignmentPattern(node)) {
|
||||
const target = getTargetOfBindingOrAssignmentElement(element);
|
||||
if (target && isAssignmentPattern(target)) {
|
||||
if (target.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
return TransformFlags.ContainsObjectRestOrSpread;
|
||||
}
|
||||
if (target.transformFlags & TransformFlags.ContainsES2018) {
|
||||
const flags = propagateAssignmentPatternFlags(target);
|
||||
if (flags) return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TransformFlags.None;
|
||||
return containsObjectRestOrSpread(node) ? TransformFlags.ContainsObjectRestOrSpread : TransformFlags.None;
|
||||
}
|
||||
|
||||
// @api
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
AssertionLevel,
|
||||
AssignmentExpression,
|
||||
AssignmentOperatorOrHigher,
|
||||
AssignmentPattern,
|
||||
BinaryExpression,
|
||||
BinaryOperator,
|
||||
BinaryOperatorToken,
|
||||
@@ -76,6 +77,7 @@ import {
|
||||
InternalEmitFlags,
|
||||
isAssignmentExpression,
|
||||
isAssignmentOperator,
|
||||
isAssignmentPattern,
|
||||
isBlock,
|
||||
isCommaListExpression,
|
||||
isComputedPropertyName,
|
||||
@@ -174,6 +176,7 @@ import {
|
||||
TextRange,
|
||||
ThisTypeNode,
|
||||
Token,
|
||||
TransformFlags,
|
||||
TypeNode,
|
||||
} from "../_namespaces/ts";
|
||||
|
||||
@@ -1742,3 +1745,31 @@ export function flattenCommaList(node: Expression) {
|
||||
flattenCommaListWorker(node, expressions);
|
||||
return expressions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk an AssignmentPattern to determine if it contains object rest (`...`) syntax. We cannot rely on
|
||||
* propagation of `TransformFlags.ContainsObjectRestOrSpread` since it isn't propagated by default in
|
||||
* ObjectLiteralExpression and ArrayLiteralExpression since we do not know whether they belong to an
|
||||
* AssignmentPattern at the time the nodes are parsed.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function containsObjectRestOrSpread(node: AssignmentPattern): boolean {
|
||||
if (node.transformFlags & TransformFlags.ContainsObjectRestOrSpread) return true;
|
||||
if (node.transformFlags & TransformFlags.ContainsES2018) {
|
||||
// check for nested spread assignments, otherwise '{ x: { a, ...b } = foo } = c'
|
||||
// will not be correctly interpreted by the ES2018 transformer
|
||||
for (const element of getElementsOfBindingOrAssignmentPattern(node)) {
|
||||
const target = getTargetOfBindingOrAssignmentElement(element);
|
||||
if (target && isAssignmentPattern(target)) {
|
||||
if (target.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
return true;
|
||||
}
|
||||
if (target.transformFlags & TransformFlags.ContainsES2018) {
|
||||
if (containsObjectRestOrSpread(target)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
concatenate,
|
||||
ConciseBody,
|
||||
ConstructorDeclaration,
|
||||
containsObjectRestOrSpread,
|
||||
createForOfBindingStatement,
|
||||
createSuperAccessVariableStatement,
|
||||
Debug,
|
||||
@@ -577,7 +578,7 @@ export function transformES2018(context: TransformationContext): (x: SourceFile
|
||||
* expression of an `ExpressionStatement`).
|
||||
*/
|
||||
function visitBinaryExpression(node: BinaryExpression, expressionResultIsUnused: boolean): Expression {
|
||||
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
if (isDestructuringAssignment(node) && containsObjectRestOrSpread(node.left)) {
|
||||
return flattenDestructuringAssignment(
|
||||
node,
|
||||
visitor,
|
||||
@@ -703,7 +704,8 @@ export function transformES2018(context: TransformationContext): (x: SourceFile
|
||||
*/
|
||||
function visitForOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined): VisitResult<Statement> {
|
||||
const ancestorFacts = enterSubtree(HierarchyFacts.IterationStatementExcludes, HierarchyFacts.IterationStatementIncludes);
|
||||
if (node.initializer.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
if (node.initializer.transformFlags & TransformFlags.ContainsObjectRestOrSpread ||
|
||||
isAssignmentPattern(node.initializer) && containsObjectRestOrSpread(node.initializer)) {
|
||||
node = transformForOfStatementWithObjectRest(node);
|
||||
}
|
||||
const result = node.awaitModifier ?
|
||||
|
||||
Reference in New Issue
Block a user