mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-13 04:57:55 -06:00
Add 'fixAllDescription' property to CodeFixAction (#22616)
* Add 'fixAllDescription' property to CodeFixAction * Code review * Add to protocol * Make fixAllDescription be just a string
This commit is contained in:
parent
2cbad6ab06
commit
3e32e15895
@ -4026,5 +4026,101 @@
|
||||
"Add definite assignment assertion to property '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95020
|
||||
},
|
||||
"Add all missing members": {
|
||||
"category": "Message",
|
||||
"code": 95022
|
||||
},
|
||||
"Infer all types from usage": {
|
||||
"category": "Message",
|
||||
"code": 95023
|
||||
},
|
||||
"Delete all unused declarations": {
|
||||
"category": "Message",
|
||||
"code": 95024
|
||||
},
|
||||
"Prefix all unused declarations with '_' where possible": {
|
||||
"category": "Message",
|
||||
"code": 95025
|
||||
},
|
||||
"Fix all detected spelling errors": {
|
||||
"category": "Message",
|
||||
"code": 95026
|
||||
},
|
||||
"Add initializers to all uninitialized properties": {
|
||||
"category": "Message",
|
||||
"code": 95027
|
||||
},
|
||||
"Add definite assignment assertions to all uninitialized properties": {
|
||||
"category": "Message",
|
||||
"code": 95028
|
||||
},
|
||||
"Add undefined type to all uninitialized properties": {
|
||||
"category": "Message",
|
||||
"code": 95029
|
||||
},
|
||||
"Change all jsdoc-style types to TypeScript": {
|
||||
"category": "Message",
|
||||
"code": 95030
|
||||
},
|
||||
"Change all jsdoc-style types to TypeScript (and add '| undefined' to nullable types)": {
|
||||
"category": "Message",
|
||||
"code": 95031
|
||||
},
|
||||
"Implement all unimplemented interfaces": {
|
||||
"category": "Message",
|
||||
"code": 95032
|
||||
},
|
||||
"Install all missing types packages": {
|
||||
"category": "Message",
|
||||
"code": 95033
|
||||
},
|
||||
"Rewrite all as indexed access types": {
|
||||
"category": "Message",
|
||||
"code": 95034
|
||||
},
|
||||
"Convert all to default imports": {
|
||||
"category": "Message",
|
||||
"code": 95035
|
||||
},
|
||||
"Make all 'super()' calls the first statement in their constructor": {
|
||||
"category": "Message",
|
||||
"code": 95036
|
||||
},
|
||||
"Add 'this.' to all unresolved variables matching a member name": {
|
||||
"category": "Message",
|
||||
"code": 95037
|
||||
},
|
||||
"Change all extended interfaces to 'implements'": {
|
||||
"category": "Message",
|
||||
"code": 95038
|
||||
},
|
||||
"Add all missing super calls": {
|
||||
"category": "Message",
|
||||
"code": 95039
|
||||
},
|
||||
"Implement all inherited abstract classes": {
|
||||
"category": "Message",
|
||||
"code": 95040
|
||||
},
|
||||
"Add all missing 'async' modifiers": {
|
||||
"category": "Message",
|
||||
"code": 95041
|
||||
},
|
||||
"Add '@ts-ignore' to all error messages": {
|
||||
"category": "Message",
|
||||
"code": 95042
|
||||
},
|
||||
"Annotate everything with types from JSDoc": {
|
||||
"category": "Message",
|
||||
"code": 95043
|
||||
},
|
||||
"Add '()' to all uncalled decorators": {
|
||||
"category": "Message",
|
||||
"code": 95044
|
||||
},
|
||||
"Convert all constructor functions to classes": {
|
||||
"category": "Message",
|
||||
"code": 95045
|
||||
}
|
||||
}
|
||||
|
||||
@ -2457,12 +2457,14 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.verifyRangeIs(expectedText, includeWhiteSpace);
|
||||
}
|
||||
|
||||
public verifyCodeFixAll(options: FourSlashInterface.VerifyCodeFixAllOptions): void {
|
||||
const { fixId, newFileContent } = options;
|
||||
const fixIds = ts.mapDefined(this.getCodeFixes(this.activeFile.fileName), a => a.fixId);
|
||||
ts.Debug.assert(ts.contains(fixIds, fixId), "No available code fix has that group id.", () => `Expected '${fixId}'. Available action ids: ${fixIds}`);
|
||||
public verifyCodeFixAll({ fixId, fixAllDescription, newFileContent, commands: expectedCommands }: FourSlashInterface.VerifyCodeFixAllOptions): void {
|
||||
const fixWithId = ts.find(this.getCodeFixes(this.activeFile.fileName), a => a.fixId === fixId);
|
||||
ts.Debug.assert(fixWithId !== undefined, "No available code fix has that group id.", () =>
|
||||
`Expected '${fixId}'. Available action ids: ${ts.mapDefined(this.getCodeFixes(this.activeFile.fileName), a => a.fixId)}`);
|
||||
ts.Debug.assertEqual(fixWithId.fixAllDescription, fixAllDescription);
|
||||
|
||||
const { changes, commands } = this.languageService.getCombinedCodeFix({ type: "file", fileName: this.activeFile.fileName }, fixId, this.formatCodeSettings, ts.defaultPreferences);
|
||||
assert.deepEqual(commands, options.commands);
|
||||
assert.deepEqual(commands, expectedCommands);
|
||||
assert(changes.every(c => c.fileName === this.activeFile.fileName), "TODO: support testing codefixes that touch multiple files");
|
||||
this.applyChanges(changes);
|
||||
this.verifyCurrentFileContent(newFileContent);
|
||||
@ -4661,6 +4663,7 @@ namespace FourSlashInterface {
|
||||
|
||||
export interface VerifyCodeFixAllOptions {
|
||||
fixId: string;
|
||||
fixAllDescription: string;
|
||||
newFileContent: string;
|
||||
commands: ReadonlyArray<{}>;
|
||||
}
|
||||
|
||||
@ -557,7 +557,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.CodeFixRequest>(CommandNames.GetCodeFixes, args);
|
||||
const response = this.processResponse<protocol.CodeFixResponse>(request);
|
||||
|
||||
return response.body.map(({ description, changes, fixId }) => ({ description, changes: this.convertChanges(changes, file), fixId }));
|
||||
return response.body.map(({ description, changes, fixId, fixAllDescription }) => ({ description, changes: this.convertChanges(changes, file), fixId, fixAllDescription }));
|
||||
}
|
||||
|
||||
getCombinedCodeFix = notImplemented;
|
||||
|
||||
@ -1701,6 +1701,8 @@ namespace ts.server.protocol {
|
||||
* This may be omitted to indicate that the code fix can't be applied in a group.
|
||||
*/
|
||||
fixId?: {};
|
||||
/** Should be present if and only if 'fixId' is. */
|
||||
fixAllDescription?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1723,9 +1723,9 @@ namespace ts.server {
|
||||
return { startPosition, endPosition };
|
||||
}
|
||||
|
||||
private mapCodeAction(project: Project, { description, changes: unmappedChanges, commands, fixId }: CodeFixAction): protocol.CodeFixAction {
|
||||
private mapCodeAction(project: Project, { description, changes: unmappedChanges, commands, fixId, fixAllDescription }: CodeFixAction): protocol.CodeFixAction {
|
||||
const changes = unmappedChanges.map(change => this.mapTextChangesToCodeEditsUsingScriptinfo(change, project.getScriptInfoForNormalizedPath(toNormalizedPath(change.fileName))));
|
||||
return { description, changes, commands, fixId };
|
||||
return { description, changes, commands, fixId, fixAllDescription };
|
||||
}
|
||||
|
||||
private mapTextChangesToCodeEdits(project: Project, textChanges: ReadonlyArray<FileTextChanges>): protocol.FileCodeEdits[] {
|
||||
|
||||
@ -27,6 +27,25 @@ namespace ts {
|
||||
const codeFixRegistrations: CodeFixRegistration[][] = [];
|
||||
const fixIdToRegistration = createMap<CodeFixRegistration>();
|
||||
|
||||
type DiagnosticAndArguments = DiagnosticMessage | [DiagnosticMessage, string] | [DiagnosticMessage, string, string];
|
||||
function diagnosticToString(diag: DiagnosticAndArguments): string {
|
||||
return isArray(diag)
|
||||
? formatStringFromArgs(getLocaleSpecificMessage(diag[0]), diag.slice(1) as ReadonlyArray<string>)
|
||||
: getLocaleSpecificMessage(diag);
|
||||
}
|
||||
|
||||
export function createCodeFixActionNoFixId(changes: FileTextChanges[], description: DiagnosticAndArguments) {
|
||||
return createCodeFixActionWorker(diagnosticToString(description), changes, /*fixId*/ undefined, /*fixAllDescription*/ undefined);
|
||||
}
|
||||
|
||||
export function createCodeFixAction(changes: FileTextChanges[], description: DiagnosticAndArguments, fixId: {}, fixAllDescription: DiagnosticAndArguments, command?: CodeActionCommand): CodeFixAction {
|
||||
return createCodeFixActionWorker(diagnosticToString(description), changes, fixId, diagnosticToString(fixAllDescription), command);
|
||||
}
|
||||
|
||||
function createCodeFixActionWorker(description: string, changes: FileTextChanges[], fixId?: {}, fixAllDescription?: string, command?: CodeActionCommand): CodeFixAction {
|
||||
return { description, changes, fixId, fixAllDescription, commands: command ? [command] : undefined };
|
||||
}
|
||||
|
||||
export function registerCodeFix(reg: CodeFixRegistration) {
|
||||
for (const error of reg.errorCodes) {
|
||||
let registrations = codeFixRegistrations[error];
|
||||
|
||||
@ -6,7 +6,7 @@ namespace ts.codefix {
|
||||
errorCodes,
|
||||
getCodeActions: (context) => {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start));
|
||||
return [{ description: getLocaleSpecificMessage(Diagnostics.Call_decorator_expression), changes, fixId }];
|
||||
return [createCodeFixAction(changes, Diagnostics.Call_decorator_expression, fixId, Diagnostics.Add_to_all_uncalled_decorators)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file!, diag.start!)),
|
||||
|
||||
@ -7,9 +7,8 @@ namespace ts.codefix {
|
||||
getCodeActions(context) {
|
||||
const decl = getDeclaration(context.sourceFile, context.span.start);
|
||||
if (!decl) return;
|
||||
const description = getLocaleSpecificMessage(Diagnostics.Annotate_with_type_from_JSDoc);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, decl));
|
||||
return [{ description, changes, fixId }];
|
||||
return [createCodeFixAction(changes, Diagnostics.Annotate_with_type_from_JSDoc, fixId, Diagnostics.Annotate_everything_with_types_from_JSDoc)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
|
||||
@ -6,7 +6,7 @@ namespace ts.codefix {
|
||||
errorCodes,
|
||||
getCodeActions(context: CodeFixContext) {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start, context.program.getTypeChecker()));
|
||||
return [{ description: getLocaleSpecificMessage(Diagnostics.Convert_function_to_an_ES2015_class), changes, fixId }];
|
||||
return [createCodeFixAction(changes, Diagnostics.Convert_function_to_an_ES2015_class, fixId, Diagnostics.Convert_all_constructor_functions_to_classes)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, err) => doChange(changes, err.file!, err.start, context.program.getTypeChecker())),
|
||||
|
||||
@ -3,7 +3,6 @@ namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module.code],
|
||||
getCodeActions(context) {
|
||||
const description = getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module);
|
||||
const { sourceFile, program } = context;
|
||||
const changes = textChanges.ChangeTracker.with(context, changes => {
|
||||
const moduleExportsChangedToDefault = convertFileToEs6Module(sourceFile, program.getTypeChecker(), changes, program.getCompilerOptions().target);
|
||||
@ -14,7 +13,7 @@ namespace ts.codefix {
|
||||
}
|
||||
});
|
||||
// No support for fix-all since this applies to the whole file at once anyway.
|
||||
return [{ description, changes, fixId: undefined }];
|
||||
return [createCodeFixActionNoFixId(changes, Diagnostics.Convert_to_ES6_module)];
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -8,8 +8,8 @@ namespace ts.codefix {
|
||||
const qualifiedName = getQualifiedName(context.sourceFile, context.span.start);
|
||||
if (!qualifiedName) return undefined;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, qualifiedName));
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Rewrite_as_the_indexed_access_type_0), [`${qualifiedName.left.text}["${qualifiedName.right.text}"]`]);
|
||||
return [{ description, changes, fixId }];
|
||||
const newText = `${qualifiedName.left.text}["${qualifiedName.right.text}"]`;
|
||||
return [createCodeFixAction(changes, [Diagnostics.Rewrite_as_the_indexed_access_type_0, newText], fixId, Diagnostics.Rewrite_all_as_indexed_access_types)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: (context) => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
|
||||
@ -16,23 +16,18 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
const fixes: CodeFixAction[] = [
|
||||
{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Disable_checking_for_this_file),
|
||||
changes: [createFileTextChanges(sourceFile.fileName, [
|
||||
// fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file.
|
||||
createCodeFixActionNoFixId(
|
||||
[createFileTextChanges(sourceFile.fileName, [
|
||||
createTextChange(sourceFile.checkJsDirective
|
||||
? createTextSpanFromBounds(sourceFile.checkJsDirective.pos, sourceFile.checkJsDirective.end)
|
||||
: createTextSpan(0, 0), `// @ts-nocheck${getNewLineOrDefaultFromHost(host, formatContext.options)}`),
|
||||
])],
|
||||
// fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file.
|
||||
fixId: undefined,
|
||||
}];
|
||||
Diagnostics.Disable_checking_for_this_file),
|
||||
];
|
||||
|
||||
if (textChanges.isValidLocationToAddComment(sourceFile, span.start)) {
|
||||
fixes.unshift({
|
||||
description: getLocaleSpecificMessage(Diagnostics.Ignore_this_error_message),
|
||||
changes: textChanges.ChangeTracker.with(context, t => makeChange(t, sourceFile, span.start)),
|
||||
fixId,
|
||||
});
|
||||
fixes.unshift(createCodeFixAction(textChanges.ChangeTracker.with(context, t => makeChange(t, sourceFile, span.start)), Diagnostics.Ignore_this_error_message, fixId, Diagnostics.Add_ts_ignore_to_all_error_messages));
|
||||
}
|
||||
|
||||
return fixes;
|
||||
|
||||
@ -97,9 +97,8 @@ namespace ts.codefix {
|
||||
|
||||
function getActionsForAddMissingMemberInJavaScriptFile(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, makeStatic: boolean): CodeFixAction | undefined {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addMissingMemberInJs(t, classDeclarationSourceFile, classDeclaration, tokenName, makeStatic));
|
||||
if (changes.length === 0) return undefined;
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(makeStatic ? Diagnostics.Initialize_static_property_0 : Diagnostics.Initialize_property_0_in_the_constructor), [tokenName]);
|
||||
return { description, changes, fixId };
|
||||
return changes.length === 0 ? undefined
|
||||
: createCodeFixAction(changes, [makeStatic ? Diagnostics.Initialize_static_property_0 : Diagnostics.Initialize_property_0_in_the_constructor, tokenName], fixId, Diagnostics.Add_all_missing_members);
|
||||
}
|
||||
|
||||
function addMissingMemberInJs(changeTracker: textChanges.ChangeTracker, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, makeStatic: boolean): void {
|
||||
@ -143,9 +142,8 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function createAddPropertyDeclarationAction(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, makeStatic: boolean, tokenName: string, typeNode: TypeNode): CodeFixAction {
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(makeStatic ? Diagnostics.Declare_static_property_0 : Diagnostics.Declare_property_0), [tokenName]);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addPropertyDeclaration(t, classDeclarationSourceFile, classDeclaration, tokenName, typeNode, makeStatic));
|
||||
return { description, changes, fixId };
|
||||
return createCodeFixAction(changes, [makeStatic ? Diagnostics.Declare_static_property_0 : Diagnostics.Declare_property_0, tokenName], fixId, Diagnostics.Add_all_missing_members);
|
||||
}
|
||||
|
||||
function addPropertyDeclaration(changeTracker: textChanges.ChangeTracker, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, typeNode: TypeNode, makeStatic: boolean): void {
|
||||
@ -178,7 +176,7 @@ namespace ts.codefix {
|
||||
|
||||
const changes = textChanges.ChangeTracker.with(context, t => t.insertNodeAtClassStart(classDeclarationSourceFile, classDeclaration, indexSignature));
|
||||
// No fixId here because code-fix-all currently only works on adding individual named properties.
|
||||
return { description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_property_0), [tokenName]), changes, fixId: undefined };
|
||||
return createCodeFixActionNoFixId(changes, [Diagnostics.Add_index_signature_for_property_0, tokenName]);
|
||||
}
|
||||
|
||||
function getActionForMethodDeclaration(
|
||||
@ -191,9 +189,8 @@ namespace ts.codefix {
|
||||
inJs: boolean,
|
||||
preferences: UserPreferences,
|
||||
): CodeFixAction | undefined {
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(makeStatic ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0), [token.text]);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addMethodDeclaration(t, classDeclarationSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences));
|
||||
return { description, changes, fixId };
|
||||
return createCodeFixAction(changes, [makeStatic ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0, token.text], fixId, Diagnostics.Add_all_missing_members);
|
||||
}
|
||||
|
||||
function addMethodDeclaration(
|
||||
|
||||
@ -12,7 +12,7 @@ namespace ts.codefix {
|
||||
const nodes = getNodes(sourceFile, span.start);
|
||||
if (!nodes) return undefined;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, nodes));
|
||||
return [{ description: getLocaleSpecificMessage(Diagnostics.Add_async_modifier_to_containing_function), changes, fixId }];
|
||||
return [createCodeFixAction(changes, Diagnostics.Add_async_modifier_to_containing_function, fixId, Diagnostics.Add_all_missing_async_modifiers)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
|
||||
@ -5,38 +5,27 @@ namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions: context => {
|
||||
const codeAction = tryGetCodeActionForInstallPackageTypes(context.host, context.sourceFile.fileName, getModuleName(context.sourceFile, context.span.start));
|
||||
return codeAction && [{ fixId, ...codeAction }];
|
||||
const { host, sourceFile, span: { start } } = context;
|
||||
const packageName = getTypesPackageNameToInstall(host, sourceFile, start);
|
||||
return packageName === undefined ? []
|
||||
: [createCodeFixAction(/*changes*/ [], [Diagnostics.Install_0, packageName], fixId, Diagnostics.Install_all_missing_types_packages, getCommand(sourceFile.fileName, packageName))];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (_, diag, commands) => {
|
||||
const pkg = getTypesPackageNameToInstall(context.host, getModuleName(diag.file, diag.start));
|
||||
const pkg = getTypesPackageNameToInstall(context.host, diag.file, diag.start);
|
||||
if (pkg) {
|
||||
commands.push(getCommand(diag.file.fileName, pkg));
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
function getModuleName(sourceFile: SourceFile, pos: number): string {
|
||||
return cast(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false), isStringLiteral).text;
|
||||
}
|
||||
|
||||
function getCommand(fileName: string, packageName: string): InstallPackageAction {
|
||||
return { type: "install package", file: fileName, packageName };
|
||||
}
|
||||
|
||||
function getTypesPackageNameToInstall(host: LanguageServiceHost, moduleName: string): string | undefined {
|
||||
function getTypesPackageNameToInstall(host: LanguageServiceHost, sourceFile: SourceFile, pos: number): string | undefined {
|
||||
const moduleName = cast(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false), isStringLiteral).text;
|
||||
const { packageName } = getPackageName(moduleName);
|
||||
// If !registry, registry not available yet, can't do anything.
|
||||
return host.isKnownTypesPackageName(packageName) ? getTypesPackageName(packageName) : undefined;
|
||||
}
|
||||
|
||||
function tryGetCodeActionForInstallPackageTypes(host: LanguageServiceHost, fileName: string, moduleName: string): CodeAction | undefined {
|
||||
const packageName = getTypesPackageNameToInstall(host, moduleName);
|
||||
return packageName === undefined ? undefined : {
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Install_0), [packageName]),
|
||||
changes: [],
|
||||
commands: [getCommand(fileName, packageName)],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ namespace ts.codefix {
|
||||
const { program, sourceFile, span } = context;
|
||||
const changes = textChanges.ChangeTracker.with(context, t =>
|
||||
addMissingMembers(getClass(sourceFile, span.start), sourceFile, program.getTypeChecker(), t, context.preferences));
|
||||
return changes.length === 0 ? undefined : [{ description: getLocaleSpecificMessage(Diagnostics.Implement_inherited_abstract_class), changes, fixId }];
|
||||
return changes.length === 0 ? undefined : [createCodeFixAction(changes, Diagnostics.Implement_inherited_abstract_class, fixId, Diagnostics.Implement_all_inherited_abstract_classes)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => {
|
||||
|
||||
@ -11,9 +11,7 @@ namespace ts.codefix {
|
||||
const checker = program.getTypeChecker();
|
||||
return mapDefined<ExpressionWithTypeArguments, CodeFixAction>(getClassImplementsHeritageClauseElements(classDeclaration), implementedTypeNode => {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addMissingDeclarations(checker, implementedTypeNode, sourceFile, classDeclaration, t, context.preferences));
|
||||
if (changes.length === 0) return undefined;
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Implement_interface_0), [implementedTypeNode.getText()]);
|
||||
return { description, changes, fixId };
|
||||
return changes.length === 0 ? undefined : createCodeFixAction(changes, [Diagnostics.Implement_interface_0, implementedTypeNode.getText(sourceFile)], fixId, Diagnostics.Implement_all_unimplemented_interfaces);
|
||||
});
|
||||
},
|
||||
fixIds: [fixId],
|
||||
|
||||
@ -10,7 +10,7 @@ namespace ts.codefix {
|
||||
if (!nodes) return undefined;
|
||||
const { constructor, superCall } = nodes;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, constructor, superCall));
|
||||
return [{ description: getLocaleSpecificMessage(Diagnostics.Make_super_call_the_first_statement_in_the_constructor), changes, fixId }];
|
||||
return [createCodeFixAction(changes, Diagnostics.Make_super_call_the_first_statement_in_the_constructor, fixId, Diagnostics.Make_all_super_calls_the_first_statement_in_their_constructor)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions(context) {
|
||||
|
||||
@ -8,7 +8,7 @@ namespace ts.codefix {
|
||||
const { sourceFile, span } = context;
|
||||
const ctr = getNode(sourceFile, span.start);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, ctr));
|
||||
return [{ description: getLocaleSpecificMessage(Diagnostics.Add_missing_super_call), changes, fixId }];
|
||||
return [createCodeFixAction(changes, Diagnostics.Add_missing_super_call, fixId, Diagnostics.Add_all_missing_super_calls)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) =>
|
||||
|
||||
@ -10,7 +10,7 @@ namespace ts.codefix {
|
||||
if (!nodes) return undefined;
|
||||
const { extendsToken, heritageClauses } = nodes;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChanges(t, sourceFile, extendsToken, heritageClauses));
|
||||
return [{ description: getLocaleSpecificMessage(Diagnostics.Change_extends_to_implements), changes, fixId }];
|
||||
return [createCodeFixAction(changes, Diagnostics.Change_extends_to_implements, fixId, Diagnostics.Change_all_extended_interfaces_to_implements)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
|
||||
@ -11,7 +11,7 @@ namespace ts.codefix {
|
||||
return undefined;
|
||||
}
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, token));
|
||||
return [{ description: getLocaleSpecificMessage(Diagnostics.Add_this_to_unresolved_variable), changes, fixId }];
|
||||
return [createCodeFixAction(changes, Diagnostics.Add_this_to_unresolved_variable, fixId, Diagnostics.Add_this_to_all_unresolved_variables_matching_a_member_name)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
|
||||
@ -5,7 +5,7 @@ namespace ts.codefix {
|
||||
getCodeActions: getActionsForInvalidImport
|
||||
});
|
||||
|
||||
function getActionsForInvalidImport(context: CodeFixContext): CodeAction[] | undefined {
|
||||
function getActionsForInvalidImport(context: CodeFixContext): CodeFixAction[] | undefined {
|
||||
const sourceFile = context.sourceFile;
|
||||
|
||||
// This is the whole import statement, eg:
|
||||
@ -19,11 +19,11 @@ namespace ts.codefix {
|
||||
return getCodeFixesForImportDeclaration(context, node);
|
||||
}
|
||||
|
||||
function getCodeFixesForImportDeclaration(context: CodeFixContext, node: ImportDeclaration) {
|
||||
function getCodeFixesForImportDeclaration(context: CodeFixContext, node: ImportDeclaration): CodeFixAction[] {
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
const namespace = getNamespaceDeclarationNode(node) as NamespaceImport;
|
||||
const opts = context.program.getCompilerOptions();
|
||||
const variations: CodeAction[] = [];
|
||||
const variations: CodeFixAction[] = [];
|
||||
|
||||
// import Bluebird from "bluebird";
|
||||
variations.push(createAction(context, sourceFile, node, makeImportDeclaration(namespace.name, /*namedImports*/ undefined, node.moduleSpecifier)));
|
||||
@ -41,12 +41,9 @@ namespace ts.codefix {
|
||||
return variations;
|
||||
}
|
||||
|
||||
function createAction(context: CodeFixContext, sourceFile: SourceFile, node: Node, replacement: Node): CodeAction {
|
||||
function createAction(context: CodeFixContext, sourceFile: SourceFile, node: Node, replacement: Node): CodeFixAction {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, node, replacement));
|
||||
return {
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Replace_import_with_0), [changes[0].textChanges[0].newText]),
|
||||
changes,
|
||||
};
|
||||
return createCodeFixActionNoFixId(changes, [Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]);
|
||||
}
|
||||
|
||||
registerCodeFix({
|
||||
@ -57,7 +54,7 @@ namespace ts.codefix {
|
||||
getCodeActions: getActionsForUsageOfInvalidImport
|
||||
});
|
||||
|
||||
function getActionsForUsageOfInvalidImport(context: CodeFixContext): CodeAction[] | undefined {
|
||||
function getActionsForUsageOfInvalidImport(context: CodeFixContext): CodeFixAction[] | undefined {
|
||||
const sourceFile = context.sourceFile;
|
||||
const targetKind = Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures.code === context.errorCode ? SyntaxKind.CallExpression : SyntaxKind.NewExpression;
|
||||
const node = findAncestor(getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false), a => a.kind === targetKind && a.getStart() === context.span.start && a.getEnd() === (context.span.start + context.span.length)) as CallExpression | NewExpression;
|
||||
@ -69,15 +66,13 @@ namespace ts.codefix {
|
||||
if (!(type.symbol && (type.symbol as TransientSymbol).originatingImport)) {
|
||||
return [];
|
||||
}
|
||||
const fixes: CodeAction[] = [];
|
||||
const fixes: CodeFixAction[] = [];
|
||||
const relatedImport = (type.symbol as TransientSymbol).originatingImport;
|
||||
if (!isImportCall(relatedImport)) {
|
||||
addRange(fixes, getCodeFixesForImportDeclaration(context, relatedImport));
|
||||
}
|
||||
fixes.push({
|
||||
description: getLocaleSpecificMessage(Diagnostics.Use_synthetic_default_member),
|
||||
changes: textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, expr, createPropertyAccess(expr, "default"), {})),
|
||||
});
|
||||
const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, expr, createPropertyAccess(expr, "default"), {}));
|
||||
fixes.push(createCodeFixActionNoFixId(changes, Diagnostics.Use_synthetic_default_member));
|
||||
return fixes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,19 +12,17 @@ namespace ts.codefix {
|
||||
if (!info) return undefined;
|
||||
const { typeNode, type } = info;
|
||||
const original = typeNode.getText(sourceFile);
|
||||
const actions = [fix(type, fixIdPlain)];
|
||||
const actions = [fix(type, fixIdPlain, Diagnostics.Change_all_jsdoc_style_types_to_TypeScript)];
|
||||
if (typeNode.kind === SyntaxKind.JSDocNullableType) {
|
||||
// for nullable types, suggest the flow-compatible `T | null | undefined`
|
||||
// in addition to the jsdoc/closure-compatible `T | null`
|
||||
actions.push(fix(checker.getNullableType(type, TypeFlags.Undefined), fixIdNullable));
|
||||
actions.push(fix(checker.getNullableType(type, TypeFlags.Undefined), fixIdNullable, Diagnostics.Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types));
|
||||
}
|
||||
return actions;
|
||||
|
||||
function fix(type: Type, fixId: string): CodeFixAction {
|
||||
const newText = checker.typeToString(type);
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Change_0_to_1), [original, newText]);
|
||||
function fix(type: Type, fixId: string, fixAllDescription: DiagnosticMessage): CodeFixAction {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, typeNode, type, checker));
|
||||
return { description, changes, fixId };
|
||||
return createCodeFixAction(changes, [Diagnostics.Change_0_to_1, original, checker.typeToString(type)], fixId, fixAllDescription);
|
||||
}
|
||||
},
|
||||
fixIds: [fixIdPlain, fixIdNullable],
|
||||
|
||||
@ -13,8 +13,7 @@ namespace ts.codefix {
|
||||
if (!info) return undefined;
|
||||
const { node, suggestion } = info;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, node, suggestion));
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Change_spelling_to_0), [suggestion]);
|
||||
return [{ description, changes, fixId }];
|
||||
return [createCodeFixAction(changes, [Diagnostics.Change_spelling_to_0, suggestion], fixId, Diagnostics.Fix_all_detected_spelling_errors)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
|
||||
@ -52,9 +52,8 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function getActionForAddMissingDefiniteAssignmentAssertion (context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction {
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_definite_assignment_assertion_to_property_0), [propertyDeclaration.getText()]);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addDefiniteAssignmentAssertion(t, context.sourceFile, propertyDeclaration));
|
||||
return { description, changes, fixId: fixIdAddDefiniteAssignmentAssertions };
|
||||
return createCodeFixAction(changes, [Diagnostics.Add_definite_assignment_assertion_to_property_0, propertyDeclaration.getText()], fixIdAddDefiniteAssignmentAssertions, Diagnostics.Add_definite_assignment_assertions_to_all_uninitialized_properties);
|
||||
}
|
||||
|
||||
function addDefiniteAssignmentAssertion(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void {
|
||||
@ -71,9 +70,8 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function getActionForAddMissingUndefinedType (context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction {
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_undefined_type_to_property_0), [propertyDeclaration.name.getText()]);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addUndefinedType(t, context.sourceFile, propertyDeclaration));
|
||||
return { description, changes, fixId: fixIdAddUndefinedType };
|
||||
return createCodeFixAction(changes, [Diagnostics.Add_undefined_type_to_property_0, propertyDeclaration.name.getText()], fixIdAddUndefinedType, Diagnostics.Add_undefined_type_to_all_uninitialized_properties);
|
||||
}
|
||||
|
||||
function addUndefinedType(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void {
|
||||
@ -82,14 +80,13 @@ namespace ts.codefix {
|
||||
changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration.type, createUnionTypeNode(types));
|
||||
}
|
||||
|
||||
function getActionForAddMissingInitializer (context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction | undefined {
|
||||
function getActionForAddMissingInitializer(context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction | undefined {
|
||||
const checker = context.program.getTypeChecker();
|
||||
const initializer = getInitializer(checker, propertyDeclaration);
|
||||
if (!initializer) return undefined;
|
||||
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_initializer_to_property_0), [propertyDeclaration.name.getText()]);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addInitializer(t, context.sourceFile, propertyDeclaration, initializer));
|
||||
return { description, changes, fixId: fixIdAddInitializer };
|
||||
return createCodeFixAction(changes, [Diagnostics.Add_initializer_to_property_0, propertyDeclaration.name.getText()], fixIdAddInitializer, Diagnostics.Add_initializers_to_all_uninitialized_properties);
|
||||
}
|
||||
|
||||
function addInitializer (changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration, initializer: Expression): void {
|
||||
|
||||
@ -13,9 +13,8 @@ namespace ts.codefix {
|
||||
const { errorCode, sourceFile } = context;
|
||||
const importDecl = tryGetFullImport(sourceFile, context.span.start);
|
||||
if (importDecl) {
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_import_from_0), [showModuleSpecifier(importDecl)]);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => t.deleteNode(sourceFile, importDecl));
|
||||
return [{ description, changes, fixId: fixIdDelete }];
|
||||
return [createCodeFixAction(changes, [Diagnostics.Remove_import_from_0, showModuleSpecifier(importDecl)], fixIdDelete, Diagnostics.Delete_all_unused_declarations)];
|
||||
}
|
||||
|
||||
const token = getToken(sourceFile, textSpanEnd(context.span));
|
||||
@ -23,14 +22,12 @@ namespace ts.codefix {
|
||||
|
||||
const deletion = textChanges.ChangeTracker.with(context, t => tryDeleteDeclaration(t, sourceFile, token));
|
||||
if (deletion.length) {
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_declaration_for_Colon_0), [token.getText()]);
|
||||
result.push({ description, changes: deletion, fixId: fixIdDelete });
|
||||
result.push(createCodeFixAction(deletion, [Diagnostics.Remove_declaration_for_Colon_0, token.getText(sourceFile)], fixIdDelete, Diagnostics.Delete_all_unused_declarations));
|
||||
}
|
||||
|
||||
const prefix = textChanges.ChangeTracker.with(context, t => tryPrefixDeclaration(t, errorCode, sourceFile, token));
|
||||
if (prefix.length) {
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Prefix_0_with_an_underscore), [token.getText()]);
|
||||
result.push({ description, changes: prefix, fixId: fixIdPrefix });
|
||||
result.push(createCodeFixAction(prefix, [Diagnostics.Prefix_0_with_an_underscore, token.getText(sourceFile)], fixIdPrefix, Diagnostics.Prefix_all_unused_declarations_with_where_possible));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@ -33,10 +33,9 @@ namespace ts.codefix {
|
||||
preferences: UserPreferences;
|
||||
}
|
||||
|
||||
function createCodeAction(descriptionDiagnostic: DiagnosticMessage, diagnosticArgs: string[], changes: FileTextChanges[]): CodeFixAction {
|
||||
const description = formatMessage.apply(undefined, [undefined, descriptionDiagnostic].concat(<any[]>diagnosticArgs));
|
||||
function createCodeAction(descriptionDiagnostic: DiagnosticMessage, diagnosticArgs: [string, string], changes: FileTextChanges[]): CodeFixAction {
|
||||
// TODO: GH#20315
|
||||
return { description, changes, fixId: undefined };
|
||||
return createCodeFixActionNoFixId(changes, [descriptionDiagnostic, ...diagnosticArgs] as [DiagnosticMessage, string, string]);
|
||||
}
|
||||
|
||||
function convertToImportCodeFixContext(context: CodeFixContext, symbolToken: Node, symbolName: string): ImportCodeFixContext {
|
||||
@ -640,13 +639,13 @@ namespace ts.codefix {
|
||||
return createCodeAction(Diagnostics.Change_0_to_1, [symbolName, `${namespacePrefix}.${symbolName}`], changes);
|
||||
}
|
||||
|
||||
function getImportCodeActions(context: CodeFixContext): CodeAction[] {
|
||||
function getImportCodeActions(context: CodeFixContext): CodeFixAction[] {
|
||||
return context.errorCode === Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
|
||||
? getActionsForUMDImport(context)
|
||||
: getActionsForNonUMDImport(context);
|
||||
}
|
||||
|
||||
function getActionsForUMDImport(context: CodeFixContext): CodeAction[] {
|
||||
function getActionsForUMDImport(context: CodeFixContext): CodeFixAction[] {
|
||||
const token = getTokenAtPosition(context.sourceFile, context.span.start, /*includeJsDocComment*/ false);
|
||||
const checker = context.program.getTypeChecker();
|
||||
|
||||
@ -702,7 +701,7 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function getActionsForNonUMDImport(context: CodeFixContext): CodeAction[] | undefined {
|
||||
function getActionsForNonUMDImport(context: CodeFixContext): CodeFixAction[] | undefined {
|
||||
// This will always be an Identifier, since the diagnostics we fix only fail on identifiers.
|
||||
const { sourceFile, span, program, cancellationToken } = context;
|
||||
const checker = program.getTypeChecker();
|
||||
|
||||
@ -33,10 +33,8 @@ namespace ts.codefix {
|
||||
const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
|
||||
let declaration!: Declaration;
|
||||
const changes = textChanges.ChangeTracker.with(context, changes => { declaration = doChange(changes, sourceFile, token, errorCode, program, cancellationToken); });
|
||||
if (changes.length === 0) return undefined;
|
||||
const name = getNameOfDeclaration(declaration).getText();
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(getDiagnostic(errorCode, token)), [name]);
|
||||
return [{ description, changes, fixId }];
|
||||
return changes.length === 0 ? undefined
|
||||
: [createCodeFixAction(changes, [getDiagnostic(errorCode, token), getNameOfDeclaration(declaration).getText(sourceFile)], fixId, Diagnostics.Infer_all_types_from_usage)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions(context) {
|
||||
|
||||
@ -8,9 +8,8 @@ namespace ts.codefix {
|
||||
const { sourceFile, span: { start } } = context;
|
||||
const info = getInfo(sourceFile, start);
|
||||
if (!info) return undefined;
|
||||
const description = getLocaleSpecificMessage(Diagnostics.Convert_to_default_import);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info));
|
||||
return [{ description, changes, fixId }];
|
||||
return [createCodeFixAction(changes, Diagnostics.Convert_to_default_import, fixId, Diagnostics.Convert_all_to_default_imports)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
|
||||
@ -440,6 +440,7 @@ namespace ts {
|
||||
* This may be omitted to indicate that the code fix can't be applied in a group.
|
||||
*/
|
||||
fixId?: {};
|
||||
fixAllDescription?: string;
|
||||
}
|
||||
|
||||
export interface CombinedCodeActions {
|
||||
|
||||
@ -4242,6 +4242,7 @@ declare namespace ts {
|
||||
* This may be omitted to indicate that the code fix can't be applied in a group.
|
||||
*/
|
||||
fixId?: {};
|
||||
fixAllDescription?: string;
|
||||
}
|
||||
interface CombinedCodeActions {
|
||||
changes: ReadonlyArray<FileTextChanges>;
|
||||
@ -6313,6 +6314,8 @@ declare namespace ts.server.protocol {
|
||||
* This may be omitted to indicate that the code fix can't be applied in a group.
|
||||
*/
|
||||
fixId?: {};
|
||||
/** Should be present if and only if 'fixId' is. */
|
||||
fixAllDescription?: string;
|
||||
}
|
||||
/**
|
||||
* Format and format on key response message.
|
||||
|
||||
@ -4494,6 +4494,7 @@ declare namespace ts {
|
||||
* This may be omitted to indicate that the code fix can't be applied in a group.
|
||||
*/
|
||||
fixId?: {};
|
||||
fixAllDescription?: string;
|
||||
}
|
||||
interface CombinedCodeActions {
|
||||
changes: ReadonlyArray<FileTextChanges>;
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "annotateWithTypeFromJSDoc",
|
||||
fixAllDescription: "Annotate everything with types from JSDoc",
|
||||
newFileContent:
|
||||
`/** @type {number} */
|
||||
var x: number;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "addMissingInvocationForDecorator",
|
||||
fixAllDescription: "Add '()' to all uncalled decorators",
|
||||
newFileContent:
|
||||
`declare function foo(): (...args: any[]) => void;
|
||||
class C {
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "addMissingMember",
|
||||
fixAllDescription: "Add all missing members",
|
||||
newFileContent:
|
||||
`class C {
|
||||
x: number;
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "addMissingMember",
|
||||
fixAllDescription: "Add all missing members",
|
||||
newFileContent:
|
||||
`class C {
|
||||
y() {
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "fixAwaitInSyncFunction",
|
||||
fixAllDescription: "Add all missing 'async' modifiers",
|
||||
newFileContent:
|
||||
`async function f() {
|
||||
await Promise.resolve();
|
||||
|
||||
@ -22,6 +22,7 @@ goTo.marker();
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "fixCannotFindModule",
|
||||
fixAllDescription: "Install all missing types packages",
|
||||
commands: [
|
||||
{ packageName: "@types/abs", file: "/a.ts", type: "install package" },
|
||||
{ packageName: "@types/zap", file: "/a.ts", type: "install package" },
|
||||
|
||||
@ -5,5 +5,6 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "fixJSDocTypes_plain",
|
||||
fixAllDescription: "Change all jsdoc-style types to TypeScript",
|
||||
newFileContent: "function f(a: number | null, b: string) {}",
|
||||
})
|
||||
|
||||
@ -5,5 +5,6 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "fixJSDocTypes_nullable",
|
||||
fixAllDescription: "Change all jsdoc-style types to TypeScript (and add '| undefined' to nullable types)",
|
||||
newFileContent: "function f(a: number | null | undefined, b: string) {}",
|
||||
})
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "fixClassDoesntImplementInheritedAbstractMember",
|
||||
fixAllDescription: "Implement all inherited abstract classes",
|
||||
newFileContent:
|
||||
`abstract class A {
|
||||
abstract m(): void;
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "fixClassIncorrectlyImplementsInterface",
|
||||
fixAllDescription: "Implement all unimplemented interfaces",
|
||||
newFileContent:
|
||||
`interface I { i(): void; }
|
||||
interface J { j(): void; }
|
||||
|
||||
@ -7,38 +7,39 @@
|
||||
//// class TT { constructor () {} }
|
||||
////
|
||||
//// class AT extends A { a () {} }
|
||||
////
|
||||
////
|
||||
//// class Foo {}
|
||||
////
|
||||
//// class T {
|
||||
////
|
||||
////
|
||||
//// a: string;
|
||||
////
|
||||
////
|
||||
//// static b: string;
|
||||
////
|
||||
////
|
||||
//// private c: string;
|
||||
////
|
||||
////
|
||||
//// d: number | undefined;
|
||||
////
|
||||
////
|
||||
//// e: string | number;
|
||||
////
|
||||
////
|
||||
//// f: 1;
|
||||
////
|
||||
////
|
||||
//// g: "123" | "456";
|
||||
////
|
||||
////
|
||||
//// h: boolean;
|
||||
////
|
||||
////
|
||||
//// i: TT;
|
||||
////
|
||||
////
|
||||
//// j: A;
|
||||
////
|
||||
////
|
||||
//// k: AT;
|
||||
////
|
||||
////
|
||||
//// l: Foo;
|
||||
//// }
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: 'addMissingPropertyDefiniteAssignmentAssertions',
|
||||
fixAllDescription: "Add definite assignment assertions to all uninitialized properties",
|
||||
newFileContent: `abstract class A { abstract a (); }
|
||||
|
||||
class TT { constructor () {} }
|
||||
|
||||
@ -7,38 +7,39 @@
|
||||
//// class TT { constructor () {} }
|
||||
////
|
||||
//// class AT extends A { a () {} }
|
||||
////
|
||||
////
|
||||
//// class Foo {}
|
||||
////
|
||||
//// class T {
|
||||
////
|
||||
////
|
||||
//// a: string;
|
||||
////
|
||||
////
|
||||
//// static b: string;
|
||||
////
|
||||
////
|
||||
//// private c: string;
|
||||
////
|
||||
////
|
||||
//// d: number | undefined;
|
||||
////
|
||||
////
|
||||
//// e: string | number;
|
||||
////
|
||||
////
|
||||
//// f: 1;
|
||||
////
|
||||
////
|
||||
//// g: "123" | "456";
|
||||
////
|
||||
////
|
||||
//// h: boolean;
|
||||
////
|
||||
////
|
||||
//// i: TT;
|
||||
////
|
||||
////
|
||||
//// j: A;
|
||||
////
|
||||
////
|
||||
//// k: AT;
|
||||
////
|
||||
////
|
||||
//// l: Foo;
|
||||
//// }
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: 'addMissingPropertyUndefinedType',
|
||||
fixAllDescription: "Add undefined type to all uninitialized properties",
|
||||
newFileContent: `abstract class A { abstract a (); }
|
||||
|
||||
class TT { constructor () {} }
|
||||
|
||||
@ -7,38 +7,39 @@
|
||||
//// class TT { constructor () {} }
|
||||
////
|
||||
//// class AT extends A { a () {} }
|
||||
////
|
||||
////
|
||||
//// class Foo {}
|
||||
////
|
||||
//// class T {
|
||||
////
|
||||
////
|
||||
//// a: string;
|
||||
////
|
||||
////
|
||||
//// static b: string;
|
||||
////
|
||||
////
|
||||
//// private c: string;
|
||||
////
|
||||
////
|
||||
//// d: number | undefined;
|
||||
////
|
||||
////
|
||||
//// e: string | number;
|
||||
////
|
||||
////
|
||||
//// f: 1;
|
||||
////
|
||||
////
|
||||
//// g: "123" | "456";
|
||||
////
|
||||
////
|
||||
//// h: boolean;
|
||||
////
|
||||
////
|
||||
//// i: TT;
|
||||
////
|
||||
////
|
||||
//// j: A;
|
||||
////
|
||||
////
|
||||
//// k: AT;
|
||||
////
|
||||
////
|
||||
//// l: Foo;
|
||||
//// }
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: 'addMissingPropertyInitializer',
|
||||
fixAllDescription: "Add initializers to all uninitialized properties",
|
||||
newFileContent: `abstract class A { abstract a (); }
|
||||
|
||||
class TT { constructor () {} }
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "classSuperMustPrecedeThisAccess",
|
||||
fixAllDescription: "Make all 'super()' calls the first statement in their constructor",
|
||||
newFileContent: `class C extends Object {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "constructorForDerivedNeedSuperCall",
|
||||
fixAllDescription: "Add all missing super calls",
|
||||
newFileContent: `class C extends Object {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "correctQualifiedNameToIndexedAccessType",
|
||||
fixAllDescription: "Rewrite all as indexed access types",
|
||||
newFileContent:
|
||||
`interface Foo {
|
||||
bar: string;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "disableJsDiagnostics",
|
||||
fixAllDescription: "Add '@ts-ignore' to all error messages",
|
||||
newFileContent:
|
||||
`let x = "";
|
||||
// @ts-ignore
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "extendsInterfaceBecomesImplements",
|
||||
fixAllDescription: "Change all extended interfaces to 'implements'",
|
||||
newFileContent: `interface I {}
|
||||
class C implements I {}
|
||||
class D implements I {}`,
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "forgottenThisPropertyAccess",
|
||||
fixAllDescription: "Add 'this.' to all unresolved variables matching a member name",
|
||||
newFileContent:
|
||||
`class C {
|
||||
foo: number;
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "correctQualifiedNameToIndexedAccessType",
|
||||
fixAllDescription: "Rewrite all as indexed access types",
|
||||
newFileContent:
|
||||
`/**
|
||||
* @typedef Foo
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "inferFromUsage",
|
||||
fixAllDescription: "Infer all types from usage",
|
||||
newFileContent:
|
||||
`function f(x: number, y: string) {
|
||||
x += 0;
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "fixSpelling",
|
||||
fixAllDescription: "Fix all detected spelling errors",
|
||||
newFileContent:
|
||||
`function f(s: string) {
|
||||
s.toString();
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "unusedIdentifier_delete",
|
||||
fixAllDescription: "Delete all unused declarations",
|
||||
newFileContent:
|
||||
`function f() {
|
||||
}`,
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "unusedIdentifier_prefix",
|
||||
fixAllDescription: "Prefix all unused declarations with '_' where possible",
|
||||
newFileContent:
|
||||
`function f(_a, _b) {
|
||||
const x = 0; // Can't be prefixed, ignored
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
goTo.file("/b.ts");
|
||||
verify.codeFixAll({
|
||||
fixId: "useDefaultImport",
|
||||
fixAllDescription: "Convert all to default imports",
|
||||
newFileContent:
|
||||
`import a1 from "./a";
|
||||
import a2 from "./a";`,
|
||||
|
||||
@ -298,7 +298,7 @@ declare namespace FourSlashInterface {
|
||||
docCommentTemplateAt(markerName: string | FourSlashInterface.Marker, expectedOffset: number, expectedText: string): void;
|
||||
noDocCommentTemplateAt(markerName: string | FourSlashInterface.Marker): void;
|
||||
rangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number): void;
|
||||
codeFixAll(options: { fixId: string, newFileContent: string, commands?: {}[] }): void;
|
||||
codeFixAll(options: { fixId: string, fixAllDescription: string, newFileContent: string, commands?: {}[] }): void;
|
||||
fileAfterApplyingRefactorAtMarker(markerName: string, expectedContent: string, refactorNameToApply: string, actionName: string, formattingOptions?: FormatCodeOptions): void;
|
||||
rangeIs(expectedText: string, includeWhiteSpace?: boolean): void;
|
||||
fileAfterApplyingRefactorAtMarker(markerName: string, expectedContent: string, refactorNameToApply: string, formattingOptions?: FormatCodeOptions): void;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user