Skip to content

Commit 990a7e7

Browse files
committed
fix: ignore simple chains with <= links
1 parent 9a401ed commit 990a7e7

File tree

8 files changed

+81
-7
lines changed

8 files changed

+81
-7
lines changed

src/asyncify.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import codeLength from './util/codeLength'
1010
import babelBugWorkarounds from './util/babelBugWorkarounds'
1111

1212
function asyncifyFunction(path: NodePath<t.Function>): void {
13-
if (returnsOrAwaitsPromises(path) || isPromiseHandler(path)) {
13+
if (returnsOrAwaitsPromises(path)) {
1414
path.node.async = true
1515
}
1616
const chains = findPromiseChains(path)

src/util/iterateChain.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import * as t from '@babel/types'
2+
import { NodePath } from '@babel/traverse'
3+
import { isPromiseMethodCall } from './predicates'
4+
5+
export default function* iterateChain(
6+
path: NodePath<t.CallExpression>
7+
): Iterable<NodePath<t.CallExpression>> {
8+
while (isPromiseMethodCall(path.node)) {
9+
yield path
10+
const callee = path.get('callee')
11+
if (callee.isMemberExpression()) {
12+
const object = (callee as NodePath<t.MemberExpression>).get('object')
13+
if (object.isCallExpression()) path = object
14+
else break
15+
}
16+
}
17+
}

src/util/shouldIgnoreChain.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,47 @@
11
import * as t from '@babel/types'
22
import { NodePath } from '@babel/traverse'
33
import generate from '@babel/generator'
4+
import iterateChain from './iterateChain'
5+
import getThenHandler from './getThenHandler'
6+
import getCatchHandler from './getCatchHandler'
7+
import getFinallyHandler from './getFinallyHandler'
8+
9+
function chainLength(path: NodePath<t.CallExpression>): number {
10+
let length = 0
11+
for (const link of iterateChain(path)) length++
12+
return length
13+
}
14+
15+
function isComplexHandler(path: NodePath<t.Expression> | null): boolean {
16+
if (!path || !path.isFunction()) return false
17+
const body = (path as NodePath<t.Function>).get('body')
18+
if (!body.isBlockStatement()) return false
19+
return (body as NodePath<t.BlockStatement>).node.body.length > 1
20+
}
21+
22+
function hasComplexHandlers(path: NodePath<t.CallExpression>): boolean {
23+
for (const link of iterateChain(path)) {
24+
if (
25+
isComplexHandler(getThenHandler(path)) ||
26+
isComplexHandler(getCatchHandler(path)) ||
27+
isComplexHandler(getFinallyHandler(path))
28+
)
29+
return true
30+
}
31+
return false
32+
}
433

534
export default function shouldIgnoreChain(
635
path: NodePath<t.CallExpression>
736
): boolean {
37+
const { parentPath } = path
38+
if (
39+
!parentPath.isReturnStatement() &&
40+
!parentPath.isAwaitExpression() &&
41+
!parentPath.isFunction()
42+
) {
43+
if (chainLength(path) <= 2 && !hasComplexHandlers(path)) return true
44+
}
845
const { ignoreChainsShorterThan } = path.state
946
return (
1047
ignoreChainsShorterThan != null &&

src/util/unwindCatch.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export default function unwindCatch(
3939
) as any
4040
}
4141
const handlerFunction = handler as NodePath<t.Function>
42+
handlerFunction.node.async = true
4243
const body = handlerFunction.get('body')
4344
if (
4445
body.isBlockStatement() &&

src/util/unwindFinally.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export default function unwindFinally(
2727
) as any
2828
}
2929
const handlerFunction = handler as NodePath<t.Function>
30+
handlerFunction.node.async = true
3031
const body = handlerFunction.get('body')
3132
if (body.isBlockStatement() && !convertConditionalReturns(body)) {
3233
return getPreceedingLink(link)

src/util/unwindThen.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export function unwindThen(
2222
}
2323

2424
if (handler.isFunction()) {
25+
handler.node.async = true
2526
const handlerFunction = handler as NodePath<t.Function>
2627
const input = handlerFunction.get('params')[0]
2728
const body = handlerFunction.get('body')

test/fixtures/ignoredSimpleChain.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const input = `
2+
function foo() {
3+
const bar = baz.then(x => x * 2).catch(err => {
4+
console.error(err.stack)
5+
})
6+
}
7+
`
8+
9+
export const options = {}
10+
11+
export const expected = input

test/fixtures/nonAwaitedChain.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
export const input = `
22
function foo() {
3-
const bar = baz.then(x => x * 2)
3+
const bar = baz.then(x => x * 2).catch(err => {
4+
console.error(err.stack)
5+
return 2
6+
})
47
}
58
`
69

7-
export const options = {
8-
ignoreChainsShorterThan: 10,
9-
}
10+
export const options = {}
1011

1112
export const expected = `
1213
function foo() {
1314
const bar = (async () => {
14-
const x = await baz
15-
return x * 2
15+
try {
16+
const x = await baz
17+
return x * 2
18+
} catch (err) {
19+
console.error(err.stack)
20+
return 2
21+
}
1622
})()
1723
}
1824
`

0 commit comments

Comments
 (0)