diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IncrementalGeneratorInitializationContextExtensions.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IncrementalGeneratorInitializationContextExtensions.cs index 0b008795884810..20a1818a33e54a 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IncrementalGeneratorInitializationContextExtensions.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IncrementalGeneratorInitializationContextExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; @@ -27,12 +28,21 @@ public static void RegisterDiagnostics(this IncrementalGeneratorInitializationCo public static void RegisterConcatenatedSyntaxOutputs(this IncrementalGeneratorInitializationContext context, IncrementalValuesProvider nodes, string fileName) where TNode : SyntaxNode { - IncrementalValueProvider generatedMethods = nodes + IncrementalValueProvider> generatedMethods = nodes .Select( static (node, ct) => node.NormalizeWhitespace().ToFullString()) - .Collect() - .Select(static (generatedSources, ct) => + .Collect(); + + context.RegisterSourceOutput(generatedMethods, + (context, generatedSources) => { + // Don't generate a file if we don't have to, to avoid the extra IDE overhead once we have generated + // files in play. + if (generatedSources.IsEmpty) + { + return; + } + StringBuilder source = new(); // Mark in source that the file is auto-generated. source.AppendLine("// "); @@ -40,13 +50,9 @@ public static void RegisterConcatenatedSyntaxOutputs(this IncrementalGene { source.AppendLine(generated); } - return source.ToString(); - }); - context.RegisterSourceOutput(generatedMethods, - (context, source) => - { - context.AddSource(fileName, source); + // Once https://github.com/dotnet/roslyn/issues/61326 is resolved, we can avoid the ToString() here. + context.AddSource(fileName, source.ToString()); }); } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs index f23a9f22c61cf3..17ba7dea2507cd 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/Compiles.cs @@ -641,33 +641,30 @@ public async Task ValidateSnippetsWithMultipleSources(string id, string[] source TestUtils.AssertPostSourceGeneratorCompilation(newComp); } - public static IEnumerable CodeSnippetsToCompileToValidateAllowUnsafeBlocks() + public static IEnumerable CodeSnippetsToVerifyNoTreesProduced() { - yield return new object[] { ID(), CodeSnippets.TrivialClassDeclarations, TestTargetFramework.Net, true }; - - { - string source = @" + string source = @" using System.Runtime.InteropServices; public class Basic { } "; - yield return new object[] { ID(), source, TestTargetFramework.Standard, false }; - yield return new object[] { ID(), source, TestTargetFramework.Framework, false }; - yield return new object[] { ID(), source, TestTargetFramework.Net, false }; - } + yield return new object[] { ID(), source, TestTargetFramework.Standard }; + yield return new object[] { ID(), source, TestTargetFramework.Framework }; + yield return new object[] { ID(), source, TestTargetFramework.Net }; } [Theory] - [MemberData(nameof(CodeSnippetsToCompileToValidateAllowUnsafeBlocks))] - public async Task ValidateRequireAllowUnsafeBlocksDiagnosticNoTrigger(string id, string source, TestTargetFramework framework, bool allowUnsafe) + [MemberData(nameof(CodeSnippetsToVerifyNoTreesProduced))] + public async Task ValidateNoGeneratedOuptutForNoImport(string id, string source, TestTargetFramework framework) { TestUtils.Use(id); - Compilation comp = await TestUtils.CreateCompilation(source, framework, allowUnsafe: allowUnsafe); + Compilation comp = await TestUtils.CreateCompilation(source, framework, allowUnsafe: false); TestUtils.AssertPreSourceGeneratorCompilation(comp); var newComp = TestUtils.RunGenerators(comp, out var generatorDiags, new Microsoft.Interop.LibraryImportGenerator()); Assert.Empty(generatorDiags); - TestUtils.AssertPostSourceGeneratorCompilation(newComp); + // Assert we didn't generate any syntax trees, even empty ones + Assert.Same(comp, newComp); } } }