Skip to content

Commit 05a936d

Browse files
authored
Fix issue reporting diagnostic in additional file when diagnostic produced by a source generator (#80071)
Resolves microsoft/vscode-dotnettools#2173 IDE diagnostic analyzers specifically go through a special path when reporting semantic diagnostics (different to other analyzers). This path had an old, bogus assert to verify that if the semantic diagnostic was in a file with no syntax tree (e.g. additional file), that also the project the file was in had no compilation (assuming it was a typescript project which has neither). However this assert now gets hit because 1. Source generator diagnostics are reported as semantic diagnostics via an IDE diagnostic analyzer ([link](https://github.com/dotnet/roslyn/blob/main/src/Workspaces/Core/Portable/Diagnostics/GeneratorDiagnosticsPlaceholderAnalyzer.cs)). 2. The Razor source generator reports diagnostics in additional files (the .razor file) This change removes the assert as it doesn't appear to be necessary or valid.
2 parents 8cd8769 + 5d579bf commit 05a936d

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/LanguageServer/ProtocolUnitTests/Diagnostics/AdditionalFileDiagnosticsTests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
using Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics;
1616
using Microsoft.CodeAnalysis.SolutionCrawler;
1717
using Microsoft.CodeAnalysis.Test.Utilities;
18+
using Microsoft.CodeAnalysis.Text;
1819
using Roslyn.Test.Utilities;
20+
using Roslyn.Test.Utilities.TestGenerators;
1921
using Xunit;
2022
using Xunit.Abstractions;
2123
using LSP = Roslyn.LanguageServer.Protocol;
@@ -151,6 +153,42 @@ public async Task TestWorkspaceDiagnosticsWithAdditionalFileInMultipleProjects(b
151153
AssertEx.Empty(results2);
152154
}
153155

156+
[Theory, CombinatorialData]
157+
public async Task TestWorkspaceDiagnosticsReportsSourceGeneratorDiagnosticInAdditionalFile(bool useVSDiagnostics, bool mutatingLspWorkspace)
158+
{
159+
var additionaFilePath = @"C:\File.razor";
160+
var workspaceXml =
161+
$"""
162+
<Workspace>
163+
<Project Language="C#" CommonReferences="true" AssemblyName="CSProj1" FilePath="C:\CSProj1.csproj">
164+
<Document FilePath="C:\C.cs"></Document>
165+
<AdditionalDocument FilePath="{additionaFilePath}">Hello</AdditionalDocument>
166+
</Project>
167+
</Workspace>
168+
""";
169+
170+
await using var testLspServer = await CreateTestWorkspaceFromXmlAsync(workspaceXml, mutatingLspWorkspace, BackgroundAnalysisScope.FullSolution, useVSDiagnostics);
171+
172+
// Add a generator to the solution that reports a source generator diagnostic in an additional file.
173+
var generator = new DiagnosticProducingGenerator(context =>
174+
{
175+
return Location.Create(additionaFilePath, TextSpan.FromBounds(0, 1), new LinePositionSpan(new LinePosition(0, 0), new LinePosition(0, 1)));
176+
});
177+
178+
testLspServer.TestWorkspace.OnAnalyzerReferenceAdded(
179+
testLspServer.GetCurrentSolution().Projects.Single().Id,
180+
new TestGeneratorReference(generator));
181+
await testLspServer.WaitForSourceGeneratorsAsync();
182+
183+
var results = await RunGetWorkspacePullDiagnosticsAsync(testLspServer, useVSDiagnostics);
184+
AssertEx.Equal(
185+
[
186+
@"C:\C.cs: []",
187+
@$"C:\File.razor: [{DiagnosticProducingGenerator.Descriptor.Id}, {MockAdditionalFileDiagnosticAnalyzer.Id}]",
188+
@"C:\CSProj1.csproj: []"
189+
], results.Select(r => $"{r.Uri.GetRequiredParsedUri().LocalPath}: [{string.Join(", ", r.Diagnostics!.Select(d => d.Code?.Value?.ToString()))}]"));
190+
}
191+
154192
protected override TestComposition Composition => base.Composition.AddParts(typeof(MockAdditionalFileDiagnosticAnalyzer), typeof(TestAdditionalFileDocumentSourceProvider));
155193

156194
private protected override TestAnalyzerReferenceByLanguage CreateTestAnalyzersReference()

src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResultBuilder.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,6 @@ public void AddExternalSemanticDiagnostics(DocumentId documentId, ImmutableArray
4141
if (diagnostics.Length == 0)
4242
return;
4343

44-
// this is for diagnostic producer that doesnt use compiler based DiagnosticAnalyzer such as TypeScript.
45-
Contract.ThrowIfTrue(Project.SupportsCompilation);
46-
4744
AddExternalDiagnostics(ref _lazySemanticLocals, documentId, diagnostics);
4845
}
4946

0 commit comments

Comments
 (0)