From 06afd8aa0aeee01e54e35e07bbb4ca76ba89f7a2 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Tue, 15 Jun 2021 12:38:14 +0300 Subject: [PATCH] fix assignment + destructiring regression (closes #2650) (#2651) * fix assignment + destructiring regression (closes #2650) * review --- src/processing/script/destructuring.ts | 19 ++++++++++++++----- src/processing/script/node-builder.ts | 4 +++- .../transformers/declaration-destructuring.ts | 5 +---- test/server/script-processor-test.js | 9 +++++++++ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/processing/script/destructuring.ts b/src/processing/script/destructuring.ts index e4c971e76..edfc7c3ad 100644 --- a/src/processing/script/destructuring.ts +++ b/src/processing/script/destructuring.ts @@ -22,7 +22,7 @@ import { import TempVariables from './transformers/temp-variables'; import INSTRUCTION from './instruction'; -type NodeBuilder = (pattern: Pattern, value: Expression, isTemp?: boolean) => void; +type NodeBuilder = (pattern: Pattern, value: Expression | null, isTemp?: boolean) => void; function processObjectProperty (prop: AssignmentProperty, temp: Identifier, build: NodeBuilder, baseTempName: string) { const pattern = prop.value; @@ -55,7 +55,10 @@ function createTempIdentifierOrUseExisting (value: Expression, build: NodeBuilde return tempIdentifier; } -function processObjectPattern (pattern: ObjectPattern, value: Expression, build: NodeBuilder, baseTempName?: string) { +function processObjectPattern (pattern: ObjectPattern, value: Expression | null, build: NodeBuilder, baseTempName?: string) { + if (!value) + return; + const properties = pattern.properties; const hasRest = properties.length && properties[properties.length - 1].type === Syntax.RestElement; const tempIdentifier = createTempIdentifierOrUseExisting(value, build, baseTempName); @@ -104,7 +107,10 @@ function processObjectPattern (pattern: ObjectPattern, value: Expression, build: } } -function processArrayPattern (pattern: ArrayPattern, value: Expression, build: NodeBuilder, baseTempName?: string) { +function processArrayPattern (pattern: ArrayPattern, value: Expression | null, build: NodeBuilder, baseTempName?: string) { + if (!value) + return; + const tempIdentifier = createTempIdentifierOrUseExisting(value, build, baseTempName); if (!baseTempName) @@ -127,7 +133,10 @@ function processArrayPattern (pattern: ArrayPattern, value: Expression, build: N } } -function processAssignmentPattern (pattern: AssignmentPattern, value: Expression, build: NodeBuilder, baseTempName?: string) { +function processAssignmentPattern (pattern: AssignmentPattern, value: Expression | null, build: NodeBuilder, baseTempName?: string) { + if (!value) + return; + const { left, right } = pattern; const tempIdentifier = createTempIdentifierOrUseExisting(value, build, baseTempName); const tempCondition = createBinaryExpression(tempIdentifier, '===', createUndefined()); @@ -141,7 +150,7 @@ function processAssignmentPattern (pattern: AssignmentPattern, value: Expression process(left, tempConditional, build, baseTempName); } -export default function process(pattern: Pattern, value: Expression, build: NodeBuilder, baseTempName?: string) { +export default function process(pattern: Pattern, value: Expression | null, build: NodeBuilder, baseTempName?: string) { if (pattern.type === Syntax.ObjectPattern) processObjectPattern(pattern, value, build, baseTempName); else if (pattern.type === Syntax.ArrayPattern) diff --git a/src/processing/script/node-builder.ts b/src/processing/script/node-builder.ts index 9f34e9eae..f47738732 100644 --- a/src/processing/script/node-builder.ts +++ b/src/processing/script/node-builder.ts @@ -46,7 +46,9 @@ export function createExpressionStatement (expression: Expression): ExpressionSt return { type: Syntax.ExpressionStatement, expression }; } -export function createAssignmentExpression (left: Pattern | MemberExpression, operator: AssignmentOperator, right: Expression): AssignmentExpression { +export function createAssignmentExpression (left: Pattern | MemberExpression, operator: AssignmentOperator, right: Expression | null): AssignmentExpression { + //@ts-ignore the `right` value can actually be null, but the AssignmentExpression type definition + // does not allow to the `right` value be null return { type: Syntax.AssignmentExpression, operator, left, right }; } diff --git a/src/processing/script/transformers/declaration-destructuring.ts b/src/processing/script/transformers/declaration-destructuring.ts index 434b83095..f552a524d 100644 --- a/src/processing/script/transformers/declaration-destructuring.ts +++ b/src/processing/script/transformers/declaration-destructuring.ts @@ -43,10 +43,7 @@ const transformer: Transformer = { const declarations = [] as VariableDeclarator[]; for (const declarator of node.declarations) { - if (!declarator.init) - continue; - - destructuring(declarator.id, declarator.init, (pattern, value) => + destructuring(declarator.id, declarator.init || null, (pattern, value) => declarations.push(createVariableDeclarator(pattern, value))); } diff --git a/test/server/script-processor-test.js b/test/server/script-processor-test.js index e2a4b6d73..37aaa87a0 100644 --- a/test/server/script-processor-test.js +++ b/test/server/script-processor-test.js @@ -1499,5 +1499,14 @@ describe('Script processor', () => { } ]); }); + + it('Should not lose empty var assignment with destructuring', () => { + testProcessing([ + { + src: 'var n, { q } = e; n();', + expected: 'var n,_hh$temp0 = e, q = _hh$temp0.q; n();' + } + ]); + }); }); });