try get add missing member return type from context (#26250)

* try get add missing member return type from context

* support contextual type
This commit is contained in:
Wenlu Wang 2018-08-24 12:31:53 +08:00 committed by Andy
parent 65da7e91e1
commit 8ba501926a
3 changed files with 43 additions and 13 deletions

View file

@ -112,27 +112,23 @@ namespace ts.codefix {
export function createMethodFromCallExpression(
context: CodeFixContextBase,
{ typeArguments, arguments: args, parent: parent }: CallExpression,
call: CallExpression,
methodName: string,
inJs: boolean,
makeStatic: boolean,
preferences: UserPreferences,
body: boolean,
): MethodDeclaration {
const { typeArguments, arguments: args, parent } = call;
const checker = context.program.getTypeChecker();
const types = map(args,
arg => {
let type = checker.getTypeAtLocation(arg);
if (type === undefined) {
return undefined;
}
// Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
type = checker.getBaseTypeOfLiteralType(type);
return checker.typeToTypeNode(type);
});
const types = map(args, arg =>
// Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(arg))));
const names = map(args, arg =>
isIdentifier(arg) ? arg.text :
isPropertyAccessExpression(arg) ? arg.name.text : undefined);
isPropertyAccessExpression(arg) ? arg.name.text : undefined);
const contextualType = checker.getContextualType(call);
const returnType = inJs ? undefined : contextualType && checker.typeToTypeNode(contextualType, call) || createKeywordTypeNode(SyntaxKind.AnyKeyword);
return createMethod(
/*decorators*/ undefined,
/*modifiers*/ makeStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined,
@ -142,7 +138,7 @@ namespace ts.codefix {
/*typeParameters*/ inJs ? undefined : map(typeArguments, (_, i) =>
createTypeParameterDeclaration(CharacterCodes.T + typeArguments!.length - 1 <= CharacterCodes.Z ? String.fromCharCode(CharacterCodes.T + i) : `T${i}`)),
/*parameters*/ createDummyParameters(args.length, names, types, /*minArgumentCount*/ undefined, inJs),
/*type*/ inJs ? undefined : createKeywordTypeNode(SyntaxKind.AnyKeyword),
/*type*/ returnType,
body ? createStubbedMethodBody(preferences) : undefined);
}

View file

@ -0,0 +1,16 @@
/// <reference path='fourslash.ts' />
//// class C {}
//// const n: number = new C().add(1, 2);
verify.codeFixAll({
fixId: "addMissingMember",
fixAllDescription: "Add all missing members",
newFileContent:
`class C {
add(arg0: number, arg1: number): number {
throw new Error("Method not implemented.");
}
}
const n: number = new C().add(1, 2);`,
});

View file

@ -0,0 +1,18 @@
/// <reference path='fourslash.ts' />
//// class C {}
//// function f(v: number): void { }
//// f(new C().add(1, 2))
verify.codeFixAll({
fixId: "addMissingMember",
fixAllDescription: "Add all missing members",
newFileContent:
`class C {
add(arg0: number, arg1: number): number {
throw new Error("Method not implemented.");
}
}
function f(v: number): void { }
f(new C().add(1, 2))`,
});