Skip to content

Commit

Permalink
Ensure an empty run result doesn't throw when generators are present. (
Browse files Browse the repository at this point in the history
…#74034)

* Ensure an empty run result doesn't throw when generators are present.
* Fix replace generators not running init for new generators and add a test
  • Loading branch information
chsienki authored Jun 26, 2024
1 parent 6a1c377 commit 1c83ce1
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,28 @@ public void RunResults_Are_Empty_Before_Generation()
Assert.Empty(results.Results);
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74033")]
public void RunResults_Are_Empty_Before_Generation_With_Generators()
{
var generator = new SingleFileTestGenerator("public class D {}", "source.cs");

GeneratorDriver driver = CSharpGeneratorDriver.Create([generator], parseOptions: TestOptions.Regular);
var results = driver.GetRunResult();

Assert.Empty(results.GeneratedTrees);
Assert.Empty(results.Diagnostics);

var result = Assert.Single(results.Results);

Assert.Null(result.Exception);
Assert.True(result.Diagnostics.IsDefault);
Assert.True(result.GeneratedSources.IsDefault);
Assert.Null(result.TrackedSteps);
Assert.Null(result.TrackedOutputSteps);
Assert.Equal(TimeSpan.Zero, result.ElapsedTime);
Assert.Equal(generator, result.Generator);
}

[Fact]
public void RunResults_Are_Available_After_Generation()
{
Expand Down Expand Up @@ -4176,5 +4198,35 @@ public static void Interceptor(this Program program, int param)
});
}
}

[Fact]
public void ReplaceGenerators_Initializes_New_Generators()
{
var generator1 = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx => { }));

bool initWasCalled = false;
var generator2 = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator2(ctx =>
{
initWasCalled = true;
ctx.RegisterSourceOutput(ctx.CompilationProvider, (context, text) =>
{
context.AddSource("generated", "");
});
}));

var compilation = CreateCompilation("class C{}");

GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { generator1 });
driver = driver.RunGenerators(compilation);
var results = driver.GetRunResult();
Assert.Empty(results.GeneratedTrees);

driver = driver.ReplaceGenerators([generator2]);
driver = driver.RunGenerators(compilation);

results = driver.GetRunResult();
Assert.True(initWasCalled);
Assert.Single(results.GeneratedTrees);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public GeneratorDriver ReplaceGenerators(ImmutableArray<ISourceGenerator> genera
}
else
{
states.Add(GeneratorState.Empty);
states.Add(default);
}
}

Expand Down Expand Up @@ -171,6 +171,11 @@ public GeneratorDriverRunResult GetRunResult()

static ImmutableArray<GeneratedSourceResult> getGeneratorSources(GeneratorState generatorState)
{
if (!generatorState.Initialized)
{
return default;
}

ArrayBuilder<GeneratedSourceResult> sources = ArrayBuilder<GeneratedSourceResult>.GetInstance(generatorState.PostInitTrees.Length + generatorState.GeneratedTrees.Length);
foreach (var tree in generatorState.PostInitTrees)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ namespace Microsoft.CodeAnalysis
internal readonly struct GeneratorState
{

/// <summary>
/// A generator state that has been initialized but produced no results
/// </summary>
public static readonly GeneratorState Empty = new GeneratorState(ImmutableArray<GeneratedSyntaxTree>.Empty,
ImmutableArray<SyntaxInputNode>.Empty,
ImmutableArray<IIncrementalGeneratorOutputNode>.Empty,
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/Core/Portable/SourceGeneration/RunResults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public ImmutableArray<Diagnostic> Diagnostics
{
if (_lazyDiagnostics.IsDefault)
{
ImmutableInterlocked.InterlockedInitialize(ref _lazyDiagnostics, Results.SelectMany(r => r.Diagnostics).ToImmutableArray());
ImmutableInterlocked.InterlockedInitialize(ref _lazyDiagnostics, Results.Where(r => !r.Diagnostics.IsDefaultOrEmpty).SelectMany(r => r.Diagnostics).ToImmutableArray());
}
return _lazyDiagnostics;
}
Expand All @@ -65,7 +65,7 @@ public ImmutableArray<SyntaxTree> GeneratedTrees
{
if (_lazyGeneratedTrees.IsDefault)
{
ImmutableInterlocked.InterlockedInitialize(ref _lazyGeneratedTrees, Results.SelectMany(r => r.GeneratedSources.Select(g => g.SyntaxTree)).ToImmutableArray());
ImmutableInterlocked.InterlockedInitialize(ref _lazyGeneratedTrees, Results.Where(r => !r.GeneratedSources.IsDefaultOrEmpty).SelectMany(r => r.GeneratedSources.Select(g => g.SyntaxTree)).ToImmutableArray());
}
return _lazyGeneratedTrees;
}
Expand Down

0 comments on commit 1c83ce1

Please sign in to comment.