Skip to content
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

Cohost inlay hint support #10672

Merged
merged 15 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
1 change: 1 addition & 0 deletions eng/targets/Services.props
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@
<ServiceHubService Include="Microsoft.VisualStudio.Razor.FoldingRange" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteFoldingRangeService+Factory" />
<ServiceHubService Include="Microsoft.VisualStudio.Razor.SignatureHelp" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteSignatureHelpService+Factory" />
<ServiceHubService Include="Microsoft.VisualStudio.Razor.DocumentHighlight" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteDocumentHighlightService+Factory" />
<ServiceHubService Include="Microsoft.VisualStudio.Razor.InlayHint" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteInlayHintService+Factory" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@
using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts;
using Microsoft.AspNetCore.Razor.LanguageServer.Hosting;
using Microsoft.AspNetCore.Razor.Threading;
using Microsoft.CodeAnalysis.Razor.Workspaces;
using Microsoft.VisualStudio.LanguageServer.Protocol;

namespace Microsoft.AspNetCore.Razor.LanguageServer.InlayHints;

[RazorLanguageServerEndpoint(Methods.TextDocumentInlayHintName)]
internal sealed class InlayHintEndpoint(LanguageServerFeatureOptions featureOptions, IInlayHintService inlayHintService, IClientConnection clientConnection)
internal sealed class InlayHintEndpoint(IInlayHintService inlayHintService, IClientConnection clientConnection)
: IRazorRequestHandler<InlayHintParams, InlayHint[]?>, ICapabilitiesProvider
{
private readonly LanguageServerFeatureOptions _featureOptions = featureOptions;
private readonly IInlayHintService _inlayHintService = inlayHintService;
private readonly IClientConnection _clientConnection = clientConnection;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ static void AddHandlers(IServiceCollection services, LanguageServerFeatureOption
services.AddHandlerWithCapabilities<SignatureHelpEndpoint>();
services.AddHandlerWithCapabilities<LinkedEditingRangeEndpoint>();
services.AddHandlerWithCapabilities<FoldingRangeEndpoint>();

services.AddSingleton<IInlayHintService, InlayHintService>();
services.AddHandlerWithCapabilities<InlayHintEndpoint>();
services.AddHandler<InlayHintResolveEndpoint>();
}

services.AddHandler<WrapWithTagEndpoint>();
Expand All @@ -204,11 +208,6 @@ static void AddHandlers(IServiceCollection services, LanguageServerFeatureOption
services.AddHandlerWithCapabilities<ProjectContextsEndpoint>();
services.AddHandlerWithCapabilities<DocumentSymbolEndpoint>();
services.AddHandlerWithCapabilities<MapCodeEndpoint>();

services.AddSingleton<IInlayHintService, InlayHintService>();

services.AddHandlerWithCapabilities<InlayHintEndpoint>();
services.AddHandler<InlayHintResolveEndpoint>();
}
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language;
Expand All @@ -13,7 +14,7 @@ namespace Microsoft.CodeAnalysis.Razor.DocumentMapping;

internal interface IRazorDocumentMappingService
{
TextEdit[] GetHostDocumentEdits(IRazorGeneratedDocument generatedDocument, TextEdit[] generatedDocumentEdits);
IEnumerable<TextChange> GetHostDocumentEdits(IRazorGeneratedDocument generatedDocument, IEnumerable<TextChange> generatedDocumentEdits);

bool TryMapToHostDocumentRange(IRazorGeneratedDocument generatedDocument, LinePositionSpan generatedDocumentRange, MappingBehavior mappingBehavior, out LinePositionSpan hostDocumentRange);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
using Microsoft.CodeAnalysis.Razor.Protocol;
Expand All @@ -16,6 +18,16 @@ namespace Microsoft.CodeAnalysis.Razor.DocumentMapping;

internal static class IRazorDocumentMappingServiceExtensions
{
public static TextEdit[] GetHostDocumentEdits(this IRazorDocumentMappingService service, IRazorGeneratedDocument generatedDocument, TextEdit[] generatedDocumentEdits)
{
var generatedDocumentSourceText = generatedDocument.GetGeneratedSourceText();
var documentText = generatedDocument.CodeDocument.AssumeNotNull().Source.Text;

var changes = generatedDocumentEdits.Select(generatedDocumentSourceText.GetTextChange);
var mappedChanges = service.GetHostDocumentEdits(generatedDocument, changes);
return mappedChanges.Select(documentText.GetTextEdit).ToArray();
}

public static bool TryMapToHostDocumentRange(this IRazorDocumentMappingService service, IRazorGeneratedDocument generatedDocument, LinePositionSpan projectedRange, out LinePositionSpan originalRange)
=> service.TryMapToHostDocumentRange(generatedDocument, projectedRange, MappingBehavior.Strict, out originalRange);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.AspNetCore.Razor.Language;

internal static class IRazorGeneratedDocumentExtensions
{
public static SourceText GetGeneratedSourceText(this IRazorGeneratedDocument generatedDocument)
{
if (generatedDocument.CodeDocument is not { } codeDocument)
{
throw new InvalidOperationException("Cannot use document mapping service on a generated document that has a null CodeDocument.");
}

return codeDocument.GetGeneratedSourceText(generatedDocument);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.

using Microsoft.AspNetCore.Razor;
using Microsoft.CodeAnalysis.Text;

namespace Roslyn.LanguageServer.Protocol;

internal static partial class RoslynLspExtensions
{
public static Range GetRange(this SourceText text, TextSpan span)
=> text.GetLinePositionSpan(span).ToRange();

public static TextSpan GetTextSpan(this SourceText text, Range range)
=> text.GetTextSpan(range.Start.Line, range.Start.Character, range.End.Line, range.End.Character);

public static TextChange GetTextChange(this SourceText text, TextEdit edit)
=> new(text.GetTextSpan(edit.Range), edit.NewText);

public static TextEdit GetTextEdit(this SourceText text, TextChange change)
=> RoslynLspFactory.CreateTextEdit(text.GetRange(change.Span), change.NewText.AssumeNotNull());

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@

using System;
using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost;
using Microsoft.VisualStudio.LanguageServer.Protocol;

namespace Microsoft.VisualStudio.Razor.LanguageClient.Extensions;
namespace Roslyn.LanguageServer.Protocol;

internal static class TextDocumentExtensions
internal static partial class RoslynLspExtensions
{
/// <summary>
/// Returns a copy of the passed in <see cref="TextDocumentIdentifier"/> with the passed in <see cref="Uri"/>.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.

using System;
using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost;

namespace Microsoft.VisualStudio.LanguageServer.Protocol;

internal static partial class VsLspExtensions
Expand All @@ -9,4 +12,27 @@ internal static partial class VsLspExtensions
=> textDocumentIdentifier is VSTextDocumentIdentifier vsIdentifier
? vsIdentifier.ProjectContext
: null;

/// <summary>
/// Returns a copy of the passed in <see cref="TextDocumentIdentifier"/> with the passed in <see cref="Uri"/>.
/// </summary>
public static TextDocumentIdentifier WithUri(this TextDocumentIdentifier textDocumentIdentifier, Uri uri)
{
if (textDocumentIdentifier is VSTextDocumentIdentifier vsTdi)
{
return new VSTextDocumentIdentifier
{
Uri = uri,
ProjectContext = vsTdi.ProjectContext
};
}

return new TextDocumentIdentifier
{
Uri = uri
};
}

public static RazorTextDocumentIdentifier ToRazorTextDocumentIdentifier(this TextDocumentIdentifier textDocumentIdentifier)
=> new RazorTextDocumentIdentifier(textDocumentIdentifier.Uri, (textDocumentIdentifier as VSTextDocumentIdentifier)?.ProjectContext?.Id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.

using Roslyn.LanguageServer.Protocol;

namespace Microsoft.CodeAnalysis.Razor.Protocol.InlayHints;

internal record class InlayHintDataWrapper(TextDocumentIdentifier TextDocument, object? OriginalData, Position OriginalPosition);
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.

using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
using Roslyn.LanguageServer.Protocol;

namespace Microsoft.CodeAnalysis.Razor.Remote;

internal interface IRemoteInlayHintService : IRemoteJsonService
{
ValueTask<InlayHint[]?> GetInlayHintsAsync(JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo, JsonSerializableDocumentId razorDocumentId, InlayHintParams inlayHintParams, bool displayAllOverride, CancellationToken cancellationToken);

ValueTask<InlayHint> ResolveHintAsync(JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo, JsonSerializableDocumentId razorDocumentId, InlayHint inlayHint, CancellationToken cancellationToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ internal static class RazorServices
internal static readonly IEnumerable<(Type, Type?)> JsonServices =
[
(typeof(IRemoteSignatureHelpService), null),
(typeof(IRemoteInlayHintService), null),
];

private const string ComponentName = "Razor";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.

using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Syntax;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost.Handlers;

Check failure on line 11 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build macOS release)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L11

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(11,1): error IDE0005: (NETCORE_ENGINEERING_TELEMETRY=Build) Using directive is unnecessary. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0005)

Check failure on line 11 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build macOS debug)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L11

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(11,1): error IDE0005: (NETCORE_ENGINEERING_TELEMETRY=Build) Using directive is unnecessary. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0005)

Check failure on line 11 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build Linux debug)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L11

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(11,1): error IDE0005: (NETCORE_ENGINEERING_TELEMETRY=Build) Using directive is unnecessary. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0005)
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
using Microsoft.CodeAnalysis.Razor.Protocol.InlayHints;
using Microsoft.CodeAnalysis.Razor.Remote;
using Microsoft.CodeAnalysis.Razor.Workspaces;
using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
using Microsoft.CodeAnalysis.Text;
using Roslyn.LanguageServer.Protocol;

namespace Microsoft.CodeAnalysis.Remote.Razor;

internal sealed partial class RemoteInlayHintService(in ServiceArgs args) : RazorDocumentServiceBase(in args), IRemoteInlayHintService
{
internal sealed class Factory : FactoryBase<IRemoteInlayHintService>
{
protected override IRemoteInlayHintService CreateService(in ServiceArgs args)
=> new RemoteInlayHintService(in args);
}

private readonly IRazorDocumentMappingService _documentMappingService = args.ExportProvider.GetExportedValue<IRazorDocumentMappingService>();
private readonly IFilePathService _filePathService = args.ExportProvider.GetExportedValue<IFilePathService>();

public ValueTask<InlayHint[]?> GetInlayHintsAsync(JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo, JsonSerializableDocumentId razorDocumentId, InlayHintParams inlayHintParams, bool displayAllOverride, CancellationToken cancellationToken)
=> RunServiceAsync(
solutionInfo,
razorDocumentId,
context => GetInlayHintsAsync(context, inlayHintParams, displayAllOverride, cancellationToken),
cancellationToken);

private async ValueTask<InlayHint[]?> GetInlayHintsAsync(RemoteDocumentContext context, InlayHintParams inlayHintParams, bool displayAllOverride, CancellationToken cancellationToken)
{
var codeDocument = await context.GetCodeDocumentAsync(cancellationToken).ConfigureAwait(false);
var csharpDocument = codeDocument.GetCSharpDocument();

var span = inlayHintParams.Range.ToLinePositionSpan();

// We are given a range by the client, but our mapping only succeeds if the start and end of the range can both be mapped
// to C#. Since that doesn't logically match what we want from inlay hints, we instead get the minimum range of mappable
// C# to get hints for. We'll filter that later, to remove the sections that can't be mapped back.
if (!_documentMappingService.TryMapToGeneratedDocumentRange(csharpDocument, span, out var projectedLinePositionSpan) &&
!codeDocument.TryGetMinimalCSharpRange(span, out projectedLinePositionSpan))
{
// There's no C# in the range.
return null;
}

var generatedDocument = await context.GetGeneratedDocumentAsync(_filePathService, cancellationToken).ConfigureAwait(false);

var textDocument = inlayHintParams.TextDocument.WithUri(generatedDocument.CreateUri());
var range = projectedLinePositionSpan.ToRange();

var hints = await InlayHints.GetInlayHintsAsync(generatedDocument, textDocument, range, displayAllOverride, cancellationToken).ConfigureAwait(false);

Check failure on line 62 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build macOS release)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L62

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(62,27): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'InlayHints' does not exist in the current context

Check failure on line 62 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build macOS debug)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L62

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(62,27): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'InlayHints' does not exist in the current context

Check failure on line 62 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build Linux release)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L62

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(62,27): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'InlayHints' does not exist in the current context

Check failure on line 62 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build Linux debug)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L62

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(62,27): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'InlayHints' does not exist in the current context

if (hints is null)
{
return null;
}

using var inlayHintsBuilder = new PooledArrayBuilder<InlayHint>();
var razorSourceText = codeDocument.Source.Text;
var csharpSourceText = codeDocument.GetCSharpSourceText();
var syntaxTree = codeDocument.GetSyntaxTree();
foreach (var hint in hints)
{
if (csharpSourceText.TryGetAbsoluteIndex(hint.Position.ToLinePosition(), out var absoluteIndex) &&
_documentMappingService.TryMapToHostDocumentPosition(csharpDocument, absoluteIndex, out var hostDocumentPosition, out var hostDocumentIndex))
{
// We know this C# maps to Razor, but does it map to Razor that we like?
var node = syntaxTree.Root.FindInnermostNode(hostDocumentIndex);
if (node?.FirstAncestorOrSelf<MarkupTagHelperAttributeValueSyntax>() is not null)
{
continue;
}
Comment on lines +78 to +83
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annoyingly, this bit of code is pretty much the only logic that could be shared with the existing inlay hints code, because everything else operates on VS LSP types, and here we're using Roslyn LSP types. The code duplication isn't great, but I'm somewhat okay with it because we have good tests for both.

Perhaps we can re-review if/when we can move the language server to Roslyn LSP types, which could be as early as preview 2.


if (hint.TextEdits is not null)
{
var changes = hint.TextEdits.Select(csharpSourceText.GetTextChange);
var mappedChanges = _documentMappingService.GetHostDocumentEdits(csharpDocument, changes);
hint.TextEdits = mappedChanges.Select(razorSourceText.GetTextEdit).ToArray();
}

hint.Data = new InlayHintDataWrapper(inlayHintParams.TextDocument, hint.Data, hint.Position);
hint.Position = hostDocumentPosition.ToPosition();

inlayHintsBuilder.Add(hint);

Check failure on line 95 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build macOS release)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L95

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(95,17): error RS0042: (NETCORE_ENGINEERING_TELEMETRY=Build) Unsupported use of non-copyable type 'Microsoft.AspNetCore.Razor.PooledObjects.PooledArrayBuilder<Roslyn.LanguageServer.Protocol.InlayHint>' in 'LocalReference' operation

Check failure on line 95 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build macOS debug)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L95

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(95,17): error RS0042: (NETCORE_ENGINEERING_TELEMETRY=Build) Unsupported use of non-copyable type 'Microsoft.AspNetCore.Razor.PooledObjects.PooledArrayBuilder<Roslyn.LanguageServer.Protocol.InlayHint>' in 'LocalReference' operation

Check failure on line 95 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build Linux release)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L95

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(95,17): error RS0042: (NETCORE_ENGINEERING_TELEMETRY=Build) Unsupported use of non-copyable type 'Microsoft.AspNetCore.Razor.PooledObjects.PooledArrayBuilder<Roslyn.LanguageServer.Protocol.InlayHint>' in 'LocalReference' operation

Check failure on line 95 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build Linux debug)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L95

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(95,17): error RS0042: (NETCORE_ENGINEERING_TELEMETRY=Build) Unsupported use of non-copyable type 'Microsoft.AspNetCore.Razor.PooledObjects.PooledArrayBuilder<Roslyn.LanguageServer.Protocol.InlayHint>' in 'LocalReference' operation
}
}

