Ejemplo n.º 1
0
        public void ParseOptions_Are_Passed_To_Generator()
        {
            var         source       = @"
class C 
{
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();
            Assert.Single(compilation.SyntaxTrees);

            ParseOptions?passedOptions = null;
            var          testGenerator = new CallbackGenerator(
                onInit: (i) => { },
                onExecute: (e) => { passedOptions = e.ParseOptions; }
                );

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(testGenerator), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver.RunFullGeneration(compilation, out _, out _);

            Assert.Same(parseOptions, passedOptions);
        }
Ejemplo n.º 2
0
        public void Error_During_Generation_Does_Not_Affect_Other_Generators()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            var exception = new InvalidOperationException("generate error");

            var generator  = new CallbackGenerator((ic) => { }, (sgc) => throw exception);
            var generator2 = new CallbackGenerator((ic) => { }, (sgc) => { }, sourceOpt: "public class D { }");

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(generator, generator2), ImmutableArray <AdditionalText> .Empty);

            driver.RunFullGeneration(compilation, out var outputCompilation, out var generatorDiagnostics);

            outputCompilation.VerifyDiagnostics();
            Assert.Equal(2, outputCompilation.SyntaxTrees.Count());

            generatorDiagnostics.Verify(
                // warning CS8785: Generator 'CallbackGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result.
                Diagnostic(ErrorCode.WRN_GeneratorFailedDuringGeneration).WithArguments("CallbackGenerator").WithLocation(1, 1)
                );
        }
Ejemplo n.º 3
0
        public void SyntaxContext_Receiver_Is_Present_When_Registered()
        {
            var source =
                @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(
                source,
                options: TestOptions.DebugDll,
                parseOptions: parseOptions
                );

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            ISyntaxContextReceiver?receiver = null;

            var testGenerator = new CallbackGenerator(
                onInit: (i) =>
                i.RegisterForSyntaxNotifications(() => new TestSyntaxContextReceiver()),
                onExecute: (e) => receiver = e.SyntaxContextReceiver
                );

            GeneratorDriver driver = CSharpGeneratorDriver.Create(
                new[] { testGenerator },
                parseOptions: parseOptions
                );

            driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out _);

            Assert.NotNull(receiver);
            Assert.IsType <TestSyntaxContextReceiver>(receiver);
        }
Ejemplo n.º 4
0
        public void RunResults_Are_Available_After_Generation()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();
            Assert.Single(compilation.SyntaxTrees);

            var generator = new CallbackGenerator((ic) => { }, (sgc) => { sgc.AddSource("test", SourceText.From("public class D {}", Encoding.UTF8)); });

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(generator), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver = driver.RunGenerators(compilation);

            var results = driver.GetRunResult();

            Assert.Single(results.GeneratedTrees);
            Assert.Single(results.Results);
            Assert.Empty(results.Diagnostics);

            var result = results.Results.Single();

            Assert.Null(result.Exception);
            Assert.Empty(result.Diagnostics);
            Assert.Single(result.GeneratedSources);
            Assert.Equal(results.GeneratedTrees.Single(), result.GeneratedSources.Single().SyntaxTree);
        }
Ejemplo n.º 5
0
        public void ParseOptions_Are_Passed_To_Generator()
        {
            var         source       = @"
class C 
{
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();
            Assert.Single(compilation.SyntaxTrees);

            ParseOptions?passedOptions = null;
            var          testGenerator = new CallbackGenerator(
                onInit: (i) => { },
                onExecute: (e) => { passedOptions = e.ParseOptions; }
                );

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { testGenerator }, parseOptions: parseOptions);

            driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out _);

            Assert.Same(parseOptions, passedOptions);
        }
Ejemplo n.º 6
0
        public void Syntax_Receiver_Is_Null_WhenNot_Registered()
        {
            var source =
                @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(
                source,
                options: TestOptions.DebugDll,
                parseOptions: parseOptions
                );

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            ISyntaxReceiver?receiver = null;

            var testGenerator = new CallbackGenerator(
                onInit: (i) => { },
                onExecute: (e) => receiver = e.SyntaxReceiver
                );

            GeneratorDriver driver = CSharpGeneratorDriver.Create(
                new[] { testGenerator },
                parseOptions: parseOptions
                );

            driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out _);

            Assert.Null(receiver);
        }
