-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ensure Location.None in additional locations can round trip correctly #76623
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -167,6 +167,43 @@ public async Task DiagnosticData_ExternalAdditionalLocationIsPreserved() | |
Assert.Equal(externalAdditionalLocation.UnmappedFileSpan, roundTripAdditionalLocation.UnmappedFileSpan); | ||
} | ||
|
||
[Fact] | ||
public async Task DiagnosticData_NoneAdditionalLocationIsPreserved() | ||
{ | ||
using var workspace = new TestWorkspace(composition: EditorTestCompositions.EditorFeatures); | ||
|
||
var additionalDocument = workspace.CurrentSolution.AddProject("TestProject", "TestProject", LanguageNames.CSharp) | ||
.AddDocument("test.cs", "", filePath: "test.cs"); | ||
|
||
var document = additionalDocument.Project.Documents.Single(); | ||
|
||
var noneAdditionalLocation = new DiagnosticDataLocation(new FileLinePositionSpan("", default)); | ||
|
||
var diagnosticData = new DiagnosticData( | ||
id: "test1", | ||
category: "Test", | ||
message: "test1 message", | ||
severity: DiagnosticSeverity.Info, | ||
defaultSeverity: DiagnosticSeverity.Info, | ||
isEnabledByDefault: true, | ||
warningLevel: 1, | ||
projectId: document.Project.Id, | ||
customTags: [], | ||
properties: ImmutableDictionary<string, string>.Empty, | ||
location: new DiagnosticDataLocation(new FileLinePositionSpan(document.FilePath, span: default), document.Id), | ||
additionalLocations: [noneAdditionalLocation], | ||
language: document.Project.Language); | ||
|
||
var diagnostic = await diagnosticData.ToDiagnosticAsync(document.Project, CancellationToken.None); | ||
var roundTripDiagnosticData = DiagnosticData.Create(diagnostic, document); | ||
|
||
var roundTripAdditionalLocation = Assert.Single(roundTripDiagnosticData.AdditionalLocations); | ||
Assert.Null(noneAdditionalLocation.DocumentId); | ||
Assert.Null(roundTripAdditionalLocation.DocumentId); | ||
Assert.Equal(noneAdditionalLocation.UnmappedFileSpan, roundTripAdditionalLocation.UnmappedFileSpan); | ||
Assert.Same(diagnostic.AdditionalLocations.Single(), Location.None); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we verify that producing diagnostics from the diagnosticdata also works and gives back Location.None? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I'm interpreting this correctly, the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah. Gotcha. That's sufficient for me |
||
} | ||
|
||
[Fact] | ||
public async Task DiagnosticData_SourceGeneratedDocumentLocationIsPreserved() | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -263,13 +263,24 @@ private static ImmutableArray<DiagnosticDataLocation> GetAdditionalLocations(Tex | |
{ | ||
if (location.IsInSource) | ||
{ | ||
builder.AddIfNotNull(CreateLocation(document.Project.Solution.GetDocument(location.SourceTree), location)); | ||
builder.Add(CreateLocation(document.Project.Solution.GetDocument(location.SourceTree), location)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
else if (location.Kind == LocationKind.ExternalFile) | ||
{ | ||
var textDocumentId = document.Project.GetDocumentForExternalLocation(location); | ||
builder.AddIfNotNull(CreateLocation(document.Project.GetTextDocument(textDocumentId), location)); | ||
builder.Add(CreateLocation(document.Project.GetTextDocument(textDocumentId), location)); | ||
} | ||
else if (location.Kind == LocationKind.None) | ||
{ | ||
builder.Add(CreateLocation(document: null, location)); | ||
} | ||
// TODO: Should we throw an exception in an else? | ||
// This will be reachable if a user creates his own type inheriting Location, and | ||
// returns, e.g, LocationKind.XmlFile in Kind override. | ||
// The case for custom `Location`s in general will be hard (if possible at all) to | ||
// always round trip correctly. | ||
// Or, maybe just always create a location with null document, so at least we guarantee that | ||
// the count of additional location created by analyzer always matches what end up being in the code fix. | ||
} | ||
|
||
return builder.ToImmutableAndClear(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assert would fail without the fix.