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); }
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) ); }
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); }
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); }
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); }
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); }
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); }
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) ); }
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()); }
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); }
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()); }
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()); }); } }
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) ); }
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()); }); } }
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); }
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); }
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]); }
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 ); }
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) ); }
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]); }
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); }
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); }
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); }
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); }
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]); }
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); }
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) ); }
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) ); }
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); }