Ejemplo n.º 7
0
        public void Syntax_Receiver_Is_Present_When_Registered()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            ISyntaxReceiver?receiver = null;

            var testGenerator = new CallbackGenerator(
                onInit: (i) => i.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver()),
                onExecute: (e) => receiver = e.SyntaxReceiver
                );

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(testGenerator), ImmutableArray <AdditionalText> .Empty);

            driver.RunFullGeneration(compilation, out _, out _);

            Assert.NotNull(receiver);
            Assert.IsType <TestSyntaxReceiver>(receiver);
        }
Ejemplo n.º 8
0
        public void Generator_Can_Report_Diagnostics()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();
            Assert.Single(compilation.SyntaxTrees);

            string description = "This is a test diagnostic";
            DiagnosticDescriptor generatorDiagnostic = new DiagnosticDescriptor("TG001", "Test Diagnostic", description, "Generators", DiagnosticSeverity.Warning, isEnabledByDefault: true, description: description);
            var diagnostic = Microsoft.CodeAnalysis.Diagnostic.Create(generatorDiagnostic, Location.None);

            var generator = new CallbackGenerator((ic) => { }, (sgc) => sgc.ReportDiagnostic(diagnostic));

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { generator }, parseOptions: parseOptions);

            driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var generatorDiagnostics);

            outputCompilation.VerifyDiagnostics();
            generatorDiagnostics.Verify(
                Diagnostic("TG001").WithLocation(1, 1)
                );
        }
Ejemplo n.º 9
0
        public void Generator_HintName_MustBe_Unique()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();
            Assert.Single(compilation.SyntaxTrees);

            var generator = new CallbackGenerator((ic) => { }, (sgc) =>
            {
                sgc.AddSource("test", SourceText.From("public class D{}", Encoding.UTF8));

                // the assert should swallow the exception, so we'll actually succesfully generate
                Assert.Throws <ArgumentException>("hintName", () => sgc.AddSource("test", SourceText.From("public class D{}", Encoding.UTF8)));

                // also throws for <name> vs <name>.cs
                Assert.Throws <ArgumentException>("hintName", () => sgc.AddSource("test.cs", SourceText.From("public class D{}", Encoding.UTF8)));
            });

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(generator), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver.RunFullGeneration(compilation, out var outputCompilation, out var generatorDiagnostics);
            outputCompilation.VerifyDiagnostics();
            generatorDiagnostics.Verify();
            Assert.Equal(2, outputCompilation.SyntaxTrees.Count());
        }
Ejemplo n.º 10
0
        public void Syntax_Receiver_Is_Null_WhenNot_Registered()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            ISyntaxReceiver?receiver = null;

            var testGenerator = new CallbackGenerator(
                onInit: (i) => { },
                onExecute: (e) => receiver = e.SyntaxReceiver
                );

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(testGenerator), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver.RunFullGeneration(compilation, out var outputCompilation, out _);

            Assert.Null(receiver);
        }
Ejemplo n.º 11
0
        public void Generator_HintName_MustBe_Unique()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();
            Assert.Single(compilation.SyntaxTrees);

            var generator = new CallbackGenerator((ic) => { }, (sgc) =>
            {
                sgc.AddSource("test", SourceText.From("public class D{}", Encoding.UTF8));

                // the assert should swallow the exception, so we'll actually successfully generate
                Assert.Throws <ArgumentException>("hintName", () => sgc.AddSource("test", SourceText.From("public class D{}", Encoding.UTF8)));

                // also throws for <name> vs <name>.cs
                Assert.Throws <ArgumentException>("hintName", () => sgc.AddSource("test.cs", SourceText.From("public class D{}", Encoding.UTF8)));
            });

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { generator }, parseOptions: parseOptions);

            driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var generatorDiagnostics);
            outputCompilation.VerifyDiagnostics();
            generatorDiagnostics.Verify();
            Assert.Equal(2, outputCompilation.SyntaxTrees.Count());
        }
Ejemplo n.º 12
0
        public void Syntax_Receiver_Can_Be_Registered_Only_Once()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            var testGenerator = new CallbackGenerator(
                onInit: initialize,
                onExecute: (e) => { }
                );

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(testGenerator), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver.RunFullGeneration(compilation, out _, out _);

            void initialize(InitializationContext initContext)
            {
                initContext.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver());
                Assert.Throws <InvalidOperationException>(() =>
                {
                    initContext.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver());
                });
            }
        }
