From 2327e60197af7bc4aba830c55000fca530456806 Mon Sep 17 00:00:00 2001 From: j4k0xb <55899582+j4k0xb@users.noreply.github.com> Date: Sat, 2 Nov 2024 14:43:08 +0100 Subject: [PATCH] fix: inline variable with multiple assignments (#121) --- packages/webcrack/src/ast-utils/inline.ts | 36 +++++++++++-------- .../src/ast-utils/test/inline.test.ts | 14 ++++++++ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/packages/webcrack/src/ast-utils/inline.ts b/packages/webcrack/src/ast-utils/inline.ts index 3b220ec3..cc0720b8 100644 --- a/packages/webcrack/src/ast-utils/inline.ts +++ b/packages/webcrack/src/ast-utils/inline.ts @@ -36,21 +36,29 @@ export function inlineVariable( ref.replaceWith(varDeclarator.init!); }); binding.path.remove(); - } else if ( - unsafeAssignments && - binding.constantViolations.length === 1 && - assignmentMatcher.match(binding.constantViolations[0]?.node) - ) { - const assignment = binding - .constantViolations[0] as NodePath; - binding.referencePaths.forEach((ref) => { - ref.replaceWith(assignment.node.right); - }); - if (assignment.parentPath.isExpressionStatement()) { - assignment.remove(); - } else { - assignment.replaceWith(assignment.node.right); + } else if (unsafeAssignments && binding.constantViolations.length >= 1) { + const assignments = binding.constantViolations + .map((path) => path.node) + .filter((node) => assignmentMatcher.match(node)); + if (!assignments.length) return; + + function getNearestAssignment(location: number) { + return assignments.findLast((assignment) => assignment.start! < location); + } + + for (const ref of binding.referencePaths) { + const assignment = getNearestAssignment(ref.node.start!); + if (assignment) ref.replaceWith(assignment.right); } + + for (const path of binding.constantViolations) { + if (path.parentPath?.isExpressionStatement()) { + path.remove(); + } else if (path.isAssignmentExpression()) { + path.replaceWith(path.node.right); + } + } + binding.path.remove(); } } diff --git a/packages/webcrack/src/ast-utils/test/inline.test.ts b/packages/webcrack/src/ast-utils/test/inline.test.ts index 5909610d..902f87e3 100644 --- a/packages/webcrack/src/ast-utils/test/inline.test.ts +++ b/packages/webcrack/src/ast-utils/test/inline.test.ts @@ -31,6 +31,20 @@ test('inline variable with assignment', () => { expect(ast).toMatchInlineSnapshot(`let b = 1;`); }); +test('inline variable with multiple assignments', () => { + const ast = parse('let a; a = 1; let b = a; a = 2; let c = a; a = 3;'); + traverse(ast, { + Program(path) { + const binding = path.scope.getBinding('a')!; + inlineVariable(binding, undefined, true); + }, + }); + expect(ast).toMatchInlineSnapshot(` + let b = 1; + let c = 2; + `); +}); + test('inline variable with assignment in an expression', () => { const ast = parse('let a; x = a = 1; let b = a;'); traverse(ast, {