diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationAndGeneratorDriverTranslationAction.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationAndGeneratorDriverTranslationAction.cs index 528645b6012f6..451d36103cbf1 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationAndGeneratorDriverTranslationAction.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationAndGeneratorDriverTranslationAction.cs @@ -5,43 +5,39 @@ using System.Threading; using System.Threading.Tasks; -namespace Microsoft.CodeAnalysis +namespace Microsoft.CodeAnalysis; + +internal partial class SolutionCompilationState { - internal partial class SolutionCompilationState + /// + /// Represents a change that needs to be made to a , , or both in response to + /// some user edit. + /// + private abstract partial class CompilationAndGeneratorDriverTranslationAction { + public abstract Task TransformCompilationAsync(Compilation oldCompilation, CancellationToken cancellationToken); + /// - /// Represents a change that needs to be made to a , , or both in response to - /// some user edit. + /// Whether or not can be called on Compilations that may contain + /// generated documents. /// - private abstract partial class CompilationAndGeneratorDriverTranslationAction - { - public virtual Task TransformCompilationAsync(Compilation oldCompilation, CancellationToken cancellationToken) - { - return Task.FromResult(oldCompilation); - } - - /// - /// Whether or not can be called on Compilations that may contain - /// generated documents. - /// - /// - /// Most translation actions add or remove a single syntax tree which means we can do the "same" change - /// to a compilation that contains the generated files and one that doesn't; however some translation actions - /// (like ) will unilaterally remove all trees, and would have unexpected - /// side effects. This opts those out of operating on ones with generated documents where there would be side effects. - /// - public abstract bool CanUpdateCompilationWithStaleGeneratedTreesIfGeneratorsGiveSameOutput { get; } + /// + /// Most translation actions add or remove a single syntax tree which means we can do the "same" change + /// to a compilation that contains the generated files and one that doesn't; however some translation actions + /// (like ) will unilaterally remove all trees, and would have unexpected + /// side effects. This opts those out of operating on ones with generated documents where there would be side effects. + /// + public abstract bool CanUpdateCompilationWithStaleGeneratedTreesIfGeneratorsGiveSameOutput { get; } - public abstract GeneratorDriver TransformGeneratorDriver(GeneratorDriver generatorDriver); + public abstract GeneratorDriver TransformGeneratorDriver(GeneratorDriver generatorDriver); - /// - /// When changes are made to a solution, we make a list of translation actions. If multiple similar changes happen in rapid - /// succession, we may be able to merge them without holding onto intermediate state. - /// - /// The action prior to this one. May be a different type. - /// A non-null if we could create a merged one, null otherwise. - public virtual CompilationAndGeneratorDriverTranslationAction? TryMergeWithPrior(CompilationAndGeneratorDriverTranslationAction priorAction) - => null; - } + /// + /// When changes are made to a solution, we make a list of translation actions. If multiple similar changes happen in rapid + /// succession, we may be able to merge them without holding onto intermediate state. + /// + /// The action prior to this one. May be a different type. + /// A non-null if we could create a merged one, null otherwise. + public virtual CompilationAndGeneratorDriverTranslationAction? TryMergeWithPrior(CompilationAndGeneratorDriverTranslationAction priorAction) + => null; } } diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationAndGeneratorDriverTranslationAction_Actions.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationAndGeneratorDriverTranslationAction_Actions.cs index 7051faf85212f..e6a33c531072d 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationAndGeneratorDriverTranslationAction_Actions.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationAndGeneratorDriverTranslationAction_Actions.cs @@ -55,10 +55,13 @@ internal sealed class TouchAdditionalDocumentAction(AdditionalDocumentState oldS private readonly AdditionalDocumentState _newState = newState; // Changing an additional document doesn't change the compilation directly, so we can "apply" the - // translation (which is a no-op). Since we use a 'false' here to mean that it's not worth keeping - // the compilation with stale trees around, answering true is still important. + // translation (which is a no-op). Since we use a 'false' here to mean that it's not worth keeping the + // compilation with stale trees around, answering true is still important. public override bool CanUpdateCompilationWithStaleGeneratedTreesIfGeneratorsGiveSameOutput => true; + public override Task TransformCompilationAsync(Compilation oldCompilation, CancellationToken cancellationToken) + => Task.FromResult(oldCompilation); + public override CompilationAndGeneratorDriverTranslationAction? TryMergeWithPrior(CompilationAndGeneratorDriverTranslationAction priorAction) { if (priorAction is TouchAdditionalDocumentAction priorTouchAction && @@ -198,12 +201,14 @@ public override GeneratorDriver TransformGeneratorDriver(GeneratorDriver generat internal sealed class AddOrRemoveAnalyzerReferencesAction(string language, ImmutableArray referencesToAdd = default, ImmutableArray referencesToRemove = default) : CompilationAndGeneratorDriverTranslationAction { - // Changing analyzer references doesn't change the compilation directly, so we can "apply" the - // translation (which is a no-op). Since we use a 'false' here to mean that it's not worth keeping - // the compilation with stale trees around, answering true is still important. + // translation (which is a no-op). Since we use a 'false' here to mean that it's not worth keeping the + // compilation with stale trees around, answering true is still important. public override bool CanUpdateCompilationWithStaleGeneratedTreesIfGeneratorsGiveSameOutput => true; + public override Task TransformCompilationAsync(Compilation oldCompilation, CancellationToken cancellationToken) + => Task.FromResult(oldCompilation); + public override GeneratorDriver TransformGeneratorDriver(GeneratorDriver generatorDriver) { if (!referencesToRemove.IsDefaultOrEmpty) @@ -222,12 +227,14 @@ public override GeneratorDriver TransformGeneratorDriver(GeneratorDriver generat internal sealed class AddAdditionalDocumentsAction(ImmutableArray additionalDocuments) : CompilationAndGeneratorDriverTranslationAction { - // Changing an additional document doesn't change the compilation directly, so we can "apply" the - // translation (which is a no-op). Since we use a 'false' here to mean that it's not worth keeping - // the compilation with stale trees around, answering true is still important. + // translation (which is a no-op). Since we use a 'false' here to mean that it's not worth keeping the + // compilation with stale trees around, answering true is still important. public override bool CanUpdateCompilationWithStaleGeneratedTreesIfGeneratorsGiveSameOutput => true; + public override Task TransformCompilationAsync(Compilation oldCompilation, CancellationToken cancellationToken) + => Task.FromResult(oldCompilation); + public override GeneratorDriver TransformGeneratorDriver(GeneratorDriver generatorDriver) { return generatorDriver.AddAdditionalTexts(additionalDocuments.SelectAsArray(static documentState => documentState.AdditionalText)); @@ -236,12 +243,14 @@ public override GeneratorDriver TransformGeneratorDriver(GeneratorDriver generat internal sealed class RemoveAdditionalDocumentsAction(ImmutableArray additionalDocuments) : CompilationAndGeneratorDriverTranslationAction { - // Changing an additional document doesn't change the compilation directly, so we can "apply" the - // translation (which is a no-op). Since we use a 'false' here to mean that it's not worth keeping - // the compilation with stale trees around, answering true is still important. + // translation (which is a no-op). Since we use a 'false' here to mean that it's not worth keeping the + // compilation with stale trees around, answering true is still important. public override bool CanUpdateCompilationWithStaleGeneratedTreesIfGeneratorsGiveSameOutput => true; + public override Task TransformCompilationAsync(Compilation oldCompilation, CancellationToken cancellationToken) + => Task.FromResult(oldCompilation); + public override GeneratorDriver TransformGeneratorDriver(GeneratorDriver generatorDriver) { return generatorDriver.RemoveAdditionalTexts(additionalDocuments.SelectAsArray(static documentState => documentState.AdditionalText)); @@ -252,6 +261,11 @@ internal sealed class ReplaceGeneratorDriverAction(GeneratorDriver oldGeneratorD { public override bool CanUpdateCompilationWithStaleGeneratedTreesIfGeneratorsGiveSameOutput => true; + // Replacing the generator doesn't change the non-generator compilation. So we can just return the old + // compilation as is. + public override Task TransformCompilationAsync(Compilation oldCompilation, CancellationToken cancellationToken) + => Task.FromResult(oldCompilation); + public override GeneratorDriver TransformGeneratorDriver(GeneratorDriver _) { // The GeneratorDriver that we have here is from a prior version of the Project, it may be missing state changes due