Ejemplo n.º 13
0
        public void Syntax_Receiver_Is_Not_Created_If_Exception_During_Initialize()
        {
            var source =
                @"
class C 
{
    int Property { get; set; }

    void Function()
    {
        var x = 5;
        x += 4;
    }
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(
                source,
                options: TestOptions.DebugDll,
                parseOptions: parseOptions
                );

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            TestSyntaxReceiver?receiver = null;
            var exception     = new Exception("test exception");
            var testGenerator = new CallbackGenerator(
                onInit: (i) =>
            {
                i.RegisterForSyntaxNotifications(() => receiver = new TestSyntaxReceiver());
                throw exception;
            },
                onExecute: (e) =>
            {
                Assert.True(false);
            }
                );

            GeneratorDriver driver = CSharpGeneratorDriver.Create(
                new[] { testGenerator },
                parseOptions: parseOptions
                );

            driver = driver.RunGeneratorsAndUpdateCompilation(
                compilation,
                out var outputCompilation,
                out var outputDiagnostics
                );
            var results = driver.GetRunResult();

            Assert.Null(receiver);

            outputDiagnostics.Verify(
                Diagnostic("CS" + (int)ErrorCode.WRN_GeneratorFailedDuringInitialization)
                .WithArguments("CallbackGenerator", "Exception", "test exception")
                .WithLocation(1, 1)
                );
        }
Ejemplo n.º 14
0
        public void Syntax_Receiver_Can_Be_Registered_Only_Once()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            var testGenerator = new CallbackGenerator(
                onInit: initialize,
                onExecute: (e) => { }
                );

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { testGenerator }, parseOptions: parseOptions);

            driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out _);

            void initialize(GeneratorInitializationContext initContext)
            {
                initContext.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver());
                Assert.Throws <InvalidOperationException>(() =>
                {
                    initContext.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver());
                });
            }
        }
Ejemplo n.º 15
0
        public void FullGeneration_Diagnostics_AreSame_As_RunResults()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();
            Assert.Single(compilation.SyntaxTrees);

            string description = "This is a test diagnostic";
            DiagnosticDescriptor generatorDiagnostic1 = new DiagnosticDescriptor("TG001", "Test Diagnostic", description, "Generators", DiagnosticSeverity.Warning, isEnabledByDefault: true, description: description);
            DiagnosticDescriptor generatorDiagnostic2 = new DiagnosticDescriptor("TG002", "Test Diagnostic", description, "Generators", DiagnosticSeverity.Warning, isEnabledByDefault: true, description: description);
            DiagnosticDescriptor generatorDiagnostic3 = new DiagnosticDescriptor("TG003", "Test Diagnostic", description, "Generators", DiagnosticSeverity.Warning, isEnabledByDefault: true, description: description);

            var diagnostic1 = Microsoft.CodeAnalysis.Diagnostic.Create(generatorDiagnostic1, Location.None);
            var diagnostic2 = Microsoft.CodeAnalysis.Diagnostic.Create(generatorDiagnostic2, Location.None);
            var diagnostic3 = Microsoft.CodeAnalysis.Diagnostic.Create(generatorDiagnostic3, Location.None);

            var generator  = new CallbackGenerator((ic) => { }, (sgc) => { sgc.ReportDiagnostic(diagnostic1); sgc.ReportDiagnostic(diagnostic2); });
            var generator2 = new CallbackGenerator2((ic) => { }, (sgc) => { sgc.ReportDiagnostic(diagnostic3); });

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(generator, generator2), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver = driver.RunFullGeneration(compilation, out _, out var fullDiagnostics);

            var results = driver.GetRunResult();

            Assert.Equal(3, results.Diagnostics.Length);
            Assert.Equal(3, fullDiagnostics.Length);
            AssertEx.Equal(results.Diagnostics, fullDiagnostics);
        }
