From b9180a067df9c94aca67c20623b35d564fdca8ab Mon Sep 17 00:00:00 2001 From: j4k0xb <55899582+j4k0xb@users.noreply.github.com> Date: Fri, 29 Dec 2023 21:22:58 +0100 Subject: [PATCH] feat: transform for loop to while loop --- apps/docs/src/concepts/unminify.md | 12 ++++++++++ .../src/unminify/test/for-to-while.test.ts | 20 ++++++++++++++++ .../src/unminify/transforms/for-to-while.ts | 23 +++++++++++++++++++ .../webcrack/src/unminify/transforms/index.ts | 1 + 4 files changed, 56 insertions(+) create mode 100644 packages/webcrack/src/unminify/test/for-to-while.test.ts create mode 100644 packages/webcrack/src/unminify/transforms/for-to-while.ts diff --git a/apps/docs/src/concepts/unminify.md b/apps/docs/src/concepts/unminify.md index 2c03ef09..fb7a0b47 100644 --- a/apps/docs/src/concepts/unminify.md +++ b/apps/docs/src/concepts/unminify.md @@ -20,6 +20,18 @@ console["log"](a); // [!code --] console.log(a); // [!code ++] ``` +## for-to-while + +```js +for (;;) a(); // [!code --] +while (true) a(); // [!code ++] +``` + +```js +for (; a < b;) c(); // [!code --] +while (a < b) c(); // [!code ++] +``` + ## infinity ```js diff --git a/packages/webcrack/src/unminify/test/for-to-while.test.ts b/packages/webcrack/src/unminify/test/for-to-while.test.ts new file mode 100644 index 00000000..56053667 --- /dev/null +++ b/packages/webcrack/src/unminify/test/for-to-while.test.ts @@ -0,0 +1,20 @@ +import { test } from 'vitest'; +import { testTransform } from '../../../test'; +import forToWhile from '../transforms/for-to-while'; + +const expectJS = testTransform(forToWhile); + +test('empty for loop to while true', () => + expectJS(`for (;;) b()`).toMatchInlineSnapshot(`while (true) b();`)); + +test('for loop with only test to while', () => + expectJS(`for (; a(); ) b();`).toMatchInlineSnapshot(`while (a()) b();`)); + +test('ignore for loop with init or update', () => + expectJS(` + for (let i = 0;;) {} + for (;; i++) {} + `).toMatchInlineSnapshot(` + for (let i = 0;;) {} + for (;; i++) {} + `)); diff --git a/packages/webcrack/src/unminify/transforms/for-to-while.ts b/packages/webcrack/src/unminify/transforms/for-to-while.ts new file mode 100644 index 00000000..12cbcdbe --- /dev/null +++ b/packages/webcrack/src/unminify/transforms/for-to-while.ts @@ -0,0 +1,23 @@ +import * as t from '@babel/types'; +import { Transform } from '../../ast-utils'; + +export default { + name: 'for-to-while', + tags: ['safe'], + visitor() { + return { + ForStatement: { + exit(path) { + const { test, body, init, update } = path.node; + if (init || update) return; + path.replaceWith( + test + ? t.whileStatement(test, body) + : t.whileStatement(t.booleanLiteral(true), body), + ); + this.changes++; + }, + }, + }; + }, +} satisfies Transform; diff --git a/packages/webcrack/src/unminify/transforms/index.ts b/packages/webcrack/src/unminify/transforms/index.ts index 63eb1552..76e892eb 100644 --- a/packages/webcrack/src/unminify/transforms/index.ts +++ b/packages/webcrack/src/unminify/transforms/index.ts @@ -1,5 +1,6 @@ export { default as blockStatements } from './block-statements'; export { default as computedProperties } from './computed-properties'; +export { default as forToWhile } from './for-to-while'; export { default as infinity } from './infinity'; export { default as invertBooleanLogic } from './invert-boolean-logic'; export { default as jsonParse } from './json-parse';