mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Add 'Remove unnecessary await' suggestion and fix (#32363)
* Add remove unnecessary await fix * Add test for removing unnecessary parens after await is gone * Fix handling of numbers in property access expressions * Don’t offer suggestion when awaited type is any/unknown * Fix random other test * Fix new expression edge cases * Only remove parens for identifiers and call expressions
This commit is contained in:
parent
60a1b1dc1a
commit
89badcc9d5
@ -26403,7 +26403,11 @@ namespace ts {
|
||||
* The runtime behavior of the `await` keyword.
|
||||
*/
|
||||
function checkAwaitedType(type: Type, errorNode: Node, diagnosticMessage: DiagnosticMessage, arg0?: string | number): Type {
|
||||
return getAwaitedType(type, errorNode, diagnosticMessage, arg0) || errorType;
|
||||
const awaitedType = getAwaitedType(type, errorNode, diagnosticMessage, arg0);
|
||||
if (awaitedType === type && !(type.flags & TypeFlags.AnyOrUnknown)) {
|
||||
addErrorOrSuggestion(/*isError*/ false, createDiagnosticForNode(errorNode, Diagnostics.await_has_no_effect_on_the_type_of_this_expression));
|
||||
}
|
||||
return awaitedType || errorType;
|
||||
}
|
||||
|
||||
function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined {
|
||||
|
||||
@ -4635,6 +4635,11 @@
|
||||
"category": "Suggestion",
|
||||
"code": 80006
|
||||
},
|
||||
"'await' has no effect on the type of this expression.": {
|
||||
"category": "Suggestion",
|
||||
"code": 80007
|
||||
},
|
||||
|
||||
"Add missing 'super()' call": {
|
||||
"category": "Message",
|
||||
"code": 90001
|
||||
@ -5095,6 +5100,14 @@
|
||||
"category": "Message",
|
||||
"code": 95085
|
||||
},
|
||||
"Remove unnecessary 'await'": {
|
||||
"category": "Message",
|
||||
"code": 95086
|
||||
},
|
||||
"Remove all unnecessary uses of 'await'": {
|
||||
"category": "Message",
|
||||
"code": 95087
|
||||
},
|
||||
|
||||
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
|
||||
"category": "Error",
|
||||
|
||||
33
src/services/codefixes/removeUnnecessaryAwait.ts
Normal file
33
src/services/codefixes/removeUnnecessaryAwait.ts
Normal file
@ -0,0 +1,33 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixId = "removeUnnecessaryAwait";
|
||||
const errorCodes = [
|
||||
Diagnostics.await_has_no_effect_on_the_type_of_this_expression.code,
|
||||
];
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions: (context) => {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span));
|
||||
if (changes.length > 0) {
|
||||
return [createCodeFixAction(fixId, changes, Diagnostics.Remove_unnecessary_await, fixId, Diagnostics.Remove_all_unnecessary_uses_of_await)];
|
||||
}
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => {
|
||||
return codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag));
|
||||
},
|
||||
});
|
||||
|
||||
function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan) {
|
||||
const awaitKeyword = tryCast(getTokenAtPosition(sourceFile, span.start), (node): node is AwaitKeywordToken => node.kind === SyntaxKind.AwaitKeyword);
|
||||
const awaitExpression = awaitKeyword && tryCast(awaitKeyword.parent, isAwaitExpression);
|
||||
if (!awaitExpression) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parenthesizedExpression = tryCast(awaitExpression.parent, isParenthesizedExpression);
|
||||
const removeParens = parenthesizedExpression && (isIdentifier(awaitExpression.expression) || isCallExpression(awaitExpression.expression));
|
||||
changeTracker.replaceNode(sourceFile, removeParens ? parenthesizedExpression || awaitExpression : awaitExpression, awaitExpression.expression);
|
||||
}
|
||||
}
|
||||
@ -80,6 +80,7 @@
|
||||
"codefixes/useDefaultImport.ts",
|
||||
"codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
"codefixes/convertToMappedObjectType.ts",
|
||||
"codefixes/removeUnnecessaryAwait.ts",
|
||||
"refactors/convertExport.ts",
|
||||
"refactors/convertImport.ts",
|
||||
"refactors/extractSymbol.ts",
|
||||
|
||||
40
tests/cases/fourslash/codeFixRemoveUnnecessaryAwait.ts
Normal file
40
tests/cases/fourslash/codeFixRemoveUnnecessaryAwait.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
////declare class C { foo(): void }
|
||||
////declare function foo(): string;
|
||||
////async function f() {
|
||||
//// await "";
|
||||
//// await 0;
|
||||
//// (await foo()).toLowerCase();
|
||||
//// (await 0).toFixed();
|
||||
//// (await new C).foo();
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Remove_unnecessary_await.message,
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`declare class C { foo(): void }
|
||||
declare function foo(): string;
|
||||
async function f() {
|
||||
"";
|
||||
await 0;
|
||||
(await foo()).toLowerCase();
|
||||
(await 0).toFixed();
|
||||
(await new C).foo();
|
||||
}`
|
||||
});
|
||||
|
||||
verify.codeFixAll({
|
||||
fixAllDescription: ts.Diagnostics.Remove_all_unnecessary_uses_of_await.message,
|
||||
fixId: "removeUnnecessaryAwait",
|
||||
newFileContent:
|
||||
`declare class C { foo(): void }
|
||||
declare function foo(): string;
|
||||
async function f() {
|
||||
"";
|
||||
0;
|
||||
foo().toLowerCase();
|
||||
(0).toFixed();
|
||||
(new C).foo();
|
||||
}`
|
||||
});
|
||||
@ -2,13 +2,14 @@
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: test123.js
|
||||
// @lib: es5
|
||||
////export function /**/MyClass() {
|
||||
////}
|
||||
////MyClass.prototype.foo = async function() {
|
||||
//// await 2;
|
||||
//// await Promise.resolve();
|
||||
////}
|
||||
////MyClass.bar = async function() {
|
||||
//// await 3;
|
||||
//// await Promise.resolve();
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
@ -18,10 +19,10 @@ verify.codeFix({
|
||||
constructor() {
|
||||
}
|
||||
async foo() {
|
||||
await 2;
|
||||
await Promise.resolve();
|
||||
}
|
||||
static async bar() {
|
||||
await 3;
|
||||
await Promise.resolve();
|
||||
}
|
||||
}
|
||||
`,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user