Ejemplo n.º 16
0
        public void Syntax_Receiver_Exception_During_Visit_Doesnt_Stop_Other_Receivers()
        {
            var         source       = @"
class C 
{
    int Property { get; set; }

    void Function()
    {
        var x = 5;
        x += 4;
    }
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            var testGenerator = new CallbackGenerator(
                onInit: (i) => i.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver(tag: 0, callback: (a) => { if (a is AssignmentExpressionSyntax)
                                                                                                                        {
                                                                                                                            throw new Exception("Test Exception");
                                                                                                                        }
                                                                                             })),
                onExecute: (e) => { }
                );

            ISyntaxReceiver?receiver       = null;
            var             testGenerator2 = new CallbackGenerator2(
                onInit: (i) => i.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver(tag: 1)),
                onExecute: (e) => { receiver = e.SyntaxReceiver; e.AddSource("test", SourceText.From("public class D{}", Encoding.UTF8)); }
                );

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(testGenerator, testGenerator2), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver = driver.RunFullGeneration(compilation, out var outputCompilation, out var outputDiagnostics);
            var results = driver.GetRunResult();

            Assert.Single(results.GeneratedTrees);
            Assert.Single(results.Diagnostics);
            Assert.Equal(2, results.Results.Length);

            Assert.Single(results.Results[0].Diagnostics);
            Assert.NotNull(results.Results[0].Exception);
            Assert.Equal("Test Exception", results.Results[0].Exception?.Message);

            Assert.Empty(results.Results[1].Diagnostics);

            var testReceiver = (TestSyntaxReceiver)receiver !;

            Assert.Equal(1, testReceiver.Tag);
            Assert.Equal(21, testReceiver.VisitedNodes.Count);

            outputDiagnostics.Verify(
                Diagnostic(ErrorCode.WRN_GeneratorFailedDuringGeneration).WithArguments("CallbackGenerator").WithLocation(1, 1)
                );
        }
        public void Syntax_Receiver_Visits_Syntax_Added_In_PostInit_From_Other_Generator()
        {
            var source = @"
class C 
{
    int Property { get; set; }

    void Function()
    {
        var x = 5;
        x += 4;
    }
}
";

            var         source2      = @"
class D
{
    int Property { get; set; }

    void Function()
    {
        var x = 5;
        x += 4;
    }
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            ISyntaxReceiver?receiver = null;

            var testGenerator = new CallbackGenerator(
                onInit: (i) => i.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver()),
                onExecute: (e) => receiver = e.SyntaxReceiver
                );

            var testGenerator2 = new CallbackGenerator2(
                onInit: (i) => i.RegisterForPostInitialization((pic) => pic.AddSource("postInit", source2)),
                onExecute: (e) => { }
                );

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { testGenerator, testGenerator2 }, parseOptions: parseOptions);

            driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out _);

            Assert.NotNull(receiver);
            Assert.IsType <TestSyntaxReceiver>(receiver);

            TestSyntaxReceiver testReceiver = (TestSyntaxReceiver)receiver !;
            var classDeclarations           = testReceiver.VisitedNodes.OfType <ClassDeclarationSyntax>().Select(c => c.Identifier.Text);

            Assert.Equal(new[] { "C", "D" }, classDeclarations);
        }
Ejemplo n.º 18
0
        public void Syntax_Receiver_Is_Not_Reused_Between_Invocations()
        {
            var         source       = @"
class C 
{
    int Property { get; set; }

    void Function()
    {
        var x = 5;
        x += 4;
    }
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            ISyntaxReceiver?receiver    = null;
            int             invocations = 0;

            var testGenerator = new CallbackGenerator(
                onInit: (i) => i.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver(++invocations)),
                onExecute: (e) => receiver = e.SyntaxReceiver
                );

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { testGenerator }, parseOptions: parseOptions);

            driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out _);

            Assert.NotNull(receiver);
            Assert.IsType <TestSyntaxReceiver>(receiver);

            TestSyntaxReceiver testReceiver = (TestSyntaxReceiver)receiver !;

            Assert.Equal(1, testReceiver.Tag);
            Assert.Equal(21, testReceiver.VisitedNodes.Count);
            Assert.IsType <CompilationUnitSyntax>(testReceiver.VisitedNodes[0]);

            var previousReceiver = receiver;

            driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out _);

            Assert.NotNull(receiver);
            Assert.NotEqual(receiver, previousReceiver);

            testReceiver = (TestSyntaxReceiver)receiver !;
            Assert.Equal(2, testReceiver.Tag);
            Assert.Equal(21, testReceiver.VisitedNodes.Count);
            Assert.IsType <CompilationUnitSyntax>(testReceiver.VisitedNodes[0]);
        }