return inlayHintsBuilder.ToArray();
}

public ValueTask<InlayHint> ResolveHintAsync(JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo, JsonSerializableDocumentId razorDocumentId, InlayHint inlayHint, CancellationToken cancellationToken)
=> RunServiceAsync(
solutionInfo,
razorDocumentId,
context => ResolveInlayHintAsync(context, inlayHint, cancellationToken),
cancellationToken);

private async ValueTask<InlayHint> ResolveInlayHintAsync(RemoteDocumentContext context, InlayHint inlayHint, CancellationToken cancellationToken)
{
var generatedDocument = await context.GetGeneratedDocumentAsync(_filePathService, cancellationToken).ConfigureAwait(false);

return await InlayHints.ResolveInlayHintAsync(generatedDocument, inlayHint, cancellationToken).ConfigureAwait(false);

Check failure on line 113 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build macOS release)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L113

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(113,22): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'InlayHints' does not exist in the current context

Check failure on line 113 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build macOS debug)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L113

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(113,22): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'InlayHints' does not exist in the current context

Check failure on line 113 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build Linux release)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L113

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(113,22): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'InlayHints' does not exist in the current context

Check failure on line 113 in src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs

View check run for this annotation

Azure Pipelines / razor-tooling-ci (Build Linux debug)

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs#L113

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/InlayHints/RemoteInlayHintService.cs(113,22): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'InlayHints' does not exist in the current context
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ public static async Task<Document> GetGeneratedDocumentAsync(this VersionedDocum
Debug.Assert(documentContext.Snapshot is RemoteDocumentSnapshot, "This method only works on document contexts created in the OOP process");

var snapshot = (RemoteDocumentSnapshot)documentContext.Snapshot;

if (snapshot.TryGetGeneratedDocument(out var generatedDocument))
{
return generatedDocument;
}

var razorDocument = snapshot.TextDocument;
var solution = razorDocument.Project.Solution;

Expand All @@ -27,13 +33,25 @@ public static async Task<Document> GetGeneratedDocumentAsync(this VersionedDocum
var projectKey = razorDocument.Project.ToProjectKey();
var generatedFilePath = filePathService.GetRazorCSharpFilePath(projectKey, razorDocument.FilePath.AssumeNotNull());
var generatedDocumentId = solution.GetDocumentIdsWithFilePath(generatedFilePath).First(d => d.ProjectId == razorDocument.Project.Id);
var generatedDocument = solution.GetDocument(generatedDocumentId).AssumeNotNull();
generatedDocument = solution.GetDocument(generatedDocumentId).AssumeNotNull();
davidwengier marked this conversation as resolved.
Show resolved Hide resolved

var csharpSourceText = await documentContext.GetCSharpSourceTextAsync(cancellationToken).ConfigureAwait(false);

// HACK: We're not in the same solution fork as the LSP server that provides content for this document
generatedDocument = generatedDocument.WithText(csharpSourceText);

return generatedDocument;
// Obviously this lock is not sufficient to avoid wasted work, but it does at least avoid mutating the snapshot
// any more than just a once of caching of the generated document, which is what is really happening with the set
// method call below.
lock (snapshot)
{
if (snapshot.TryGetGeneratedDocument(out var generatedDocument2))
{
return generatedDocument2;
}

snapshot.SetGeneratedDocument(generatedDocument);
return generatedDocument;
}
davidwengier marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading
Loading