Skip to content

Commit

Permalink
feat: transform nullish coalescing default parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
j4k0xb committed Dec 29, 2023
1 parent aa262c0 commit e54edca
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 13 deletions.
5 changes: 5 additions & 0 deletions apps/docs/src/concepts/transpile.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ var _a$b; // [!code --]
a.b ?? c; // [!code ++]
```
```js
function foo(foo, qux = (_foo$bar => (_foo$bar = foo.bar) !== null && _foo$bar !== undefined ? _foo$bar : "qux")()) {} // [!code --]
function foo(foo, qux = foo.bar ?? "qux") {} // [!code ++]
```
## nullish-coalescing-assignment
```js
Expand Down
6 changes: 4 additions & 2 deletions packages/webcrack/src/ast-utils/matcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,14 @@ export function isReadonlyObject(
export function isTemporaryVariable(
binding: Binding | undefined,
references: number,
kind: 'var' | 'param' = 'var',
): binding is Binding {
return (
binding !== undefined &&
binding.references === references &&
binding.constantViolations.length === 1 &&
binding.path.isVariableDeclarator() &&
binding.path.node.init === null
(kind === 'var'
? binding.path.isVariableDeclarator() && binding.path.node.init === null
: binding.path.listKey === 'params' && binding.path.isIdentifier())
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,14 @@ test.todo('member expression (esbuild)', () =>
`),
);

test.todo('default param (Babel)', () =>
test('default param (Babel)', () =>
expectJS(`
function foo(foo, qux = (_foo$bar => (_foo$bar = foo.bar) !== null && _foo$bar !== void 0 ? _foo$bar : "qux")()) {}
function bar(bar, qux = bar !== null && bar !== void 0 ? bar : "qux") {}
function foo(foo, qux = (_foo$bar => (_foo$bar = foo.bar) !== null && _foo$bar !== undefined ? _foo$bar : "qux")()) {}
function bar(bar, qux = bar !== null && bar !== undefined ? bar : "qux") {}
`).toMatchInlineSnapshot(`
function foo(foo, qux = foo.bar ?? "qux") {}
function bar(bar, qux = bar ?? "qux") {}
`),
);
`));

// TODO: add unminify transform or different matchers?
test.todo('flipped', () =>
Expand Down
30 changes: 24 additions & 6 deletions packages/webcrack/src/transpile/transforms/nullish-coalescing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,36 @@ export default {
right,
);

const iifeMatcher = m.callExpression(
m.arrowFunctionExpression(
[m.fromCapture(tmpVar)],
m.anyExpression(),
false,
),
[],
);

return {
ConditionalExpression: {
exit(path) {
if (idMatcher.match(path.node)) {
const binding = path.scope.getBinding(tmpVar.current!.name);
if (!isTemporaryVariable(binding, 2)) return;

binding.path.remove();
path.replaceWith(
t.logicalExpression('??', left.current!, right.current!),
);
this.changes++;
if (
iifeMatcher.match(path.parentPath.parent) &&
isTemporaryVariable(binding, 2, 'param')
) {
path.parentPath.parentPath!.replaceWith(
t.logicalExpression('??', left.current!, right.current!),
);
this.changes++;
} else if (isTemporaryVariable(binding, 2, 'var')) {
binding.path.remove();
path.replaceWith(
t.logicalExpression('??', left.current!, right.current!),
);
this.changes++;
}
} else if (idLooseMatcher.match(path.node)) {
const binding = path.scope.getBinding(tmpVar.current!.name);
if (!isTemporaryVariable(binding, 1)) return;
Expand Down

0 comments on commit e54edca

Please sign in to comment.