Ejemplo n.º 19
0
        public void SyntaxContext_Receiver_Visits_Syntax_In_Compilation()
        {
            var source =
                @"
class C 
{
    int Property { get; set; }

    void Function()
    {
        var x = 5;
        x += 4;
    }
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(
                source,
                options: TestOptions.DebugDll,
                parseOptions: parseOptions
                );

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            ISyntaxContextReceiver?receiver = null;

            var testGenerator = new CallbackGenerator(
                onInit: (i) =>
                i.RegisterForSyntaxNotifications(() => new TestSyntaxContextReceiver()),
                onExecute: (e) => receiver = e.SyntaxContextReceiver
                );

            GeneratorDriver driver = CSharpGeneratorDriver.Create(
                new[] { testGenerator },
                parseOptions: parseOptions
                );

            driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out _);

            Assert.NotNull(receiver);
            Assert.IsType <TestSyntaxContextReceiver>(receiver);

            TestSyntaxContextReceiver testReceiver = (TestSyntaxContextReceiver)receiver !;

            Assert.Equal(21, testReceiver.VisitedNodes.Count);
            Assert.IsType <CompilationUnitSyntax>(testReceiver.VisitedNodes[0].Node);
            Assert.NotNull(testReceiver.VisitedNodes[0].SemanticModel);
            Assert.Equal(
                testReceiver.VisitedNodes[0].SemanticModel.SyntaxTree,
                testReceiver.VisitedNodes[0].Node.SyntaxTree
                );
        }
Ejemplo n.º 20
0
        public void Syntax_Receiver_Exception_During_Visit()
        {
            var         source       = @"
class C 
{
    int Property { get; set; }

    void Function()
    {
        var x = 5;
        x += 4;
    }
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            var exception     = new Exception("Test Exception");
            var testGenerator = new CallbackGenerator(
                onInit: (i) => i.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver(tag: 0, callback: (a) => { if (a is AssignmentExpressionSyntax)
                                                                                                                        {
                                                                                                                            throw exception;
                                                                                                                        }
                                                                                             })),
                onExecute: (e) => { e.AddSource("test", SourceText.From("public class D{}", Encoding.UTF8)); }
                );

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { testGenerator }, parseOptions: parseOptions);

            driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var outputDiagnostics);
            var results = driver.GetRunResult();

            Assert.Empty(results.GeneratedTrees);
            Assert.Single(results.Diagnostics);
            Assert.Single(results.Results);
            Assert.Single(results.Results[0].Diagnostics);

            Assert.NotNull(results.Results[0].Exception);
            Assert.Equal("Test Exception", results.Results[0].Exception?.Message);

            outputDiagnostics.Verify(
                Diagnostic("CS" + (int)ErrorCode.WRN_GeneratorFailedDuringGeneration).WithArguments("CallbackGenerator", "Exception", "Test Exception").WithLocation(1, 1)
                );
        }
Ejemplo n.º 21
0
        public void RunResults_Combine_Diagnostics()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();
            Assert.Single(compilation.SyntaxTrees);

            string description = "This is a test diagnostic";
            DiagnosticDescriptor generatorDiagnostic1 = new DiagnosticDescriptor("TG001", "Test Diagnostic", description, "Generators", DiagnosticSeverity.Warning, isEnabledByDefault: true, description: description);
            DiagnosticDescriptor generatorDiagnostic2 = new DiagnosticDescriptor("TG002", "Test Diagnostic", description, "Generators", DiagnosticSeverity.Warning, isEnabledByDefault: true, description: description);
            DiagnosticDescriptor generatorDiagnostic3 = new DiagnosticDescriptor("TG003", "Test Diagnostic", description, "Generators", DiagnosticSeverity.Warning, isEnabledByDefault: true, description: description);

            var diagnostic1 = Microsoft.CodeAnalysis.Diagnostic.Create(generatorDiagnostic1, Location.None);
            var diagnostic2 = Microsoft.CodeAnalysis.Diagnostic.Create(generatorDiagnostic2, Location.None);
            var diagnostic3 = Microsoft.CodeAnalysis.Diagnostic.Create(generatorDiagnostic3, Location.None);

            var generator  = new CallbackGenerator((ic) => { }, (sgc) => { sgc.ReportDiagnostic(diagnostic1); sgc.ReportDiagnostic(diagnostic2); });
            var generator2 = new CallbackGenerator2((ic) => { }, (sgc) => { sgc.ReportDiagnostic(diagnostic3); });

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { generator, generator2 }, parseOptions: parseOptions);

            driver = driver.RunGenerators(compilation);

            var results = driver.GetRunResult();

            Assert.Equal(2, results.Results.Length);
            Assert.Equal(3, results.Diagnostics.Length);
            Assert.Empty(results.GeneratedTrees);

            var result1 = results.Results[0];
            var result2 = results.Results[1];

            Assert.Null(result1.Exception);
            Assert.Equal(2, result1.Diagnostics.Length);
            Assert.Empty(result1.GeneratedSources);
            Assert.Equal(results.Diagnostics[0], result1.Diagnostics[0]);
            Assert.Equal(results.Diagnostics[1], result1.Diagnostics[1]);

            Assert.Null(result2.Exception);
            Assert.Single(result2.Diagnostics);
            Assert.Empty(result2.GeneratedSources);
            Assert.Equal(results.Diagnostics[2], result2.Diagnostics[0]);
        }
