From 5d579bfa8da7cea480665f760f03ec35a1d4f94c Mon Sep 17 00:00:00 2001 From: David Barbet Date: Thu, 28 Aug 2025 14:15:26 -0700 Subject: [PATCH] Fix issue reporting diagnostic in additional file when diagnostic produced by a source generator --- .../AdditionalFileDiagnosticsTests.cs | 38 +++++++++++++++++++ .../DiagnosticAnalysisResultBuilder.cs | 3 -- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/LanguageServer/ProtocolUnitTests/Diagnostics/AdditionalFileDiagnosticsTests.cs b/src/LanguageServer/ProtocolUnitTests/Diagnostics/AdditionalFileDiagnosticsTests.cs index 037f2a333e3ca..35adfcd839818 100644 --- a/src/LanguageServer/ProtocolUnitTests/Diagnostics/AdditionalFileDiagnosticsTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/Diagnostics/AdditionalFileDiagnosticsTests.cs @@ -15,7 +15,9 @@ using Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics; using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; +using Roslyn.Test.Utilities.TestGenerators; using Xunit; using Xunit.Abstractions; using LSP = Roslyn.LanguageServer.Protocol; @@ -151,6 +153,42 @@ public async Task TestWorkspaceDiagnosticsWithAdditionalFileInMultipleProjects(b AssertEx.Empty(results2); } + [Theory, CombinatorialData] + public async Task TestWorkspaceDiagnosticsReportsSourceGeneratorDiagnosticInAdditionalFile(bool useVSDiagnostics, bool mutatingLspWorkspace) + { + var additionaFilePath = @"C:\File.razor"; + var workspaceXml = + $""" + + + + Hello + + + """; + + await using var testLspServer = await CreateTestWorkspaceFromXmlAsync(workspaceXml, mutatingLspWorkspace, BackgroundAnalysisScope.FullSolution, useVSDiagnostics); + + // Add a generator to the solution that reports a source generator diagnostic in an additional file. + var generator = new DiagnosticProducingGenerator(context => + { + return Location.Create(additionaFilePath, TextSpan.FromBounds(0, 1), new LinePositionSpan(new LinePosition(0, 0), new LinePosition(0, 1))); + }); + + testLspServer.TestWorkspace.OnAnalyzerReferenceAdded( + testLspServer.GetCurrentSolution().Projects.Single().Id, + new TestGeneratorReference(generator)); + await testLspServer.WaitForSourceGeneratorsAsync(); + + var results = await RunGetWorkspacePullDiagnosticsAsync(testLspServer, useVSDiagnostics); + AssertEx.Equal( + [ + @"C:\C.cs: []", + @$"C:\File.razor: [{DiagnosticProducingGenerator.Descriptor.Id}, {MockAdditionalFileDiagnosticAnalyzer.Id}]", + @"C:\CSProj1.csproj: []" + ], results.Select(r => $"{r.Uri.GetRequiredParsedUri().LocalPath}: [{string.Join(", ", r.Diagnostics!.Select(d => d.Code?.Value?.ToString()))}]")); + } + protected override TestComposition Composition => base.Composition.AddParts(typeof(MockAdditionalFileDiagnosticAnalyzer), typeof(TestAdditionalFileDocumentSourceProvider)); private protected override TestAnalyzerReferenceByLanguage CreateTestAnalyzersReference() diff --git a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResultBuilder.cs b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResultBuilder.cs index 966d0da39492b..c526a396c47e6 100644 --- a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResultBuilder.cs +++ b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResultBuilder.cs @@ -41,9 +41,6 @@ public void AddExternalSemanticDiagnostics(DocumentId documentId, ImmutableArray if (diagnostics.Length == 0) return; - // this is for diagnostic producer that doesnt use compiler based DiagnosticAnalyzer such as TypeScript. - Contract.ThrowIfTrue(Project.SupportsCompilation); - AddExternalDiagnostics(ref _lazySemanticLocals, documentId, diagnostics); }