Example #1
0
        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));
        }
Example #2
0
        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));
        }
Example #3
0
        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));
        }