Ejemplo n.º 22
0
        public void RunResults_Combine_SyntaxTrees()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();
            Assert.Single(compilation.SyntaxTrees);

            var generator  = new CallbackGenerator((ic) => { }, (sgc) => { sgc.AddSource("test", SourceText.From("public class D {}", Encoding.UTF8)); sgc.AddSource("test2", SourceText.From("public class E {}", Encoding.UTF8)); });
            var generator2 = new SingleFileTestGenerator("public class F{}");
            var generator3 = new SingleFileTestGenerator2("public class G{}");

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(generator, generator2, generator3), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver = driver.RunGenerators(compilation);

            var results = driver.GetRunResult();

            Assert.Equal(4, results.GeneratedTrees.Length);
            Assert.Equal(3, results.Results.Length);
            Assert.Empty(results.Diagnostics);

            var result1 = results.Results[0];
            var result2 = results.Results[1];
            var result3 = results.Results[2];

            Assert.Null(result1.Exception);
            Assert.Empty(result1.Diagnostics);
            Assert.Equal(2, result1.GeneratedSources.Length);
            Assert.Equal(results.GeneratedTrees[0], result1.GeneratedSources[0].SyntaxTree);
            Assert.Equal(results.GeneratedTrees[1], result1.GeneratedSources[1].SyntaxTree);

            Assert.Null(result2.Exception);
            Assert.Empty(result2.Diagnostics);
            Assert.Single(result2.GeneratedSources);
            Assert.Equal(results.GeneratedTrees[2], result2.GeneratedSources[0].SyntaxTree);

            Assert.Null(result3.Exception);
            Assert.Empty(result3.Diagnostics);
            Assert.Single(result3.GeneratedSources);
            Assert.Equal(results.GeneratedTrees[3], result3.GeneratedSources[0].SyntaxTree);
        }
Ejemplo n.º 23
0
        public void Syntax_Receiver_Exception_During_Visit_Stops_Visits_On_Other_Trees()
        {
            var         source1      = @"
class C 
{
    int Property { get; set; }
}
";
            var         source2      = @"
class D
{
    public void Method() { }
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(new[] { source1, source2 }, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Equal(2, compilation.SyntaxTrees.Count());

            TestSyntaxReceiver receiver1 = new TestSyntaxReceiver(tag: 0, callback: (a) => { if (a is PropertyDeclarationSyntax)
                                                                                             {
                                                                                                 throw new Exception("Test Exception");
                                                                                             }
                                                                  });
            var testGenerator1 = new CallbackGenerator(
                onInit: (i) => i.RegisterForSyntaxNotifications(() => receiver1),
                onExecute: (e) => { }
                );

            TestSyntaxReceiver receiver2 = new TestSyntaxReceiver(tag: 1);
            var testGenerator2           = new CallbackGenerator2(
                onInit: (i) => i.RegisterForSyntaxNotifications(() => receiver2),
                onExecute: (e) => { }
                );

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { testGenerator1, testGenerator2 }, parseOptions: parseOptions);

            driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var outputDiagnostics);
            var results = driver.GetRunResult();

            Assert.DoesNotContain(receiver1.VisitedNodes, n => n is MethodDeclarationSyntax);
            Assert.Contains(receiver2.VisitedNodes, n => n is MethodDeclarationSyntax);
        }
Ejemplo n.º 24
0
        public void Generator_Is_Not_Initialized_If_Not_Run()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            int initCount = 0, executeCount = 0;
            var generator = new CallbackGenerator((ic) => initCount++, (sgc) => executeCount++);

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { generator }, parseOptions: parseOptions);

            Assert.Equal(0, initCount);
            Assert.Equal(0, executeCount);
        }
