示例#1
0
        public static Assembly Compile(Xamarin.Android.Binder.CodeGeneratorOptions options,
                                       string assemblyFileName, IEnumerable <string> AdditionalSourceDirectories,
                                       out bool hasErrors, out string output, bool allowWarnings)
        {
            var generatedCodePath = options.ManagedCallableWrapperSourceOutputDirectory;
            var sourceFiles       = Directory.EnumerateFiles(generatedCodePath, "*.cs",
                                                             SearchOption.AllDirectories).ToList();

            sourceFiles = sourceFiles.Select(x => Path.GetFullPath(x)).ToList();

            var supportFiles = Directory.EnumerateFiles(Path.Combine(Path.GetDirectoryName(supportFilePath), "SupportFiles"),
                                                        "*.cs", SearchOption.AllDirectories);

            sourceFiles.AddRange(supportFiles);

            foreach (var dir in AdditionalSourceDirectories)
            {
                var additonal = Directory.EnumerateFiles(dir, "*.cs", SearchOption.AllDirectories);
                sourceFiles.AddRange(additonal);
            }

            CompilerParameters parameters = new CompilerParameters();

            parameters.GenerateExecutable = false;
            parameters.GenerateInMemory   = true;
            parameters.CompilerOptions    = "/unsafe";
            parameters.OutputAssembly     = assemblyFileName;
            parameters.ReferencedAssemblies.Add(unitTestFrameworkAssemblyPath);
            parameters.ReferencedAssemblies.Add(typeof(Enumerable).Assembly.Location);

            var binDir = Path.GetDirectoryName(typeof(BaseGeneratorTest).Assembly.Location);
            var facDir = GetFacadesPath();

            parameters.ReferencedAssemblies.Add(Path.Combine(binDir, "Java.Interop.dll"));
            parameters.ReferencedAssemblies.Add(Path.Combine(facDir, "netstandard.dll"));
#if DEBUG
            parameters.IncludeDebugInformation = true;
#else
            parameters.IncludeDebugInformation = false;
#endif

            using (var codeProvider = GetCodeDomProvider()) {
                CompilerResults results = codeProvider.CompileAssemblyFromFile(parameters, sourceFiles.ToArray());

                hasErrors = false;

                foreach (CompilerError message in results.Errors)
                {
                    hasErrors |= !message.IsWarning || !allowWarnings;
                }
                output = string.Join(Environment.NewLine, results.Output.Cast <string> ());

                return(results.CompiledAssembly);
            }
        }
示例#2
0
        public static Assembly Compile(Xamarin.Android.Binder.CodeGeneratorOptions options,
                                       string assemblyFileName, IEnumerable <string> AdditionalSourceDirectories,
                                       out bool hasErrors, out string output, bool allowWarnings)
        {
            // Gather all the files we need to compile
            var generatedCodePath = options.ManagedCallableWrapperSourceOutputDirectory;
            var sourceFiles       = Directory.EnumerateFiles(generatedCodePath, "*.cs",
                                                             SearchOption.AllDirectories).ToList();

            sourceFiles = sourceFiles.Select(x => Path.GetFullPath(x)).ToList();

            var supportFiles = Directory.EnumerateFiles(Path.Combine(Path.GetDirectoryName(supportFilePath), "SupportFiles"),
                                                        "*.cs", SearchOption.AllDirectories);

            sourceFiles.AddRange(supportFiles);

            foreach (var dir in AdditionalSourceDirectories)
            {
                var additonal = Directory.EnumerateFiles(dir, "*.cs", SearchOption.AllDirectories);
                sourceFiles.AddRange(additonal);
            }

            // Parse the source files
            var syntax_trees = sourceFiles.Distinct().Select(s => CSharpSyntaxTree.ParseText(File.ReadAllText(s))).ToArray();

            // Set up the assemblies we need to reference
            var binDir = Path.GetDirectoryName(typeof(BaseGeneratorTest).Assembly.Location);
            var facDir = GetFacadesPath();

            var references = new [] {
                MetadataReference.CreateFromFile(unitTestFrameworkAssemblyPath),
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
                MetadataReference.CreateFromFile(Path.Combine(binDir, "Java.Interop.dll")),
                MetadataReference.CreateFromFile(Path.Combine(facDir, "netstandard.dll"))
            };

            // Compile!
            var compilation = CSharpCompilation.Create(
                Path.GetFileName(assemblyFileName),
                syntaxTrees: syntax_trees,
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true));

            // Save assembly to a memory stream and load it with reflection
            using (var ms = new MemoryStream()) {
                var result  = compilation.Emit(ms);
                var success = result.Success && (allowWarnings || !result.Diagnostics.Any(d => d.Severity == DiagnosticSeverity.Warning));

                if (!success)
                {
                    var failures = result.Diagnostics.Where(diagnostic =>
                                                            diagnostic.Severity == DiagnosticSeverity.Warning ||
                                                            diagnostic.Severity == DiagnosticSeverity.Error);

                    hasErrors = true;
                    output    = OutputDiagnostics(failures);
                }
                else
                {
                    ms.Seek(0, SeekOrigin.Begin);

                    hasErrors = false;
                    output    = null;

                    return(Assembly.Load(ms.ToArray()));
                }
            }

            return(null);
        }
