-
Notifications
You must be signed in to change notification settings - Fork 0
test: pin diagnostic-location safety across incremental updates #144
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
Merged
ANcpLua
merged 2 commits into
main
from
test/incremental-diagnostic-location-regression
Jun 14, 2026
Merged
Changes from 1 commit
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
...s/ANcpLua.Roslyn.Utilities.DiscriminatedUnion.Tests/IncrementalDiagnosticLocationTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| using ANcpLua.Roslyn.Utilities.Testing.GeneratorHelpers; | ||
| using AwesomeAssertions; | ||
| using Microsoft.CodeAnalysis; | ||
| using Microsoft.CodeAnalysis.CSharp; | ||
| using Xunit; | ||
|
|
||
| namespace ANcpLua.Analyzers.DiscriminatedUnion.Tests; | ||
|
|
||
| /// <summary> | ||
| /// Regression guard for the bug class fixed by dotnet/roslyn#82113 (issue #82032): a generator | ||
| /// diagnostic whose location was captured against a longer tree must not survive a shrinking | ||
| /// incremental edit as an out-of-range span. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Our diagnostics flow through <c>DiagnosticInfo</c>/<c>LocationInfo</c>, which reconstruct an | ||
| /// <em>external-file</em> location (never source-tree-bound) at report time. The driver never | ||
| /// range-validates external locations, so a shrinking edit can neither crash the generator nor | ||
| /// emit a stale span. This test fails if that guarantee regresses — e.g. if <c>ToLocation()</c> | ||
| /// ever produced a source-tree-bound location. | ||
| /// </remarks> | ||
| public sealed class IncrementalDiagnosticLocationTests | ||
| { | ||
| [Fact] | ||
| public void Shrinking_Edit_Keeps_Diagnostic_Location_In_Range_Without_Crashing() | ||
| { | ||
| // A union root with no cases reports AL0301 at the whole record declaration. The padded | ||
| // namespace/identifier pushes that span far past the length of the shrunk tree below. | ||
| const string longSource = """ | ||
| using ANcpLua.Analyzers.DiscriminatedUnion; | ||
|
|
||
| namespace NamespacePaddingToPushTheDiagnosticSpanFarPastTheShrunkTree | ||
| { | ||
| [DiscriminatedUnion] | ||
| public partial record RootWithNoCasesAndADeliberatelyLongIdentifier | ||
| { | ||
| } | ||
| } | ||
| """; | ||
|
|
||
| // Still reports AL0301, but the tree is far shorter than the original diagnostic span. | ||
| const string shortSource = | ||
| "using ANcpLua.Analyzers.DiscriminatedUnion;[DiscriminatedUnion]public partial record R{}"; | ||
|
|
||
| var compilation = GeneratorTestHelper.CreateCompilation(longSource); | ||
| GeneratorDriver driver = CSharpGeneratorDriver.Create(new DiscriminatedUnionGenerator().AsSourceGenerator()); | ||
|
|
||
| driver = driver.RunGenerators(compilation, TestContext.Current.CancellationToken); | ||
| var firstDiagnostic = driver.GetRunResult().Diagnostics.Single(d => d.Id == "AL0301"); | ||
|
|
||
| var oldTree = compilation.SyntaxTrees.Single(); | ||
| var newTree = CSharpSyntaxTree.ParseText( | ||
| shortSource, | ||
| (CSharpParseOptions)oldTree.Options, | ||
| cancellationToken: TestContext.Current.CancellationToken); | ||
| var shrunk = compilation.ReplaceSyntaxTree(oldTree, newTree); | ||
|
|
||
| // Precondition: the original span genuinely would be out of range for the shrunk tree — | ||
| // otherwise the edit would not exercise the bug class at all. | ||
| firstDiagnostic.Location.SourceSpan.End.Should() | ||
| .BeGreaterThan(newTree.Length, "the edit must shrink the tree below the original diagnostic span"); | ||
|
|
||
| driver = driver.RunGenerators(shrunk, TestContext.Current.CancellationToken); | ||
| var afterEdit = driver.GetRunResult().Diagnostics; | ||
|
|
||
| // No crash diagnostic (e.g. CS8785 "generator failed"): the only generator diagnostic is AL0301. | ||
| afterEdit.Should().ContainSingle() | ||
| .Which.Id.Should().Be("AL0301", "the generator must re-report AL0301 and must not crash on the edit"); | ||
|
|
||
| var second = afterEdit[0]; | ||
| second.Location.IsInSource.Should() | ||
| .BeFalse("LocationInfo reconstructs an external-file location the driver never range-validates"); | ||
| second.Location.SourceSpan.End.Should() | ||
| .BeLessThanOrEqualTo(newTree.Length, "the reported location must stay within the current tree after the edit"); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.