Skip to content

Finish use of ABC instead of interface TODOs #1740

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

Merged
merged 4 commits into from
Mar 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/PowerShellEditorServices/Server/PsesDebugServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ public async Task StartAsync()
.WithHandler<StackTraceHandler>()
.WithHandler<ScopesHandler>()
.WithHandler<VariablesHandler>()
.WithHandler<DebuggerActionHandlers>()
.WithHandler<ContinueHandler>()
.WithHandler<NextHandler>()
.WithHandler<PauseHandler>()
.WithHandler<StepInHandler>()
.WithHandler<StepOutHandler>()
.WithHandler<SourceHandler>()
.WithHandler<SetVariableHandler>()
.WithHandler<DebugEvaluateHandler>()
Expand Down
4 changes: 2 additions & 2 deletions src/PowerShellEditorServices/Server/PsesLanguageServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ public async Task StartAsync()
.WithOutput(_outputStream)
.WithServices(serviceCollection =>
{

// NOTE: This adds a lot of services!
serviceCollection.AddPsesLanguageServices(_hostDetails);
})
Expand All @@ -94,7 +93,8 @@ public async Task StartAsync()
.WithHandler<GetVersionHandler>()
.WithHandler<PsesConfigurationHandler>()
.WithHandler<PsesFoldingRangeHandler>()
.WithHandler<PsesDocumentFormattingHandlers>()
.WithHandler<PsesDocumentFormattingHandler>()
.WithHandler<PsesDocumentRangeFormattingHandler>()
.WithHandler<PsesReferencesHandler>()
.WithHandler<PsesDocumentSymbolHandler>()
.WithHandler<PsesDocumentHighlightHandler>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,78 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.PowerShell.EditorServices.Services;
using OmniSharp.Extensions.DebugAdapter.Protocol.Requests;
using OmniSharp.Extensions.JsonRpc;

