Skip to content

Commit 0ed4684

Browse files
authored
Code Actions - Add fix all support (#6310)
* wip * wip * feedback * remove comment * comments * comments
1 parent b05277d commit 0ed4684

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

l10n/bundle.l10n.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@
128128
"Choose and set default": "Choose and set default",
129129
"Do not load any": "Do not load any",
130130
"C# configuration has changed. Would you like to reload the window to apply your changes?": "C# configuration has changed. Would you like to reload the window to apply your changes?",
131+
"Pick a fix all scope": "Pick a fix all scope",
132+
"Fix All Code Action": "Fix All Code Action",
131133
"pipeArgs must be a string or a string array type": "pipeArgs must be a string or a string array type",
132134
"Name not defined in current configuration.": "Name not defined in current configuration.",
133135
"Configuration \"{0}\" in launch.json does not have a {1} argument with {2} for remote process listing.": "Configuration \"{0}\" in launch.json does not have a {1} argument with {2} for remote process listing.",

src/lsptoolshost/fixAllCodeAction.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
import * as RoslynProtocol from './roslynProtocol';
8+
import { LSPAny } from 'vscode-languageserver-protocol';
9+
import { RoslynLanguageServer } from './roslynLanguageServer';
10+
import { URIConverter, createConverter } from 'vscode-languageclient/lib/common/protocolConverter';
11+
import { UriConverter } from './uriConverter';
12+
13+
export function registerCodeActionFixAllCommands(
14+
context: vscode.ExtensionContext,
15+
languageServer: RoslynLanguageServer,
16+
outputChannel: vscode.OutputChannel
17+
) {
18+
context.subscriptions.push(
19+
vscode.commands.registerCommand(
20+
'roslyn.client.fixAllCodeAction',
21+
async (request): Promise<void> => registerFixAllResolveCodeAction(languageServer, request, outputChannel)
22+
)
23+
);
24+
}
25+
26+
async function registerFixAllResolveCodeAction(
27+
languageServer: RoslynLanguageServer,
28+
codeActionData: any,
29+
outputChannel: vscode.OutputChannel
30+
) {
31+
if (codeActionData) {
32+
const data = <LSPAny>codeActionData;
33+
const result = await vscode.window.showQuickPick(data.FixAllFlavors, {
34+
placeHolder: vscode.l10n.t('Pick a fix all scope'),
35+
});
36+
37+
await vscode.window.withProgress(
38+
{
39+
location: vscode.ProgressLocation.Notification,
40+
title: vscode.l10n.t('Fix All Code Action'),
41+
cancellable: true,
42+
},
43+
async (_, token) => {
44+
if (result) {
45+
const fixAllCodeAction: RoslynProtocol.RoslynFixAllCodeAction = {
46+
title: data.UniqueIdentifier,
47+
data: data,
48+
scope: result,
49+
};
50+
51+
const response = await languageServer.sendRequest(
52+
RoslynProtocol.CodeActionFixAllResolveRequest.type,
53+
fixAllCodeAction,
54+
token
55+
);
56+
57+
if (response.edit) {
58+
const uriConverter: URIConverter = (value: string): vscode.Uri =>
59+
UriConverter.deserialize(value);
60+
const protocolConverter = createConverter(uriConverter, true, true);
61+
const fixAllEdit = await protocolConverter.asWorkspaceEdit(response.edit);
62+
if (!(await vscode.workspace.applyEdit(fixAllEdit))) {
63+
const componentName = '[roslyn.client.fixAllCodeAction]';
64+
const errorMessage = 'Failed to make a fix all edit for completion.';
65+
outputChannel.show();
66+
outputChannel.appendLine(`${componentName} ${errorMessage}`);
67+
throw new Error('Tried to insert multiple code action edits, but an error occurred.');
68+
}
69+
}
70+
}
71+
}
72+
);
73+
}
74+
}

src/lsptoolshost/roslynLanguageServer.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { RoslynLanguageServerEvents } from './languageServerEvents';
5252
import { registerShowToastNotification } from './showToastNotification';
5353
import { registerRazorCommands } from './razorCommands';
5454
import { registerOnAutoInsert } from './onAutoInsert';
55+
import { registerCodeActionFixAllCommands } from './fixAllCodeAction';
5556
import { commonOptions, languageServerOptions, omnisharpOptions } from '../shared/options';
5657
import { NamedPipeInformation } from './roslynProtocol';
5758
import { IDisposable } from '../disposable';
@@ -862,6 +863,8 @@ export async function activateRoslynLanguageServer(
862863
// Register any commands that need to be handled by the extension.
863864
registerCommands(context, languageServer, hostExecutableResolver, _channel);
864865

866+
registerCodeActionFixAllCommands(context, languageServer, _channel);
867+
865868
registerRazorCommands(context, languageServer);
866869

867870
registerUnitTestingCommands(context, languageServer, dotnetTestChannel);

src/lsptoolshost/roslynProtocol.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import { Command } from 'vscode';
77
import * as lsp from 'vscode-languageserver-protocol';
8+
import { CodeAction } from 'vscode-languageserver-protocol';
89
import { ProjectConfigurationMessage } from '../shared/projectConfiguration';
910

1011
export interface WorkspaceDebugConfigurationParams {
@@ -141,6 +142,10 @@ export interface BuildOnlyDiagnosticIdsResult {
141142
ids: string[];
142143
}
143144

145+
export interface RoslynFixAllCodeAction extends CodeAction {
146+
scope: string;
147+
}
148+
144149
export interface NamedPipeInformation {
145150
pipeName: string;
146151
}
@@ -218,3 +223,9 @@ export namespace BuildOnlyDiagnosticIdsRequest {
218223
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer;
219224
export const type = new lsp.RequestType0<BuildOnlyDiagnosticIdsResult, void>(method);
220225
}
226+
227+
export namespace CodeActionFixAllResolveRequest {
228+
export const method = 'codeAction/resolveFixAll';
229+
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer;
230+
export const type = new lsp.RequestType<RoslynFixAllCodeAction, RoslynFixAllCodeAction, void>(method);
231+
}

0 commit comments

Comments
 (0)