Skip to content

Commit 75d4290

Browse files
committed
Merge branch 'yonran-fix-async-getter-setter'
2 parents b10f84c + 3c4daed commit 75d4290

File tree

5 files changed

+71
-7
lines changed

5 files changed

+71
-7
lines changed

src/asyncify.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import unwindPromiseChain from './util/unwindPromiseChain'
88
import finalCleanup from './util/finalCleanup'
99
import codeLength from './util/codeLength'
1010
import babelBugWorkarounds from './util/babelBugWorkarounds'
11+
import isGetterOrSetter from './util/isGetterOrSetter'
1112

1213
function asyncifyFunction(path: NodePath<t.Function>): void {
13-
if (returnsOrAwaitsPromises(path)) {
14+
if (returnsOrAwaitsPromises(path) && !isGetterOrSetter(path)) {
1415
path.node.async = true
1516
}
1617
const chains = findPromiseChains(path)

src/util/isGetterOrSetter.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as t from '@babel/types'
2+
import { NodePath } from '@babel/traverse'
3+
4+
export default function isGetterOrSetter(
5+
path: NodePath<t.Function> | null
6+
): boolean {
7+
return (
8+
path !== null &&
9+
(path.isObjectMethod() || path.isClassMethod()) &&
10+
(path.node.kind === 'get' || path.node.kind === 'set')
11+
)
12+
}

src/util/shouldIgnoreChain.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import iterateChain from './iterateChain'
55
import getThenHandler from './getThenHandler'
66
import getCatchHandler from './getCatchHandler'
77
import getFinallyHandler from './getFinallyHandler'
8+
import isGetterOrSetter from './isGetterOrSetter'
89

910
function chainLength(path: NodePath<t.CallExpression>): number {
1011
let length = 0
@@ -36,9 +37,10 @@ export default function shouldIgnoreChain(
3637
): boolean {
3738
const { parentPath } = path
3839
if (
39-
!parentPath.isReturnStatement() &&
40-
!parentPath.isAwaitExpression() &&
41-
!parentPath.isFunction()
40+
(!parentPath.isReturnStatement() &&
41+
!parentPath.isAwaitExpression() &&
42+
!parentPath.isFunction()) ||
43+
isGetterOrSetter(path.getFunctionParent())
4244
) {
4345
if (chainLength(path) <= 2 && !hasComplexHandlers(path)) return true
4446
}

src/util/unwindPromiseChain.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ import { unwindThen } from './unwindThen'
99
import unwindFinally from './unwindFinally'
1010
import parentStatement from './parentStatement'
1111
import replaceWithImmediatelyInvokedAsyncArrowFunction from './replaceWithImmediatelyInvokedAsyncArrowFunction'
12+
import isGetterOrSetter from './isGetterOrSetter'
1213

1314
export default function unwindPromiseChain(
1415
path: NodePath<t.CallExpression>
1516
): void {
1617
if (
17-
!path.parentPath.isAwaitExpression() &&
18-
!path.parentPath.isReturnStatement() &&
19-
!path.parentPath.isFunction()
18+
(!path.parentPath.isAwaitExpression() &&
19+
!path.parentPath.isReturnStatement() &&
20+
!path.parentPath.isFunction()) ||
21+
isGetterOrSetter(path.getFunctionParent())
2022
) {
2123
path = replaceWithImmediatelyInvokedAsyncArrowFunction(path)[1]
2224
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
export const input = `
2+
class A {
3+
method() {return p.then(x => f(x))}
4+
get prop() {return p.then(x => f(x))}
5+
set prop(val) {return p.then(x => f(x))}
6+
get longchain() {return p.then(x => f(x)).then(y => g(y)).then(z => h(z))}
7+
}
8+
const obj = {
9+
method() {return p.then(x => f(x))},
10+
get prop() {return p.then(x => f(x))},
11+
set prop(val) {return p.then(x => f(x))}
12+
};
13+
`
14+
export const expected = `
15+
class A {
16+
async method() {
17+
const x = await p;
18+
return f(x);
19+
}
20+
get prop() {
21+
return p.then(x => f(x))
22+
}
23+
set prop(val) {
24+
return p.then(x => f(x))
25+
}
26+
get longchain() {
27+
return (async () => {
28+
const x = await p
29+
const y = await f(x)
30+
const z = await g(y)
31+
return await h(z)
32+
})()
33+
}
34+
}
35+
const obj = {
36+
async method() {
37+
const x = await p;
38+
return f(x);
39+
},
40+
get prop() {
41+
return p.then(x => f(x))
42+
},
43+
set prop(val) {
44+
return p.then(x => f(x))
45+
}
46+
};
47+
`

0 commit comments

Comments
 (0)