diff --git a/src/PowerShellEditorServices/Server/PsesLanguageServer.cs b/src/PowerShellEditorServices/Server/PsesLanguageServer.cs index 58d52bb3a..b9a795d06 100644 --- a/src/PowerShellEditorServices/Server/PsesLanguageServer.cs +++ b/src/PowerShellEditorServices/Server/PsesLanguageServer.cs @@ -109,6 +109,7 @@ public async Task StartAsync() .WithHandler( new JsonRpcHandlerOptions() { RequestProcessType = RequestProcessType.Serial }) .WithHandler() + .WithHandler() .WithHandler() .WithHandler() .WithHandler() diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs new file mode 100644 index 000000000..7a05b489e --- /dev/null +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs @@ -0,0 +1,78 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.PowerShell.EditorServices.Services; +using Microsoft.PowerShell.EditorServices.Services.Symbols; +using Microsoft.PowerShell.EditorServices.Services.TextDocument; +using Microsoft.PowerShell.EditorServices.Utility; +using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; +using OmniSharp.Extensions.LanguageServer.Protocol.Document; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; + +namespace Microsoft.PowerShell.EditorServices.Handlers; + +/// +/// Resolves PowerShell types and parameters as inlay hints for the LSP client. See: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_inlayHints +/// +internal class PsesInlayHandler( + ILoggerFactory loggerFactory, + SymbolsService symbolsService, + WorkspaceService workspaceService +) : InlayHintsHandlerBase +{ + private readonly ILogger logger = loggerFactory.CreateLogger(); + + /// + /// Expresses the capabilities of our Inlay Hints handler to the LSP + /// + protected override InlayHintRegistrationOptions CreateRegistrationOptions(InlayHintClientCapabilities capability, ClientCapabilities clientCapabilities) => new() + { + DocumentSelector = LspUtils.PowerShellDocumentSelector, + WorkDoneProgress = false, //TODO: Report progress for large documents + ResolveProvider = false //TODO: Add a resolve Provider for detailed inlay information + }; + + public override async Task Handle(InlayHint request, CancellationToken cancellationToken) => throw new NotImplementedException(); + + public override async Task Handle(InlayHintParams request, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + logger.LogDebug("InlayHint request canceled for file: {Uri}", request.TextDocument.Uri); + return null; + } + + // TODO: Limit search to request.range + ScriptFile scriptFile = workspaceService.GetFile(request.TextDocument.Uri); + + IEnumerable symbolReferences = + symbolsService.FindSymbolsInFile(scriptFile); + + if (symbolReferences is null) + { + return null; + } + + IEnumerable inlayHints = + from s in symbolReferences + where s.Type is SymbolType.Variable or SymbolType.Parameter + select new InlayHint + { + Kind = s.Type is SymbolType.Parameter ? InlayHintKind.Parameter : InlayHintKind.Type, + // TODO: Integrate ScriptPositionAdapter once rename PR is merged + Position = new Position( + s.ScriptRegion.StartLineNumber - 1, + s.ScriptRegion.StartColumnNumber - 1 + ), + Label = "TypeGoesHere:" //Fixme: Get the type of the symbol + }; + + return new InlayHintContainer(inlayHints); + } +}