Ejemplo n.º 25
0
        public void Generator_Is_Not_Initialized_If_Not_Run()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            int initCount = 0, executeCount = 0;
            var generator = new CallbackGenerator((ic) => initCount++, (sgc) => executeCount++);

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(generator), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            Assert.Equal(0, initCount);
            Assert.Equal(0, executeCount);
        }
Ejemplo n.º 26
0
        public void Syntax_Receiver_Visits_Syntax_In_Compilation()
        {
            var         source       = @"
class C 
{
    int Property { get; set; }

    void Function()
    {
        var x = 5;
        x += 4;
    }
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            ISyntaxReceiver?receiver = null;

            var testGenerator = new CallbackGenerator(
                onInit: (i) => i.RegisterForSyntaxNotifications(() => new TestSyntaxReceiver()),
                onExecute: (e) => receiver = e.SyntaxReceiver
                );

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(testGenerator), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver.RunFullGeneration(compilation, out _, out _);

            Assert.NotNull(receiver);
            Assert.IsType <TestSyntaxReceiver>(receiver);

            TestSyntaxReceiver testReceiver = (TestSyntaxReceiver)receiver !;

            Assert.Equal(21, testReceiver.VisitedNodes.Count);
            Assert.IsType <CompilationUnitSyntax>(testReceiver.VisitedNodes[0]);
        }
Ejemplo n.º 27
0
        public void Generator_Is_Initialized_Before_Running()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            int initCount = 0, executeCount = 0;
            var generator = new CallbackGenerator((ic) => initCount++, (sgc) => executeCount++);

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(generator), ImmutableArray <AdditionalText> .Empty);

            driver.RunFullGeneration(compilation, out var outputCompilation, out var diagnostics);

            Assert.Equal(1, initCount);
            Assert.Equal(1, executeCount);
        }
Ejemplo n.º 28
0
        public void Adding_A_Source_Text_Without_Encoding_Fails_Generation()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();
            Assert.Single(compilation.SyntaxTrees);

            var generator = new CallbackGenerator((ic) => { }, (sgc) => { sgc.AddSource("a", SourceText.From("")); });

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(generator), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver.RunFullGeneration(compilation, out _, out var outputDiagnostics);

            Assert.Single(outputDiagnostics);
            outputDiagnostics.Verify(
                Diagnostic("CS" + (int)ErrorCode.WRN_GeneratorFailedDuringGeneration).WithArguments("CallbackGenerator", "ArgumentException", "The provided SourceText must have an explicit encoding set. (Parameter 'source')").WithLocation(1, 1)
                );
        }
Ejemplo n.º 29
0
        public void Syntax_Receiver_Is_Not_Created_If_Exception_During_Initialize()
        {
            var         source       = @"
class C 
{
    int Property { get; set; }

    void Function()
    {
        var x = 5;
        x += 4;
    }
}
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            TestSyntaxReceiver?receiver = null;
            var testGenerator           = new CallbackGenerator(
                onInit: (i) => { i.RegisterForSyntaxNotifications(() => receiver = new TestSyntaxReceiver()); throw new Exception("test exception"); },
                onExecute: (e) => { Assert.True(false); }
                );

            GeneratorDriver driver = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(testGenerator), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty);

            driver = driver.RunFullGeneration(compilation, out var outputCompilation, out var outputDiagnostics);
            var results = driver.GetRunResult();

            Assert.Null(receiver);

            outputDiagnostics.Verify(
                Diagnostic(ErrorCode.WRN_GeneratorFailedDuringInitialization).WithArguments("CallbackGenerator").WithLocation(1, 1)
                );
        }
Ejemplo n.º 30
0
        public void Generator_Is_Only_Initialized_Once()
        {
            var         source       = @"
class C { }
";
            var         parseOptions = TestOptions.Regular;
            Compilation compilation  = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);

            compilation.VerifyDiagnostics();

            Assert.Single(compilation.SyntaxTrees);

            int initCount = 0, executeCount = 0;
            var generator = new CallbackGenerator((ic) => initCount++, (sgc) => executeCount++, source: "public class C { }");

            GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { generator }, parseOptions: parseOptions);

            driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out _);
            driver = driver.RunGeneratorsAndUpdateCompilation(outputCompilation, out outputCompilation, out _);
            driver.RunGeneratorsAndUpdateCompilation(outputCompilation, out outputCompilation, out _);

            Assert.Equal(1, initCount);
            Assert.Equal(3, executeCount);
        }