From 627db433234f5cadfe391454ffc2ff7ba851858a Mon Sep 17 00:00:00 2001
From: Justin Grote <JustinGrote@users.noreply.github.com>
Date: Wed, 24 Jan 2024 19:20:23 -0800
Subject: [PATCH 1/3] Initial Attempt

---
 .../Server/PsesLanguageServer.cs              |  1 +
 .../TextDocument/Handlers/InlayHintHandler.cs | 76 +++++++++++++++++++
 2 files changed, 77 insertions(+)
 create mode 100644 src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs

diff --git a/src/PowerShellEditorServices/Server/PsesLanguageServer.cs b/src/PowerShellEditorServices/Server/PsesLanguageServer.cs
index 74319e828..51426d661 100644
--- a/src/PowerShellEditorServices/Server/PsesLanguageServer.cs
+++ b/src/PowerShellEditorServices/Server/PsesLanguageServer.cs
@@ -112,6 +112,7 @@ public async Task StartAsync()
                     .WithHandler<PsesCompletionHandler>(
                         new JsonRpcHandlerOptions() { RequestProcessType = RequestProcessType.Serial })
                     .WithHandler<PsesHoverHandler>()
+                    .WithHandler<PsesInlayHandler>()
                     .WithHandler<PsesSignatureHelpHandler>()
                     .WithHandler<PsesDefinitionHandler>()
                     .WithHandler<TemplateHandlers>()
diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs
new file mode 100644
index 000000000..688302ff0
--- /dev/null
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs
@@ -0,0 +1,76 @@
+// 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;
+
+/// <summary>
+/// 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
+/// </summary>
+internal class PsesInlayHandler(
+    ILoggerFactory loggerFactory,
+    SymbolsService symbolsService,
+    WorkspaceService workspaceService
+) : InlayHintsHandlerBase
+{
+    private readonly ILogger logger = loggerFactory.CreateLogger<PsesInlayHandler>();
+
+    /// <summary>
+    /// Expresses the capabilities of our Inlay Hints handler to the LSP
+    /// </summary>
+    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<InlayHint> Handle(InlayHint request, CancellationToken cancellationToken) => throw new NotImplementedException();
+
+    public override async Task<InlayHintContainer> 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<SymbolReference> symbolReferences =
+            symbolsService.FindSymbolsInFile(scriptFile);
+
+        if (symbolReferences is null)
+        {
+            return null;
+        }
+
+        IEnumerable<InlayHint> inlayHints =
+            from s in symbolReferences
+            where s.Type == SymbolType.Variable | s.Type == SymbolType.Parameter
+            select new InlayHint
+            {
+                Kind = InlayHintKind.Type,
+                Position = new Position(
+                    s.ScriptRegion.StartLineNumber - 1,
+                    s.ScriptRegion.StartColumnNumber - 1),
+                Label = s.Type.ToString()
+            };
+
+        return new InlayHintContainer(inlayHints);
+    }
+}

From 36286e068b190d34a3400bd8d68bf225f2c05212 Mon Sep 17 00:00:00 2001
From: Justin Grote <JustinGrote@users.noreply.github.com>
Date: Wed, 24 Jan 2024 21:25:28 -0800
Subject: [PATCH 2/3] Stub out some potential completion stuff

---
 .../Services/TextDocument/Handlers/InlayHintHandler.cs          | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs
index 688302ff0..0559d979b 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs
@@ -68,7 +68,7 @@ from s in symbolReferences
                 Position = new Position(
                     s.ScriptRegion.StartLineNumber - 1,
                     s.ScriptRegion.StartColumnNumber - 1),
-                Label = s.Type.ToString()
+                Label = "TypeGoesHere:" //Fixme: Get the type of the symbol
             };
 
         return new InlayHintContainer(inlayHints);

From ded43a68a31d50c9b3c7462351b617f79ad361ff Mon Sep 17 00:00:00 2001
From: Justin Grote <JustinGrote@users.noreply.github.com>
Date: Thu, 17 Oct 2024 18:16:45 -0700
Subject: [PATCH 3/3] Get more specific with the filter

---
 .../Services/TextDocument/Handlers/InlayHintHandler.cs    | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs
index 0559d979b..7a05b489e 100644
--- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs
+++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/InlayHintHandler.cs
@@ -61,13 +61,15 @@ public override async Task<InlayHintContainer> Handle(InlayHintParams request, C
 
         IEnumerable<InlayHint> inlayHints =
             from s in symbolReferences
-            where s.Type == SymbolType.Variable | s.Type == SymbolType.Parameter
+            where s.Type is SymbolType.Variable or SymbolType.Parameter
             select new InlayHint
             {
-                Kind = InlayHintKind.Type,
+                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),
+                    s.ScriptRegion.StartColumnNumber - 1
+                ),
                 Label = "TypeGoesHere:" //Fixme: Get the type of the symbol
             };