|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
namespace Microsoft.CodeAnalysis
{
internal partial class SolutionState
{
private partial class CompilationTracker
{
/// <summary>
/// When we're working with compilations, we often have two: a compilation that does not contain generated files
/// (which we might need later to run generators again), and one that has the stale generated files that we might
/// be able to reuse as well. In those cases we have to do the same transformations to both, and this gives us
/// a handy way to do precisely that while not forking compilations twice if there are no generated files anywhere.
/// </summary>
internal readonly struct CompilationPair
{
public CompilationPair(Compilation withoutGeneratedDocuments, Compilation withGeneratedDocuments) : this()
{
CompilationWithoutGeneratedDocuments = withoutGeneratedDocuments;
CompilationWithGeneratedDocuments = withGeneratedDocuments;
}
public Compilation CompilationWithoutGeneratedDocuments { get; }
public Compilation CompilationWithGeneratedDocuments { get; }
public CompilationPair ReplaceSyntaxTree(SyntaxTree oldTree, SyntaxTree newTree)
{
return WithChange(static (compilation, trees) => compilation.ReplaceSyntaxTree(trees.oldTree, trees.newTree), (oldTree, newTree));
}
public CompilationPair AddSyntaxTree(SyntaxTree newTree)
{
return WithChange(static (compilation, t) => compilation.AddSyntaxTrees(t), newTree);
}
public CompilationPair WithPreviousScriptCompilation(Compilation previousScriptCompilation)
{
return WithChange(static (compilation, priorCompilation) => compilation.WithScriptCompilationInfo(compilation.ScriptCompilationInfo!.WithPreviousScriptCompilation(priorCompilation)), previousScriptCompilation);
}
public CompilationPair WithReferences(IReadOnlyCollection<MetadataReference> metadataReferences)
{
return WithChange(static (c, r) => c.WithReferences(r), metadataReferences);
}
private CompilationPair WithChange<TArg>(Func<Compilation, TArg, Compilation> change, TArg arg)
{
var changedWithoutGeneratedDocuments = change(CompilationWithoutGeneratedDocuments, arg);
if (CompilationWithoutGeneratedDocuments == CompilationWithGeneratedDocuments)
{
// If we didn't have any generated files, then no reason to transform twice
return new CompilationPair(changedWithoutGeneratedDocuments, changedWithoutGeneratedDocuments);
}
var changedWithGeneratedDocuments = change(CompilationWithGeneratedDocuments, arg);
return new CompilationPair(changedWithoutGeneratedDocuments, changedWithGeneratedDocuments);
}
}
}
}
}
|