Skip to content

Commit 027ff4e

Browse files
Merge pull request #1740 from PowerShell/andschwa/abcs
Finish use of ABC instead of interface TODOs
2 parents 5098f0d + 5e2681d commit 027ff4e

File tree

7 files changed

+126
-141
lines changed

7 files changed

+126
-141
lines changed

src/PowerShellEditorServices/Server/PsesDebugServer.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ public async Task StartAsync()
8181
.WithHandler<StackTraceHandler>()
8282
.WithHandler<ScopesHandler>()
8383
.WithHandler<VariablesHandler>()
84-
.WithHandler<DebuggerActionHandlers>()
84+
.WithHandler<ContinueHandler>()
85+
.WithHandler<NextHandler>()
86+
.WithHandler<PauseHandler>()
87+
.WithHandler<StepInHandler>()
88+
.WithHandler<StepOutHandler>()
8589
.WithHandler<SourceHandler>()
8690
.WithHandler<SetVariableHandler>()
8791
.WithHandler<DebugEvaluateHandler>()

src/PowerShellEditorServices/Server/PsesLanguageServer.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ public async Task StartAsync()
8080
.WithOutput(_outputStream)
8181
.WithServices(serviceCollection =>
8282
{
83-
8483
// NOTE: This adds a lot of services!
8584
serviceCollection.AddPsesLanguageServices(_hostDetails);
8685
})
@@ -94,7 +93,8 @@ public async Task StartAsync()
9493
.WithHandler<GetVersionHandler>()
9594
.WithHandler<PsesConfigurationHandler>()
9695
.WithHandler<PsesFoldingRangeHandler>()
97-
.WithHandler<PsesDocumentFormattingHandlers>()
96+
.WithHandler<PsesDocumentFormattingHandler>()
97+
.WithHandler<PsesDocumentRangeFormattingHandler>()
9898
.WithHandler<PsesReferencesHandler>()
9999
.WithHandler<PsesDocumentSymbolHandler>()
100100
.WithHandler<PsesDocumentHighlightHandler>()

src/PowerShellEditorServices/Services/DebugAdapter/Handlers/DebuggerActionHandlers.cs

+36-17
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,78 @@
44
using System;
55
using System.Threading;
66
using System.Threading.Tasks;
7-
using Microsoft.Extensions.Logging;
87
using Microsoft.PowerShell.EditorServices.Services;
98
using OmniSharp.Extensions.DebugAdapter.Protocol.Requests;
109
using OmniSharp.Extensions.JsonRpc;
1110

