static async Task Main(string[] args) { // Attempt to set the version of MSBuild. var visualStudioInstances = MSBuildLocator.QueryVisualStudioInstances().ToArray(); var instance = visualStudioInstances.FirstOrDefault(i => i.Name.Contains("2019")); Console.WriteLine($"Using MSBuild at '{instance.MSBuildPath}' to load projects."); // NOTE: Be sure to register an instance with the MSBuildLocator // before calling MSBuildWorkspace.Create() // otherwise, MSBuildWorkspace won't MEF compose. MSBuildLocator.RegisterInstance(instance); using (var workspace = MSBuildWorkspace.Create()) { // Print message for WorkspaceFailed event to help diagnosing project load failures. workspace.WorkspaceFailed += (o, e) => Console.WriteLine(e.Diagnostic.Message); var solutionPath = Path.GetFullPath(Path.Combine(Assembly.GetExecutingAssembly().Location, @"..\..\..\..\..", "MetaJson.sln")); Console.WriteLine($"Loading solution '{solutionPath}'"); // Attach progress reporter so we print projects as they are loaded. var solution = await workspace.OpenSolutionAsync(solutionPath, new ConsoleProgressReporter()); Console.WriteLine($"Finished loading solution '{solutionPath}'"); // TODO: Do analysis on the projects in the loaded solution Project sampleProject = solution.Projects.FirstOrDefault(p => p.Name.Equals("SampleApp")); Compilation sampleAppProjectCompilation = await sampleProject.GetCompilationAsync(); CSharpGeneratorDriver driver = CSharpGeneratorDriver.Create(new MetaJson.MetaJsonSourceGenerator()); driver.RunGenerators(sampleAppProjectCompilation); } }
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); }
/// <inheritdoc cref="CreateExecutionContext(Compilation, GeneratorInitialize)"/> public static GeneratorExecutionContext CreateExecutionContext(Compilation?compilation) { SourceGeneratorProxy proxy = new(); CSharpGeneratorDriver driver = CSharpGeneratorDriver.Create(proxy); _ = driver.RunGenerators(compilation ?? CreateBaseCompilation()); return(proxy.ExecutionContext); }
/// <summary> /// Creates a new, non-defaulted <see cref="GeneratorExecutionContext"/> using a <see cref="CSharpGeneratorDriver"/>. /// </summary> /// <param name="compilation">A <see cref="Compilation"/> to be assigned to the newly-created <see cref="GeneratorExecutionContext"/>.</param> /// <param name="onInitialize">Action to be performed instead of the proper <see cref="ISourceGenerator.Initialize(GeneratorInitializationContext)"/> method.</param> /// <remarks> /// This method accepts <see cref="Compilation"/> instead of <see cref="CSharpCompilation"/> /// to allow the user to intentionally pass invalid <see cref="Compilation"/> to the <see cref="ISourceGenerator.Execute(GeneratorExecutionContext)"/> /// to perform proper unit tests regarding validation. /// </remarks> public static GeneratorExecutionContext CreateExecutionContext(Compilation?compilation, GeneratorInitialize?onInitialize) { SourceGeneratorProxy proxy = new(); if (onInitialize is not null) { proxy.OnInitialize += onInitialize; } CSharpGeneratorDriver driver = CSharpGeneratorDriver.Create(proxy); _ = driver.RunGenerators(compilation ?? CreateBaseCompilation()); return(proxy.ExecutionContext); }
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 = new CSharpGeneratorDriver(parseOptions, ImmutableArray.Create <ISourceGenerator>(generator, generator2), CompilerAnalyzerConfigOptionsProvider.Empty, ImmutableArray <AdditionalText> .Empty); 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); }