public static ClangSharpSourceCompilation Create( string sourceDirectory, string arch, string interopFileName, Dictionary <string, string> remaps, Dictionary <string, Dictionary <string, string> > enumAdditions, IEnumerable <string> enumsMakeFlags, Dictionary <string, string> typeImports, Dictionary <string, string> requiredNamespaces, HashSet <string> reducePointerLevels, IEnumerable <string> addedRefs) { sourceDirectory = Path.GetFullPath(sourceDirectory); var netstandardPath = FindNetstandardDllPath(); if (!File.Exists(netstandardPath)) { throw new FileNotFoundException("Failed to find the netstandard DLL."); } List <MetadataReference> refs = new List <MetadataReference>(); refs.Add(MetadataReference.CreateFromFile(interopFileName)); refs.Add(MetadataReference.CreateFromFile(netstandardPath)); if (addedRefs != null) { foreach (var r in addedRefs) { refs.Add(MetadataReference.CreateFromFile(r)); } } List <SyntaxTree> syntaxTrees = new List <SyntaxTree>(); var sourceFiles = Directory.GetFiles(sourceDirectory, "*.cs", SearchOption.AllDirectories).Where(f => IsValidCsSourceFile(f, arch)); System.Threading.Tasks.ParallelOptions opt = new System.Threading.Tasks.ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount * 2 }; System.Threading.Tasks.Parallel.ForEach(sourceFiles, opt, (sourceFile) => { string fileToRead = Path.GetFullPath(sourceFile); var tree = CSharpSyntaxTree.ParseText(File.ReadAllText(fileToRead), null, fileToRead); lock (syntaxTrees) { syntaxTrees.Add(tree); } }); syntaxTrees = NamesToCorrectNamespacesMover.MoveNamesToCorrectNamespaces(syntaxTrees, requiredNamespaces); GetTreeInfo(syntaxTrees, out var emptyStucts, out var enumMemberNames); #if MakeSingleThreaded opt.MaxDegreeOfParallelism = 1; #endif string objDir = Path.Combine(sourceDirectory, $"obj\\{arch}"); Directory.CreateDirectory(objDir); HashSet <string> enumsMakeFlagsHashSet = enumsMakeFlags != null ? new HashSet <string>(enumsMakeFlags) : new HashSet <string>(); List <SyntaxTree> cleanedTrees = new List <SyntaxTree>(); System.Threading.Tasks.Parallel.ForEach(syntaxTrees, opt, (tree) => { // Turn c:\dir\generated\foo.cs into c:\dir\generated\obj\foo.modified.cs string modifiedFile = Path.ChangeExtension(tree.FilePath, ".modified.cs"); string fileWithSubDir = modifiedFile.Substring(sourceDirectory.Length); if (fileWithSubDir.StartsWith('\\')) { fileWithSubDir = fileWithSubDir.Substring(1); } modifiedFile = Path.Combine(objDir, fileWithSubDir); // e.g. c:\dir\generated\obj string newSubDir = Path.GetDirectoryName(modifiedFile); if (!Directory.Exists(newSubDir)) { Directory.CreateDirectory(newSubDir); } var cleanedTree = MetadataSyntaxTreeCleaner.CleanSyntaxTree(tree, remaps, enumAdditions, enumsMakeFlagsHashSet, requiredNamespaces, emptyStucts, enumMemberNames, modifiedFile); lock (cleanedTrees) { cleanedTrees.Add(cleanedTree); } }); if (arch == "crossarch") { CrossArchSyntaxMap crossArchSyntaxMap = CrossArchSyntaxMap.LoadFromTrees(cleanedTrees); cleanedTrees = CrossArchTreeMerger.MergeTrees(crossArchSyntaxMap, cleanedTrees); } foreach (var cleanedTree in cleanedTrees) { File.WriteAllText(cleanedTree.FilePath, cleanedTree.GetText().ToString()); } CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions(OutputKind.WindowsRuntimeMetadata, allowUnsafe: true); var comp = CSharpCompilation.Create( null, cleanedTrees, refs, compilationOptions); return(new ClangSharpSourceCompilation(comp, typeImports)); }
public static ClangSharpSourceCompilation Create( string sourceDirectory, string interopFileName, Dictionary <string, string> remaps, Dictionary <string, string> typeImports, Dictionary <string, string> requiredNamespaces, HashSet <string> reducePointerLevels) { sourceDirectory = Path.GetFullPath(sourceDirectory); var netstandardPath = FindNetstandardDllPath(); if (!File.Exists(netstandardPath)) { throw new FileNotFoundException("Failed to find the netstandard DLL."); } List <MetadataReference> refs = new List <MetadataReference>(); refs.Add(MetadataReference.CreateFromFile(interopFileName)); refs.Add(MetadataReference.CreateFromFile(netstandardPath)); List <SyntaxTree> syntaxTrees = new List <SyntaxTree>(); var sourceFiles = Directory.GetFiles(sourceDirectory, "*.cs", SearchOption.AllDirectories).Where(f => !f.EndsWith("modified.cs")); System.Threading.Tasks.ParallelOptions opt = new System.Threading.Tasks.ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount * 2 }; System.Threading.Tasks.Parallel.ForEach(sourceFiles, opt, (sourceFile) => { string fileToRead = Path.GetFullPath(sourceFile); var tree = CSharpSyntaxTree.ParseText(File.ReadAllText(fileToRead), null, fileToRead); lock (syntaxTrees) { syntaxTrees.Add(tree); } }); syntaxTrees = NamesToCorrectNamespacesMover.MoveNamesToCorrectNamespaces(syntaxTrees, requiredNamespaces); HashSet <string> foundNonEmptyStructs = GetNonEmptyStructs(syntaxTrees); #if MakeSingleThreaded opt.MaxDegreeOfParallelism = 1; #endif string objDir = Path.Combine(sourceDirectory, "obj"); Directory.CreateDirectory(objDir); List <SyntaxTree> cleanedTrees = new List <SyntaxTree>(); System.Threading.Tasks.Parallel.ForEach(syntaxTrees, opt, (tree) => { // Turn c:\dir\generated\foo.cs into c:\dir\generated\obj\foo.modified.cs string modifiedFile = Path.ChangeExtension(tree.FilePath, ".modified.cs"); string fileWithSubDir = modifiedFile.Substring(sourceDirectory.Length); if (fileWithSubDir.StartsWith('\\')) { fileWithSubDir = fileWithSubDir.Substring(1); } modifiedFile = Path.Combine(objDir, fileWithSubDir); // e.g. c:\dir\generated\obj string newSubDir = Path.GetDirectoryName(modifiedFile); if (!Directory.Exists(newSubDir)) { Directory.CreateDirectory(newSubDir); } var cleanedTree = MetadataSyntaxTreeCleaner.CleanSyntaxTree(tree, remaps, requiredNamespaces, foundNonEmptyStructs, modifiedFile); File.WriteAllText(modifiedFile, cleanedTree.GetText().ToString()); lock (cleanedTrees) { cleanedTrees.Add(cleanedTree); } }); CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions(OutputKind.WindowsRuntimeMetadata, allowUnsafe: true); var comp = CSharpCompilation.Create( null, cleanedTrees, refs, compilationOptions); return(new ClangSharpSourceCompilation(comp, typeImports)); }
public static ClangSharpSourceCompilation Create( string sourceDirectory, string interopFileName, Dictionary <string, string> remaps, Dictionary <string, string> typeImports, Dictionary <string, string> requiredNamespaces) { var netstandardPath = FindNetstandardDllPath(); if (!File.Exists(netstandardPath)) { throw new FileNotFoundException("Failed to find the netstandard DLL."); } List <MetadataReference> refs = new List <MetadataReference>(); refs.Add(MetadataReference.CreateFromFile(interopFileName)); refs.Add(MetadataReference.CreateFromFile(netstandardPath)); List <SyntaxTree> syntaxTrees = new List <SyntaxTree>(); var sourceFiles = Directory.GetFiles(sourceDirectory, "*.cs", SearchOption.AllDirectories); System.Threading.Tasks.ParallelOptions opt = new System.Threading.Tasks.ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount * 2 }; System.Threading.Tasks.Parallel.ForEach(sourceFiles, opt, (sourceFile) => { if (sourceFile.EndsWith("modified.cs")) { return; } string fileToRead = Path.GetFullPath(sourceFile); var tree = CSharpSyntaxTree.ParseText(File.ReadAllText(fileToRead), null, fileToRead); lock (syntaxTrees) { syntaxTrees.Add(tree); } }); syntaxTrees = NamesToCorrectNamespacesMover.MoveNamesToCorrectNamespaces(syntaxTrees, requiredNamespaces); HashSet <string> foundNonEmptyStructs = GetNonEmptyStructs(syntaxTrees); List <SyntaxTree> cleanedTrees = new List <SyntaxTree>(); System.Threading.Tasks.Parallel.ForEach(syntaxTrees, opt, (tree) => { string modifiedFile = Path.ChangeExtension(tree.FilePath, ".modified.cs"); var cleanedTree = MetadataSyntaxTreeCleaner.CleanSyntaxTree(tree, remaps, requiredNamespaces, foundNonEmptyStructs, modifiedFile); File.WriteAllText(modifiedFile, cleanedTree.GetText().ToString()); lock (cleanedTrees) { cleanedTrees.Add(cleanedTree); } }); CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions(OutputKind.WindowsRuntimeMetadata, allowUnsafe: true); var comp = CSharpCompilation.Create( //Path.GetFileName(outputFileName), null, cleanedTrees, refs, compilationOptions); return(new ClangSharpSourceCompilation(comp, typeImports)); }