Skip to content

Commit a1c72a3

Browse files
committed
Ensure Location.None in additional locations can round trip correctly
1 parent 978be80 commit a1c72a3

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/EditorFeatures/Test/Diagnostics/DiagnosticDataTests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,43 @@ public async Task DiagnosticData_ExternalAdditionalLocationIsPreserved()
167167
Assert.Equal(externalAdditionalLocation.UnmappedFileSpan, roundTripAdditionalLocation.UnmappedFileSpan);
168168
}
169169

170+
[Fact]
171+
public async Task DiagnosticData_NoneAdditionalLocationIsPreserved()
172+
{
173+
using var workspace = new TestWorkspace(composition: EditorTestCompositions.EditorFeatures);
174+
175+
var additionalDocument = workspace.CurrentSolution.AddProject("TestProject", "TestProject", LanguageNames.CSharp)
176+
.AddDocument("test.cs", "", filePath: "test.cs");
177+
178+
var document = additionalDocument.Project.Documents.Single();
179+
180+
var noneAdditionalLocation = new DiagnosticDataLocation(new FileLinePositionSpan("", default));
181+
182+
var diagnosticData = new DiagnosticData(
183+
id: "test1",
184+
category: "Test",
185+
message: "test1 message",
186+
severity: DiagnosticSeverity.Info,
187+
defaultSeverity: DiagnosticSeverity.Info,
188+
isEnabledByDefault: true,
189+
warningLevel: 1,
190+
projectId: document.Project.Id,
191+
customTags: [],
192+
properties: ImmutableDictionary<string, string>.Empty,
193+
location: new DiagnosticDataLocation(new FileLinePositionSpan(document.FilePath, span: default), document.Id),
194+
additionalLocations: [noneAdditionalLocation],
195+
language: document.Project.Language);
196+
197+
var diagnostic = await diagnosticData.ToDiagnosticAsync(document.Project, CancellationToken.None);
198+
var roundTripDiagnosticData = DiagnosticData.Create(diagnostic, document);
199+
200+
var roundTripAdditionalLocation = Assert.Single(roundTripDiagnosticData.AdditionalLocations);
201+
Assert.Null(noneAdditionalLocation.DocumentId);
202+
Assert.Null(roundTripAdditionalLocation.DocumentId);
203+
Assert.Equal(noneAdditionalLocation.UnmappedFileSpan, roundTripAdditionalLocation.UnmappedFileSpan);
204+
Assert.Same(diagnostic.AdditionalLocations.Single(), Location.None);
205+
}
206+
170207
[Fact]
171208
public async Task DiagnosticData_SourceGeneratedDocumentLocationIsPreserved()
172209
{

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,24 @@ private static ImmutableArray<DiagnosticDataLocation> GetAdditionalLocations(Tex
263263
{
264264
if (location.IsInSource)
265265
{
266-
builder.AddIfNotNull(CreateLocation(document.Project.Solution.GetDocument(location.SourceTree), location));
266+
builder.Add(CreateLocation(document.Project.Solution.GetDocument(location.SourceTree), location));
267267
}
268268
else if (location.Kind == LocationKind.ExternalFile)
269269
{
270270
var textDocumentId = document.Project.GetDocumentForExternalLocation(location);
271-
builder.AddIfNotNull(CreateLocation(document.Project.GetTextDocument(textDocumentId), location));
271+
builder.Add(CreateLocation(document.Project.GetTextDocument(textDocumentId), location));
272272
}
273+
else if (location.Kind == LocationKind.None)
274+
{
275+
builder.Add(CreateLocation(document: null, location));
276+
}
277+
// TODO: Should we throw an exception in an else?
278+
// This will be reachable if a user creates his own type inheriting Location, and
279+
// returns, e.g, LocationKind.XmlFile in Kind override.
280+
// The case for custom `Location`s in general will be hard (if possible at all) to
281+
// always round trip correctly.
282+
// Or, maybe just always create a location with null document, so at least we guarantee that
283+
// the count of additional location created by analyzer always matches what end up being in the code fix.
273284
}
274285

275286
return builder.ToImmutableAndClear();

0 commit comments

Comments
 (0)