Skip to content

Commit

Permalink
fix: inline variable with multiple assignments (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
j4k0xb committed Nov 2, 2024
1 parent 4fb9c6b commit 2327e60
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 14 deletions.
36 changes: 22 additions & 14 deletions packages/webcrack/src/ast-utils/inline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<t.AssignmentExpression>;
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();
}
}
Expand Down
14 changes: 14 additions & 0 deletions packages/webcrack/src/ast-utils/test/inline.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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, {
Expand Down

0 comments on commit 2327e60

Please sign in to comment.