Skip to content

Commit

Permalink
Code Actions - Add fix all support (#6310)
Browse files Browse the repository at this point in the history
* wip

* wip

* feedback

* remove comment

* comments

* comments
  • Loading branch information
akhera99 authored Oct 2, 2023
1 parent b05277d commit 0ed4684
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 0 deletions.
2 changes: 2 additions & 0 deletions l10n/bundle.l10n.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@
"Choose and set default": "Choose and set default",
"Do not load any": "Do not load any",
"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?",
"Pick a fix all scope": "Pick a fix all scope",
"Fix All Code Action": "Fix All Code Action",
"pipeArgs must be a string or a string array type": "pipeArgs must be a string or a string array type",
"Name not defined in current configuration.": "Name not defined in current configuration.",
"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.",
Expand Down
74 changes: 74 additions & 0 deletions src/lsptoolshost/fixAllCodeAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as vscode from 'vscode';
import * as RoslynProtocol from './roslynProtocol';
import { LSPAny } from 'vscode-languageserver-protocol';
import { RoslynLanguageServer } from './roslynLanguageServer';
import { URIConverter, createConverter } from 'vscode-languageclient/lib/common/protocolConverter';
import { UriConverter } from './uriConverter';

export function registerCodeActionFixAllCommands(
context: vscode.ExtensionContext,
languageServer: RoslynLanguageServer,
outputChannel: vscode.OutputChannel
) {
context.subscriptions.push(
vscode.commands.registerCommand(
'roslyn.client.fixAllCodeAction',
async (request): Promise<void> => registerFixAllResolveCodeAction(languageServer, request, outputChannel)
)
);
}

async function registerFixAllResolveCodeAction(
languageServer: RoslynLanguageServer,
codeActionData: any,
outputChannel: vscode.OutputChannel
) {
if (codeActionData) {
const data = <LSPAny>codeActionData;
const result = await vscode.window.showQuickPick(data.FixAllFlavors, {
placeHolder: vscode.l10n.t('Pick a fix all scope'),
});

await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
title: vscode.l10n.t('Fix All Code Action'),
cancellable: true,
},
async (_, token) => {
if (result) {
const fixAllCodeAction: RoslynProtocol.RoslynFixAllCodeAction = {
title: data.UniqueIdentifier,
data: data,
scope: result,
};

const response = await languageServer.sendRequest(
RoslynProtocol.CodeActionFixAllResolveRequest.type,
fixAllCodeAction,
token
);

if (response.edit) {
const uriConverter: URIConverter = (value: string): vscode.Uri =>
UriConverter.deserialize(value);
const protocolConverter = createConverter(uriConverter, true, true);
const fixAllEdit = await protocolConverter.asWorkspaceEdit(response.edit);
if (!(await vscode.workspace.applyEdit(fixAllEdit))) {
const componentName = '[roslyn.client.fixAllCodeAction]';
const errorMessage = 'Failed to make a fix all edit for completion.';
outputChannel.show();
outputChannel.appendLine(`${componentName} ${errorMessage}`);
throw new Error('Tried to insert multiple code action edits, but an error occurred.');
}
}
}
}
);
}
}
3 changes: 3 additions & 0 deletions src/lsptoolshost/roslynLanguageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import { RoslynLanguageServerEvents } from './languageServerEvents';
import { registerShowToastNotification } from './showToastNotification';
import { registerRazorCommands } from './razorCommands';
import { registerOnAutoInsert } from './onAutoInsert';
import { registerCodeActionFixAllCommands } from './fixAllCodeAction';
import { commonOptions, languageServerOptions, omnisharpOptions } from '../shared/options';
import { NamedPipeInformation } from './roslynProtocol';
import { IDisposable } from '../disposable';
Expand Down Expand Up @@ -862,6 +863,8 @@ export async function activateRoslynLanguageServer(
// Register any commands that need to be handled by the extension.
registerCommands(context, languageServer, hostExecutableResolver, _channel);

registerCodeActionFixAllCommands(context, languageServer, _channel);

registerRazorCommands(context, languageServer);

registerUnitTestingCommands(context, languageServer, dotnetTestChannel);
Expand Down
11 changes: 11 additions & 0 deletions src/lsptoolshost/roslynProtocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { Command } from 'vscode';
import * as lsp from 'vscode-languageserver-protocol';
import { CodeAction } from 'vscode-languageserver-protocol';
import { ProjectConfigurationMessage } from '../shared/projectConfiguration';

export interface WorkspaceDebugConfigurationParams {
Expand Down Expand Up @@ -141,6 +142,10 @@ export interface BuildOnlyDiagnosticIdsResult {
ids: string[];
}

export interface RoslynFixAllCodeAction extends CodeAction {
scope: string;
}

export interface NamedPipeInformation {
pipeName: string;
}
Expand Down Expand Up @@ -218,3 +223,9 @@ export namespace BuildOnlyDiagnosticIdsRequest {
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer;
export const type = new lsp.RequestType0<BuildOnlyDiagnosticIdsResult, void>(method);
}

export namespace CodeActionFixAllResolveRequest {
export const method = 'codeAction/resolveFixAll';
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer;
export const type = new lsp.RequestType<RoslynFixAllCodeAction, RoslynFixAllCodeAction, void>(method);
}

0 comments on commit 0ed4684

Please sign in to comment.