Skip to content

Commit 65177ac

Browse files
Validate generator diagnostics after incremental updates (#82113)
Fixes #82032. --------- Co-authored-by: Cyrus Najmabadi <cyrus.najmabadi@gmail.com>
1 parent a80bb70 commit 65177ac

2 files changed

Lines changed: 60 additions & 8 deletions

File tree

src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests.cs

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@
2020
using Roslyn.Test.Utilities.TestGenerators;
2121
using Roslyn.Utilities;
2222
using Xunit;
23+
using Xunit.Abstractions;
24+
2325
namespace Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.SourceGeneration
2426
{
25-
public class GeneratorDriverTests
27+
public class GeneratorDriverTests(ITestOutputHelper output)
2628
: CSharpTestBase
2729
{
30+
private readonly ITestOutputHelper _output = output;
31+
2832
[Fact]
2933
public void Running_With_No_Changes_Is_NoOp()
3034
{
@@ -3891,6 +3895,48 @@ public void Diagnostic_SpanOutsideRange_Incremental()
38913895
compilation.VerifyDiagnostics();
38923896
}
38933897

3898+
[Fact]
3899+
[WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1805836")]
3900+
[WorkItem("https://github.com/dotnet/roslyn/issues/82032")]
3901+
public void Diagnostic_SpanOutsideRange_Incremental_Update()
3902+
{
3903+
var source = "class SomewhatLongClassName {}";
3904+
var parseOptions = TestOptions.RegularPreview;
3905+
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions, sourceFileName: "/original");
3906+
compilation.VerifyDiagnostics();
3907+
3908+
var generator = new PipelineCallbackGenerator(ctx =>
3909+
{
3910+
var inputs = ctx.SyntaxProvider.CreateSyntaxProvider(
3911+
static (node, ct) => node.IsKind(SyntaxKind.ClassDeclaration),
3912+
static (ctx, ct) => 0);
3913+
ctx.RegisterSourceOutput(inputs, (ctx, input) =>
3914+
{
3915+
var tree = compilation.SyntaxTrees.Single();
3916+
ctx.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(
3917+
"TEST0001",
3918+
"Test",
3919+
"Test diagnostic",
3920+
DiagnosticSeverity.Warning,
3921+
DiagnosticSeverity.Warning,
3922+
isEnabledByDefault: true,
3923+
warningLevel: 1,
3924+
location: Location.Create(tree, TextSpan.FromBounds(20, 21))));
3925+
});
3926+
}).AsSourceGenerator();
3927+
3928+
GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { generator }, parseOptions: parseOptions);
3929+
driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out compilation, out var diagnostics);
3930+
diagnostics.Verify(Diagnostic("TEST0001", "a").WithLocation(1, 21));
3931+
3932+
source = "class C {}";
3933+
compilation = compilation.ReplaceSyntaxTree(compilation.SyntaxTrees.Single(), CSharpSyntaxTree.ParseText(source, parseOptions, path: "/original"));
3934+
driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out compilation, out diagnostics);
3935+
3936+
VerifyArgumentExceptionDiagnostic(diagnostics.Single(), nameof(PipelineCallbackGenerator), string.Format(CodeAnalysisResources.InvalidDiagnosticLocationReported, "TEST0001", "/original"), "diagnostic");
3937+
compilation.VerifyDiagnostics();
3938+
}
3939+
38943940
[ConditionalFact(typeof(IsEnglishLocal))]
38953941
[WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1805836")]
38963942
public void Diagnostic_SpanOutsideRange_Incremental_AdditionalLocations()
@@ -4237,19 +4283,16 @@ static void replace(ref Compilation compilation, CSharpParseOptions parseOptions
42374283
}
42384284
}
42394285

4240-
private static void VerifyArgumentExceptionDiagnostic(
4286+
private void VerifyArgumentExceptionDiagnostic(
42414287
Diagnostic diagnostic,
42424288
string generatorName,
42434289
string message,
42444290
string parameterName,
42454291
bool initialization = false)
42464292
{
4247-
var expectedMessage =
4248-
#if NET
4249-
$"{message} (Parameter '{parameterName}')";
4250-
#else
4251-
$"{message}{Environment.NewLine}Parameter name: {parameterName}";
4252-
#endif
4293+
_output.WriteLine(diagnostic.ToString());
4294+
4295+
var expectedMessage = new ArgumentException(message: message, paramName: parameterName).Message;
42534296
VerifyGeneratorExceptionDiagnostic<ArgumentException>(diagnostic, generatorName, expectedMessage, initialization);
42544297
}
42554298

src/Compilers/Core/Portable/SourceGeneration/GeneratorDriver.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,15 @@ private static ImmutableArray<Diagnostic> FilterDiagnostics(Compilation compilat
427427
ArrayBuilder<Diagnostic> filteredDiagnostics = ArrayBuilder<Diagnostic>.GetInstance();
428428
foreach (var diag in generatorDiagnostics)
429429
{
430+
try
431+
{
432+
DiagnosticAnalysisContextHelpers.VerifyArguments(diag, compilation, isSupportedDiagnostic: static (_, _) => true, cancellationToken);
433+
}
434+
catch (ArgumentException ex)
435+
{
436+
throw new UserFunctionException(ex);
437+
}
438+
430439
if (compilation.Options.FilterDiagnostic(diag, cancellationToken) is { } filtered &&
431440
suppressMessageState.ApplySourceSuppressions(filtered) is { } effective)
432441
{

0 commit comments

Comments
 (0)