diff --git a/Directory.Packages.props b/Directory.Packages.props index 4c339cad567..bb6f569f4f9 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,8 +6,8 @@ --> <_MicrosoftWebToolsPackageVersion>17.11.11-preview-0001 - <_MicrosoftVisualStudioShellPackagesVersion>18.0.2101-preview.1 - <_MicrosoftVisualStudioPackagesVersion>18.0.332-preview + <_MicrosoftVisualStudioShellPackagesVersion>18.0.2188-preview.1 + <_MicrosoftVisualStudioPackagesVersion>18.0.404-preview <_VisualStudioLanguageServerProtocolVersion>17.12.1-preview <_MicrosoftExtensionsPackageVersion>9.0.0 <_BasicReferenceAssembliesVersion>1.7.2 @@ -15,7 +15,7 @@ <_MicrosoftVisualStudioExtensibilityTestingVersion>0.1.800-beta <_MicrosoftVisualStudioLanguageServicesPackageVersion>$(MicrosoftVisualStudioLanguageServicesPackageVersion) <_XunitPackageVersion>2.9.2 - <_MicrosoftBuildPackageVersion>17.15.0-preview-25353-11 + <_MicrosoftBuildPackageVersion>17.15.0-preview-25357-08 @@ -86,7 +86,7 @@ - + diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 71683ac0231..8bd3866a02a 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,28 +6,28 @@ This file should be imported by eng/Versions.props - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 - 5.3.0-2.25601.4 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 + 5.3.0-2.25630.5 10.0.0-beta.25626.5 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0168f5d912c..d9726ed4b05 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -2,93 +2,93 @@ - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 - + https://github.com/dotnet/roslyn - a618d6246ead857f8c7de055bfde0f3438aa136a + 635d2b812121ef9fafe0de223b09be64e5a4a291 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 ea2e5bb9dc6..86a23e2ae63 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 @@ -6,6 +6,7 @@ using System.Composition; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost; @@ -79,8 +80,7 @@ public ImmutableArray GetRegistrations(VSInternalClientCapabilitie cancellationToken).ConfigureAwait(false); } - var results = await GetDiagnosticsAsync(razorDocument, cancellationToken).ConfigureAwait(false); - + var results = await GetVSDiagnosticsAsync(razorDocument, cancellationToken).ConfigureAwait(false); if (results is null) { return null; @@ -93,6 +93,37 @@ public ImmutableArray GetRegistrations(VSInternalClientCapabilitie }]; } + private async Task GetVSDiagnosticsAsync(TextDocument razorDocument, CancellationToken cancellationToken) + { + var diagnostics = await GetDiagnosticsAsync(razorDocument, cancellationToken).ConfigureAwait(false); + if (diagnostics is null) + { + return null; + } + + // We always use Roslyn's project understanding, and in VS the project Id is not necessarily the Id that is reported by Roslyn + // for diagnostics. Rather than try to replicate any of this behaviour directly, we just take Roslyn as the source of truth, + // and force the project information to match what it would produce, regardless of where it comes from or how we might have + // filtered or converted it. + var projectInfo = new[] { ExternalHandlers.Diagnostics.GetProjectInformation(razorDocument.Project) }; + + var results = new VSDiagnostic[diagnostics.Length]; + for (var i = 0; i < diagnostics.Length; i++) + { + var vsDiagnostic = JsonHelpers.Convert(diagnostics[i]).AssumeNotNull(); + vsDiagnostic.Projects = projectInfo; + + // Setting a unique identifier ensures that VS will show project info in the error list, and things like the "Current Project" + // filter will work. Putting the Razor file path in the identifier ensures that files in multiple projects get their diagnostics + // de-duped. + vsDiagnostic.Identifier = (vsDiagnostic.Code, razorDocument.FilePath, vsDiagnostic.Range, vsDiagnostic.Message).GetHashCode().ToString(); + + results[i] = vsDiagnostic; + } + + return results; + } + protected override VSInternalDocumentDiagnosticsParams CreateHtmlParams(Uri uri) { return new VSInternalDocumentDiagnosticsParams @@ -157,7 +188,7 @@ private async Task GetCSharpTaskListItemsAsync(TextDocument raz internal readonly struct TestAccessor(CohostDocumentPullDiagnosticsEndpoint instance) { public Task HandleRequestAsync(TextDocument razorDocument, CancellationToken cancellationToken) - => instance.GetDiagnosticsAsync(razorDocument, cancellationToken); + => instance.GetVSDiagnosticsAsync(razorDocument, cancellationToken); public Task HandleTaskListItemRequestAsync(TextDocument razorDocument, ImmutableArray taskListDescriptors, CancellationToken cancellationToken) => instance.HandleTaskListItemRequestAsync(razorDocument, taskListDescriptors, cancellationToken); 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 58cee9b2304..563c963418c 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 @@ -16,6 +16,74 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost; public partial class CohostDocumentPullDiagnosticsTest { + [Fact] + public Task OneOfEachDiagnostic() + { + TestCode input = """ +
+ + {|HTM1337:|} + + {|RZ10012:|} + +
+ + + + + + @code + { + public void IJustMetYou() + { + {|CS0103:CallMeMaybe|}(); + } + } + """; + + return VerifyDiagnosticsAsync(input, + htmlResponse: [new VSInternalDiagnosticReport + { + Diagnostics = + [ + new VSDiagnostic + { + Code = "HTM1337", + Range = SourceText.From(input.Text).GetRange(input.NamedSpans["HTM1337"].First()), + Projects = [new VSDiagnosticProjectInformation() + { + ProjectIdentifier = "Html" + }] + }, + new VSDiagnostic + { + Code = "TS2304", + Range = SourceText.From(input.Text).GetRange(input.NamedSpans["TS2304"].First()), + Projects = [new VSDiagnosticProjectInformation() + { + ProjectIdentifier = "TypeScript" + }] + }, + new VSDiagnostic + { + Code = "CSS002", + Range = SourceText.From(input.Text).GetRange(input.NamedSpans["CSS002"].First()), + Projects = [new VSDiagnosticProjectInformation() + { + ProjectIdentifier = "CSS" + }] + }, + ] + }]); + } + [Fact] public Task Html() { @@ -451,5 +519,21 @@ private async Task VerifyDiagnosticsAsync(TestCode input, VSInternalDiagnosticRe } AssertEx.EqualOrDiff(input.OriginalInput, testOutput); + + if (!taskListRequest) + { + Assert.NotNull(report.Diagnostics); + Assert.All(report.Diagnostics, + d => + { + var vsDiagnostic = Assert.IsType(d); + Assert.NotNull(vsDiagnostic.Identifier); + Assert.NotNull(vsDiagnostic.Projects); + var project = Assert.Single(vsDiagnostic.Projects); + Assert.NotNull(project.ProjectIdentifier); + // We always report the same project info for all diagnostics + Assert.Same(project, ((VSDiagnostic)report.Diagnostics.First()).Projects.Single()); + }); + } } }