Skip to content

Commit e3a3ea0

Browse files
authored
fix(eslint-plugin): [promise-function-async] bad fixer with computed and literal methods (typescript-eslint#3163)
1 parent 6a25faf commit e3a3ea0

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

packages/eslint-plugin/src/rules/promise-function-async.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
AST_NODE_TYPES,
3+
AST_TOKEN_TYPES,
34
TSESTree,
45
} from '@typescript-eslint/experimental-utils';
56
import * as ts from 'typescript';
@@ -156,8 +157,40 @@ export default util.createRule<Options, MessageIds>({
156157
(node.parent.type === AST_NODE_TYPES.Property &&
157158
node.parent.method))
158159
) {
159-
return fixer.insertTextBefore(node.parent.key, 'async ');
160+
// this function is a class method or object function property shorthand
161+
const method = node.parent;
162+
163+
// the token to put `async` before
164+
let keyToken = sourceCode.getFirstToken(method)!;
165+
166+
// if there are decorators then skip past them
167+
if (
168+
method.type === AST_NODE_TYPES.MethodDefinition &&
169+
method.decorators
170+
) {
171+
const lastDecorator =
172+
method.decorators[method.decorators.length - 1];
173+
keyToken = sourceCode.getTokenAfter(lastDecorator)!;
174+
}
175+
176+
// if current token is a keyword like `static` or `public` then skip it
177+
while (keyToken.type === AST_TOKEN_TYPES.Keyword) {
178+
keyToken = sourceCode.getTokenAfter(keyToken)!;
179+
}
180+
181+
// check if there is a space between key and previous token
182+
const insertSpace = !sourceCode.isSpaceBetween!(
183+
sourceCode.getTokenBefore(keyToken)!,
184+
keyToken,
185+
);
186+
187+
let code = 'async ';
188+
if (insertSpace) {
189+
code = ` ${code}`;
190+
}
191+
return fixer.insertTextBefore(keyToken, code);
160192
}
193+
161194
return fixer.insertTextBefore(node, 'async ');
162195
},
163196
});

packages/eslint-plugin/tests/rules/promise-function-async.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { noFormat } from '@typescript-eslint/experimental-utils/src/eslint-utils';
12
import rule from '../../src/rules/promise-function-async';
23
import { getFixturesRootDir, RuleTester } from '../RuleTester';
34

@@ -630,6 +631,41 @@ class Test {
630631
public async test() {
631632
return Promise.resolve(123);
632633
}
634+
}
635+
`,
636+
},
637+
{
638+
code: noFormat`
639+
class Test {
640+
@decorator(async () => {})
641+
static protected[(1)]() {
642+
return Promise.resolve(1);
643+
}
644+
public'bar'() {
645+
return Promise.resolve(2);
646+
}
647+
private['baz']() {
648+
return Promise.resolve(3);
649+
}
650+
}
651+
`,
652+
errors: [
653+
{ line: 4, column: 3, messageId },
654+
{ line: 7, column: 3, messageId },
655+
{ line: 10, column: 3, messageId },
656+
],
657+
output: noFormat`
658+
class Test {
659+
@decorator(async () => {})
660+
static protected async [(1)]() {
661+
return Promise.resolve(1);
662+
}
663+
public async 'bar'() {
664+
return Promise.resolve(2);
665+
}
666+
private async ['baz']() {
667+
return Promise.resolve(3);
668+
}
633669
}
634670
`,
635671
},

0 commit comments

Comments
 (0)