Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code Actions - Add fix all support #6310

Merged
merged 10 commits into from
Oct 2, 2023

Conversation

akhera99
Copy link
Member

@akhera99 akhera99 commented Sep 7, 2023

  • Creates a new CodeAction type, RoslynFixAllCodeAction that specifies the scope being used for fix all
  • Creates a new request to retrieve the new CodeAction type that contains a WorkspaceEdit with fix all edits
  • Resolves at the middleware layer
  • Uses quick picks to determine the selected scope and passes that along
  • Converts the LSP WorkspaceEdit to a VS Code WorkspaceEdit and tries to apply it.
Untitled.video.mp4

@ShreyasJejurkar
Copy link

Thank you for this, great work! 🎉

@akhera99 akhera99 marked this pull request as ready for review September 13, 2023 21:34
@akhera99 akhera99 requested a review from a team as a code owner September 13, 2023 21:34
resolveCodeAction: async (codeAction, token, next) => {
const lspCodeAction = <CodeAction>codeAction;
const data = lspCodeAction.data;
if (data.FixAllFlavors) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it comes from Roslyn, but it is amusing that it is called FixAll"Flavors" and not "Scopes" or "Kinds".

src/lsptoolshost/roslynLanguageServer.ts Outdated Show resolved Hide resolved
src/lsptoolshost/roslynLanguageServer.ts Outdated Show resolved Hide resolved
src/lsptoolshost/roslynLanguageServer.ts Outdated Show resolved Hide resolved
src/lsptoolshost/roslynLanguageServer.ts Outdated Show resolved Hide resolved
@@ -202,6 +205,46 @@ export class RoslynLanguageServer {
workspace: {
configuration: (params) => readConfigurations(params),
},
resolveCodeAction: async (codeAction, token, next) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I like the approach you took here, but it is slightly different from what we talked about before. I like this better anyway though, but we can simplify a little bit more.

Since you're directly applying the workspace edit (via vscode.workspace.applyEdit) and not returning a resolved code action to vscode, it would be better to have this implementation just be a command.

Essentially:

  1. On the server side, instead of adding the flavor to the 'data' object, you would return a fix all code action that contains a command (e.g. roslyn.fixAll) with arguments containing whatever flavor information you need to call back to the server as you do now. An example of where we do this is here - https://github.com/dotnet/roslyn/blob/main/src/Features/LanguageServer/Protocol/Handler/CodeLens/CodeLensHandler.cs#L149
  2. Instead of implementing this as part of the resolveCodeAction middleware - you would move this implementation to a command handler. The implementation here basically wouldn't change (minus my other feedback). For example, where the client implements the command I linked above - https://github.com/dotnet/vscode-csharp/blob/main/src/lsptoolshost/unitTesting.ts#L21

Then what happens is that when you select the fix all action in the list - the vscode LSP client will invoke our command handler (based on the command id we returned in the code action)

src/lsptoolshost/roslynLanguageServer.ts Outdated Show resolved Hide resolved
const result = await protocolConverter.asWorkspaceEdit(response.edit);

if (!(await vscode.workspace.applyEdit(result))) {
throw new Error(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after you've finished addressing the other comments (e.g. moving to a command), can you make sure that if this fails it shows an error toast? if it doesn't we might need to explicitly show one.

@@ -202,6 +203,46 @@ export class RoslynLanguageServer {
workspace: {
configuration: (params) => readConfigurations(params),
},
// resolveCodeAction: async (codeAction, token, next) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should remove

}
);

if (!(await vscode.workspace.applyEdit(fixAllEdit))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the apply edit should go inside the progress as well. I think it won't be cancellable because you don't pass in the cancellation token

);

if (!(await vscode.workspace.applyEdit(fixAllEdit))) {
throw new Error('Tried to insert multiple code action edits, but an error occurred.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test this to make sure the error is visible (hopefully in the C# output window). If not you may need to manually write it there via passing in the output channel

@akhera99 akhera99 enabled auto-merge (squash) October 2, 2023 19:56
@akhera99 akhera99 merged commit 0ed4684 into dotnet:main Oct 2, 2023
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants