示例#1
0
        internal static async Task <IReadOnlyList <Diagnostic> > RunGenerator(
            string code, bool compile = false, LanguageVersion langVersion = LanguageVersion.Preview, MetadataReference[]?additionalRefs = null, bool allowUnsafe = false, CancellationToken cancellationToken = default)
        {
            var proj = new AdhocWorkspace()
                       .AddSolution(SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Create()))
                       .AddProject("RegexGeneratorTest", "RegexGeneratorTest.dll", "C#")
                       .WithMetadataReferences(additionalRefs is not null ? References.Concat(additionalRefs) : References)
                       .WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: allowUnsafe)
                                               .WithNullableContextOptions(NullableContextOptions.Enable))
                       .WithParseOptions(new CSharpParseOptions(langVersion))
                       .AddDocument("RegexGenerator.g.cs", SourceText.From(code, Encoding.UTF8)).Project;

            Assert.True(proj.Solution.Workspace.TryApplyChanges(proj.Solution));

            Compilation?comp = await proj !.GetCompilationAsync(CancellationToken.None).ConfigureAwait(false);

            Debug.Assert(comp is not null);

            var generator = new RegexGenerator();
            CSharpGeneratorDriver    cgd = CSharpGeneratorDriver.Create(new[] { generator.AsSourceGenerator() }, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(langVersion));
            GeneratorDriver          gd  = cgd.RunGenerators(comp !, cancellationToken);
            GeneratorDriverRunResult generatorResults = gd.GetRunResult();

            if (!compile)
            {
                return(generatorResults.Diagnostics);
            }

            comp = comp.AddSyntaxTrees(generatorResults.GeneratedTrees.ToArray());
            EmitResult results = comp.Emit(Stream.Null, cancellationToken: cancellationToken);
            ImmutableArray <Diagnostic> generatorDiagnostics = generatorResults.Diagnostics.RemoveAll(d => d.Severity <= DiagnosticSeverity.Hidden);
            ImmutableArray <Diagnostic> resultsDiagnostics   = results.Diagnostics.RemoveAll(d => d.Severity <= DiagnosticSeverity.Hidden);

            if (!results.Success || resultsDiagnostics.Length != 0 || generatorDiagnostics.Length != 0)
            {
                throw new ArgumentException(
                          string.Join(Environment.NewLine, resultsDiagnostics.Concat(generatorDiagnostics)) + Environment.NewLine +
                          string.Join(Environment.NewLine, generatorResults.GeneratedTrees.Select(t => t.ToString())));
            }

            return(generatorResults.Diagnostics.Concat(results.Diagnostics).Where(d => d.Severity != DiagnosticSeverity.Hidden).ToArray());
        }