private bool CheckForErrors(CodeAnalyzer codeAnalyzer) { bool hasErrors = false; if (codeAnalyzer.Diagnostics.Any(diag => diag.Severity == DiagnosticSeverity.Error || diag.Severity == DiagnosticSeverity.Warning)) { var oldColor = Console.ForegroundColor; foreach (var diagnostic in codeAnalyzer.Diagnostics) { switch (diagnostic.Severity) { case DiagnosticSeverity.Error: Console.ForegroundColor = ConsoleColor.Red; hasErrors = true; break; case DiagnosticSeverity.Warning: Console.ForegroundColor = ConsoleColor.Yellow; break; default: Console.ForegroundColor = oldColor; break; } Console.WriteLine(diagnostic.ToString()); } Console.ForegroundColor = oldColor; } return(!hasErrors); }
/// <summary> /// The main entry point to run the code generation based on the given options. /// /// Main phases of execution are: /// 1. Load the code into roslyn /// 1. Parse Source Files into syntax trees /// 2. Load the references /// 3. Run the compiler to create the Linked semantic model. /// 2. Analyze the roslyn Compilation unit /// 1. Detect react types in the code /// 2. Build a Model for the assembly /// 3. Generate code /// 1. Use the Model from step 2 to emit a C# Syntax Tree /// 2. Write the SyntaxTree to a file. /// </summary> public async Task <bool> Run(Options options) { var codeAnalyzer = new CodeAnalyzer(m_cancellationToken); // Load the code into roslyn using (new ConsoleMeasurement("Parsing source files")) { await codeAnalyzer.ParseSourceFilesAsync( GetDistinctExistingFiles(options.SourceFiles), options.Defines.Select(def => def.Trim())); } using (new ConsoleMeasurement("Loading references")) { await codeAnalyzer.LoadMetadataReferencesAsync( GetDistinctExistingFiles(options.References)); } using (new ConsoleMeasurement("Compiling")) { if (!codeAnalyzer.TryCompileAndCheckForErrors()) { CheckForErrors(codeAnalyzer); return(false); } } // Extract the model form the assembly ReactAssembly assembly; using (new ConsoleMeasurement("Finding types")) { assembly = codeAnalyzer.AnalyzeAndConstructAssemblyModel(); } // Check if any errors have been logged and display them. if (!CheckForErrors(codeAnalyzer)) { return(false); } var codeGenerator = new CodeGenerator(codeAnalyzer.ReactTypes, options.Namespace); CSharpSyntaxNode node; using (new ConsoleMeasurement("Generating code")) { node = codeGenerator.Generate(assembly); } var code = node.NormalizeWhitespace(indentation: " ", elasticTrivia: false).ToFullString(); if (!await TryWriteFileIfDifferent(options.OutputFile, code)) { return(false); } return(true); }