public GenerationResult( Document document, SemanticModel semanticModel, IReadOnlyList <Diagnostic> generatorDiagnostics, IReadOnlyList <Diagnostic> compilationDiagnostics) { this.Document = document; this.SemanticModel = semanticModel; this.Declarations = CSharpDeclarationComputer.GetDeclarationsInSpan(semanticModel, TextSpan.FromBounds(0, semanticModel.SyntaxTree.Length), true, CancellationToken.None); this.GeneratorDiagnostics = generatorDiagnostics; this.CompilationDiagnostics = compilationDiagnostics; }
public ImmutableArray <DeclarationInfo> GetDeclarationsInSpan(SemanticModel model, TextSpan span, bool getSymbol, CancellationToken cancellationToken) { return(CSharpDeclarationComputer.GetDeclarationsInSpan(model, span, getSymbol, cancellationToken)); }
public GenerationResult(Document document, SemanticModel semanticModel) { this.Document = document; this.SemanticModel = semanticModel; this.Declarations = CSharpDeclarationComputer.GetDeclarationsInSpan(semanticModel, TextSpan.FromBounds(0, semanticModel.SyntaxTree.Length), true, CancellationToken.None); }
public void Execute() { Task.Run(async delegate { AppDomain.CurrentDomain.AssemblyResolve += (s, e) => { return(this.TryLoadAssembly(new AssemblyName(e.Name))); }; var project = this.CreateProject(); var outputFiles = new List <ITaskItem>(); var writtenFiles = new List <ITaskItem>(); string generatorAssemblyInputsFile = Path.Combine(this.IntermediateOutputDirectory, "CodeGeneration.Roslyn.InputAssemblies.txt"); // For incremental build, we want to consider the input->output files as well as the assemblies involved in code generation. DateTime assembliesLastModified = GetLastModifiedAssemblyTime(generatorAssemblyInputsFile); var explicitIncludeList = new HashSet <string>( from item in this.Compile where string.Equals(item.GetMetadata("Generator"), $"MSBuild:{this.TargetName}", StringComparison.OrdinalIgnoreCase) select item.ItemSpec, StringComparer.OrdinalIgnoreCase); foreach (var inputDocument in project.Documents) { this.CancellationToken.ThrowIfCancellationRequested(); // Skip over documents that aren't on the prescribed list of files to scan. if (!explicitIncludeList.Contains(inputDocument.Name)) { continue; } string sourceHash = inputDocument.Name.GetHashCode().ToString("x", CultureInfo.InvariantCulture); string outputFilePath = Path.Combine(this.IntermediateOutputDirectory, Path.GetFileNameWithoutExtension(inputDocument.Name) + $".{sourceHash}.generated.cs"); // Code generation is relatively fast, but it's not free. // And when we run the Simplifier.ReduceAsync it's dog slow. // So skip files that haven't changed since we last generated them. bool generated = false; DateTime outputLastModified = File.GetLastWriteTime(outputFilePath); if (File.GetLastWriteTime(inputDocument.Name) > outputLastModified || assembliesLastModified > outputLastModified) { this.Log.LogMessage(MessageImportance.Normal, "{0} -> {1}", inputDocument.Name, outputFilePath); var outputDocument = await DocumentTransform.TransformAsync( inputDocument, new ProgressLogger(this.Log, inputDocument.Name)); // Only produce a new file if the generated document is not empty. var semanticModel = await outputDocument.GetSemanticModelAsync(this.CancellationToken); if (!CSharpDeclarationComputer.GetDeclarationsInSpan(semanticModel, TextSpan.FromBounds(0, semanticModel.SyntaxTree.Length), false, this.CancellationToken).IsEmpty) { var outputText = await outputDocument.GetTextAsync(this.CancellationToken); using (var outputFileStream = File.OpenWrite(outputFilePath)) using (var outputWriter = new StreamWriter(outputFileStream)) { outputText.Write(outputWriter); // Truncate any data that may be beyond this point if the file existed previously. outputWriter.Flush(); outputFileStream.SetLength(outputFileStream.Position); } generated = true; } } else { generated = true; } if (generated) { var outputItem = new TaskItem(outputFilePath); outputFiles.Add(outputItem); } } SaveGeneratorAssemblyList(generatorAssemblyInputsFile); writtenFiles.Add(new TaskItem(generatorAssemblyInputsFile)); this.GeneratedCompile = outputFiles.ToArray(); this.AdditionalWrittenFiles = writtenFiles.ToArray(); }).GetAwaiter().GetResult(); }
public void Execute() { Task.Run(async delegate { var project = this.CreateProject(); var outputFiles = new List <ITaskItem>(); // For incremental build, we want to consider the input->output files as well as the assemblies involved in code generation. DateTime assembliesLastModified = GetLastModifiedAssemblyTime(); foreach (var inputDocument in project.Documents) { this.CancellationToken.ThrowIfCancellationRequested(); // Skip over documents that aren't on the prescribed list of files to scan. if (!this.CompileToGenerateFromAttributes.Any(i => i.ItemSpec == inputDocument.Name)) { continue; } string outputFilePath = Path.Combine(this.IntermediateOutputDirectory, Path.GetFileNameWithoutExtension(inputDocument.Name) + ".generated.cs"); // Code generation is relatively fast, but it's not free. // And when we run the Simplifier.ReduceAsync it's dog slow. // So skip files that haven't changed since we last generated them. bool generated = false; DateTime outputLastModified = File.GetLastWriteTime(outputFilePath); if (File.GetLastWriteTime(inputDocument.Name) > outputLastModified || assembliesLastModified > outputLastModified) { this.Log.LogMessage(MessageImportance.Normal, "{0} -> {1}", inputDocument.Name, outputFilePath); var outputDocument = await DocumentTransform.TransformAsync(inputDocument, new ProgressLogger(this.Log, inputDocument.Name)); // Only produce a new file if the generated document is not empty. var semanticModel = await outputDocument.GetSemanticModelAsync(this.CancellationToken); if (!CSharpDeclarationComputer.GetDeclarationsInSpan(semanticModel, TextSpan.FromBounds(0, semanticModel.SyntaxTree.Length), false, this.CancellationToken).IsEmpty) { var outputText = await outputDocument.GetTextAsync(this.CancellationToken); using (var outputFileStream = File.OpenWrite(outputFilePath)) using (var outputWriter = new StreamWriter(outputFileStream)) { outputText.Write(outputWriter); // Truncate any data that may be beyond this point if the file existed previously. outputWriter.Flush(); outputFileStream.SetLength(outputFileStream.Position); } generated = true; } } else { generated = true; } if (generated) { var outputItem = new TaskItem(outputFilePath); outputFiles.Add(outputItem); } } this.GeneratedCompile = outputFiles.ToArray(); }).GetAwaiter().GetResult(); }