namespace Microsoft.PowerShell.EditorServices.Handlers
{
// TODO: Inherit from ABCs instead of satisfying interfaces.
internal class DebuggerActionHandlers : IContinueHandler, INextHandler, IPauseHandler, IStepInHandler, IStepOutHandler
internal class ContinueHandler : ContinueHandlerBase
{
private readonly ILogger _logger;
private readonly DebugService _debugService;

public DebuggerActionHandlers(
ILoggerFactory loggerFactory,
DebugService debugService)
{
_logger = loggerFactory.CreateLogger<ContinueHandlerBase>();
_debugService = debugService;
}
public ContinueHandler(DebugService debugService) => _debugService = debugService;

public Task<ContinueResponse> Handle(ContinueArguments request, CancellationToken cancellationToken)
public override Task<ContinueResponse> Handle(ContinueArguments request, CancellationToken cancellationToken)
{
_debugService.Continue();
return Task.FromResult(new ContinueResponse());
}
}

internal class NextHandler : NextHandlerBase
{
private readonly DebugService _debugService;

public Task<NextResponse> Handle(NextArguments request, CancellationToken cancellationToken)
public NextHandler(DebugService debugService) => _debugService = debugService;

public override Task<NextResponse> Handle(NextArguments request, CancellationToken cancellationToken)
{
_debugService.StepOver();
return Task.FromResult(new NextResponse());
}
}

internal class PauseHandler : PauseHandlerBase
{
private readonly DebugService _debugService;

public Task<PauseResponse> Handle(PauseArguments request, CancellationToken cancellationToken)
public PauseHandler(DebugService debugService) => _debugService = debugService;

public override Task<PauseResponse> Handle(PauseArguments request, CancellationToken cancellationToken)
{
try
{
_debugService.Break();
return Task.FromResult(new PauseResponse());
}
catch(NotSupportedException e)
catch (NotSupportedException e)
{
throw new RpcErrorException(0, e.Message);
}
}
}

internal class StepInHandler : StepInHandlerBase
{
private readonly DebugService _debugService;

public StepInHandler(DebugService debugService) => _debugService = debugService;

public Task<StepInResponse> Handle(StepInArguments request, CancellationToken cancellationToken)
public override Task<StepInResponse> Handle(StepInArguments request, CancellationToken cancellationToken)
{
_debugService.StepIn();
return Task.FromResult(new StepInResponse());
}
}

internal class StepOutHandler : StepOutHandlerBase
{
private readonly DebugService _debugService;

public StepOutHandler(DebugService debugService) => _debugService = debugService;

public Task<StepOutResponse> Handle(StepOutArguments request, CancellationToken cancellationToken)
public override Task<StepOutResponse> Handle(StepOutArguments request, CancellationToken cancellationToken)
{
_debugService.StepOut();
return Task.FromResult(new StepOutResponse());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,12 @@ public PsesCodeActionHandler(ILoggerFactory factory, AnalysisService analysisSer
_analysisService = analysisService;
}

protected override CodeActionRegistrationOptions CreateRegistrationOptions(CodeActionCapability capability, ClientCapabilities clientCapabilities)
protected override CodeActionRegistrationOptions CreateRegistrationOptions(CodeActionCapability capability, ClientCapabilities clientCapabilities) => new()
{
return new()
{
// TODO: What do we do with the arguments?
DocumentSelector = LspUtils.PowerShellDocumentSelector,
CodeActionKinds = new CodeActionKind[] { CodeActionKind.QuickFix }
};
}
// TODO: What do we do with the arguments?
DocumentSelector = LspUtils.PowerShellDocumentSelector,
CodeActionKinds = new CodeActionKind[] { CodeActionKind.QuickFix }
};

// TODO: Either fix or ignore "method lacks 'await'" warning.
public override async Task<CodeAction> Handle(CodeAction request, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,70 +19,46 @@

namespace Microsoft.PowerShell.EditorServices.Handlers
{
// TODO: Use ABCs.
internal class PsesCodeLensHandlers : ICodeLensHandler, ICodeLensResolveHandler
internal class PsesCodeLensHandlers : CodeLensHandlerBase
{
private readonly ILogger _logger;
private readonly SymbolsService _symbolsService;
private readonly WorkspaceService _workspaceService;
private CodeLensCapability _capability;
private readonly Guid _id = Guid.NewGuid();
Guid ICanBeIdentifiedHandler.Id => _id;

public PsesCodeLensHandlers(ILoggerFactory factory, SymbolsService symbolsService, WorkspaceService workspaceService, ConfigurationService configurationService)
public PsesCodeLensHandlers(ILoggerFactory factory, SymbolsService symbolsService, WorkspaceService workspaceService)
{
_logger = factory.CreateLogger<PsesCodeLensHandlers>();
_workspaceService = workspaceService;
_symbolsService = symbolsService;
}

public CodeLensRegistrationOptions GetRegistrationOptions(CodeLensCapability capability, ClientCapabilities clientCapabilities) => new CodeLensRegistrationOptions
protected override CodeLensRegistrationOptions CreateRegistrationOptions(CodeLensCapability capability, ClientCapabilities clientCapabilities) => new()
{
DocumentSelector = LspUtils.PowerShellDocumentSelector,
ResolveProvider = true
};

public void SetCapability(CodeLensCapability capability, ClientCapabilities clientCapabilities)
{
_capability = capability;
}

public Task<CodeLensContainer> Handle(CodeLensParams request, CancellationToken cancellationToken)
public override Task<CodeLensContainer> Handle(CodeLensParams request, CancellationToken cancellationToken)
{
ScriptFile scriptFile = _workspaceService.GetFile(request.TextDocument.Uri);

CodeLens[] codeLensResults = ProvideCodeLenses(scriptFile);

return Task.FromResult(new CodeLensContainer(codeLensResults));
}

public bool CanResolve(CodeLens value)
{
CodeLensData codeLensData = value.Data.ToObject<CodeLensData>();
return value?.Data != null && _symbolsService.GetCodeLensProviders().Any(provider => provider.ProviderId.Equals(codeLensData.ProviderId));
}

public Task<CodeLens> Handle(CodeLens request, CancellationToken cancellationToken)
public override Task<CodeLens> Handle(CodeLens request, CancellationToken cancellationToken)
{
// TODO: Catch deserializtion exception on bad object
CodeLensData codeLensData = request.Data.ToObject<CodeLensData>();

ICodeLensProvider originalProvider = _symbolsService
.GetCodeLensProviders()
.FirstOrDefault(provider => provider.ProviderId.Equals(codeLensData.ProviderId));
.FirstOrDefault(provider => provider.ProviderId.Equals(codeLensData.ProviderId, StringComparison.Ordinal));

ScriptFile scriptFile =
_workspaceService.GetFile(
codeLensData.Uri);
ScriptFile scriptFile = _workspaceService.GetFile(codeLensData.Uri);

return originalProvider.ResolveCodeLens(request, scriptFile);
}

public void SetCapability(CodeLensCapability capability)
{
_capability = capability;
}

/// <summary>
/// Get all the CodeLenses for a given script file.
/// </summary>
Expand All @@ -104,30 +80,23 @@ private CodeLens[] ProvideCodeLenses(ScriptFile scriptFile)
/// An IEnumerable containing the results of all providers
/// that were invoked successfully.
/// </returns>
private IEnumerable<TResult> InvokeProviders<TResult>(
Func<ICodeLensProvider, TResult> invokeFunc)
private IEnumerable<TResult> InvokeProviders<TResult>(Func<ICodeLensProvider, TResult> invokeFunc)
{
Stopwatch invokeTimer = new Stopwatch();
List<TResult> providerResults = new List<TResult>();
Stopwatch invokeTimer = new();
List<TResult> providerResults = new();

foreach (ICodeLensProvider provider in _symbolsService.GetCodeLensProviders())
{
try
{
invokeTimer.Restart();

providerResults.Add(invokeFunc(provider));

invokeTimer.Stop();

this._logger.LogTrace(
$"Invocation of provider '{provider.GetType().Name}' completed in {invokeTimer.ElapsedMilliseconds}ms.");
_logger.LogTrace($"Invocation of provider '{provider.GetType().Name}' completed in {invokeTimer.ElapsedMilliseconds}ms.");
}
catch (Exception e)
{
this._logger.LogException(
$"Exception caught while invoking provider {provider.GetType().Name}:",
e);
_logger.LogException($"Exception caught while invoking provider {provider.GetType().Name}:", e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,12 @@

namespace Microsoft.PowerShell.EditorServices.Handlers
{
// TODO: Use ABCs.
internal class PsesCompletionHandler : ICompletionHandler, ICompletionResolveHandler
internal class PsesCompletionHandler : CompletionHandlerBase
{
private readonly ILogger _logger;
private readonly IRunspaceContext _runspaceContext;
private readonly IInternalPowerShellExecutionService _executionService;
private readonly WorkspaceService _workspaceService;
private CompletionCapability _capability;
private readonly Guid _id = Guid.NewGuid();

Guid ICanBeIdentifiedHandler.Id => _id;

public PsesCompletionHandler(
ILoggerFactory factory,
Expand All @@ -46,14 +41,15 @@ public PsesCompletionHandler(
_workspaceService = workspaceService;
}

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

public async Task<CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken)
public override async Task<CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken)
{
int cursorLine = request.Position.Line + 1;
int cursorColumn = request.Position.Character + 1;
Expand All @@ -68,13 +64,8 @@ public async Task<CompletionList> Handle(CompletionParams request, CancellationT
return new CompletionList(completionResults);
}

public static bool CanResolve(CompletionItem value)
{
return value.Kind == CompletionItemKind.Function;
}

// Handler for "completionItem/resolve". In VSCode this is fired when a completion item is highlighted in the completion list.
public async Task<CompletionItem> Handle(CompletionItem request, CancellationToken cancellationToken)
public override async Task<CompletionItem> Handle(CompletionItem request, CancellationToken cancellationToken)
{
// We currently only support this request for anything that returns a CommandInfo:
// functions, cmdlets, aliases. No detail means the module hasn't been imported yet and
Expand Down Expand Up @@ -105,11 +96,6 @@ public async Task<CompletionItem> Handle(CompletionItem request, CancellationTok
return request;
}

public void SetCapability(CompletionCapability capability, ClientCapabilities clientCapabilities)
{
_capability = capability;
}

/// <summary>
/// Gets completions for a statement contained in the given
/// script file at the specified line and column position.
Expand All @@ -126,7 +112,7 @@ public void SetCapability(CompletionCapability capability, ClientCapabilities cl
/// <returns>
/// A CommandCompletion instance completions for the identified statement.
/// </returns>
public async Task<IEnumerable<CompletionItem>> GetCompletionsInFileAsync(
internal async Task<IEnumerable<CompletionItem>> GetCompletionsInFileAsync(
ScriptFile scriptFile,
int lineNumber,
int columnNumber,
Expand All @@ -142,15 +128,15 @@ public async Task<IEnumerable<CompletionItem>> GetCompletionsInFileAsync(
_logger,
cancellationToken).ConfigureAwait(false);

// Only calculate the replacement range if there are completions.
BufferRange replacedRange = new(0, 0, 0, 0);
if (result.CompletionMatches.Count > 0)
if (result.CompletionMatches.Count == 0)
{
replacedRange = scriptFile.GetRangeBetweenOffsets(
result.ReplacementIndex,
result.ReplacementIndex + result.ReplacementLength);
return Array.Empty<CompletionItem>();
}

BufferRange replacedRange = scriptFile.GetRangeBetweenOffsets(
result.ReplacementIndex,
result.ReplacementIndex + result.ReplacementLength);

// Create OmniSharp CompletionItems from PowerShell CompletionResults. We use a for loop
// because the index is used for sorting.
CompletionItem[] completionItems = new CompletionItem[result.CompletionMatches.Count];
Expand Down Expand Up @@ -282,8 +268,8 @@ private static bool TryBuildSnippet(string completionText, out string snippet)
// Since we want to use a "tab stop" we need to escape a few things.
StringBuilder sb = new StringBuilder(completionText)
.Replace(@"\", @"\\")
.Replace(@"}", @"\}")
.Replace(@"$", @"\$");
.Replace("}", @"\}")
.Replace("$", @"\$");
snippet = sb.Insert(sb.Length - 1, "$0").ToString();
return true;
}
Expand Down
Loading