示例#3
0
        public static Assembly Compile(Xamarin.Android.Binder.CodeGeneratorOptions options,
                                       string assemblyFileName, IEnumerable <string> AdditionalSourceDirectories,
                                       out bool hasErrors, out string output, bool allowWarnings)
        {
            // Gather all the files we need to compile
            var generatedCodePath = options.ManagedCallableWrapperSourceOutputDirectory;
            var sourceFiles       = Directory.EnumerateFiles(generatedCodePath, "*.cs",
                                                             SearchOption.AllDirectories).ToList();

            sourceFiles = sourceFiles.Select(x => Path.GetFullPath(x)).ToList();

            var supportFiles = Directory.EnumerateFiles(Path.Combine(Path.GetDirectoryName(supportFilePath), "SupportFiles"),
                                                        "*.cs", SearchOption.AllDirectories);

            sourceFiles.AddRange(supportFiles);

            foreach (var dir in AdditionalSourceDirectories)
            {
                var additonal = Directory.EnumerateFiles(dir, "*.cs", SearchOption.AllDirectories);
                sourceFiles.AddRange(additonal);
            }

            var preprocessorSymbols = new List <string> ();

            if (options.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1)
            {
                preprocessorSymbols.Add("JAVA_INTEROP1");
            }
#if NET
            preprocessorSymbols.Add("NET");
#endif  // NET

            var parseOptions = new CSharpParseOptions(preprocessorSymbols: preprocessorSymbols);


            // Parse the source files
            var syntax_trees = sourceFiles.Distinct()
                               .Select(s => CSharpSyntaxTree.ParseText(File.ReadAllText(s), options: parseOptions))
                               .ToArray();

            // Set up the assemblies we need to reference
            var binDir = Path.GetDirectoryName(typeof(BaseGeneratorTest).Assembly.Location);
            var facDir = GetFacadesPath();

            var referencePaths = new[] {
                unitTestFrameworkAssemblyPath,
                typeof(object).Assembly.Location,
                typeof(Enumerable).Assembly.Location,
                typeof(Uri).Assembly.Location,
                Path.Combine(binDir, "Java.Interop.dll"),
                Path.Combine(facDir, "netstandard.dll"),
#if NET
                Path.Combine(facDir, "System.Runtime.dll"),
#endif  // NET
            };

            var references = referencePaths.Select(p => MetadataReference.CreateFromFile(p)).ToArray();

            string testCommandLine =
                $"csc \"-out:{Path.GetFileName (assemblyFileName)}\" " +
                $"-unsafe -t:library " +
                string.Join(" ", preprocessorSymbols.Select(p => $"\"-define:{p}\"")) + " " +
                string.Join(" ", referencePaths.Select(p => $"\"-r:{p}\"")) + " " +
                string.Join(" ", sourceFiles)
            ;

            Console.WriteLine($"# Trying to compile: {testCommandLine}");

            // Compile!
            var compilation = CSharpCompilation.Create(
                Path.GetFileName(assemblyFileName),
                syntaxTrees: syntax_trees,
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true));

            // Save assembly to a memory stream and load it with reflection
            using (var ms = new MemoryStream()) {
                var result  = compilation.Emit(ms);
                var success = result.Success && (allowWarnings || !result.Diagnostics.Any(d => d.Severity == DiagnosticSeverity.Warning));

                if (!success)
                {
                    var failures = result.Diagnostics.Where(diagnostic =>
                                                            diagnostic.Severity == DiagnosticSeverity.Warning ||
                                                            diagnostic.Severity == DiagnosticSeverity.Error);

                    hasErrors = true;
                    output    = OutputDiagnostics(failures);
                }
                else
                {
                    ms.Seek(0, SeekOrigin.Begin);

                    hasErrors = false;
                    output    = null;

                    return(Assembly.Load(ms.ToArray()));
                }
            }

            return(null);
        }