Skip to content

Commit

Permalink
feat: remove double not (#71)
Browse files Browse the repository at this point in the history
  • Loading branch information
j4k0xb committed Jun 6, 2024
1 parent bc42f4e commit 9440b92
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
22 changes: 22 additions & 0 deletions apps/docs/src/concepts/unminify.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,28 @@ if (x) {
1 // [!code ++]
```

## remove-double-not

```js
if (!!a) b(); // [!code --]
if (a) b(); // [!code ++]
```

```js
!!a ? b() : c(); // [!code --]
a ? b() : c(); // [!code ++]
```

```js
return !!!a; // [!code --]
return !a; // [!code ++]
```

```js
[].filter(a => !!a); // [!code --]
[].filter(a => a); // [!code ++]
```

## sequence

```js
Expand Down
33 changes: 33 additions & 0 deletions packages/webcrack/src/unminify/test/remove-double-not.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { test } from 'vitest';
import { testTransform } from '../../../test';
import removeDoubleNot from '../transforms/remove-double-not';

const expectJS = testTransform(removeDoubleNot);

test('if statement', () =>
expectJS(`
if (!!a) {}
`).toMatchInlineSnapshot(`
if (a) {}
`));

test('ternary', () =>
expectJS(`
!!a ? b : c;
`).toMatchInlineSnapshot(`
a ? b : c;
`));

test('triple not', () =>
expectJS(`
return !!!a;
`).toMatchInlineSnapshot(`
return !a;
`));

test('array filter', () =>
expectJS(`
[].filter(a => !!a);
`).toMatchInlineSnapshot(`
[].filter(a => a);
`));
1 change: 1 addition & 0 deletions packages/webcrack/src/unminify/transforms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { default as mergeElseIf } from './merge-else-if';
export { default as mergeStrings } from './merge-strings';
export { default as numberExpressions } from './number-expressions';
export { default as rawLiterals } from './raw-literals';
export { default as removeDoubleNot } from './remove-double-not';
export { default as sequence } from './sequence';
export { default as splitForLoopVars } from './split-for-loop-vars';
export { default as splitVariableDeclarations } from './split-variable-declarations';
Expand Down
61 changes: 61 additions & 0 deletions packages/webcrack/src/unminify/transforms/remove-double-not.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { NodePath } from '@babel/traverse';
import * as t from '@babel/types';
import * as m from '@codemod/matchers';
import { constMemberExpression, type Transform } from '../../ast-utils';

export default {
name: 'remove-double-not',
tags: ['safe'],
visitor() {
const expression = m.capture(m.anyExpression());
const doubleNot = m.unaryExpression(
'!',
m.unaryExpression('!', expression),
);
const tripleNot = m.unaryExpression('!', doubleNot);
const arrayCall = m.callExpression(
constMemberExpression(
m.arrayExpression(),
m.or(
'filter',
'find',
'findLast',
'findIndex',
'findLastIndex',
'some',
'every',
),
),
[m.arrowFunctionExpression(m.anything(), doubleNot)],
);

return {
Conditional: {
exit(path) {
if (doubleNot.match(path.node.test)) {
path.get('test').replaceWith(expression.current!);
this.changes++;
}
},
},
UnaryExpression: {
exit(path) {
if (tripleNot.match(path.node)) {
path.replaceWith(t.unaryExpression('!', expression.current!));
this.changes++;
}
},
},
CallExpression: {
exit(path) {
if (arrayCall.match(path.node)) {
(path.get('arguments.0.body') as NodePath).replaceWith(
expression.current!,
);
this.changes++;
}
},
},
};
},
} satisfies Transform;

0 comments on commit 9440b92

Please sign in to comment.