private static TempFile GenerateDll(string assemblyName, TempDirectory directory, string csSource, params MetadataReference[] additionalReferences)
 {
     return(GenerateDll(assemblyName, directory, csSource, publicSign: false, additionalReferences));
 }
        public static TempFile CreateCSharpAnalyzerAssemblyWithTestAnalyzer(TempDirectory dir, string assemblyName)
        {
            var analyzerSource = @"
using System;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class TestAnalyzer : DiagnosticAnalyzer
{
    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { throw new NotImplementedException(); } }
    public override void Initialize(AnalysisContext context) { throw new NotImplementedException(); }
}";

            var metadata = dir.CopyFile(typeof(System.Reflection.Metadata.MetadataReader).Assembly.Location);
            var immutable = dir.CopyFile(typeof(ImmutableArray).Assembly.Location);
            var analyzer = dir.CopyFile(typeof(DiagnosticAnalyzer).Assembly.Location);

            var analyzerCompilation = CSharpCompilation.Create(
                assemblyName,
                new SyntaxTree[] { SyntaxFactory.ParseSyntaxTree(analyzerSource) },
                new MetadataReference[]
                {
                    TestBase.SystemRuntimePP7Ref,
                    MetadataReference.CreateFromFile(immutable.Path),
                    MetadataReference.CreateFromFile(analyzer.Path)
                },
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            return dir.CreateFile(assemblyName + ".dll").WriteAllBytes(analyzerCompilation.EmitToArray());
        }
        public AssemblyLoadTestFixture()
        {
            _temp      = new TempRoot();
            _directory = _temp.CreateDirectory();

            const string Delta1Source = @"
using System.Text;

[assembly: System.Reflection.AssemblyTitle(""Delta"")]
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]

namespace Delta
{
    public class D
    {
        public void Write(StringBuilder sb, string s)
        {
            sb.AppendLine(""Delta: "" + s);
        }
    }
}
";

            Delta1 = GenerateDll("Delta", _directory, Delta1Source);
            var delta1Reference = MetadataReference.CreateFromFile(Delta1.Path);

            DeltaPublicSigned1 = GenerateDll("DeltaPublicSigned", _directory.CreateDirectory("Delta1PublicSigned"), Delta1Source, publicSign: true);

            const string GammaSource = @"
using System.Text;
using Delta;

