mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
feat(51870): Add a Quick Fix to add an additional parameter to a method or function (#56411)
This commit is contained in:
parent
55153b0274
commit
140fa7e5d1
@ -7792,6 +7792,30 @@
|
||||
"category": "Message",
|
||||
"code": 95187
|
||||
},
|
||||
"Add missing parameter to '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95188
|
||||
},
|
||||
"Add missing parameters to '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95189
|
||||
},
|
||||
"Add all missing parameters": {
|
||||
"category": "Message",
|
||||
"code": 95190
|
||||
},
|
||||
"Add optional parameter to '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95191
|
||||
},
|
||||
"Add optional parameters to '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95192
|
||||
},
|
||||
"Add all optional parameters": {
|
||||
"category": "Message",
|
||||
"code": 95193
|
||||
},
|
||||
|
||||
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
|
||||
"category": "Error",
|
||||
|
||||
@ -31,6 +31,7 @@ export * from "../codefixes/fixSpelling";
|
||||
export * from "../codefixes/returnValueCorrect";
|
||||
export * from "../codefixes/fixAddMissingMember";
|
||||
export * from "../codefixes/fixAddMissingNewOperator";
|
||||
export * from "../codefixes/fixAddMissingParam";
|
||||
export * from "../codefixes/fixCannotFindModule";
|
||||
export * from "../codefixes/fixClassDoesntImplementInheritedAbstractMember";
|
||||
export * from "../codefixes/fixClassSuperMustPrecedeThisAccess";
|
||||
|
||||
327
src/services/codefixes/fixAddMissingParam.ts
Normal file
327
src/services/codefixes/fixAddMissingParam.ts
Normal file
@ -0,0 +1,327 @@
|
||||
import {
|
||||
append,
|
||||
ArrowFunction,
|
||||
CodeFixAction,
|
||||
declarationNameToString,
|
||||
Diagnostics,
|
||||
factory,
|
||||
filter,
|
||||
findAncestor,
|
||||
first,
|
||||
forEach,
|
||||
FunctionDeclaration,
|
||||
FunctionExpression,
|
||||
FunctionLikeDeclaration,
|
||||
getNameOfAccessExpression,
|
||||
getNameOfDeclaration,
|
||||
getTokenAtPosition,
|
||||
isAccessExpression,
|
||||
isCallExpression,
|
||||
isIdentifier,
|
||||
isParameter,
|
||||
isPropertyDeclaration,
|
||||
isSourceFileFromLibrary,
|
||||
isVariableDeclaration,
|
||||
last,
|
||||
lastOrUndefined,
|
||||
length,
|
||||
map,
|
||||
MethodDeclaration,
|
||||
Node,
|
||||
NodeBuilderFlags,
|
||||
ParameterDeclaration,
|
||||
Program,
|
||||
QuestionToken,
|
||||
some,
|
||||
SourceFile,
|
||||
SyntaxKind,
|
||||
textChanges,
|
||||
Type,
|
||||
TypeChecker,
|
||||
TypeNode,
|
||||
} from "../_namespaces/ts";
|
||||
import {
|
||||
codeFixAll,
|
||||
createCodeFixAction,
|
||||
registerCodeFix,
|
||||
} from "../_namespaces/ts.codefix";
|
||||
|
||||
const addMissingParamFixId = "addMissingParam";
|
||||
const addOptionalParamFixId = "addOptionalParam";
|
||||
const errorCodes = [Diagnostics.Expected_0_arguments_but_got_1.code];
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
fixIds: [addMissingParamFixId, addOptionalParamFixId],
|
||||
getCodeActions(context) {
|
||||
const info = getInfo(context.sourceFile, context.program, context.span.start);
|
||||
if (info === undefined) return undefined;
|
||||
|
||||
const { name, declarations, newParameters, newOptionalParameters } = info;
|
||||
const actions: CodeFixAction[] = [];
|
||||
|
||||
if (length(newParameters)) {
|
||||
append(
|
||||
actions,
|
||||
createCodeFixAction(
|
||||
addMissingParamFixId,
|
||||
textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, declarations, newParameters)),
|
||||
[length(newParameters) > 1 ? Diagnostics.Add_missing_parameters_to_0 : Diagnostics.Add_missing_parameter_to_0, name],
|
||||
addMissingParamFixId,
|
||||
Diagnostics.Add_all_missing_parameters,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (length(newOptionalParameters)) {
|
||||
append(
|
||||
actions,
|
||||
createCodeFixAction(
|
||||
addOptionalParamFixId,
|
||||
textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, declarations, newOptionalParameters)),
|
||||
[length(newOptionalParameters) > 1 ? Diagnostics.Add_optional_parameters_to_0 : Diagnostics.Add_optional_parameter_to_0, name],
|
||||
addOptionalParamFixId,
|
||||
Diagnostics.Add_all_optional_parameters,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return actions;
|
||||
},
|
||||
getAllCodeActions: context =>
|
||||
codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
const info = getInfo(context.sourceFile, context.program, diag.start);
|
||||
if (info) {
|
||||
const { declarations, newParameters, newOptionalParameters } = info;
|
||||
if (context.fixId === addMissingParamFixId) {
|
||||
doChange(changes, context.sourceFile, declarations, newParameters);
|
||||
}
|
||||
if (context.fixId === addOptionalParamFixId) {
|
||||
doChange(changes, context.sourceFile, declarations, newOptionalParameters);
|
||||
}
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
type ConvertibleSignatureDeclaration =
|
||||
| FunctionDeclaration
|
||||
| FunctionExpression
|
||||
| ArrowFunction
|
||||
| MethodDeclaration;
|
||||
|
||||
interface SignatureInfo {
|
||||
readonly newParameters: ParameterInfo[];
|
||||
readonly newOptionalParameters: ParameterInfo[];
|
||||
readonly name: string;
|
||||
readonly declarations: ConvertibleSignatureDeclaration[];
|
||||
}
|
||||
|
||||
interface ParameterInfo {
|
||||
readonly pos: number;
|
||||
readonly declaration: ParameterDeclaration;
|
||||
}
|
||||
|
||||
function getInfo(sourceFile: SourceFile, program: Program, pos: number): SignatureInfo | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
const callExpression = findAncestor(token, isCallExpression);
|
||||
if (callExpression === undefined || length(callExpression.arguments) === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const checker = program.getTypeChecker();
|
||||
const type = checker.getTypeAtLocation(callExpression.expression);
|
||||
const convertibleSignatureDeclarations = filter(type.symbol.declarations, isConvertibleSignatureDeclaration);
|
||||
if (convertibleSignatureDeclarations === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const nonOverloadDeclaration = lastOrUndefined(convertibleSignatureDeclarations);
|
||||
if (
|
||||
nonOverloadDeclaration === undefined ||
|
||||
nonOverloadDeclaration.body === undefined ||
|
||||
isSourceFileFromLibrary(program, nonOverloadDeclaration.getSourceFile())
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const name = tryGetName(nonOverloadDeclaration);
|
||||
if (name === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const newParameters: ParameterInfo[] = [];
|
||||
const newOptionalParameters: ParameterInfo[] = [];
|
||||
const parametersLength = length(nonOverloadDeclaration.parameters);
|
||||
const argumentsLength = length(callExpression.arguments);
|
||||
if (parametersLength > argumentsLength) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const declarations = [nonOverloadDeclaration, ...getOverloads(nonOverloadDeclaration, convertibleSignatureDeclarations)];
|
||||
for (let i = 0, pos = 0, paramIndex = 0; i < argumentsLength; i++) {
|
||||
const arg = callExpression.arguments[i];
|
||||
const expr = isAccessExpression(arg) ? getNameOfAccessExpression(arg) : arg;
|
||||
const type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(arg)));
|
||||
const parameter = pos < parametersLength ? nonOverloadDeclaration.parameters[pos] : undefined;
|
||||
if (
|
||||
parameter &&
|
||||
checker.isTypeAssignableTo(type, checker.getTypeAtLocation(parameter))
|
||||
) {
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const name = expr && isIdentifier(expr) ? expr.text : `p${paramIndex++}`;
|
||||
const typeNode = typeToTypeNode(checker, type, nonOverloadDeclaration);
|
||||
append(newParameters, {
|
||||
pos: i,
|
||||
declaration: createParameter(name, typeNode, /*questionToken*/ undefined),
|
||||
});
|
||||
|
||||
if (isOptionalPos(declarations, pos)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
append(newOptionalParameters, {
|
||||
pos: i,
|
||||
declaration: createParameter(name, typeNode, factory.createToken(SyntaxKind.QuestionToken)),
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
newParameters,
|
||||
newOptionalParameters,
|
||||
name: declarationNameToString(name),
|
||||
declarations,
|
||||
};
|
||||
}
|
||||
|
||||
function tryGetName(node: FunctionLikeDeclaration) {
|
||||
const name = getNameOfDeclaration(node);
|
||||
if (name) {
|
||||
return name;
|
||||
}
|
||||
|
||||
if (
|
||||
isVariableDeclaration(node.parent) && isIdentifier(node.parent.name) ||
|
||||
isPropertyDeclaration(node.parent) ||
|
||||
isParameter(node.parent)
|
||||
) {
|
||||
return node.parent.name;
|
||||
}
|
||||
}
|
||||
|
||||
function typeToTypeNode(checker: TypeChecker, type: Type, enclosingDeclaration: Node) {
|
||||
return checker.typeToTypeNode(checker.getWidenedType(type), enclosingDeclaration, NodeBuilderFlags.NoTruncation)
|
||||
?? factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword);
|
||||
}
|
||||
|
||||
function doChange(
|
||||
changes: textChanges.ChangeTracker,
|
||||
sourceFile: SourceFile,
|
||||
declarations: ConvertibleSignatureDeclaration[],
|
||||
newParameters: ParameterInfo[],
|
||||
) {
|
||||
forEach(declarations, declaration => {
|
||||
if (length(declaration.parameters)) {
|
||||
changes.replaceNodeRangeWithNodes(
|
||||
sourceFile,
|
||||
first(declaration.parameters),
|
||||
last(declaration.parameters),
|
||||
updateParameters(declaration, newParameters),
|
||||
{
|
||||
joiner: ", ",
|
||||
indentation: 0,
|
||||
leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll,
|
||||
trailingTriviaOption: textChanges.TrailingTriviaOption.Include,
|
||||
},
|
||||
);
|
||||
}
|
||||
else {
|
||||
forEach(updateParameters(declaration, newParameters), (parameter, index) => {
|
||||
if (length(declaration.parameters) === 0 && index === 0) {
|
||||
changes.insertNodeAt(sourceFile, declaration.parameters.end, parameter);
|
||||
}
|
||||
else {
|
||||
changes.insertNodeAtEndOfList(sourceFile, declaration.parameters, parameter);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isConvertibleSignatureDeclaration(node: Node): node is ConvertibleSignatureDeclaration {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function updateParameters(node: ConvertibleSignatureDeclaration, newParameters: readonly ParameterInfo[]) {
|
||||
const parameters = map(node.parameters, p =>
|
||||
factory.createParameterDeclaration(
|
||||
p.modifiers,
|
||||
p.dotDotDotToken,
|
||||
p.name,
|
||||
p.questionToken,
|
||||
p.type,
|
||||
p.initializer,
|
||||
));
|
||||
for (const { pos, declaration } of newParameters) {
|
||||
const prev = pos > 0 ? parameters[pos - 1] : undefined;
|
||||
parameters.splice(
|
||||
pos,
|
||||
0,
|
||||
factory.updateParameterDeclaration(
|
||||
declaration,
|
||||
declaration.modifiers,
|
||||
declaration.dotDotDotToken,
|
||||
declaration.name,
|
||||
prev && prev.questionToken ? factory.createToken(SyntaxKind.QuestionToken) : declaration.questionToken,
|
||||
declaration.type,
|
||||
declaration.initializer,
|
||||
),
|
||||
);
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
function getOverloads(implementation: ConvertibleSignatureDeclaration, declarations: readonly ConvertibleSignatureDeclaration[]): ConvertibleSignatureDeclaration[] {
|
||||
const overloads: ConvertibleSignatureDeclaration[] = [];
|
||||
for (const declaration of declarations) {
|
||||
if (isOverload(declaration)) {
|
||||
if (length(declaration.parameters) === length(implementation.parameters)) {
|
||||
overloads.push(declaration);
|
||||
continue;
|
||||
}
|
||||
if (length(declaration.parameters) > length(implementation.parameters)) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
return overloads;
|
||||
}
|
||||
|
||||
function isOverload(declaration: ConvertibleSignatureDeclaration) {
|
||||
return isConvertibleSignatureDeclaration(declaration) && declaration.body === undefined;
|
||||
}
|
||||
|
||||
function createParameter(name: string, type: TypeNode, questionToken: QuestionToken | undefined) {
|
||||
return factory.createParameterDeclaration(
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
name,
|
||||
questionToken,
|
||||
type,
|
||||
/*initializer*/ undefined,
|
||||
);
|
||||
}
|
||||
|
||||
function isOptionalPos(declarations: ConvertibleSignatureDeclaration[], pos: number) {
|
||||
return length(declarations) && some(declarations, d => pos < length(d.parameters) && !!d.parameters[pos] && d.parameters[pos].questionToken === undefined);
|
||||
}
|
||||
@ -18,5 +18,5 @@ verify.signatureHelp({
|
||||
kind: "retrigger"
|
||||
}
|
||||
})
|
||||
verify.not.codeFixAvailable() // trigger typecheck
|
||||
verify.not.codeFixAvailable(); // trigger typecheck
|
||||
verify.errorExistsBetweenMarkers("1", "2");
|
||||
|
||||
12
tests/cases/fourslash/codeFixAddMissingParam1.ts
Normal file
12
tests/cases/fourslash/codeFixAddMissingParam1.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f() {}|]
|
||||
////
|
||||
////const a = 1;
|
||||
////f(a);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "f"],
|
||||
index: 0,
|
||||
newRangeContent: "function f(a: number) {}"
|
||||
});
|
||||
13
tests/cases/fourslash/codeFixAddMissingParam10.ts
Normal file
13
tests/cases/fourslash/codeFixAddMissingParam10.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f() {}|]
|
||||
////
|
||||
////const a = 1;
|
||||
////const b = "";
|
||||
////f(a, b, true);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameters_to_0.message, "f"],
|
||||
index: 0,
|
||||
newRangeContent: "function f(a: number, b: string, p0: boolean) {}"
|
||||
});
|
||||
14
tests/cases/fourslash/codeFixAddMissingParam11.ts
Normal file
14
tests/cases/fourslash/codeFixAddMissingParam11.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////class C {
|
||||
//// [|private p = () => {}|]
|
||||
//// m(a: boolean) {
|
||||
//// this.p(a);
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "p"],
|
||||
index: 0,
|
||||
newRangeContent: "private p = (a: boolean) => {}"
|
||||
});
|
||||
11
tests/cases/fourslash/codeFixAddMissingParam12.ts
Normal file
11
tests/cases/fourslash/codeFixAddMissingParam12.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f([|cb = () => {}|]) {
|
||||
//// cb("");
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "cb"],
|
||||
index: 0,
|
||||
newRangeContent: "cb = (p0: string) => {}"
|
||||
});
|
||||
20
tests/cases/fourslash/codeFixAddMissingParam13.ts
Normal file
20
tests/cases/fourslash/codeFixAddMissingParam13.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f(a: string): string;
|
||||
////function f(a: string, b: number): string;
|
||||
////function f(a: string, b?: number): string {
|
||||
//// return "";
|
||||
////}
|
||||
////f("", 1, "");
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "f"],
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`function f(a: string): string;
|
||||
function f(a: string, b: number, p0: string): string;
|
||||
function f(a: string, b?: number, p0?: string): string {
|
||||
return "";
|
||||
}
|
||||
f("", 1, "");`
|
||||
});
|
||||
20
tests/cases/fourslash/codeFixAddMissingParam14.ts
Normal file
20
tests/cases/fourslash/codeFixAddMissingParam14.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f(a: string): string;
|
||||
////function f(a: string, b: number): string;
|
||||
////function f(a: string, b?: number): string {
|
||||
//// return "";
|
||||
////}
|
||||
////f("", "", 1);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "f"],
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`function f(a: string): string;
|
||||
function f(a: string, p0: string, b: number): string;
|
||||
function f(a: string, p0: string, b?: number): string {
|
||||
return "";
|
||||
}
|
||||
f("", "", 1);`
|
||||
});
|
||||
6
tests/cases/fourslash/codeFixAddMissingParam15.ts
Normal file
6
tests/cases/fourslash/codeFixAddMissingParam15.ts
Normal file
@ -0,0 +1,6 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f(a: number, b: number) {}
|
||||
////f();
|
||||
|
||||
verify.not.codeFixAvailable("addMissingParam");
|
||||
20
tests/cases/fourslash/codeFixAddMissingParam16.ts
Normal file
20
tests/cases/fourslash/codeFixAddMissingParam16.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f(a: string, b: string): string
|
||||
////function f(a: number, b: number): number
|
||||
////function f(a: number | string, b: number | string): number | string {
|
||||
//// return a + b;
|
||||
////}
|
||||
////f(1, 2, "")
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "f"],
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`function f(a: string, b: string, p0: string): string
|
||||
function f(a: number, b: number, p0: string): number
|
||||
function f(a: number | string, b: number | string, p0: string): number | string {
|
||||
return a + b;
|
||||
}
|
||||
f(1, 2, "")`
|
||||
});
|
||||
13
tests/cases/fourslash/codeFixAddMissingParam2.ts
Normal file
13
tests/cases/fourslash/codeFixAddMissingParam2.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f(a: number) {}|]
|
||||
////
|
||||
////const a = 1;
|
||||
////const b = 1;
|
||||
////f(a, b);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "f"],
|
||||
index: 0,
|
||||
newRangeContent: "function f(a: number, b: number) {}"
|
||||
});
|
||||
16
tests/cases/fourslash/codeFixAddMissingParam3.ts
Normal file
16
tests/cases/fourslash/codeFixAddMissingParam3.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////class C {
|
||||
//// private a = 1;
|
||||
////
|
||||
//// [|m1() {}|]
|
||||
//// m2() {
|
||||
//// this.m1(this.a);
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "m1"],
|
||||
index: 0,
|
||||
newRangeContent: "m1(a: number) {}"
|
||||
});
|
||||
11
tests/cases/fourslash/codeFixAddMissingParam4.ts
Normal file
11
tests/cases/fourslash/codeFixAddMissingParam4.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f() {}|]
|
||||
////
|
||||
////f("");
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "f"],
|
||||
index: 0,
|
||||
newRangeContent: "function f(p0: string) {}"
|
||||
});
|
||||
11
tests/cases/fourslash/codeFixAddMissingParam5.ts
Normal file
11
tests/cases/fourslash/codeFixAddMissingParam5.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|const f = function () {}|]
|
||||
////
|
||||
////f("");
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "f"],
|
||||
index: 0,
|
||||
newRangeContent: "const f = function (p0: string) {}"
|
||||
});
|
||||
11
tests/cases/fourslash/codeFixAddMissingParam6.ts
Normal file
11
tests/cases/fourslash/codeFixAddMissingParam6.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|const f = () => {}|]
|
||||
////
|
||||
////f("");
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "f"],
|
||||
index: 0,
|
||||
newRangeContent: "const f = (p0: string) => {}"
|
||||
});
|
||||
14
tests/cases/fourslash/codeFixAddMissingParam7.ts
Normal file
14
tests/cases/fourslash/codeFixAddMissingParam7.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////class C {
|
||||
//// [|m1() {}|]
|
||||
//// m2(a: boolean) {
|
||||
//// this.m1(a);
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameter_to_0.message, "m1"],
|
||||
index: 0,
|
||||
newRangeContent: "m1(a: boolean) {}"
|
||||
});
|
||||
14
tests/cases/fourslash/codeFixAddMissingParam8.ts
Normal file
14
tests/cases/fourslash/codeFixAddMissingParam8.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f(a: number) {}|]
|
||||
////
|
||||
////const a = 1;
|
||||
////const b = 1;
|
||||
////const c = 1;
|
||||
////f(a, b, c);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameters_to_0.message, "f"],
|
||||
index: 0,
|
||||
newRangeContent: "function f(a: number, b: number, c: number) {}"
|
||||
});
|
||||
10
tests/cases/fourslash/codeFixAddMissingParam9.ts
Normal file
10
tests/cases/fourslash/codeFixAddMissingParam9.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f() {}|]
|
||||
////f("", { x: 1 }, [ "" ], true);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_missing_parameters_to_0.message, "f"],
|
||||
index: 0,
|
||||
newRangeContent: "function f(p0: string, p1: { x: number; }, p2: string[], p3: boolean) {}"
|
||||
});
|
||||
52
tests/cases/fourslash/codeFixAddMissingParam_all.ts
Normal file
52
tests/cases/fourslash/codeFixAddMissingParam_all.ts
Normal file
@ -0,0 +1,52 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////[|function f1() {}|]
|
||||
////
|
||||
////const a = 1;
|
||||
////const b = "";
|
||||
////f1(a, b, true);
|
||||
////
|
||||
////function f2() {}
|
||||
////f2("", { x: 1 }, [ "" ], true);
|
||||
////
|
||||
////class C {
|
||||
//// [|m1() {}|]
|
||||
//// m2(a: boolean) {
|
||||
//// this.m1(a);
|
||||
//// }
|
||||
////}
|
||||
////
|
||||
////function f3(a: string): string;
|
||||
////function f3(a: string, b: number): string;
|
||||
////function f3(a: string, b?: number): string {
|
||||
//// return "";
|
||||
////}
|
||||
////f3("", "", 1);
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "addMissingParam",
|
||||
fixAllDescription: ts.Diagnostics.Add_all_missing_parameters.message,
|
||||
newFileContent:
|
||||
`function f1(a: number, b: string, p0: boolean) {}
|
||||
|
||||
const a = 1;
|
||||
const b = "";
|
||||
f1(a, b, true);
|
||||
|
||||
function f2(p0: string, p1: { x: number; }, p2: string[], p3: boolean) {}
|
||||
f2("", { x: 1 }, [ "" ], true);
|
||||
|
||||
class C {
|
||||
m1(a: boolean) {}
|
||||
m2(a: boolean) {
|
||||
this.m1(a);
|
||||
}
|
||||
}
|
||||
|
||||
function f3(a: string): string;
|
||||
function f3(a: string, p0: string, b: number): string;
|
||||
function f3(a: string, p0: string, b?: number): string {
|
||||
return "";
|
||||
}
|
||||
f3("", "", 1);`
|
||||
});
|
||||
12
tests/cases/fourslash/codeFixAddOptionalParam1.ts
Normal file
12
tests/cases/fourslash/codeFixAddOptionalParam1.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f() {}|]
|
||||
////
|
||||
////const a = 1;
|
||||
////f(a);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "f"],
|
||||
index: 1,
|
||||
newRangeContent: "function f(a?: number) {}"
|
||||
});
|
||||
13
tests/cases/fourslash/codeFixAddOptionalParam10.ts
Normal file
13
tests/cases/fourslash/codeFixAddOptionalParam10.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f() {}|]
|
||||
////
|
||||
////const a = 1;
|
||||
////const b = "";
|
||||
////f(a, b, true);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameters_to_0.message, "f"],
|
||||
index: 1,
|
||||
newRangeContent: "function f(a?: number, b?: string, p0?: boolean) {}"
|
||||
});
|
||||
14
tests/cases/fourslash/codeFixAddOptionalParam11.ts
Normal file
14
tests/cases/fourslash/codeFixAddOptionalParam11.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////class C {
|
||||
//// [|private p = () => {}|]
|
||||
//// m(a: boolean) {
|
||||
//// this.p(a);
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "p"],
|
||||
index: 1,
|
||||
newRangeContent: "private p = (a?: boolean) => {}"
|
||||
});
|
||||
11
tests/cases/fourslash/codeFixAddOptionalParam12.ts
Normal file
11
tests/cases/fourslash/codeFixAddOptionalParam12.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f([|cb = () => {}|]) {
|
||||
//// cb("");
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "cb"],
|
||||
index: 1,
|
||||
newRangeContent: "cb = (p0?: string) => {}"
|
||||
});
|
||||
20
tests/cases/fourslash/codeFixAddOptionalParam13.ts
Normal file
20
tests/cases/fourslash/codeFixAddOptionalParam13.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f(a: string): string;
|
||||
////function f(a: string, b: number): string;
|
||||
////function f(a: string, b?: number): string {
|
||||
//// return "";
|
||||
////}
|
||||
////f("", 1, "");
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "f"],
|
||||
index: 1,
|
||||
newFileContent:
|
||||
`function f(a: string): string;
|
||||
function f(a: string, b: number, p0?: string): string;
|
||||
function f(a: string, b?: number, p0?: string): string {
|
||||
return "";
|
||||
}
|
||||
f("", 1, "");`
|
||||
});
|
||||
10
tests/cases/fourslash/codeFixAddOptionalParam14.ts
Normal file
10
tests/cases/fourslash/codeFixAddOptionalParam14.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f(a: string): string;
|
||||
////function f(a: string, b: number): string;
|
||||
////function f(a: string, b?: number): string {
|
||||
//// return "";
|
||||
////}
|
||||
////f("", "", 1);
|
||||
|
||||
verify.not.codeFixAvailable("addOptionalParam");
|
||||
6
tests/cases/fourslash/codeFixAddOptionalParam15.ts
Normal file
6
tests/cases/fourslash/codeFixAddOptionalParam15.ts
Normal file
@ -0,0 +1,6 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f(a: number, b: number) {}
|
||||
////f();
|
||||
|
||||
verify.not.codeFixAvailable("addOptionalParam");
|
||||
20
tests/cases/fourslash/codeFixAddOptionalParam16.ts
Normal file
20
tests/cases/fourslash/codeFixAddOptionalParam16.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f(a: string): string;
|
||||
////function f(a: string, b?: number): string;
|
||||
////function f(a: string, b?: number): string {
|
||||
//// return "";
|
||||
////}
|
||||
////f("", "", 1);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "f"],
|
||||
index: 1,
|
||||
newFileContent:
|
||||
`function f(a: string): string;
|
||||
function f(a: string, p0?: string, b?: number): string;
|
||||
function f(a: string, p0?: string, b?: number): string {
|
||||
return "";
|
||||
}
|
||||
f("", "", 1);`
|
||||
});
|
||||
20
tests/cases/fourslash/codeFixAddOptionalParam17.ts
Normal file
20
tests/cases/fourslash/codeFixAddOptionalParam17.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function f(a: string, b: string): string
|
||||
////function f(a: number, b: number): number
|
||||
////function f(a: number | string, b: number | string): number | string {
|
||||
//// return a + b;
|
||||
////}
|
||||
////f(1, 2, "")
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "f"],
|
||||
index: 1,
|
||||
newFileContent:
|
||||
`function f(a: string, b: string, p0?: string): string
|
||||
function f(a: number, b: number, p0?: string): number
|
||||
function f(a: number | string, b: number | string, p0?: string): number | string {
|
||||
return a + b;
|
||||
}
|
||||
f(1, 2, "")`
|
||||
});
|
||||
6
tests/cases/fourslash/codeFixAddOptionalParam18.ts
Normal file
6
tests/cases/fourslash/codeFixAddOptionalParam18.ts
Normal file
@ -0,0 +1,6 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f(a: number, c: string) {}|]
|
||||
////f(1, 1, "");
|
||||
|
||||
verify.not.codeFixAvailable("addOptionalParam");
|
||||
13
tests/cases/fourslash/codeFixAddOptionalParam2.ts
Normal file
13
tests/cases/fourslash/codeFixAddOptionalParam2.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f(a: number) {}|]
|
||||
////
|
||||
////const a = 1;
|
||||
////const b = 1;
|
||||
////f(a, b);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "f"],
|
||||
index: 1,
|
||||
newRangeContent: "function f(a: number, b?: number) {}"
|
||||
});
|
||||
16
tests/cases/fourslash/codeFixAddOptionalParam3.ts
Normal file
16
tests/cases/fourslash/codeFixAddOptionalParam3.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////class C {
|
||||
//// private a = 1;
|
||||
////
|
||||
//// [|m1() {}|]
|
||||
//// m2() {
|
||||
//// this.m1(this.a);
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "m1"],
|
||||
index: 1,
|
||||
newRangeContent: "m1(a?: number) {}"
|
||||
});
|
||||
11
tests/cases/fourslash/codeFixAddOptionalParam4.ts
Normal file
11
tests/cases/fourslash/codeFixAddOptionalParam4.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f() {}|]
|
||||
////
|
||||
////f("");
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "f"],
|
||||
index: 1,
|
||||
newRangeContent: "function f(p0?: string) {}"
|
||||
});
|
||||
11
tests/cases/fourslash/codeFixAddOptionalParam5.ts
Normal file
11
tests/cases/fourslash/codeFixAddOptionalParam5.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|const f = function () {}|]
|
||||
////
|
||||
////f("");
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "f"],
|
||||
index: 1,
|
||||
newRangeContent: "const f = function (p0?: string) {}"
|
||||
});
|
||||
11
tests/cases/fourslash/codeFixAddOptionalParam6.ts
Normal file
11
tests/cases/fourslash/codeFixAddOptionalParam6.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|const f = () => {}|]
|
||||
////
|
||||
////f("");
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "f"],
|
||||
index: 1,
|
||||
newRangeContent: "const f = (p0?: string) => {}"
|
||||
});
|
||||
14
tests/cases/fourslash/codeFixAddOptionalParam7.ts
Normal file
14
tests/cases/fourslash/codeFixAddOptionalParam7.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////class C {
|
||||
//// [|m1() {}|]
|
||||
//// m2(a: boolean) {
|
||||
//// this.m1(a);
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameter_to_0.message, "m1"],
|
||||
index: 1,
|
||||
newRangeContent: "m1(a?: boolean) {}"
|
||||
});
|
||||
14
tests/cases/fourslash/codeFixAddOptionalParam8.ts
Normal file
14
tests/cases/fourslash/codeFixAddOptionalParam8.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f(a: number) {}|]
|
||||
////
|
||||
////const a = 1;
|
||||
////const b = 1;
|
||||
////const c = 1;
|
||||
////f(a, b, c);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameters_to_0.message, "f"],
|
||||
index: 1,
|
||||
newRangeContent: "function f(a: number, b?: number, c?: number) {}"
|
||||
});
|
||||
10
tests/cases/fourslash/codeFixAddOptionalParam9.ts
Normal file
10
tests/cases/fourslash/codeFixAddOptionalParam9.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////[|function f() {}|]
|
||||
////f("", { x: 1 }, [ "" ], true);
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Add_optional_parameters_to_0.message, "f"],
|
||||
index: 1,
|
||||
newRangeContent: "function f(p0?: string, p1?: { x: number; }, p2?: string[], p3?: boolean) {}"
|
||||
});
|
||||
52
tests/cases/fourslash/codeFixAddOptionalParam_all.ts
Normal file
52
tests/cases/fourslash/codeFixAddOptionalParam_all.ts
Normal file
@ -0,0 +1,52 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////[|function f1() {}|]
|
||||
////
|
||||
////const a = 1;
|
||||
////const b = "";
|
||||
////f1(a, b, true);
|
||||
////
|
||||
////function f2() {}
|
||||
////f2("", { x: 1 }, [ "" ], true);
|
||||
////
|
||||
////class C {
|
||||
//// [|m1() {}|]
|
||||
//// m2(a: boolean) {
|
||||
//// this.m1(a);
|
||||
//// }
|
||||
////}
|
||||
////
|
||||
////function f3(a: string): string;
|
||||
////function f3(a: string, b?: number): string;
|
||||
////function f3(a: string, b?: number): string {
|
||||
//// return "";
|
||||
////}
|
||||
////f3("", "", 1);
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "addOptionalParam",
|
||||
fixAllDescription: ts.Diagnostics.Add_all_optional_parameters.message,
|
||||
newFileContent:
|
||||
`function f1(a?: number, b?: string, p0?: boolean) {}
|
||||
|
||||
const a = 1;
|
||||
const b = "";
|
||||
f1(a, b, true);
|
||||
|
||||
function f2(p0?: string, p1?: { x: number; }, p2?: string[], p3?: boolean) {}
|
||||
f2("", { x: 1 }, [ "" ], true);
|
||||
|
||||
class C {
|
||||
m1(a?: boolean) {}
|
||||
m2(a: boolean) {
|
||||
this.m1(a);
|
||||
}
|
||||
}
|
||||
|
||||
function f3(a: string): string;
|
||||
function f3(a: string, p0?: string, b?: number): string;
|
||||
function f3(a: string, p0?: string, b?: number): string {
|
||||
return "";
|
||||
}
|
||||
f3("", "", 1);`
|
||||
});
|
||||
@ -13,4 +13,4 @@
|
||||
////f(new C())
|
||||
|
||||
|
||||
verify.rangeAfterCodeFix("x: number | C, y: undefined",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0);
|
||||
verify.rangeAfterCodeFix("x: number | C, y: undefined",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 1);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user