public void DoNotPersist() { string text = @"class C { }"; var compilation = CSharpCompilation.Create(GetUniqueName(), new[] { CSharpSyntaxTree.ParseText(text) }, new[] { MscorlibRef }); var generator = new SimpleSourceGenerator(context => context.AddCompilationUnit("__c", CSharpSyntaxTree.ParseText(@"class __C { }"))); using (var directory = new DisposableDirectory(Temp)) { var path = directory.Path; ImmutableArray <Diagnostic> diagnostics; var trees = compilation.GenerateSource( ImmutableArray.Create <SourceGenerator>(generator), path, writeToDisk: false, cancellationToken: default(CancellationToken), diagnostics: out diagnostics); Assert.Equal(1, trees.Length); var filePath = Path.Combine(path, "__c.cs"); Assert.Equal(filePath, trees[0].FilePath); Assert.False(File.Exists(filePath)); } }
public void Paths() { string text = @"class C { }"; var compilation = CSharpCompilation.Create(GetUniqueName(), new[] { CSharpSyntaxTree.ParseText(text) }, new[] { MscorlibRef }); var generator = new SimpleSourceGenerator(context => context.AddCompilationUnit("__c", CSharpSyntaxTree.ParseText(@"class __C { }"))); using (var directory = new DisposableDirectory(Temp)) { ImmutableArray <Diagnostic> diagnostics; // Null path. Assert.Throws <ArgumentNullException>(() => compilation.GenerateSource( ImmutableArray.Create <SourceGenerator>(generator), path: null, writeToDisk: false, cancellationToken: default(CancellationToken), diagnostics: out diagnostics)); // Relative path. var path = Path.GetFileName(directory.Path); var trees = compilation.GenerateSource( ImmutableArray.Create <SourceGenerator>(generator), path, writeToDisk: false, cancellationToken: default(CancellationToken), diagnostics: out diagnostics); Assert.Equal(1, trees.Length); var filePath = Path.Combine(path, "__c.cs"); Assert.Equal(filePath, trees[0].FilePath); } }
private void Persist(Encoding generatedEncoding, Encoding persistedEncoding) { var compilation = CSharpCompilation.Create(GetUniqueName(), new[] { CSharpSyntaxTree.ParseText(@"class C { }") }, new[] { MscorlibRef }); var generatedText = @"class __C { }"; var generator = new SimpleSourceGenerator(context => context.AddCompilationUnit("__c", CSharpSyntaxTree.ParseText(generatedText, encoding: generatedEncoding))); using (var directory = new DisposableDirectory(Temp)) { var path = directory.Path; ImmutableArray <Diagnostic> diagnostics; var trees = compilation.GenerateSource( ImmutableArray.Create <SourceGenerator>(generator), path, writeToDisk: true, cancellationToken: default(CancellationToken), diagnostics: out diagnostics); Assert.Equal(1, trees.Length); var filePath = Path.Combine(path, "__c.cs"); Assert.Equal(filePath, trees[0].FilePath); Assert.True(File.Exists(filePath)); using (var reader = new StreamReader(filePath, detectEncodingFromByteOrderMarks: true)) { // Need at least one read to get encoding. var persistedText = reader.ReadToEnd(); Assert.Equal(persistedEncoding, reader.CurrentEncoding); Assert.Equal(persistedText, generatedText); } } }
public void RunAnalyzersAfterGeneratingSource() { string text = @"class C { }"; using (var directory = new DisposableDirectory(Temp)) { var file = directory.CreateFile("c.cs"); file.WriteAllText(text); int analyzerCalls = 0; ImmutableArray <SyntaxTree> treesToAnalyze; var analyzer = new MyAnalyzer(c => { analyzerCalls++; Assert.True(treesToAnalyze.IsDefault); treesToAnalyze = ImmutableArray.CreateRange(c.Compilation.SyntaxTrees); }); int generatorCalls = 0; var generator = new SimpleSourceGenerator(c => { generatorCalls++; c.AddCompilationUnit("__c", CSharpSyntaxTree.ParseText("class __C { }")); }); var compiler = new MyCompiler( baseDirectory: directory.Path, args: new[] { "/nologo", "/preferreduilang:en", "/t:library", file.Path }, analyzers: ImmutableArray.Create <DiagnosticAnalyzer>(analyzer), generators: ImmutableArray.Create <SourceGenerator>(generator)); var builder = new StringBuilder(); using (var writer = new StringWriter(builder)) { compiler.Run(writer); } var output = builder.ToString(); // No errors from analyzer. Assert.Equal("", output); Assert.Equal(1, generatorCalls); Assert.Equal(1, analyzerCalls); Assert.Equal(2, treesToAnalyze.Length); } }
public void TestSourceGenerators() { string source0 = @"partial class C { D F() { return (D)G; } } class P { static void Main() { } }"; string source1 = @"partial class C { const object G = null; } class D { }"; var generator = new SimpleSourceGenerator(c => c.AddCompilationUnit("__c", CSharpSyntaxTree.ParseText(source1))); var generatorReference = new SourceGeneratorReference(ImmutableArray.Create <SourceGenerator>(generator)); using (var directory = new DisposableDirectory(Temp)) { var outputPath = Path.Combine(directory.Path, "obj", "debug"); Directory.CreateDirectory(outputPath); var projectId = ProjectId.CreateNewId(); var docId = DocumentId.CreateNewId(projectId); var workspace = new AdhocWorkspace(); var projectInfo = ProjectInfo.Create( projectId, VersionStamp.Default, name: "C", assemblyName: "C.dll", language: LanguageNames.CSharp, outputFilePath: outputPath + Path.DirectorySeparatorChar); var solution = workspace.CurrentSolution .AddProject(projectInfo) .AddMetadataReference(projectId, MscorlibRef) .AddDocument(docId, "C.cs", source0) .AddAnalyzerReference(projectId, generatorReference); bool ok = workspace.TryApplyChanges(solution); Assert.True(ok); var actualAnalyzerReferences = solution.GetProject(projectId).AnalyzerReferences; Assert.Equal(1, actualAnalyzerReferences.Count); Assert.Equal(generatorReference, actualAnalyzerReferences[0]); var actualGenerators = actualAnalyzerReferences[0].GetSourceGenerators(LanguageNames.CSharp); Assert.Equal(1, actualGenerators.Length); Assert.Equal(generator, actualGenerators[0]); // Before generating source. solution = workspace.CurrentSolution; var project = solution.GetProject(projectId); Assert.Equal(1, project.DocumentIds.Count); var doc = solution.GetDocument(docId); var model = doc.GetSemanticModelAsync().Result; Assert.NotNull(model); var compilation = model.Compilation; var trees = compilation.SyntaxTrees.ToArray(); Assert.Equal(1, trees.Length); // After generating source. workspace.UpdateGeneratedDocumentsIfNecessary(projectId); solution = workspace.CurrentSolution; project = solution.GetProject(projectId); Assert.Equal(2, project.DocumentIds.Count); doc = solution.GetDocument(docId); model = doc.GetSemanticModelAsync().Result; Assert.NotNull(model); compilation = model.Compilation; trees = compilation.SyntaxTrees.ToArray(); Assert.Equal(2, trees.Length); var tree = trees[1]; doc = solution.GetDocument(tree); Assert.NotNull(doc); Assert.True(doc.State.IsGenerated); var actualSource = tree.GetText().ToString(); Assert.Equal(source1, actualSource); var filePath = doc.FilePath; Assert.NotNull(filePath); Assert.Equal(outputPath, Path.GetDirectoryName(filePath)); // Workspace should not write files to disk. Assert.False(File.Exists(filePath)); } }