namespace Gamma
{
    public class G
    {
        public void Write(StringBuilder sb, string s)
        {
            D d = new D();

            d.Write(sb, ""Gamma: "" + s);
        }
    }
}
";

            Gamma = GenerateDll("Gamma", _directory, GammaSource, delta1Reference);
            GammaReferencingPublicSigned = GenerateDll("GammaReferencingPublicSigned", _directory.CreateDirectory("GammaReferencingPublicSigned"), GammaSource, MetadataReference.CreateFromFile(DeltaPublicSigned1.Path));

            var gammaReference = MetadataReference.CreateFromFile(Gamma.Path);

            Beta = GenerateDll("Beta", _directory, @"
using System.Text;
using Gamma;

namespace Beta
{
    public class B
    {
        public void Write(StringBuilder sb, string s)
        {
            G g = new G();

            g.Write(sb, ""Beta: "" + s);
        }
    }
}
", gammaReference);

            Alpha = GenerateDll("Alpha", _directory, @"
using System.Text;
using Gamma;

namespace Alpha
{
    public class A
    {
        public void Write(StringBuilder sb, string s)
        {
            G g = new G();
            g.Write(sb, ""Alpha: "" + s);
        }
    }
}
", gammaReference);

            const string Delta2Source = @"
using System.Text;

[assembly: System.Reflection.AssemblyTitle(""Delta"")]
[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")]

namespace Delta
{
    public class D
    {
        public void Write(StringBuilder sb, string s)
        {
            sb.AppendLine(""Delta.2: "" + s);
        }
    }
}
";

            var v2Directory = _directory.CreateDirectory("Version2");

            Delta2 = GenerateDll("Delta", v2Directory, Delta2Source);
            var v2PublicSignedDirectory = _directory.CreateDirectory("Version2PublicSigned");

            DeltaPublicSigned2 = GenerateDll("DeltaPublicSigned", v2PublicSignedDirectory, Delta2Source, publicSign: true);

            var delta2Reference = MetadataReference.CreateFromFile(Delta2.Path);

            const string EpsilonSource = @"
using System.Text;
using Delta;

namespace Epsilon
{
    public class E
    {
        public void Write(StringBuilder sb, string s)
        {
            D d = new D();

            d.Write(sb, ""Epsilon: "" + s);
        }
    }
}
";

            Epsilon = GenerateDll("Epsilon", v2Directory, EpsilonSource, delta2Reference);
            EpsilonReferencingPublicSigned = GenerateDll("EpsilonReferencingPublicSigned", v2PublicSignedDirectory, EpsilonSource, MetadataReference.CreateFromFile(DeltaPublicSigned2.Path));

            var v2BDirectory = _directory.CreateDirectory("Version2B");

            Delta2B = GenerateDll("Delta", v2BDirectory, @"
using System.Text;

[assembly: System.Reflection.AssemblyTitle(""Delta"")]
[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")]

namespace Delta
{
    public class D
    {
        public void Write(StringBuilder sb, string s)
        {
            sb.AppendLine(""Delta.2B: "" + s);
        }
    }
}
");

            var v3Directory = _directory.CreateDirectory("Version3");

            Delta3 = GenerateDll("Delta", v3Directory, @"
using System.Text;

[assembly: System.Reflection.AssemblyTitle(""Delta"")]
[assembly: System.Reflection.AssemblyVersion(""3.0.0.0"")]

namespace Delta
{
    public class D
    {
        public void Write(StringBuilder sb, string s)
        {
            sb.AppendLine(""Delta.3: "" + s);
        }
    }
}
");

            var sciUserDirectory  = _directory.CreateDirectory("SCIUser");
            var compilerReference = MetadataReference.CreateFromFile(typeof(Microsoft.CodeAnalysis.SyntaxNode).Assembly.Location);

            UserSystemCollectionsImmutable = GenerateDll("System.Collections.Immutable", sciUserDirectory, @"
namespace System.Collections.Immutable
{
    public static class ImmutableArray
    {
        public static ImmutableArray<T> Create<T>(T t) => new();
    }

    public struct ImmutableArray<T>
    {
        public int Length => 42;

        public static int MyMethod() => 42;
    }
}
", compilerReference);

            var userSystemCollectionsImmutableReference = MetadataReference.CreateFromFile(UserSystemCollectionsImmutable.Path);

            AnalyzerReferencesSystemCollectionsImmutable1 = GenerateDll("AnalyzerUsesSystemCollectionsImmutable1", sciUserDirectory, @"
using System.Text;
using System.Collections.Immutable;

public class Analyzer
{
    public void Method(StringBuilder sb)
    {
        sb.Append(ImmutableArray<object>.MyMethod());
    }
}
", userSystemCollectionsImmutableReference, compilerReference);

            AnalyzerReferencesSystemCollectionsImmutable2 = GenerateDll("AnalyzerUsesSystemCollectionsImmutable2", sciUserDirectory, @"
using System.Text;
using System.Collections.Immutable;

public class Analyzer
{
    public void Method(StringBuilder sb)
    {
        sb.Append(ImmutableArray.Create(""a"").Length);
    }
}
", userSystemCollectionsImmutableReference, compilerReference);

            var analyzerReferencesDelta1Directory = _directory.CreateDirectory("AnalyzerReferencesDelta1");
            var delta1InAnalyzerReferencesDelta1  = analyzerReferencesDelta1Directory.CopyFile(Delta1.Path);

            AnalyzerReferencesDelta1 = GenerateDll("AnalyzerReferencesDelta1", _directory, @"
using System.Text;
using Delta;

public class Analyzer
{
    public void Method(StringBuilder sb)
    {
        var d = new D();
        d.Write(sb, ""Hello"");
    }
}
", MetadataReference.CreateFromFile(delta1InAnalyzerReferencesDelta1.Path), compilerReference);

            var faultyAnalyzerDirectory = _directory.CreateDirectory("FaultyAnalyzer");

            FaultyAnalyzer = GenerateDll("FaultyAnalyzer", faultyAnalyzerDirectory, @"
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
public abstract class TestAnalyzer : DiagnosticAnalyzer
{
}
", compilerReference);

            var realSciReference = MetadataReference.CreateFromFile(typeof(ImmutableArray).Assembly.Location);
            var analyzerWithDependencyDirectory = _directory.CreateDirectory("AnalyzerWithDependency");

            AnalyzerDependency = GenerateDll("AnalyzerDependency", analyzerWithDependencyDirectory, @"
using System;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

public abstract class AbstractTestAnalyzer : DiagnosticAnalyzer
{
    protected static string SomeString = nameof(SomeString);
    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { throw new NotImplementedException(); } }
    public override void Initialize(AnalysisContext context) { throw new NotImplementedException(); }
}
", realSciReference, compilerReference);

            AnalyzerWithDependency = GenerateDll("Analyzer", analyzerWithDependencyDirectory, @"
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed class TestAnalyzer : AbstractTestAnalyzer
{
    private static string SomeString2 = AbstractTestAnalyzer.SomeString;
}", realSciReference, compilerReference, MetadataReference.CreateFromFile(AnalyzerDependency.Path));

            AnalyzerWithNativeDependency = GenerateDll("AnalyzerWithNativeDependency", _directory, @"
using System;
using System.Runtime.InteropServices;

public class Class1
{
    [DllImport(""kernel32.dll"", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern int GetFileAttributesW(string lpFileName);

    public int GetFileAttributes(string path)
    {
        return GetFileAttributesW(path);
    }
}

");
        }