Skip to content

Commit

Permalink
feat: merge swtich transformation into un-if-statement`
Browse files Browse the repository at this point in the history
  • Loading branch information
pionxzh committed Sep 3, 2023
1 parent 44929a5 commit 0e04d01
Show file tree
Hide file tree
Showing 6 changed files with 638 additions and 676 deletions.
27 changes: 14 additions & 13 deletions packages/unminify/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,31 +172,32 @@ Flips comparisons that are in the form of "literal comes first" to "literal come

### `un-if-statement`

Unwraps nested ternary expressions into if-else statements.\
Conditionally returns early if possible.
Unwraps nested ternary expressions into if-else statements.

```diff
- a ? b() : c ? d() : e()
+ if(a) {
+ if (a) {
+ b();
+ } else if(c) {
+ } else if (c) {
+ d();
+ } else {
+ e();
+ }
```

This rule will try to do more by adopting `Early Exit` pattern (on statement level).
This rule will try to adopting `Early Exit` pattern if possible.

```diff
- a ? b() : c ? d() : e()
+ if(a) {
+ b();
+ }
+ if(c) {
+ d();
+ }
+ e();
while (condition) {
- return a ? b() : c ? d() : e()
+ if (a) {
+ return b();
+ }
+ if (c) {
+ return d();
+ }
+ return e();
}
```

### `un-switch-statement`
Expand Down
259 changes: 247 additions & 12 deletions packages/unminify/src/transformations/__tests__/un-if-statement.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,7 @@ import { defineInlineTest } from './test-utils'

const inlineTest = defineInlineTest(transform)

// inlineTest('return simple logical expression',
// `
// return x == 'a' || x == 'b' || x == 'c' && x == 'd'
// `,
// `
// if (!)
// `,
// )

inlineTest('simple ternary expression',
inlineTest('simple ternary expression #1',
`
x ? a() : b()
`,
Expand All @@ -25,11 +16,31 @@ if (x) {
`,
)

inlineTest('simple ternary expression #2',
`
obj[foo] = cond ? 10 : 20;
cond ? obj[bar] = 10 : obj[bar] = 20;
`,
`
obj[foo] = cond ? 10 : 20;
if (cond) {
obj[bar] = 10;
} else {
obj[bar] = 20;
}
`,
)

inlineTest('simple logical expression',
`
x && a();
x || b();
x ?? c();
!x && a();
!x || b();
!x ?? c();
`,
`
if (x) {
Expand All @@ -43,10 +54,22 @@ if (!x) {
if (x == null) {
c();
}
if (!x) {
a();
}
if (!!x) {
b();
}
if (!x == null) {
c();
}
`,
)

inlineTest('nested ternary expression',
inlineTest('nested ternary expression #1',
`
a ? b() : c ? d() : e() ? g ? h() : i() : j()
`,
Expand All @@ -67,6 +90,89 @@ if (a) {
`,
)

inlineTest('nested ternary expression #2',
`
a ? b() : c ? d() : e() && (g || h());
`,
`
if (a) {
b();
} else if (c) {
d();
} else if (e()) {
if (!g) {
h();
}
}
`,
)

inlineTest('nested ternary expression #3',
`
foo ? x() : bar ? y() : baz && z();
foo ? x() : bar ? y() : baz ? z() : t();
`,
`
if (foo) {
x();
} else if (bar) {
y();
} else if (baz) {
z();
}
if (foo) {
x();
} else if (bar) {
y();
} else if (baz) {
z();
} else {
t();
}
`,
)

inlineTest('nested ternary expression #4',
`
a() && b() ? c() : d();
a() && b() && c();
`,
`
if (a() && b()) {
c();
} else {
d();
}
if (a() && b()) {
c();
}
`,
)

inlineTest('nested ternary expression #5',
`
(foo && bar) ? x() : y();
(foo && bar) ? x() : (baz || t) ? y() : z();
`,
`
if ((foo && bar)) {
x();
} else {
y();
}
if ((foo && bar)) {
x();
} else if ((baz || t)) {
y();
} else {
z();
}
`,
)

inlineTest('nested ternary expression with early return',
`
for (var i = 0; i < 10; i++) {
Expand All @@ -84,9 +190,19 @@ for (var i = 0; i < 10; i++) {
}
return e();
}
`,
)

// inlineTest('return simple logical expression',
// `
// return x == 'a' || x == 'b' || x == 'c' && x == 'd'
// `,
// `
// if (!)
// `,
// )

inlineTest('nested logical expression',
`
x == 'a' || x == 'b' || x == 'c' && x == 'd'
Expand All @@ -96,7 +212,7 @@ x == 'a' || x == 'b' || x == 'c' && x == 'd'
`,
)

inlineTest('should not transform if statement',
inlineTest('should not transform these cases',
`
var foo = x && a();
Expand Down Expand Up @@ -174,3 +290,122 @@ if (x) {
}
`,
)

inlineTest('should transform ternary to switch statement',
`
foo == 'bar'
? bar()
: foo == 'baz'
? baz()
: foo == 'qux'
? qux()
: quux()
`,
`
switch (foo) {
case 'bar':
bar();
break;
case 'baz':
baz();
break;
case 'qux':
qux();
break;
default:
quux();
break;
}
`,
)

inlineTest('should transform ternary which contains multiple conditions to switch statement',
`
foo == 'bar'
? bar()
: foo == 'baz' || foo == 'baz2'
? baz()
: foo == 'qux1' || foo == 'qux2' || foo == 'qux3'
? qux()
: foo == 'quy4' || foo == 'quy5' || foo == 'quy6'
? quy()
: quc()
`,
`
switch (foo) {
case 'bar':
bar();
break;
case 'baz':
case 'baz2':
baz();
break;
case 'qux1':
case 'qux2':
case 'qux3':
qux();
break;
case 'quy4':
case 'quy5':
case 'quy6':
quy();
break;
default:
quc();
break;
}
`,
)

inlineTest('should transform ternary which contains multiple conditions to switch statement (no default)',
`
foo == 'bar'
? bar()
: foo == 'baz'
? baz()
: foo == 'qux' || foo == 'quux' && qux();
`,
`
switch (foo) {
case 'bar':
bar();
break;
case 'baz':
baz();
break;
case 'qux':
case 'quux':
qux();
break;
}
`,
)

inlineTest('should transform to switch statement with multiple first cases', `
e === 2 || e === 9
? foo()
: e === 3
? bar()
: e === 4 || e === 5
? baz()
: fail(e);
`,
`
switch (e) {
case 2:
case 9:
foo();
break;
case 3:
bar();
break;
case 4:
case 5:
baz();
break;
default:
fail(e);
break;
}
`,
)
Loading

0 comments on commit 0e04d01

Please sign in to comment.