1211
namespace Microsoft.PowerShell.EditorServices.Handlers
1312
{
14-
// TODO: Inherit from ABCs instead of satisfying interfaces.
15-
internal class DebuggerActionHandlers : IContinueHandler, INextHandler, IPauseHandler, IStepInHandler, IStepOutHandler
13+
internal class ContinueHandler : ContinueHandlerBase
1614
{
17-
private readonly ILogger _logger;
1815
private readonly DebugService _debugService;
1916

20-
public DebuggerActionHandlers(
21-
ILoggerFactory loggerFactory,
22-
DebugService debugService)
23-
{
24-
_logger = loggerFactory.CreateLogger<ContinueHandlerBase>();
25-
_debugService = debugService;
26-
}
17+
public ContinueHandler(DebugService debugService) => _debugService = debugService;
2718

28-
public Task<ContinueResponse> Handle(ContinueArguments request, CancellationToken cancellationToken)
19+
public override Task<ContinueResponse> Handle(ContinueArguments request, CancellationToken cancellationToken)
2920
{
3021
_debugService.Continue();
3122
return Task.FromResult(new ContinueResponse());
3223
}
24+
}
25+
26+
internal class NextHandler : NextHandlerBase
27+
{
28+
private readonly DebugService _debugService;
3329

34-
public Task<NextResponse> Handle(NextArguments request, CancellationToken cancellationToken)
30+
public NextHandler(DebugService debugService) => _debugService = debugService;
31+
32+
public override Task<NextResponse> Handle(NextArguments request, CancellationToken cancellationToken)
3533
{
3634
_debugService.StepOver();
3735
return Task.FromResult(new NextResponse());
3836
}
37+
}
38+
39+
internal class PauseHandler : PauseHandlerBase
40+
{
41+
private readonly DebugService _debugService;
3942

40-
public Task<PauseResponse> Handle(PauseArguments request, CancellationToken cancellationToken)
43+
public PauseHandler(DebugService debugService) => _debugService = debugService;
44+
45+
public override Task<PauseResponse> Handle(PauseArguments request, CancellationToken cancellationToken)
4146
{
4247
try
4348
{
4449
_debugService.Break();
4550
return Task.FromResult(new PauseResponse());
4651
}
47-
catch(NotSupportedException e)
52+
catch (NotSupportedException e)
4853
{
4954
throw new RpcErrorException(0, e.Message);
5055
}
5156
}
57+
}
58+
59+
internal class StepInHandler : StepInHandlerBase
60+
{
61+
private readonly DebugService _debugService;
62+
63+
public StepInHandler(DebugService debugService) => _debugService = debugService;
5264

53-
public Task<StepInResponse> Handle(StepInArguments request, CancellationToken cancellationToken)
65+
public override Task<StepInResponse> Handle(StepInArguments request, CancellationToken cancellationToken)
5466
{
5567
_debugService.StepIn();
5668
return Task.FromResult(new StepInResponse());
5769
}
70+
}
71+
72+
internal class StepOutHandler : StepOutHandlerBase
73+
{
74+
private readonly DebugService _debugService;
75+
76+
public StepOutHandler(DebugService debugService) => _debugService = debugService;
5877

59-
public Task<StepOutResponse> Handle(StepOutArguments request, CancellationToken cancellationToken)
78+
public override Task<StepOutResponse> Handle(StepOutArguments request, CancellationToken cancellationToken)
6079
{
6180
_debugService.StepOut();
6281
return Task.FromResult(new StepOutResponse());

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

+5-8
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,12 @@ public PsesCodeActionHandler(ILoggerFactory factory, AnalysisService analysisSer
2626
_analysisService = analysisService;
2727
}
2828

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

3936
// TODO: Either fix or ignore "method lacks 'await'" warning.
4037
public override async Task<CodeAction> Handle(CodeAction request, CancellationToken cancellationToken)

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

+12-43
Original file line numberDiff line numberDiff line change
@@ -19,70 +19,46 @@
1919

2020
namespace Microsoft.PowerShell.EditorServices.Handlers
2121
{
22-
// TODO: Use ABCs.
23-
internal class PsesCodeLensHandlers : ICodeLensHandler, ICodeLensResolveHandler
22+
internal class PsesCodeLensHandlers : CodeLensHandlerBase
2423
{
2524
private readonly ILogger _logger;
2625
private readonly SymbolsService _symbolsService;
2726
private readonly WorkspaceService _workspaceService;
28-
private CodeLensCapability _capability;
29-
private readonly Guid _id = Guid.NewGuid();
30-
Guid ICanBeIdentifiedHandler.Id => _id;
3127

32-
public PsesCodeLensHandlers(ILoggerFactory factory, SymbolsService symbolsService, WorkspaceService workspaceService, ConfigurationService configurationService)
28+
public PsesCodeLensHandlers(ILoggerFactory factory, SymbolsService symbolsService, WorkspaceService workspaceService)
3329
{
3430
_logger = factory.CreateLogger<PsesCodeLensHandlers>();
3531
_workspaceService = workspaceService;
3632
_symbolsService = symbolsService;
3733
}
3834

39-
public CodeLensRegistrationOptions GetRegistrationOptions(CodeLensCapability capability, ClientCapabilities clientCapabilities) => new CodeLensRegistrationOptions
35+
protected override CodeLensRegistrationOptions CreateRegistrationOptions(CodeLensCapability capability, ClientCapabilities clientCapabilities) => new()
4036
{
4137
DocumentSelector = LspUtils.PowerShellDocumentSelector,
4238
ResolveProvider = true
4339
};
4440

45-
public void SetCapability(CodeLensCapability capability, ClientCapabilities clientCapabilities)
46-
{
47-
_capability = capability;
48-
}
49-
50-
public Task<CodeLensContainer> Handle(CodeLensParams request, CancellationToken cancellationToken)
41+
public override Task<CodeLensContainer> Handle(CodeLensParams request, CancellationToken cancellationToken)
5142
{
5243
ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);
53-
5444
CodeLens[] codeLensResults = ProvideCodeLenses(scriptFile);
55-
5645
return Task.FromResult(new CodeLensContainer(codeLensResults));
5746
}
5847

59-
public bool CanResolve(CodeLens value)
60-
{
61-
CodeLensData codeLensData = value.Data.ToObject<CodeLensData>();
62-
return value?.Data != null && _symbolsService.GetCodeLensProviders().Any(provider => provider.ProviderId.Equals(codeLensData.ProviderId));
63-
}
64-
65-
public Task<CodeLens> Handle(CodeLens request, CancellationToken cancellationToken)
48+
public override Task<CodeLens> Handle(CodeLens request, CancellationToken cancellationToken)
6649
{
6750
// TODO: Catch deserializtion exception on bad object
6851
CodeLensData codeLensData = request.Data.ToObject<CodeLensData>();
6952

7053
ICodeLensProvider originalProvider = _symbolsService
7154
.GetCodeLensProviders()
72-
.FirstOrDefault(provider => provider.ProviderId.Equals(codeLensData.ProviderId));
55+
.FirstOrDefault(provider => provider.ProviderId.Equals(codeLensData.ProviderId, StringComparison.Ordinal));
7356

74-
ScriptFile scriptFile =
75-
_workspaceService.GetFile(
76-
codeLensData.Uri);
57+
ScriptFile scriptFile = _workspaceService.GetFile(codeLensData.Uri);
7758

7859
return originalProvider.ResolveCodeLens(request, scriptFile);
7960
}
8061

81-
public void SetCapability(CodeLensCapability capability)
82-
{
83-
_capability = capability;
84-
}
85-
8662
/// <summary>
8763
/// Get all the CodeLenses for a given script file.
8864
/// </summary>
@@ -104,30 +80,23 @@ private CodeLens[] ProvideCodeLenses(ScriptFile scriptFile)
10480
/// An IEnumerable containing the results of all providers
10581
/// that were invoked successfully.
10682
/// </returns>
107-
private IEnumerable<TResult> InvokeProviders<TResult>(
108-
Func<ICodeLensProvider, TResult> invokeFunc)
83+
private IEnumerable<TResult> InvokeProviders<TResult>(Func<ICodeLensProvider, TResult> invokeFunc)
10984
{
110-
Stopwatch invokeTimer = new Stopwatch();
111-
List<TResult> providerResults = new List<TResult>();
85+
Stopwatch invokeTimer = new();
86+
List<TResult> providerResults = new();
11287

11388
foreach (ICodeLensProvider provider in _symbolsService.GetCodeLensProviders())
11489
{
11590
try
11691
{
11792
invokeTimer.Restart();
118-
11993
providerResults.Add(invokeFunc(provider));
120-
12194
invokeTimer.Stop();
122-
123-
this._logger.LogTrace(
124-
$"Invocation of provider '{provider.GetType().Name}' completed in {invokeTimer.ElapsedMilliseconds}ms.");
95+
_logger.LogTrace($"Invocation of provider '{provider.GetType().Name}' completed in {invokeTimer.ElapsedMilliseconds}ms.");
12596
}
12697
catch (Exception e)
12798
{
128-
this._logger.LogException(
129-
$"Exception caught while invoking provider {provider.GetType().Name}:",
130-
e);
99+
_logger.LogException($"Exception caught while invoking provider {provider.GetType().Name}:", e);
131100
}
132101
}
133102

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

+14-28
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,12 @@
2222

2323
namespace Microsoft.PowerShell.EditorServices.Handlers
2424
{
25-
// TODO: Use ABCs.
26-
internal class PsesCompletionHandler : ICompletionHandler, ICompletionResolveHandler
25+
internal class PsesCompletionHandler : CompletionHandlerBase
2726
{
2827
private readonly ILogger _logger;
2928
private readonly IRunspaceContext _runspaceContext;
3029
private readonly IInternalPowerShellExecutionService _executionService;
3130
private readonly WorkspaceService _workspaceService;
32-
private CompletionCapability _capability;
33-
private readonly Guid _id = Guid.NewGuid();
34-
35-
Guid ICanBeIdentifiedHandler.Id => _id;
3631

3732
public PsesCompletionHandler(
3833
ILoggerFactory factory,
@@ -46,14 +41,15 @@ public PsesCompletionHandler(
4641
_workspaceService = workspaceService;
4742
}
4843

49-
public CompletionRegistrationOptions GetRegistrationOptions(CompletionCapability capability, ClientCapabilities clientCapabilities) => new()
44+
protected override CompletionRegistrationOptions CreateRegistrationOptions(CompletionCapability capability, ClientCapabilities clientCapabilities) => new()
5045
{
46+
// TODO: What do we do with the arguments?
5147
DocumentSelector = LspUtils.PowerShellDocumentSelector,
5248
ResolveProvider = true,
5349
TriggerCharacters = new[] { ".", "-", ":", "\\", "$" }
5450
};
5551

56-
public async Task<CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken)
52+
public override async Task<CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken)
5753
{
5854
int cursorLine = request.Position.Line + 1;
5955
int cursorColumn = request.Position.Character + 1;
@@ -68,13 +64,8 @@ public async Task<CompletionList> Handle(CompletionParams request, CancellationT
6864
return new CompletionList(completionResults);
6965
}
7066

71-
public static bool CanResolve(CompletionItem value)
72-
{
73-
return value.Kind == CompletionItemKind.Function;
74-
}
75-
7667
// Handler for "completionItem/resolve". In VSCode this is fired when a completion item is highlighted in the completion list.
77-
public async Task<CompletionItem> Handle(CompletionItem request, CancellationToken cancellationToken)
68+
public override async Task<CompletionItem> Handle(CompletionItem request, CancellationToken cancellationToken)
7869
{
7970
// We currently only support this request for anything that returns a CommandInfo:
8071
// functions, cmdlets, aliases. No detail means the module hasn't been imported yet and
@@ -105,11 +96,6 @@ public async Task<CompletionItem> Handle(CompletionItem request, CancellationTok
10596
return request;
10697
}
10798

108-
public void SetCapability(CompletionCapability capability, ClientCapabilities clientCapabilities)
109-
{
110-
_capability = capability;
111-
}
112-
11399
/// <summary>
114100
/// Gets completions for a statement contained in the given
115101
/// script file at the specified line and column position.
@@ -126,7 +112,7 @@ public void SetCapability(CompletionCapability capability, ClientCapabilities cl
126112
/// <returns>
127113
/// A CommandCompletion instance completions for the identified statement.
128114
/// </returns>
129-
public async Task<IEnumerable<CompletionItem>> GetCompletionsInFileAsync(
115+
internal async Task<IEnumerable<CompletionItem>> GetCompletionsInFileAsync(
130116
ScriptFile scriptFile,
131117
int lineNumber,
132118
int columnNumber,
@@ -142,15 +128,15 @@ public async Task<IEnumerable<CompletionItem>> GetCompletionsInFileAsync(
142128
_logger,
143129
cancellationToken).ConfigureAwait(false);
144130

145-
// Only calculate the replacement range if there are completions.
146-
BufferRange replacedRange = new(0, 0, 0, 0);
147-
if (result.CompletionMatches.Count > 0)
131+
if (result.CompletionMatches.Count == 0)
148132
{
149-
replacedRange = scriptFile.GetRangeBetweenOffsets(
150-
result.ReplacementIndex,
151-
result.ReplacementIndex + result.ReplacementLength);
133+
return Array.Empty<CompletionItem>();
152134
}
153135

136+
BufferRange replacedRange = scriptFile.GetRangeBetweenOffsets(
137+
result.ReplacementIndex,
138+
result.ReplacementIndex + result.ReplacementLength);
139+
154140
// Create OmniSharp CompletionItems from PowerShell CompletionResults. We use a for loop
155141
// because the index is used for sorting.
156142
CompletionItem[] completionItems = new CompletionItem[result.CompletionMatches.Count];
@@ -282,8 +268,8 @@ private static bool TryBuildSnippet(string completionText, out string snippet)
282268
// Since we want to use a "tab stop" we need to escape a few things.
283269
StringBuilder sb = new StringBuilder(completionText)
284270
.Replace(@"\", @"\\")
285-
.Replace(@"}", @"\}")
286-
.Replace(@"$", @"\$");
271+
.Replace("}", @"\}")
272+
.Replace("$", @"\$");
287273
snippet = sb.Insert(sb.Length - 1, "$0").ToString();
288274
return true;
289275
}

0 commit comments

Comments
 (0)