Just insert the keyword

This commit is contained in:
Andy Hanson 2018-01-08 13:49:12 -08:00
parent 10d2f20225
commit 13195190fc
10 changed files with 55 additions and 51 deletions

View file

@ -3845,7 +3845,7 @@
},
"Convert to async": {
"category": "Message",
"code": 90028
"code": 90029
},
"Convert function to an ES2015 class": {
"category": "Message",

View file

@ -9,44 +9,33 @@ namespace ts.codefix {
errorCodes,
getCodeActions(context) {
const { sourceFile, span } = context;
const node = getNode(sourceFile, span.start);
const node = getNodeToInsertBefore(sourceFile, span.start);
if (!node) return undefined;
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, node));
return [{ description: getLocaleSpecificMessage(Diagnostics.Convert_to_async), changes, fixId }];
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) =>
doChange(changes, context.sourceFile, getNode(diag.file, diag.start!))),
doChange(changes, context.sourceFile, getNodeToInsertBefore(diag.file, diag.start!))),
});
function getNode(sourceFile: SourceFile, pos: number): FunctionLikeDeclaration {
function getNodeToInsertBefore(sourceFile: SourceFile, pos: number): Node | undefined {//name
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
const containingFunction = getContainingFunction(token);
if (!isFunctionLikeDeclaration(containingFunction) ||
isConstructorDeclaration(containingFunction) ||
isGetAccessorDeclaration(containingFunction) ||
isSetAccessorDeclaration(containingFunction)) return;
return containingFunction;
switch (containingFunction.kind) {
case SyntaxKind.MethodDeclaration:
return containingFunction.name;
case SyntaxKind.FunctionExpression:
case SyntaxKind.FunctionDeclaration:
return findChildOfKind(containingFunction, SyntaxKind.FunctionKeyword, sourceFile);
case SyntaxKind.ArrowFunction:
return findChildOfKind(containingFunction, SyntaxKind.OpenParenToken, sourceFile) || first(containingFunction.parameters);
default:
return undefined;
}
}
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, decl: FunctionLikeDeclaration) {
const asyncToken = createToken(SyntaxKind.AsyncKeyword);
const modifiers = decl.modifiers ? decl.modifiers.concat(asyncToken) : createNodeArray([asyncToken]);
let changed;
switch (decl.kind) {
case SyntaxKind.MethodDeclaration:
changed = createMethod(decl.decorators, modifiers, decl.asteriskToken, decl.name, decl.questionToken, decl.typeParameters, decl.parameters, decl.type, decl.body);
break;
case SyntaxKind.FunctionExpression:
changed = createFunctionExpression(modifiers, decl.asteriskToken, decl.name, decl.typeParameters, decl.parameters, decl.type, decl.body);
break;
case SyntaxKind.FunctionDeclaration:
changed = createFunctionDeclaration(decl.decorators, modifiers, decl.asteriskToken, decl.name, decl.typeParameters, decl.parameters, decl.type, decl.body);
break;
case SyntaxKind.ArrowFunction:
changed = createArrowFunction(modifiers, decl.typeParameters, decl.parameters, decl.type, decl.equalsGreaterThanToken, decl.body);
break;
}
changes.replaceNode(sourceFile, decl, changed);
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, insertBefore: Node): void {
changes.insertModifierBefore(sourceFile, SyntaxKind.AsyncKeyword, insertBefore);
}
}

View file

@ -345,6 +345,11 @@ namespace ts.textChanges {
return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween));
}
public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void {
const pos = before.getStart(sourceFile);
this.replaceWithSingle(sourceFile, pos, pos, createToken(modifier), { suffix: " " });
}
public changeIdentifierToPropertyAccess(sourceFile: SourceFile, prefix: string, node: Identifier): void {
const startPosition = getAdjustedStartPosition(sourceFile, node, {}, Position.Start);
this.replaceWithSingle(sourceFile, startPosition, startPosition, createPropertyAccess(createIdentifier(prefix), ""), {});

View file

@ -6,9 +6,8 @@
verify.codeFix({
description: "Convert to async",
index: 0,
newFileContent:
`async function f() {\r
await Promise.resolve();\r
`async function f() {
await Promise.resolve();
}`,
});

View file

@ -7,10 +7,9 @@
verify.codeFix({
description: "Convert to async",
index: 0,
newFileContent:
`const f = async function() {\r
await Promise.resolve();\r
await Promise.resolve();\r
`const f = async function() {
await Promise.resolve();
await Promise.resolve();
}`,
});

View file

@ -8,10 +8,10 @@
verify.codeFix({
description: "Convert to async",
index: 0,
newFileContent:
`class Foo {
async bar() {\r
await Promise.resolve();\r
}}`,
async bar() {
await Promise.resolve();
}
}`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
////const f = promise => {
//// await promise;
////}
verify.codeFix({
description: "Convert to async",
newFileContent:
`const f = async promise => {
await promise;
}`,
});

View file

@ -6,9 +6,8 @@
verify.codeFix({
description: "Convert to async",
index: 0,
newFileContent:
`const f = async (promise) => {\r
await promise;\r
`const f = async (promise) => {
await promise;
}`,
});

View file

@ -8,11 +8,10 @@
verify.codeFix({
description: "Convert to async",
index: 0,
newFileContent:
`function f() => {\r
for await (const x of g()) {\r
console.log(x);\r
}\r
`async function f() {
for await (const x of g()) {
console.log(x);
}
}`,
});

View file

@ -11,10 +11,11 @@
verify.codeFixAll({
fixId: "fixAwaitInSyncFunction",
newFileContent:
`async function f() {\r
await Promise.resolve();\r
`async function f() {
await Promise.resolve();
}
const g = async () => {\r
await f();\r
const g = async () => {
await f();
}`,
});