diff --git a/Directory.Packages.props b/Directory.Packages.props index 15b85644c50..2693b63e3e4 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -28,7 +28,7 @@ - + diff --git a/eng/Version.Details.props b/eng/Version.Details.props index f3142a335af..7c7a497ed3b 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,27 +6,27 @@ This file should be imported by eng/Versions.props - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 - 5.0.0-2.25421.11 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 + 5.0.0-2.25452.2 9.0.0-beta.25428.3 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4a87af0e1ff..30d504eecbd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -2,89 +2,89 @@ - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be - + https://github.com/dotnet/roslyn - 2a2f7bb1b54522b1af28e8cc7b61024612f0ce17 + e5924c0044a45b9b10ccde820a447adbb636f8be diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Diagnostics/CohostDocumentPullDiagnosticsEndpointBase.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Diagnostics/CohostDocumentPullDiagnosticsEndpointBase.cs index 43871e6b632..d86516a7fc2 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Diagnostics/CohostDocumentPullDiagnosticsEndpointBase.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.CohostingShared/Diagnostics/CohostDocumentPullDiagnosticsEndpointBase.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Threading; @@ -98,13 +96,23 @@ protected virtual TRequest CreateHtmlParams(Uri uri) } _logger.LogDebug($"Reporting {diagnostics.Length} diagnostics back to the client"); - return diagnostics.ToArray(); + return [.. diagnostics]; + } + + protected static Task TryGetGeneratedDocumentAsync(TextDocument razorDocument, CancellationToken cancellationToken) + { + if (!razorDocument.TryComputeHintNameFromRazorDocument(out var hintName)) + { + return SpecializedTasks.Null(); + } + + return razorDocument.Project.TryGetSourceGeneratedDocumentFromHintNameAsync(hintName, cancellationToken); } private async Task GetCSharpDiagnosticsAsync(TextDocument razorDocument, Guid correletionId, CancellationToken cancellationToken) { - if (!razorDocument.TryComputeHintNameFromRazorDocument(out var hintName) || - await razorDocument.Project.TryGetSourceGeneratedDocumentFromHintNameAsync(hintName, cancellationToken).ConfigureAwait(false) is not { } generatedDocument) + var generatedDocument = await TryGetGeneratedDocumentAsync(razorDocument, cancellationToken).ConfigureAwait(false); + if (generatedDocument is null) { return []; } @@ -114,7 +122,7 @@ await razorDocument.Project.TryGetSourceGeneratedDocumentFromHintNameAsync(hintN using var _ = _telemetryReporter.TrackLspRequest(LspMethodName, "Razor.ExternalAccess", TelemetryThresholds.DiagnosticsSubLSPTelemetryThreshold, correletionId); var supportsVisualStudioExtensions = _clientCapabilitiesService.ClientCapabilities.SupportsVisualStudioExtensions; var diagnostics = await ExternalHandlers.Diagnostics.GetDocumentDiagnosticsAsync(generatedDocument, supportsVisualStudioExtensions, cancellationToken).ConfigureAwait(false); - return diagnostics.ToArray(); + return [.. diagnostics]; } private async Task GetHtmlDiagnosticsAsync(TextDocument razorDocument, Guid correletionId, CancellationToken cancellationToken) diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Diagnostics/RazorTranslateDiagnosticsService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Diagnostics/RazorTranslateDiagnosticsService.cs index 7c5825133b4..8561b41269d 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Diagnostics/RazorTranslateDiagnosticsService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Diagnostics/RazorTranslateDiagnosticsService.cs @@ -113,7 +113,7 @@ private static LspDiagnostic[] FilterHTMLDiagnostics( return filteredDiagnostics; } - private LspDiagnostic[] MapDiagnostics( + internal LspDiagnostic[] MapDiagnostics( RazorLanguageKind languageKind, LspDiagnostic[] diagnostics, IDocumentSnapshot documentSnapshot, diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteDiagnosticsService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteDiagnosticsService.cs index 3027f9f3cd9..37847d0dac7 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteDiagnosticsService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Remote/IRemoteDiagnosticsService.cs @@ -21,5 +21,6 @@ ValueTask> GetTaskListDiagnosticsAsync( JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo, JsonSerializableDocumentId documentId, ImmutableArray taskListDescriptors, + LspDiagnostic[] csharpTaskItems, CancellationToken cancellationToken); } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Diagnostics/RemoteDiagnosticsService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Diagnostics/RemoteDiagnosticsService.cs index 8ad937aaf89..f67c7345fb2 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Diagnostics/RemoteDiagnosticsService.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/Diagnostics/RemoteDiagnosticsService.cs @@ -4,6 +4,7 @@ using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis.ExternalAccess.Razor; using Microsoft.CodeAnalysis.Razor.Diagnostics; using Microsoft.CodeAnalysis.Razor.Protocol; @@ -56,20 +57,25 @@ public ValueTask> GetTaskListDiagnosticsAsync( JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo, JsonSerializableDocumentId documentId, ImmutableArray taskListDescriptors, + LspDiagnostic[] csharpTaskItems, CancellationToken cancellationToken) => RunServiceAsync( solutionInfo, documentId, - context => GetTaskListDiagnosticsAsync(context, taskListDescriptors, cancellationToken), + context => GetTaskListDiagnosticsAsync(context, taskListDescriptors, csharpTaskItems, cancellationToken), cancellationToken); - private static async ValueTask> GetTaskListDiagnosticsAsync( + private async ValueTask> GetTaskListDiagnosticsAsync( RemoteDocumentContext context, ImmutableArray taskListDescriptors, + LspDiagnostic[] csharpTaskItems, CancellationToken cancellationToken) { var codeDocument = await context.GetCodeDocumentAsync(cancellationToken).ConfigureAwait(false); - return TaskListDiagnosticProvider.GetTaskListDiagnostics(codeDocument, taskListDescriptors); + using var diagnostics = new PooledArrayBuilder(); + diagnostics.AddRange(TaskListDiagnosticProvider.GetTaskListDiagnostics(codeDocument, taskListDescriptors)); + diagnostics.AddRange(_translateDiagnosticsService.MapDiagnostics(RazorLanguageKind.CSharp, csharpTaskItems, context.Snapshot, codeDocument)); + return diagnostics.ToImmutableAndClear(); } } diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostDocumentPullDiagnosticsEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostDocumentPullDiagnosticsEndpoint.cs index 8be5c8cc4bc..ea2e5bb9dc6 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostDocumentPullDiagnosticsEndpoint.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostDocumentPullDiagnosticsEndpoint.cs @@ -15,6 +15,7 @@ using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.Telemetry; using Microsoft.CodeAnalysis.Razor.Workspaces.Settings; +using ExternalHandlers = Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost.Handlers; namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost; @@ -43,6 +44,7 @@ internal sealed class CohostDocumentPullDiagnosticsEndpoint( { private readonly IRemoteServiceInvoker _remoteServiceInvoker = remoteServiceInvoker; private readonly IClientSettingsManager _clientSettingsManager = clientSettingsManager; + private readonly IClientCapabilitiesService _clientCapabilitiesService = clientCapabilitiesService; protected override string LspMethodName => VSInternalMethods.DocumentPullDiagnosticName; protected override bool SupportsHtmlDiagnostics => true; @@ -115,9 +117,11 @@ protected override LspDiagnostic[] ExtractHtmlDiagnostics(VSInternalDiagnosticRe private async Task HandleTaskListItemRequestAsync(TextDocument razorDocument, ImmutableArray taskListDescriptors, CancellationToken cancellationToken) { + var csharpTaskItems = await GetCSharpTaskListItemsAsync(razorDocument, cancellationToken).ConfigureAwait(false); + var diagnostics = await _remoteServiceInvoker.TryInvokeAsync>( razorDocument.Project.Solution, - (service, solutionInfo, cancellationToken) => service.GetTaskListDiagnosticsAsync(solutionInfo, razorDocument.Id, taskListDescriptors, cancellationToken), + (service, solutionInfo, cancellationToken) => service.GetTaskListDiagnosticsAsync(solutionInfo, razorDocument.Id, taskListDescriptors, csharpTaskItems, cancellationToken), cancellationToken).ConfigureAwait(false); if (diagnostics.IsDefaultOrEmpty) @@ -135,6 +139,19 @@ private async Task HandleTaskListItemRequestAsync( ]; } + private async Task GetCSharpTaskListItemsAsync(TextDocument razorDocument, CancellationToken cancellationToken) + { + var generatedDocument = await TryGetGeneratedDocumentAsync(razorDocument, cancellationToken).ConfigureAwait(false); + if (generatedDocument is null) + { + return []; + } + + var supportsVisualStudioExtensions = _clientCapabilitiesService.ClientCapabilities.SupportsVisualStudioExtensions; + var csharpTaskItems = await ExternalHandlers.Diagnostics.GetTaskListAsync(generatedDocument, supportsVisualStudioExtensions, cancellationToken).ConfigureAwait(false); + return [.. csharpTaskItems]; + } + internal TestAccessor GetTestAccessor() => new(this); internal readonly struct TestAccessor(CohostDocumentPullDiagnosticsEndpoint instance) diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Cohosting/CohostTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Cohosting/CohostTestBase.cs index e82db07ca4d..cd30a002dc7 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Cohosting/CohostTestBase.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common.Cohosting/CohostTestBase.cs @@ -137,7 +137,7 @@ protected virtual TextDocument CreateProjectAndRazorDocument( return CreateProjectAndRazorDocument(remoteWorkspace, projectId, miscellaneousFile, documentId, documentFilePath, contents, additionalFiles, inGlobalNamespace); } - protected TextDocument CreateProjectAndRazorDocument(CodeAnalysis.Workspace workspace, ProjectId projectId, bool miscellaneousFile, DocumentId documentId, string documentFilePath, string contents, (string fileName, string contents)[]? additionalFiles, bool inGlobalNamespace) + protected static TextDocument CreateProjectAndRazorDocument(CodeAnalysis.Workspace workspace, ProjectId projectId, bool miscellaneousFile, DocumentId documentId, string documentFilePath, string contents, (string fileName, string contents)[]? additionalFiles, bool inGlobalNamespace) { // We simulate a miscellaneous file project by not having a project file path. var projectFilePath = miscellaneousFile ? null : TestProjectData.SomeProject.FilePath; diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostDocumentPullDiagnosticsTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostDocumentPullDiagnosticsTest.cs index 7516a2a2993..49822f1b6a5 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostDocumentPullDiagnosticsTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CohostDocumentPullDiagnosticsTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.LanguageServer.Test; using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.CodeAnalysis.Razor.Diagnostics; @@ -409,6 +408,10 @@ public Task TODOComments() => VerifyDiagnosticsAsync(""" @using System.Threading.Tasks; + // TODO: This isn't C# + + TODO: Nor is this +
@*{|TODO: TODO: This does |}*@ @@ -416,6 +419,11 @@ public Task TODOComments() @* TODONT: This doesn't *@
+ + @code { + // This looks different because Roslyn only reports zero width ranges for task lists + // {|TODO:|}TODO: Write some C# code too + } """, taskListRequest: true); @@ -448,7 +456,8 @@ private async Task VerifyDiagnosticsAsync(TestCode input, VSInternalDiagnosticRe }); var testOutput = input.Text; - foreach (var (index, text) in markers.OrderByDescending(i => i.index)) + // Ordering by text last means start tags get sorted before end tags, for zero width ranges + foreach (var (index, text) in markers.OrderByDescending(i => i.index).ThenByDescending(i => i.text)) { testOutput = testOutput.Insert(index, text); }