Skip to content

Commit

Permalink
(OmniSharpGH-1205) Adds support for code actions in .cake files
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorkstromm committed Jun 4, 2018
1 parent faadb82 commit dad9932
Show file tree
Hide file tree
Showing 7 changed files with 365 additions and 3 deletions.
39 changes: 39 additions & 0 deletions src/OmniSharp.Cake/Extensions/ResponseExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using OmniSharp.Models.Navigate;
using OmniSharp.Models.MembersTree;
using OmniSharp.Models.Rename;
using OmniSharp.Models.V2;

namespace OmniSharp.Cake.Extensions
{
Expand Down Expand Up @@ -85,6 +86,44 @@ public static async Task<RenameResponse> TranslateAsync(this RenameResponse resp
return response;
}

public static async Task<RunCodeActionResponse> TranslateAsync(this RunCodeActionResponse response, OmniSharpWorkspace workspace)
{
if (response?.Changes == null)
{
return response;
}

var fileOperations = new List<FileOperationResponse>();
var changes = new Dictionary<string, List<LinePositionSpanTextChange>>();

foreach (var fileOperation in response.Changes)
{
if (fileOperation.ModificationType == FileModificationType.Modified &&
fileOperation is ModifiedFileResponse modifiedFile)
{
await PopulateModificationsAsync(modifiedFile, workspace, changes);
}

fileOperations.Add(fileOperation);
}

foreach (var change in changes)
{

if (!(fileOperations.FirstOrDefault(x => x.FileName == change.Key &&
x.ModificationType == FileModificationType.Modified)
is ModifiedFileResponse modifiedFile))
{
continue;
}

modifiedFile.Changes = change.Value;
}

response.Changes = fileOperations;
return response;
}

private static async Task<FileMemberElement> TranslateAsync(this FileMemberElement element, OmniSharpWorkspace workspace, Request request)
{
element.Location = await element.Location.TranslateAsync(workspace, request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public virtual async Task<TResponse> Handle(TRequest request)
return await TranslateResponse(response, request);
}

public virtual bool IsValid(TRequest request) => true;
protected virtual bool IsValid(TRequest request) => true;

protected virtual async Task<TRequest> TranslateRequestAsync(TRequest req)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public CodeCheckHandler(
{
}

public override bool IsValid(CodeCheckRequest request) =>
protected override bool IsValid(CodeCheckRequest request) =>
!string.IsNullOrEmpty(request.FileName);

protected override Task<QuickFixResponse> TranslateResponse(QuickFixResponse response, CodeCheckRequest request)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Composition;
using System.Threading.Tasks;
using OmniSharp.Cake.Utilities;
using OmniSharp.Mef;
using OmniSharp.Models.V2;

namespace OmniSharp.Cake.Services.RequestHandlers.Refactoring.V2
{
public abstract class BaseCodeActionsHandler<TRequest, TResponse> : CakeRequestHandler<TRequest, TResponse>
where TRequest : ICodeActionRequest
{
protected BaseCodeActionsHandler(
OmniSharpWorkspace workspace)
: base(workspace)
{
}

protected override async Task<TRequest> TranslateRequestAsync(TRequest request)
{
if (request.Selection != null)
{
var startLine = await LineIndexHelper.TranslateToGenerated(request.FileName, request.Selection.Start.Line, Workspace);
request.Selection.End.Line = request.Selection.Start.Line != request.Selection.End.Line
? await LineIndexHelper.TranslateToGenerated(request.FileName, request.Selection.End.Line, Workspace)
: startLine;
request.Selection.Start.Line = startLine;
}

return await base.TranslateRequestAsync(request);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
using System.Composition;
using System.Linq;
using System.Threading.Tasks;
using OmniSharp.Cake.Utilities;
using OmniSharp.Mef;
using OmniSharp.Models.V2;

namespace OmniSharp.Cake.Services.RequestHandlers.Refactoring.V2
{
[OmniSharpHandler(OmniSharpEndpoints.V2.GetCodeActions, Constants.LanguageNames.Cake), Shared]
public class GetCodeActionsHandler : CakeRequestHandler<GetCodeActionsRequest, GetCodeActionsResponse>
public class GetCodeActionsHandler : BaseCodeActionsHandler<GetCodeActionsRequest, GetCodeActionsResponse>
{
[ImportingConstructor]
public GetCodeActionsHandler(
OmniSharpWorkspace workspace)
: base(workspace)
{
}

protected override Task<GetCodeActionsResponse> TranslateResponse(GetCodeActionsResponse response, GetCodeActionsRequest request)
{
if (response?.CodeActions == null)
{
return Task.FromResult(response);
}

// At this point, we remove the "Rename file to.." code actions as these will
// return the buffer as known to Roslyn to the client. Currently we don't store
// the buffer as seen by the client and it's next to impossible to reverse it.
response.CodeActions = response.CodeActions
.Where(x => !x.Identifier.StartsWith("Rename file to"))
.ToList();

return Task.FromResult(response);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using System.Composition;
using System.Threading.Tasks;
using OmniSharp.Cake.Extensions;
using OmniSharp.Mef;
using OmniSharp.Models;
using OmniSharp.Models.FileOpen;
using OmniSharp.Models.V2;

namespace OmniSharp.Cake.Services.RequestHandlers.Refactoring.V2
{
[OmniSharpHandler(OmniSharpEndpoints.V2.RunCodeAction, Constants.LanguageNames.Cake), Shared]
public class RunCodeActionsHandler : BaseCodeActionsHandler<RunCodeActionRequest, RunCodeActionResponse>
{
[ImportingConstructor]
public RunCodeActionsHandler(
OmniSharpWorkspace workspace)
: base(workspace)
{
}

protected override bool IsValid(RunCodeActionRequest request) => request.WantsTextChanges;

protected override Task<RunCodeActionResponse> TranslateResponse(RunCodeActionResponse response, RunCodeActionRequest request)
{
return response.TranslateAsync(Workspace);
}
}
}
Loading

0 comments on commit dad9932

Please sign in to comment.