Skip to content

Commit

Permalink
Merge branch 'yonran-fix-async-getter-setter'
Browse files Browse the repository at this point in the history
  • Loading branch information
jedwards1211 committed Aug 21, 2021
2 parents b10f84c + 3c4daed commit 75d4290
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 7 deletions.
3 changes: 2 additions & 1 deletion src/asyncify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import unwindPromiseChain from './util/unwindPromiseChain'
import finalCleanup from './util/finalCleanup'
import codeLength from './util/codeLength'
import babelBugWorkarounds from './util/babelBugWorkarounds'
import isGetterOrSetter from './util/isGetterOrSetter'

function asyncifyFunction(path: NodePath<t.Function>): void {
if (returnsOrAwaitsPromises(path)) {
if (returnsOrAwaitsPromises(path) && !isGetterOrSetter(path)) {
path.node.async = true
}
const chains = findPromiseChains(path)
Expand Down
12 changes: 12 additions & 0 deletions src/util/isGetterOrSetter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as t from '@babel/types'
import { NodePath } from '@babel/traverse'

export default function isGetterOrSetter(
path: NodePath<t.Function> | null
): boolean {
return (
path !== null &&
(path.isObjectMethod() || path.isClassMethod()) &&
(path.node.kind === 'get' || path.node.kind === 'set')
)
}
8 changes: 5 additions & 3 deletions src/util/shouldIgnoreChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import iterateChain from './iterateChain'
import getThenHandler from './getThenHandler'
import getCatchHandler from './getCatchHandler'
import getFinallyHandler from './getFinallyHandler'
import isGetterOrSetter from './isGetterOrSetter'

function chainLength(path: NodePath<t.CallExpression>): number {
let length = 0
Expand Down Expand Up @@ -36,9 +37,10 @@ export default function shouldIgnoreChain(
): boolean {
const { parentPath } = path
if (
!parentPath.isReturnStatement() &&
!parentPath.isAwaitExpression() &&
!parentPath.isFunction()
(!parentPath.isReturnStatement() &&
!parentPath.isAwaitExpression() &&
!parentPath.isFunction()) ||
isGetterOrSetter(path.getFunctionParent())
) {
if (chainLength(path) <= 2 && !hasComplexHandlers(path)) return true
}
Expand Down
8 changes: 5 additions & 3 deletions src/util/unwindPromiseChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import { unwindThen } from './unwindThen'
import unwindFinally from './unwindFinally'
import parentStatement from './parentStatement'
import replaceWithImmediatelyInvokedAsyncArrowFunction from './replaceWithImmediatelyInvokedAsyncArrowFunction'
import isGetterOrSetter from './isGetterOrSetter'

export default function unwindPromiseChain(
path: NodePath<t.CallExpression>
): void {
if (
!path.parentPath.isAwaitExpression() &&
!path.parentPath.isReturnStatement() &&
!path.parentPath.isFunction()
(!path.parentPath.isAwaitExpression() &&
!path.parentPath.isReturnStatement() &&
!path.parentPath.isFunction()) ||
isGetterOrSetter(path.getFunctionParent())
) {
path = replaceWithImmediatelyInvokedAsyncArrowFunction(path)[1]
}
Expand Down
47 changes: 47 additions & 0 deletions test/fixtures/bugs_GetterAndSetterCannotBeAsync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export const input = `
class A {
method() {return p.then(x => f(x))}
get prop() {return p.then(x => f(x))}
set prop(val) {return p.then(x => f(x))}
get longchain() {return p.then(x => f(x)).then(y => g(y)).then(z => h(z))}
}
const obj = {
method() {return p.then(x => f(x))},
get prop() {return p.then(x => f(x))},
set prop(val) {return p.then(x => f(x))}
};
`
export const expected = `
class A {
async method() {
const x = await p;
return f(x);
}
get prop() {
return p.then(x => f(x))
}
set prop(val) {
return p.then(x => f(x))
}
get longchain() {
return (async () => {
const x = await p
const y = await f(x)
const z = await g(y)
return await h(z)
})()
}
}
const obj = {
async method() {
const x = await p;
return f(x);
},
get prop() {
return p.then(x => f(x))
},
set prop(val) {
return p.then(x => f(x))
}
};
`

0 comments on commit 75d4290

Please sign in to comment.