Skip to content

Commit ea5da00

Browse files
Merge pull request #1718 from PowerShell/andschwa/multiple-codeactions
Return a code action for each diagnostic record
2 parents 640eac8 + f853cee commit ea5da00

File tree

1 file changed

+32
-30
lines changed

1 file changed

+32
-30
lines changed

src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeActionHandler.cs

+32-30
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33

44
using System;
55
using System.Collections.Generic;
6-
using System.Linq;
76
using System.Threading;
87
using System.Threading.Tasks;
98
using Microsoft.Extensions.Logging;
109
using Microsoft.PowerShell.EditorServices.Services;
1110
using Microsoft.PowerShell.EditorServices.Services.TextDocument;
1211
using Microsoft.PowerShell.EditorServices.Utility;
13-
using Newtonsoft.Json.Linq;
1412
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
1513
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
1614
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
@@ -21,21 +19,22 @@ internal class PsesCodeActionHandler : CodeActionHandlerBase
2119
{
2220
private readonly ILogger _logger;
2321
private readonly AnalysisService _analysisService;
24-
private readonly WorkspaceService _workspaceService;
2522

26-
public PsesCodeActionHandler(ILoggerFactory factory, AnalysisService analysisService, WorkspaceService workspaceService)
23+
public PsesCodeActionHandler(ILoggerFactory factory, AnalysisService analysisService)
2724
{
2825
_logger = factory.CreateLogger<PsesCodeActionHandler>();
2926
_analysisService = analysisService;
30-
_workspaceService = workspaceService;
3127
}
3228

33-
protected override CodeActionRegistrationOptions CreateRegistrationOptions(CodeActionCapability capability, ClientCapabilities clientCapabilities) => new CodeActionRegistrationOptions
29+
protected override CodeActionRegistrationOptions CreateRegistrationOptions(CodeActionCapability capability, ClientCapabilities clientCapabilities)
30+
{
31+
return new()
3432
{
35-
// TODO: What do we do with the arguments?
36-
DocumentSelector = LspUtils.PowerShellDocumentSelector,
37-
CodeActionKinds = new CodeActionKind[] { CodeActionKind.QuickFix }
38-
};
33+
// TODO: What do we do with the arguments?
34+
DocumentSelector = LspUtils.PowerShellDocumentSelector,
35+
CodeActionKinds = new CodeActionKind[] { CodeActionKind.QuickFix }
36+
};
37+
}
3938

4039
// TODO: Either fix or ignore "method lacks 'await'" warning.
4140
public override async Task<CodeAction> Handle(CodeAction request, CancellationToken cancellationToken)
@@ -65,7 +64,7 @@ public override async Task<CommandOrCodeActionContainer> Handle(CodeActionParams
6564
return Array.Empty<CommandOrCodeAction>();
6665
}
6766

68-
var codeActions = new List<CommandOrCodeAction>();
67+
List<CommandOrCodeAction> codeActions = new();
6968

7069
// If there are any code fixes, send these commands first so they appear at top of "Code Fix" menu in the client UI.
7170
foreach (Diagnostic diagnostic in request.Context.Diagnostics)
@@ -81,31 +80,34 @@ public override async Task<CommandOrCodeActionContainer> Handle(CodeActionParams
8180
string diagnosticId = AnalysisService.GetUniqueIdFromDiagnostic(diagnostic);
8281
if (corrections.TryGetValue(diagnosticId, out MarkerCorrection correction))
8382
{
84-
codeActions.Add(new CodeAction
83+
foreach (ScriptRegion edit in correction.Edits)
8584
{
86-
Title = correction.Name,
87-
Kind = CodeActionKind.QuickFix,
88-
Edit = new WorkspaceEdit
85+
codeActions.Add(new CodeAction
8986
{
90-
DocumentChanges = new Container<WorkspaceEditDocumentChange>(
91-
new WorkspaceEditDocumentChange(
92-
new TextDocumentEdit
93-
{
94-
TextDocument = new OptionalVersionedTextDocumentIdentifier
87+
Title = correction.Name,
88+
Kind = CodeActionKind.QuickFix,
89+
Edit = new WorkspaceEdit
90+
{
91+
DocumentChanges = new Container<WorkspaceEditDocumentChange>(
92+
new WorkspaceEditDocumentChange(
93+
new TextDocumentEdit
9594
{
96-
Uri = request.TextDocument.Uri
97-
},
98-
Edits = new TextEditContainer(correction.Edits.Select(ScriptRegion.ToTextEdit))
99-
}))
100-
}
101-
});
95+
TextDocument = new OptionalVersionedTextDocumentIdentifier
96+
{
97+
Uri = request.TextDocument.Uri
98+
},
99+
Edits = new TextEditContainer(ScriptRegion.ToTextEdit(edit))
100+
}))
101+
}
102+
});
103+
}
102104
}
103105
}
104106

105107
// Add "show documentation" commands last so they appear at the bottom of the client UI.
106108
// These commands do not require code fixes. Sometimes we get a batch of diagnostics
107109
// to create commands for. No need to create multiple show doc commands for the same rule.
108-
var ruleNamesProcessed = new HashSet<string>();
110+
HashSet<string> ruleNamesProcessed = new();
109111
foreach (Diagnostic diagnostic in request.Context.Diagnostics)
110112
{
111113
if (
@@ -119,8 +121,8 @@ public override async Task<CommandOrCodeActionContainer> Handle(CodeActionParams
119121
if (string.Equals(diagnostic.Source, "PSScriptAnalyzer", StringComparison.OrdinalIgnoreCase) &&
120122
!ruleNamesProcessed.Contains(diagnostic.Code?.String))
121123
{
122-
ruleNamesProcessed.Add(diagnostic.Code?.String);
123-
var title = $"Show documentation for: {diagnostic.Code?.String}";
124+
_ = ruleNamesProcessed.Add(diagnostic.Code?.String);
125+
string title = $"Show documentation for: {diagnostic.Code?.String}";
124126
codeActions.Add(new CodeAction
125127
{
126128
Title = title,
@@ -132,7 +134,7 @@ public override async Task<CommandOrCodeActionContainer> Handle(CodeActionParams
132134
{
133135
Title = title,
134136
Name = "PowerShell.ShowCodeActionDocumentation",
135-
Arguments = JArray.FromObject(new[] { diagnostic.Code?.String })
137+
Arguments = Newtonsoft.Json.Linq.JArray.FromObject(new[] { diagnostic.Code?.String })
136138
}
137139
});
138140
}

0 commit comments

Comments
 (0)