/// <summary> /// Creates a class instance from a source code file. /// Will build a <see cref="Compilation"/>, a <see cref="SyntaxTree"> and a <see cref="CompilationUnitSyntax"/>. /// </summary> /// <param name="filename">Source code file.</param> /// <returns>Instance of ClassCodeInfo.</returns> internal static SourceCodeInfo FromSourceCodeFile(string filename) { if (System.IO.File.Exists(filename) == false) { throw new System.IO.FileNotFoundException($"The file '{filename}' could not be found."); } //var fileContent = AppendDummyMainToCodeFromFile(filename); var fileContent = System.IO.File.ReadAllText(filename); var tree = CSharpSyntaxTree.ParseText(fileContent, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1)); var compilationRoot = tree.GetCompilationUnitRoot(); var classes = compilationRoot .Members .OfType <NamespaceDeclarationSyntax>() .SelectMany( x => x.Members.OfType <ClassDeclarationSyntax>() ); var dd = typeof(Enumerable).GetTypeInfo().Assembly.Location; var coreDir = System.IO.Directory.GetParent(dd); var code = new SourceCodeInfo(); code.classSyntaxes = classes; code.compilation = CSharpCompilation .Create("DocsGeneratorDynamic") .WithOptions(CreateDefaultCompilerOptions()) .AddSyntaxTrees(tree) .AddReferences( MetadataReference.CreateFromFile(typeof(string).Assembly.Location), MetadataReference.CreateFromFile("../src/bin/Debug/netcoreapp2.0/sharpstrap.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "mscorlib.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.Core.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.Linq.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.Diagnostics.Process.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.IO.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.ComponentModel.Primitives.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.ComponentModel.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.Collections.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.Console.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.Runtime.Extensions.dll"), MetadataReference.CreateFromFile(coreDir.FullName + System.IO.Path.DirectorySeparatorChar + "System.Runtime.dll") ); var compilationResult = code.compilation.GetDiagnostics(); var compilationErrors = compilationResult.Where(x => x.Severity == DiagnosticSeverity.Error).Select(x => x.GetMessage()); code.ErrorMessages = new ReadOnlyCollection <string>(compilationErrors.ToList()); code.root = compilationRoot; code.tree = tree; code.LoadClassAndPropertyComments(); return(code); }
static void Main(string[] args) { if (args.Length != 2) { Console.WriteLine("This tool requires exactly two parameters:"); Console.WriteLine("1. filename of the markdown template"); Console.WriteLine("2. filename of the output"); return; } if (System.IO.File.Exists(args[0]) == false) { Console.WriteLine($"The file '{args[0]}' does not exist."); return; } templateFilename = args[0]; if (System.IO.File.Exists(args[1])) { Console.WriteLine("The destination file exists, overwrite? [y/N]"); var key = Console.ReadKey().KeyChar; if (key != 'y' && key != 'Y') { return; } } manualFilename = args[1]; var moduleFiles = GetModuleFilenames(); Console.WriteLine("Found the following code files to run through the code analysis:"); foreach (var file in moduleFiles) { Console.WriteLine(file); } Console.WriteLine("Preparing code analysis for all source code files."); foreach (var file in moduleFiles) { var analysis = SourceCodeInfo.FromSourceCodeFile(file); if (analysis.HasErrors) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"Compilation of '{file}' resulted in the following errors:"); Console.WriteLine(string.Join(Environment.NewLine, analysis.ErrorMessages)); } foreach (var c in analysis.ClassPropertyComments) { classPropertyCodeInfos.Add(c); } foreach (var c in analysis.ClassComments) { classCodeInfos.Add(c); } } var types = GetModulesTypes(); Console.WriteLine("Found the following module classes in the assembly:"); foreach (var t in types) { Console.WriteLine(t.Name); } foreach (var type in types.Where(t => t.IsAbstract == false)) { GetCommentsForClassProperties(type); } var manual = FillMarkdownTemplate(System.IO.File.ReadAllLines(templateFilename)); System.IO.File.WriteAllText(manualFilename, manual); }