diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorCompletionBenchmark.cs b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorCompletionBenchmark.cs index 91e78ab0323..3f94fccd98e 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorCompletionBenchmark.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorCompletionBenchmark.cs @@ -43,7 +43,7 @@ public async Task SetupAsync() var delegatedCompletionListProvider = new TestDelegatedCompletionListProvider(responseRewriters, documentMappingService, clientNotifierServiceBase, completionListCache); var completionListProvider = new CompletionListProvider(razorCompletionListProvider, delegatedCompletionListProvider); - CompletionEndpoint = new RazorCompletionEndpoint(completionListProvider); + CompletionEndpoint = new RazorCompletionEndpoint(completionListProvider, telemetryReporter: null); var clientCapabilities = new VSInternalClientCapabilities { @@ -147,7 +147,7 @@ public TestDelegatedCompletionListProvider(IEnumerable GetCompletionListAsync(int absoluteIndex, VSInternalCompletionContext completionContext, VersionedDocumentContext documentContext, VSInternalClientCapabilities clientCapabilities, CancellationToken cancellationToken) + public override Task GetCompletionListAsync(int absoluteIndex, VSInternalCompletionContext completionContext, VersionedDocumentContext documentContext, VSInternalClientCapabilities clientCapabilities, Guid correlationId, CancellationToken cancellationToken) { return Task.FromResult( new VSInternalCompletionList diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensBenchmark.cs b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensBenchmark.cs index 2bdcfa024ce..03344406795 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensBenchmark.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensBenchmark.cs @@ -93,10 +93,11 @@ public async Task RazorSemanticTokensRangeAsync() }; var cancellationToken = CancellationToken.None; var documentVersion = 1; + var correlationId = Guid.Empty; await UpdateDocumentAsync(documentVersion, DocumentSnapshot, cancellationToken).ConfigureAwait(false); await RazorSemanticTokenService.GetSemanticTokensAsync( - textDocumentIdentifier, Range, DocumentContext, SemanticTokensLegend, cancellationToken).ConfigureAwait(false); + textDocumentIdentifier, Range, DocumentContext, SemanticTokensLegend, correlationId, cancellationToken).ConfigureAwait(false); } private async Task UpdateDocumentAsync(int newVersion, IDocumentSnapshot documentSnapshot, CancellationToken cancellationToken) @@ -142,6 +143,7 @@ internal override Task> GetCSharpSemanticRangesAsync( TextDocumentIdentifier textDocumentIdentifier, Range razorRange, long documentVersion, + Guid correlationId, CancellationToken cancellationToken, string previousResultId = null) { diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensRangeEndpointBenchmark.cs b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensRangeEndpointBenchmark.cs index b33c2861daf..0ded0ac7e3a 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensRangeEndpointBenchmark.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensRangeEndpointBenchmark.cs @@ -73,7 +73,7 @@ public async Task InitializeRazorSemanticAsync() var version = 1; DocumentContext = new VersionedDocumentContext(documentUri, documentSnapshot, version); Logger = new NoopLogger(); - SemanticTokensRangeEndpoint = new SemanticTokensRangeEndpoint(); + SemanticTokensRangeEndpoint = new SemanticTokensRangeEndpoint(telemetryReporter: null); _ = SemanticTokensRangeEndpoint.GetRegistration(new VSInternalClientCapabilities() { SupportsVisualStudioExtensions = true }); var text = await DocumentContext.GetSourceTextAsync(CancellationToken.None).ConfigureAwait(false); @@ -163,6 +163,7 @@ internal override Task> GetCSharpSemanticRangesAsync( TextDocumentIdentifier textDocumentIdentifier, Range razorRange, long documentVersion, + Guid correlationId, CancellationToken cancellationToken, string previousResultId = null) { diff --git a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensScrollingBenchmark.cs b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensScrollingBenchmark.cs index 2d299d22557..1a1423655e8 100644 --- a/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensScrollingBenchmark.cs +++ b/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorSemanticTokensScrollingBenchmark.cs @@ -85,6 +85,7 @@ public async Task RazorSemanticTokensRangeScrollingAsync() Uri = DocumentUri }; var cancellationToken = CancellationToken.None; + var correlationId = Guid.Empty; var documentVersion = 1; await UpdateDocumentAsync(documentVersion, DocumentSnapshot).ConfigureAwait(false); @@ -105,6 +106,7 @@ public async Task RazorSemanticTokensRangeScrollingAsync() range, DocumentContext, SemanticTokensLegend, + correlationId, cancellationToken); lineCount = newLineCount; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer.Protocol/DelegatedTypes.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer.Protocol/DelegatedTypes.cs index 21ea8194339..f4e9807c7d7 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer.Protocol/DelegatedTypes.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer.Protocol/DelegatedTypes.cs @@ -46,7 +46,8 @@ internal record DelegatedCompletionParams( Position ProjectedPosition, RazorLanguageKind ProjectedKind, VSInternalCompletionContext Context, - TextEdit? ProvisionalTextEdit) : IDelegatedParams; + TextEdit? ProvisionalTextEdit, + Guid CorrelationId) : IDelegatedParams; internal record DelegatedCompletionResolutionContext( DelegatedCompletionParams OriginalRequestParams, diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CodeActionEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CodeActionEndpoint.cs index 1f93417a4f8..fc577a3529b 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CodeActionEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CodeActionEndpoint.cs @@ -27,9 +27,10 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions; -[LanguageServerEndpoint(Methods.TextDocumentCodeActionName)] +[LanguageServerEndpoint(LspEndpointName)] internal sealed class CodeActionEndpoint : IRazorRequestHandler[]?>, IRegistrationExtension { + public const string LspEndpointName = Methods.TextDocumentCodeActionName; private readonly IRazorDocumentMappingService _documentMappingService; private readonly IEnumerable _razorCodeActionProviders; private readonly IEnumerable _csharpCodeActionProviders; @@ -86,7 +87,7 @@ public CodeActionEndpoint( cancellationToken.ThrowIfCancellationRequested(); var correlationId = Guid.NewGuid(); - using var __ = _telemetryReporter?.TrackLspRequest(Methods.TextDocumentCodeActionName, LanguageServerConstants.RazorLanguageServerName, correlationId); + using var __ = _telemetryReporter?.TrackLspRequest(LspEndpointName, LanguageServerConstants.RazorLanguageServerName, correlationId); var razorCodeActions = await GetRazorCodeActionsAsync(razorCodeActionContext, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/CompletionListProvider.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/CompletionListProvider.cs index 4c9b308694c..6447ce08339 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/CompletionListProvider.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/CompletionListProvider.cs @@ -1,6 +1,7 @@ // 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 System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -33,11 +34,12 @@ public CompletionListProvider(RazorCompletionListProvider razorCompletionListPro VSInternalCompletionContext completionContext, VersionedDocumentContext documentContext, VSInternalClientCapabilities clientCapabilities, + Guid correlationId, CancellationToken cancellationToken) { // First we delegate to get completion items from the individual language server var delegatedCompletionList = IsValidTrigger(_delegatedCompletionListProvider.TriggerCharacters, completionContext) - ? await _delegatedCompletionListProvider.GetCompletionListAsync(absoluteIndex, completionContext, documentContext, clientCapabilities, cancellationToken).ConfigureAwait(false) + ? await _delegatedCompletionListProvider.GetCompletionListAsync(absoluteIndex, completionContext, documentContext, clientCapabilities, correlationId, cancellationToken).ConfigureAwait(false) : null; // Extract the items we got back from the delegated server, to inform tag helper completion diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionListProvider.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionListProvider.cs index af7b5e42182..2a0e17ce8a6 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionListProvider.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/Delegation/DelegatedCompletionListProvider.cs @@ -1,6 +1,7 @@ // 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 System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -48,6 +49,7 @@ public DelegatedCompletionListProvider( VSInternalCompletionContext completionContext, VersionedDocumentContext documentContext, VSInternalClientCapabilities clientCapabilities, + Guid correlationId, CancellationToken cancellationToken) { var positionInfo = await _documentMappingService.GetPositionInfoAsync(documentContext, absoluteIndex, cancellationToken).ConfigureAwait(false); @@ -73,7 +75,8 @@ public DelegatedCompletionListProvider( positionInfo.Position, positionInfo.LanguageKind, completionContext, - provisionalTextEdit); + provisionalTextEdit, + correlationId); var delegatedResponse = await _languageServer.SendRequestAsync( LanguageServerConstants.RazorCompletionEndpointName, diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorCompletionEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorCompletionEndpoint.cs index 01a9d7928ed..b52840bb88c 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorCompletionEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorCompletionEndpoint.cs @@ -1,12 +1,15 @@ // 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 System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.LanguageServer.Common; using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts; using Microsoft.AspNetCore.Razor.LanguageServer.Extensions; +using Microsoft.AspNetCore.Razor.Telemetry; using Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion; @@ -14,11 +17,13 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Completion; internal class RazorCompletionEndpoint : IVSCompletionEndpoint { private readonly CompletionListProvider _completionListProvider; + private readonly ITelemetryReporter? _telemetryReporter; private VSInternalClientCapabilities? _clientCapabilities; - public RazorCompletionEndpoint(CompletionListProvider completionListProvider) + public RazorCompletionEndpoint(CompletionListProvider completionListProvider, ITelemetryReporter? telemetryReporter) { _completionListProvider = completionListProvider; + _telemetryReporter = telemetryReporter; } public bool MutatesSolutionState => false; @@ -65,11 +70,14 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(CompletionParams request return null; } + var correlationId = Guid.NewGuid(); + using var _ = _telemetryReporter?.TrackLspRequest(Methods.TextDocumentCompletionName, LanguageServerConstants.RazorLanguageServerName, correlationId); var completionList = await _completionListProvider.GetCompletionListAsync( hostDocumentIndex, completionContext, documentContext, _clientCapabilities!, + correlationId, cancellationToken).ConfigureAwait(false); return completionList; } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Models/ProvideSemanticTokensRangeParams.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Models/ProvideSemanticTokensRangeParams.cs index 628006b4681..c92aa56dd2a 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Models/ProvideSemanticTokensRangeParams.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Models/ProvideSemanticTokensRangeParams.cs @@ -1,6 +1,7 @@ // 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 System.Runtime.Serialization; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -14,10 +15,14 @@ internal class ProvideSemanticTokensRangeParams : SemanticTokensParams [DataMember(Name = "range", IsRequired = true)] public Range Range { get; } - public ProvideSemanticTokensRangeParams(TextDocumentIdentifier textDocument, long requiredHostDocumentVersion, Range range) + [DataMember(Name = "correlationId", IsRequired = true)] + public Guid CorrelationId { get; } + + public ProvideSemanticTokensRangeParams(TextDocumentIdentifier textDocument, long requiredHostDocumentVersion, Range range, Guid correlationId) { TextDocument = textDocument; RequiredHostDocumentVersion = requiredHostDocumentVersion; Range = range; + CorrelationId = correlationId; } } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/SemanticTokensRangeEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/SemanticTokensRangeEndpoint.cs index 9f16f7c94f7..fbc47a10159 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/SemanticTokensRangeEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/SemanticTokensRangeEndpoint.cs @@ -5,17 +5,26 @@ using System.Diagnostics; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.LanguageServer.Common; using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts; using Microsoft.AspNetCore.Razor.LanguageServer.Semantic.Models; +using Microsoft.AspNetCore.Razor.Telemetry; using Microsoft.CommonLanguageServerProtocol.Framework; using Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.AspNetCore.Razor.LanguageServer.Semantic; -[LanguageServerEndpoint(Methods.TextDocumentSemanticTokensRangeName)] +[LanguageServerEndpoint(LspEndpointName)] internal sealed class SemanticTokensRangeEndpoint : IRazorRequestHandler, IRegistrationExtension { + public const string LspEndpointName = Methods.TextDocumentSemanticTokensRangeName; private RazorSemanticTokensLegend? _razorSemanticTokensLegend; + private readonly ITelemetryReporter? _telemetryReporter; + + public SemanticTokensRangeEndpoint(ITelemetryReporter? telemetryReporter) + { + _telemetryReporter = telemetryReporter; + } public bool MutatesSolutionState { get; } = false; @@ -49,7 +58,9 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(SemanticTokensRangeParam var documentContext = requestContext.GetRequiredDocumentContext(); var semanticTokensInfoService = requestContext.GetRequiredService(); - var semanticTokens = await semanticTokensInfoService.GetSemanticTokensAsync(request.TextDocument, request.Range, documentContext, _razorSemanticTokensLegend.AssumeNotNull(), cancellationToken).ConfigureAwait(false); + var correlationId = Guid.NewGuid(); + using var _ = _telemetryReporter?.TrackLspRequest(LspEndpointName, LanguageServerConstants.RazorLanguageServerName, correlationId); + var semanticTokens = await semanticTokensInfoService.GetSemanticTokensAsync(request.TextDocument, request.Range, documentContext, _razorSemanticTokensLegend.AssumeNotNull(), correlationId, cancellationToken).ConfigureAwait(false); var amount = semanticTokens is null ? "no" : (semanticTokens.Data.Length / 5).ToString(Thread.CurrentThread.CurrentCulture); requestContext.Logger.LogInformation("Returned {amount} semantic tokens for range {request.Range} in {request.TextDocument.Uri}.", amount, request.Range, request.TextDocument.Uri); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Services/IRazorSemanticTokenInfoService.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Services/IRazorSemanticTokenInfoService.cs index f90444e51a7..a506293458a 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Services/IRazorSemanticTokenInfoService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Services/IRazorSemanticTokenInfoService.cs @@ -1,6 +1,7 @@ // 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 System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -9,5 +10,5 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Semantic; internal interface IRazorSemanticTokensInfoService { - Task GetSemanticTokensAsync(TextDocumentIdentifier textDocumentIdentifier, Range range, VersionedDocumentContext documentContext, RazorSemanticTokensLegend razorSemanticTokensLegend, CancellationToken cancellationToken); + Task GetSemanticTokensAsync(TextDocumentIdentifier textDocumentIdentifier, Range range, VersionedDocumentContext documentContext, RazorSemanticTokensLegend razorSemanticTokensLegend, Guid correlationId, CancellationToken cancellationToken); } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Services/RazorSemanticTokensInfoService.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Services/RazorSemanticTokensInfoService.cs index 41117051f3e..845a4476690 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Services/RazorSemanticTokensInfoService.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/Services/RazorSemanticTokensInfoService.cs @@ -47,6 +47,7 @@ public RazorSemanticTokensInfoService( Range range, VersionedDocumentContext documentContext, RazorSemanticTokensLegend razorSemanticTokensLegend, + Guid correlationId, CancellationToken cancellationToken) { var codeDocument = await documentContext.GetCodeDocumentAsync(cancellationToken).ConfigureAwait(false); @@ -58,7 +59,7 @@ public RazorSemanticTokensInfoService( try { csharpSemanticRanges = await GetCSharpSemanticRangesAsync( - codeDocument, textDocumentIdentifier, range, documentContext.Version, cancellationToken).ConfigureAwait(false); + codeDocument, textDocumentIdentifier, range, documentContext.Version, correlationId, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { @@ -108,6 +109,7 @@ public RazorSemanticTokensInfoService( TextDocumentIdentifier textDocumentIdentifier, Range razorRange, long documentVersion, + Guid correlationId, CancellationToken cancellationToken, string? previousResultId = null) { @@ -120,7 +122,7 @@ public RazorSemanticTokensInfoService( return new List(); } - var csharpResponse = await GetMatchingCSharpResponseAsync(textDocumentIdentifier, documentVersion, csharpRange, cancellationToken).ConfigureAwait(false); + var csharpResponse = await GetMatchingCSharpResponseAsync(textDocumentIdentifier, documentVersion, csharpRange, correlationId, cancellationToken).ConfigureAwait(false); // Indicates an issue with retrieving the C# response (e.g. no response or C# is out of sync with us). // Unrecoverable, return default to indicate no change. We've already queued up a refresh request in @@ -210,9 +212,10 @@ internal static bool TryGetMinimalCSharpRange(RazorCodeDocument codeDocument, Ra TextDocumentIdentifier textDocumentIdentifier, long documentVersion, Range csharpRange, + Guid correlationId, CancellationToken cancellationToken) { - var parameter = new ProvideSemanticTokensRangeParams(textDocumentIdentifier, documentVersion, csharpRange); + var parameter = new ProvideSemanticTokensRangeParams(textDocumentIdentifier, documentVersion, csharpRange, correlationId); var csharpResponse = await _languageServer.SendRequestAsync( RazorLanguageServerCustomMessageTargets.RazorProvideSemanticTokensRangeEndpoint, diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/DefaultRazorLanguageServerCustomMessageTarget.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/DefaultRazorLanguageServerCustomMessageTarget.cs index a8212041de0..1a09c953783 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/DefaultRazorLanguageServerCustomMessageTarget.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServerClient.Razor/DefaultRazorLanguageServerCustomMessageTarget.cs @@ -297,10 +297,11 @@ public override async Task HtmlOnTypeFormatting codeActionParams.CodeActionParams.TextDocument.Uri = virtualDocumentSnapshot.Uri; var textBuffer = virtualDocumentSnapshot.Snapshot.TextBuffer; - using var _ = _telemetryReporter.TrackLspRequest(Methods.TextDocumentCodeActionName, languageServerName, codeActionParams.CorrelationId); + var lspMethodName = Methods.TextDocumentCodeActionName; + using var _ = _telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, codeActionParams.CorrelationId); var requests = _requestInvoker.ReinvokeRequestOnMultipleServersAsync>( textBuffer, - Methods.TextDocumentCodeActionName, + lspMethodName, SupportsCodeActionResolve, codeActionParams.CodeActionParams, cancellationToken).ConfigureAwait(false); @@ -418,10 +419,13 @@ public override async Task HtmlOnTypeFormatting }; var textBuffer = csharpDoc.Snapshot.TextBuffer; + var languageServerName = RazorLSPConstants.RazorCSharpLanguageServerName; + var lspMethodName = Methods.TextDocumentSemanticTokensRangeName; + using var _ = _telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, semanticTokensParams.CorrelationId); var csharpResults = await _requestInvoker.ReinvokeRequestOnServerAsync( textBuffer, - Methods.TextDocumentSemanticTokensRangeName, - RazorLSPConstants.RazorCSharpLanguageServerName, + lspMethodName, + languageServerName, newParams, cancellationToken).ConfigureAwait(false); @@ -874,9 +878,11 @@ private static bool SupportsFoldingRange(JToken token) try { var textBuffer = virtualDocumentSnapshot.Snapshot.TextBuffer; + var lspMethodName = Methods.TextDocumentCompletion.Name; + using var _ = _telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, request.CorrelationId); var response = await _requestInvoker.ReinvokeRequestOnServerAsync( textBuffer, - Methods.TextDocumentCompletion.Name, + lspMethodName, languageServerName, completionParams, cancellationToken).ConfigureAwait(continueOnCapturedContext); @@ -1169,10 +1175,11 @@ public override Task ImplementationAsync(DelegatedPosition }, }; - using var _ = _telemetryReporter.TrackLspRequest(VSInternalMethods.DocumentPullDiagnosticName, delegatedLanguageServerName, correlationId); + var lspMethodName = VSInternalMethods.DocumentPullDiagnosticName; + using var _ = _telemetryReporter.TrackLspRequest(lspMethodName, delegatedLanguageServerName, correlationId); var response = await _requestInvoker.ReinvokeRequestOnServerAsync( virtualDocument.Snapshot.TextBuffer, - VSInternalMethods.DocumentPullDiagnosticName, + lspMethodName, delegatedLanguageServerName, request, cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/CompletionListProviderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/CompletionListProviderTest.cs index fe22c25fe99..f8b3d58a60a 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/CompletionListProviderTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/CompletionListProviderTest.cs @@ -50,7 +50,7 @@ public async Task MultipleCompletionLists_Merges() // Act var completionList = await provider.GetCompletionListAsync( - absoluteIndex: 0, _completionContext, _documentContext, _clientCapabilities, DisposalToken); + absoluteIndex: 0, _completionContext, _documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); // Assert Assert.NotSame(_completionList1, completionList); @@ -67,7 +67,7 @@ public async Task MultipleCompletionLists_DifferentCommitCharacters_OnlyCallsApp // Act var completionList = await provider.GetCompletionListAsync( - absoluteIndex: 0, _completionContext, _documentContext, _clientCapabilities, DisposalToken); + absoluteIndex: 0, _completionContext, _documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); // Assert Assert.Same(_completionList2, completionList); @@ -91,6 +91,7 @@ public override Task GetCompletionListAsync( VSInternalCompletionContext completionContext, VersionedDocumentContext documentContext, VSInternalClientCapabilities clientCapabilities, + Guid correlationId, CancellationToken cancellationToken) { return Task.FromResult(_completionList); diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/DelegatedCompletionItemResolverTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/DelegatedCompletionItemResolverTest.cs index b7a0258440e..991d81059bf 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/DelegatedCompletionItemResolverTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/DelegatedCompletionItemResolverTest.cs @@ -56,8 +56,8 @@ public DelegatedCompletionItemResolverTest(ITestOutputHelper testOutput) }; var documentContext = TestDocumentContext.From("C:/path/to/file.cshtml", hostDocumentVersion: 0); - _csharpCompletionParams = new DelegatedCompletionParams(documentContext.Identifier, new Position(10, 6), RazorLanguageKind.CSharp, new VSInternalCompletionContext(), ProvisionalTextEdit: null); - _htmlCompletionParams = new DelegatedCompletionParams(documentContext.Identifier, new Position(0, 0), RazorLanguageKind.Html, new VSInternalCompletionContext(), ProvisionalTextEdit: null); + _csharpCompletionParams = new DelegatedCompletionParams(documentContext.Identifier, new Position(10, 6), RazorLanguageKind.CSharp, new VSInternalCompletionContext(), ProvisionalTextEdit: null, CorrelationId: Guid.Empty); + _htmlCompletionParams = new DelegatedCompletionParams(documentContext.Identifier, new Position(0, 0), RazorLanguageKind.Html, new VSInternalCompletionContext(), ProvisionalTextEdit: null, CorrelationId: Guid.Empty); _documentContextFactory = new TestDocumentContextFactory(); _formattingService = new AsyncLazy(() => TestRazorFormattingService.CreateWithFullSupportAsync()); _mappingService = new RazorDocumentMappingService(TestLanguageServerFeatureOptions.Instance, new TestDocumentContextFactory(), LoggerFactory); @@ -261,7 +261,7 @@ private async Task CreateCSharpServerAsync(RazorCodeDocumen var provider = TestDelegatedCompletionListProvider.Create(csharpServer, LoggerFactory, DisposalToken); var completionList = await provider.GetCompletionListAsync( - cursorPosition, completionContext, documentContext, _clientCapabilities, DisposalToken); + cursorPosition, completionContext, documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); return (completionList, provider.DelegatedParams); } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/DelegatedCompletionListProviderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/DelegatedCompletionListProviderTest.cs index cd93cc5b431..c078757e12b 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/DelegatedCompletionListProviderTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/DelegatedCompletionListProviderTest.cs @@ -45,7 +45,7 @@ public async Task ResponseRewritersGetExecutedInOrder() // Act var completionList = await provider.GetCompletionListAsync( - absoluteIndex: 1, completionContext, documentContext, _clientCapabilities, DisposalToken); + absoluteIndex: 1, completionContext, documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); // Assert Assert.Collection(completionList.Items, @@ -63,7 +63,7 @@ public async Task HtmlDelegation_Invoked() // Act await _provider.GetCompletionListAsync( - absoluteIndex: 1, completionContext, documentContext, _clientCapabilities, DisposalToken); + absoluteIndex: 1, completionContext, documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); // Assert var delegatedParameters = _provider.DelegatedParams; @@ -90,7 +90,7 @@ public async Task HtmlDelegation_TriggerCharacter() // Act await _provider.GetCompletionListAsync( - absoluteIndex: 1, completionContext, documentContext, _clientCapabilities, DisposalToken); + absoluteIndex: 1, completionContext, documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); // Assert var delegatedParameters = _provider.DelegatedParams; @@ -118,7 +118,7 @@ public async Task HtmlDelegation_UnsupportedTriggerCharacter_TranslatesToInvoked // Act await _provider.GetCompletionListAsync( - absoluteIndex: 1, completionContext, documentContext, _clientCapabilities, DisposalToken); + absoluteIndex: 1, completionContext, documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); // Assert var delegatedParameters = _provider.DelegatedParams; @@ -171,7 +171,7 @@ public async Task RazorDelegation_Noop() // Act var completionList = await _provider.GetCompletionListAsync( - absoluteIndex: 11, completionContext, documentContext, _clientCapabilities, DisposalToken); + absoluteIndex: 11, completionContext, documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); // Assert Assert.Null(completionList); @@ -194,7 +194,7 @@ public async Task ProvisionalCompletion_TranslatesToCSharpWithProvisionalTextEdi // Act await _provider.GetCompletionListAsync( - absoluteIndex: 10, completionContext, documentContext, _clientCapabilities, DisposalToken); + absoluteIndex: 10, completionContext, documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); // Assert var delegatedParameters = _provider.DelegatedParams; @@ -224,7 +224,7 @@ public async Task DotTriggerInMiddleOfCSharpImplicitExpressionNotTreatedAsProvis // Act await _provider.GetCompletionListAsync( - absoluteIndex: 10, completionContext, documentContext, _clientCapabilities, DisposalToken); + absoluteIndex: 10, completionContext, documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); // Assert var delegatedParameters = _provider.DelegatedParams; @@ -294,7 +294,7 @@ private async Task GetCompletionListAsync(string conte var provider = TestDelegatedCompletionListProvider.Create(csharpServer, LoggerFactory, DisposalToken); var completionList = await provider.GetCompletionListAsync( - absoluteIndex: cursorPosition, completionContext, documentContext, _clientCapabilities, DisposalToken); + absoluteIndex: cursorPosition, completionContext, documentContext, _clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); return completionList; } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/ResponseRewriterTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/ResponseRewriterTestBase.cs index b053482626e..f56413b1a5b 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/ResponseRewriterTestBase.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/Delegation/ResponseRewriterTestBase.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.LanguageServer.Test.Common; using Microsoft.AspNetCore.Razor.Test.Common; @@ -30,7 +31,7 @@ protected async Task GetRewrittenCompletionListAsync(i var documentContext = TestDocumentContext.From("C:/path/to/file.cshtml", codeDocument, hostDocumentVersion: 0); var provider = TestDelegatedCompletionListProvider.Create(initialCompletionList, LoggerFactory, Rewriter); var clientCapabilities = new VSInternalClientCapabilities(); - var completionList = await provider.GetCompletionListAsync(absoluteIndex, completionContext, documentContext, clientCapabilities, DisposalToken); + var completionList = await provider.GetCompletionListAsync(absoluteIndex, completionContext, documentContext, clientCapabilities, correlationId: Guid.Empty, cancellationToken: DisposalToken); return completionList; } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionEndpointTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionEndpointTest.cs index 823fd526566..c367333b158 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionEndpointTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/RazorCompletionEndpointTest.cs @@ -24,7 +24,7 @@ public async Task Handle_NoDocumentContext_NoCompletionItems() { // Arrange var documentPath = "C:/path/to/document.cshtml"; - var completionEndpoint = new RazorCompletionEndpoint(completionListProvider: null); + var completionEndpoint = new RazorCompletionEndpoint(completionListProvider: null, telemetryReporter: null); var request = new CompletionParams() { TextDocument = new TextDocumentIdentifier() diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/RazorSemanticTokenInfoServiceTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/RazorSemanticTokenInfoServiceTest.cs index b6eb39dc11c..0a17c759054 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/RazorSemanticTokenInfoServiceTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Semantic/RazorSemanticTokenInfoServiceTest.cs @@ -704,9 +704,10 @@ private async Task AssertSemanticTokensAsync( var textDocumentIdentifier = textDocumentIdentifiers.Dequeue(); var documentContext = documentContexts.Peek(); + var correlationId = Guid.Empty; // Act - var tokens = await service.GetSemanticTokensAsync(textDocumentIdentifier, range, documentContext, TestRazorSemanticTokensLegend.Instance, DisposalToken); + var tokens = await service.GetSemanticTokensAsync(textDocumentIdentifier, range, documentContext, TestRazorSemanticTokensLegend.Instance, correlationId, DisposalToken); // Assert AssertSemanticTokensMatchesBaseline(tokens?.Data); diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServerClient.Razor.Test/DefaultRazorLanguageServerCustomMessageTargetTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServerClient.Razor.Test/DefaultRazorLanguageServerCustomMessageTargetTest.cs index 26cfef63c12..40beae1d86e 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServerClient.Razor.Test/DefaultRazorLanguageServerCustomMessageTargetTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServerClient.Razor.Test/DefaultRazorLanguageServerCustomMessageTargetTest.cs @@ -281,7 +281,8 @@ public async Task ProvideSemanticTokensAsync_CannotLookupDocument_ReturnsNullAsy Uri = new Uri("C:/path/to/file.razor") }, requiredHostDocumentVersion: 1, - range: new Range()); + range: new Range(), + correlationId: Guid.Empty); // Act var result = await target.ProvideSemanticTokensRangeAsync(request, DisposalToken); @@ -309,7 +310,8 @@ public async Task ProvideSemanticTokensAsync_CannotLookupVirtualDocument_Returns Uri = new Uri("C:/path/to/file.razor") }, requiredHostDocumentVersion: 0, - range: new Range()); + range: new Range(), + correlationId: Guid.Empty); // Act var result = await target.ProvideSemanticTokensRangeAsync(request, DisposalToken); @@ -357,6 +359,7 @@ public async Task ProvideSemanticTokensAsync_ReturnsSemanticTokensAsync() var outputWindowLogger = Mock.Of(MockBehavior.Strict); var telemetryReporter = new Mock(MockBehavior.Strict); telemetryReporter.Setup(r => r.BeginBlock(It.IsAny(), It.IsAny(), It.IsAny>())).Returns(NullScope.Instance); + telemetryReporter.Setup(r => r.TrackLspRequest(It.IsAny(), It.IsAny(), It.IsAny())).Returns(NullScope.Instance); var target = new DefaultRazorLanguageServerCustomMessageTarget( documentManager.Object, JoinableTaskContext, requestInvoker.Object, @@ -367,7 +370,8 @@ public async Task ProvideSemanticTokensAsync_ReturnsSemanticTokensAsync() Uri = new Uri("C:/path/to%20-%20project/file.razor") }, requiredHostDocumentVersion: 0, - range: new Range()); + range: new Range(), + correlationId: Guid.Empty); var expectedResults = new ProvideSemanticTokensResponse(expectedCSharpResults.Data, documentVersion); // Act