diff --git a/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCodeActionHandler.cs b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCodeActionHandler.cs index 4453359080..fbc96b11c2 100644 --- a/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCodeActionHandler.cs +++ b/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCodeActionHandler.cs @@ -1,29 +1,23 @@ using System.Linq; using System.Collections.Generic; -using System.Diagnostics; using System.Threading; using System.Threading.Tasks; -using MediatR; -using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Protocol; using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; using OmniSharp.Extensions.LanguageServer.Protocol.Models; using OmniSharp.Extensions.LanguageServer.Protocol.Server; -using OmniSharp.Models.V2.CodeActions; using OmniSharp.Extensions.LanguageServer.Protocol.Document; -using OmniSharp.Extensions.LanguageServer.Protocol.Workspace; -using OmniSharp.Models; using Diagnostic = OmniSharp.Extensions.LanguageServer.Protocol.Models.Diagnostic; +using OmniSharp.Models.V2.CodeActions; namespace OmniSharp.LanguageServerProtocol.Handlers { - internal sealed class OmniSharpCodeActionHandler : CodeActionHandlerBase, IExecuteCommandHandler + internal sealed class OmniSharpCodeActionHandler : CodeActionHandlerBase { public static IEnumerable Enumerate( RequestHandlers handlers, - ISerializer serializer, ILanguageServer mediator, DocumentVersions versions) { @@ -31,16 +25,13 @@ public static IEnumerable Enumerate( .OfType, Mef.IRequestHandler>()) { - yield return new OmniSharpCodeActionHandler(getActionsHandler, runActionHandler, selector, serializer, mediator, versions); + yield return new OmniSharpCodeActionHandler(getActionsHandler, runActionHandler, selector, mediator, versions); } } private readonly Mef.IRequestHandler _getActionsHandler; - private readonly ExecuteCommandRegistrationOptions _executeCommandRegistrationOptions; - private ExecuteCommandCapability _executeCommandCapability; - private Mef.IRequestHandler _runActionHandler; + private readonly Mef.IRequestHandler _runActionHandler; private readonly DocumentSelector _documentSelector; - private readonly ISerializer _serializer; private readonly ILanguageServer _server; private readonly DocumentVersions _documentVersions; @@ -48,24 +39,21 @@ public OmniSharpCodeActionHandler( Mef.IRequestHandler getActionsHandler, Mef.IRequestHandler runActionHandler, DocumentSelector documentSelector, - ISerializer serializer, ILanguageServer server, DocumentVersions documentVersions) { _getActionsHandler = getActionsHandler; _runActionHandler = runActionHandler; _documentSelector = documentSelector; - _serializer = serializer; _server = server; _documentVersions = documentVersions; - _executeCommandRegistrationOptions = new ExecuteCommandRegistrationOptions() - { - Commands = new Container("omnisharp/executeCodeAction"), - }; } public override async Task Handle(CodeActionParams request, CancellationToken cancellationToken) { + var codeActionCaps = _server.ClientSettings.Capabilities.TextDocument.CodeAction.Value; + bool clientCanResolveEditProp = codeActionCaps.ResolveSupport?.Properties.Contains("edit") ?? false; + var omnisharpRequest = new GetCodeActionsRequest { FileName = Helpers.FromUri(request.TextDocument.Uri), @@ -87,40 +75,44 @@ public override async Task Handle(CodeActionParams else if (ca.Identifier.StartsWith("Change ")) { kind = CodeActionKind.QuickFix; } else { kind = CodeActionKind.Refactor; } - codeActions.Add( - new CodeAction - { - Title = ca.Name, - Kind = kind, - Diagnostics = new Container(), - Edit = new WorkspaceEdit(), - Command = Command.Create("omnisharp/executeCodeAction") - .WithArguments(new CommandData() - { - Uri = request.TextDocument.Uri, - Identifier = ca.Identifier, - Name = ca.Name, - Range = request.Range, - }) - with { Title = ca.Name } - }); + var codeAction = new CodeAction { + Title = ca.Name, + Kind = kind, + Diagnostics = new Container(), + Edit = null, + Data = JObject.FromObject( + new CommandData() + { + Uri = request.TextDocument.Uri, + Identifier = ca.Identifier, + Name = ca.Name, + Range = request.Range, + }) + }; + + if (!clientCanResolveEditProp) + { + var codeActionResolution = await this.Handle(codeAction, cancellationToken); + + codeAction = codeAction with { + Edit = codeActionResolution.Edit, + Data = null, + }; + } + + codeActions.Add(codeAction); } return new CommandOrCodeActionContainer( codeActions.Select(ca => new CommandOrCodeAction(ca))); } - public override Task Handle(CodeAction request, CancellationToken cancellationToken) + public override async Task Handle(CodeAction request, CancellationToken cancellationToken) { - return Task.FromResult(request); - } + var data = request.Data.ToObject(); - public async Task Handle(ExecuteCommandParams request, CancellationToken cancellationToken) - { - Debug.Assert(request.Command == "omnisharp/executeCodeAction"); - var data = request.ExtractArguments(_serializer); - - var omnisharpCaRequest = new RunCodeActionRequest { + var omnisharpCaRequest = new RunCodeActionRequest + { Identifier = data.Identifier, FileName = data.Uri.GetFileSystemPath(), Column = data.Range.Start.Character, @@ -139,19 +131,16 @@ public async Task Handle(ExecuteCommandParams request, CancellationToken c _server.ClientSettings.Capabilities.Workspace!.WorkspaceEdit.Value, _documentVersions ); - ; - await _server.Workspace.ApplyWorkspaceEdit(new ApplyWorkspaceEditParams() + return new CodeAction { - Label = data.Name, - Edit = edit - }, cancellationToken); - - // Do something with response? - //if (response.Applied) + Edit = edit, + }; + } + else + { + return new CodeAction(); } - - return Unit.Value; } class CommandData @@ -162,12 +151,6 @@ class CommandData public Range Range { get; set;} } - ExecuteCommandRegistrationOptions IRegistration.GetRegistrationOptions(ExecuteCommandCapability capability, ClientCapabilities clientCapabilities) - { - _executeCommandCapability = capability; - return _executeCommandRegistrationOptions; - } - protected override CodeActionRegistrationOptions CreateRegistrationOptions(CodeActionCapability capability, ClientCapabilities clientCapabilities) { return new CodeActionRegistrationOptions() @@ -177,6 +160,7 @@ protected override CodeActionRegistrationOptions CreateRegistrationOptions(CodeA CodeActionKind.SourceOrganizeImports, CodeActionKind.Refactor, CodeActionKind.RefactorExtract), + ResolveProvider = true, }; } } diff --git a/src/OmniSharp.LanguageServerProtocol/LanguageServerHost.cs b/src/OmniSharp.LanguageServerProtocol/LanguageServerHost.cs index ea5af6d28d..9df052daed 100644 --- a/src/OmniSharp.LanguageServerProtocol/LanguageServerHost.cs +++ b/src/OmniSharp.LanguageServerProtocol/LanguageServerHost.cs @@ -381,7 +381,7 @@ internal static void RegisterHandlers(ILanguageServer server, CompositionHost co .Concat(OmniSharpReferencesHandler.Enumerate(handlers)) .Concat(OmniSharpImplementationHandler.Enumerate(handlers)) .Concat(OmniSharpCodeLensHandler.Enumerate(handlers)) - .Concat(OmniSharpCodeActionHandler.Enumerate(handlers, serializer, server, documentVersions)) + .Concat(OmniSharpCodeActionHandler.Enumerate(handlers, server, documentVersions)) .Concat(OmniSharpDocumentFormattingHandler.Enumerate(handlers)) .Concat(OmniSharpDocumentFormatRangeHandler.Enumerate(handlers)) .Concat(OmniSharpDocumentOnTypeFormattingHandler.Enumerate(handlers)))