Пример #1
0
        public void CompileIfRequired(ilspy::Mono.Cecil.AssemblyDefinition assembly, bool stopBeforeGeneratingCode = false)
        {
            if (_compiler != null && _previousAssembly == assembly
            && (_isFullyCompiled || stopBeforeGeneratingCode))
                return;

            CompilationErrors = null;
            _compiler = null;

#if DEBUG
            var framework = Frameworks.Instance.GetBySdkVersion(15);
#else
            var framework = Frameworks.Instance.GetNewestVersion();
#endif
            string frameworkFolder = framework.Folder;
            var refFolders = new List<string> { frameworkFolder };

            var module = new XModule();
            var classLoader = new AssemblyClassLoader(module.OnClassLoaded);
            var resolver = new AssemblyResolver(refFolders, classLoader, module.OnAssemblyLoaded);
            var parameter = new ReaderParameters(ReadingMode.Immediate) { AssemblyResolver = resolver,ReadSymbols = true};

            var assemblies = new[] { resolver.Load(assembly.MainModule.FullyQualifiedName, parameter) }.ToList();
            List<AssemblyDefinition> references = new List<AssemblyDefinition>();
            
            if(assembly.MainModule.Name != "dot42.dll")
                references = new[] { resolver.Load(AssemblyConstants.SdkAssemblyName, parameter) }.ToList();
            
            foreach (var a in assemblies)
                references.Remove(a);

            var c = new AssemblyCompiler(CompilationMode.All, assemblies, references, new Table("pkg.name"),
                                         new NameConverter("pkg.name", ""), true, 
                                         new AssemblyClassLoader(file => { }), definition => null,
                                         new DexMethodBodyCompilerCache(), new HashSet<string>(), 
                                         module, _generateSetNextInstructionCode);

            c.StopCompilationBeforeGeneratingCode = stopBeforeGeneratingCode;
            c.StopAtFirstError = false;
            
            try
            {
                c.Compile();
            }
            catch (AggregateException ex)
            {
                CompilationErrors = ex.Flatten().InnerExceptions.Select(e => e.Message.Replace(": ", "\n//      ").Replace("; ", "\n//      &  ")).ToList();
            }

            if (c.MapFile != null)
            {
                c.MapFile.Optimize();
                MapFile = new MapFileLookup(c.MapFile);
            }

            _compiler = c;
            _previousAssembly = assembly;
            _isFullyCompiled = !stopBeforeGeneratingCode;
        }
Пример #2
0
        /// <summary>
        /// Default ctor
        /// </summary>
        public JarImporter(string jarFilePath, string libraryName, bool importAsStubs, bool importPublicOnly, string sourceOutputPath, AssemblyResolver assemblyResolver, IEnumerable<string> excludedPackages, bool useAutoExcludedPackages)
        {
#if DEBUG
            //Debugger.Launch();
#endif
            this.jarFilePath = jarFilePath;
            this.libraryName = libraryName;
            this.importAsStubs = importAsStubs;
            this.sourceOutputPath = sourceOutputPath;
            this.assemblyResolver = assemblyResolver;
            if (useAutoExcludedPackages)
            {
                excludedPackages = AutoExcludedPackages;
            }
            target = new TargetFramework(this, assemblyResolver.ClassLoader, new DocModel(), null, importAsStubs, importPublicOnly, excludedPackages);
        }
Пример #3
0
        /// <summary>
        /// Default ctor
        /// </summary>
        private ManifestBuilder(string assemblyFile, IEnumerable<string> referenceFolders, string packageName, NameConverter nsConverter, bool debuggable, List<string> appWidgetProviderCodeFiles, string targetSdkVersion)
        {
#if DEBUG
            //Debugger.Launch();
#endif

            module = new XModule();
            this.packageName = packageName;
            this.nsConverter = nsConverter;
            this.debuggable = debuggable;
            this.appWidgetProviderCodeFiles = appWidgetProviderCodeFiles;
            this.targetSdkVersion = targetSdkVersion;

            // Load assembly file
            if (!File.Exists(assemblyFile))
                throw new ArgumentException(string.Format("Assembly {0} not found", assemblyFile));

            var assemblyResolver = new AssemblyResolver(referenceFolders, null, module.OnAssemblyLoaded); 
            var parameters = new ReaderParameters { AssemblyResolver = assemblyResolver};
            assembly = assemblyResolver.Load(assemblyFile, parameters);
        }
Пример #4
0
        /// <summary>
        /// Compile an assembly into a dex file.
        /// </summary>
        private static void CompileAssembly(CommandLineOptions options, NameConverter nsConverter)
        {
            // Load resource type usage info file
            var usedTypeNames = LoadResourceTypeUsageInformation(options);

            // Load assemblies
            var assemblies = new List<AssemblyDefinition>();
            var module = new XModule();
            var classLoader = new AssemblyClassLoader(module.OnClassLoaded);
            var resolver = new AssemblyResolver(options.ReferenceFolders, classLoader, module.OnAssemblyLoaded);
            var readerParameters = new ReaderParameters(ReadingMode.Immediate)
            {
                AssemblyResolver = resolver,
                SymbolReaderProvider = new SafeSymbolReaderProvider(),
                ReadSymbols = true
            };
            foreach (var asmPath in options.Assemblies)
            {
                var asm = resolver.Load(asmPath, readerParameters);
                module.OnAssemblyLoaded(asm);
                classLoader.LoadAssembly(asm);
                assemblies.Add(asm);
            }
            // Load references
            var references = new List<AssemblyDefinition>();
            foreach (var refPath in options.References)
            {
                var asm = resolver.Load(refPath, readerParameters);
                module.OnAssemblyLoaded(asm);
                classLoader.LoadAssembly(asm);
                references.Add(asm);
            }

            // Load resources
            Table table;
            using (var stream = new FileStream(options.InputResources, FileMode.Open, FileAccess.Read))
            {
                table = new Table(stream);
            }

            // Create compiler
            var compiler = new AssemblyCompiler(options.CompilationMode, assemblies, references, table, nsConverter, options.DebugInfo, classLoader, usedTypeNames, module);
            compiler.Compile();
            compiler.Save(options.OutputFolder, options.FreeAppsKeyPath);
        }
Пример #5
0
        /// <summary>
        /// Program main code
        /// </summary>
        /// <returns>true on success, false on usage due to invalid options</returns>
        internal static bool MainCode(CommandLineOptions options)
        {
            if (options.ShowHelp)
            {
                return false;
            }

            // Detect target
            var target = Locations.SetTarget(options.Target);

            // Build APK/BAR?
            if (!string.IsNullOrEmpty(options.PackagePath))
            {
#if DEBUG
                //Debugger.Launch();
#endif

                // Build APK first
                var apkPath = options.PackagePath;
                if (target == Targets.BlackBerry)
                {
                    // Put APK in TEMP folder
                    apkPath = Path.GetTempFileName() + ".apk";
                }

                var apkBuilder = new ApkBuilder.ApkBuilder(apkPath);
                apkBuilder.MapFilePath = Path.ChangeExtension(options.PackagePath, ".d42map");
                apkBuilder.ManifestPath = options.ManifestFile;
                apkBuilder.DexFiles.AddRange(options.DexFiles);
                apkBuilder.MapFiles.AddRange(options.MapFiles);
                if (options.Assemblies.Any())
                {
                    apkBuilder.Assemblies.AddRange(options.Assemblies);
                }
                apkBuilder.ResourcesFolder = options.ResourcesFolder;
                apkBuilder.PfxFile = options.PfxFile;
                apkBuilder.PfxPassword = options.PfxPassword;
                apkBuilder.CertificateThumbprint = options.CertificateThumbprint;
                apkBuilder.FreeAppsKeyPath = options.FreeAppsKeyPath;
                apkBuilder.PackageName = options.PackageName;
                apkBuilder.NativeCodeLibraries.AddRange(options.NativeCodeLibs);
                apkBuilder.Build();

                if (target == Targets.BlackBerry)
                {
                    // Now build BAR
                    var barBuilder = new BarBuilder.BarBuilder(options.PackagePath);
                    barBuilder.ApkPath = apkPath;
                    barBuilder.DebugTokenPath = options.DebugToken;
                    barBuilder.Build();                    
                }
            }
            else if (!string.IsNullOrEmpty(options.JarFile)) // Import jar file?
            {
                var module = new XModule();
                var resolver = new AssemblyResolver(options.ReferenceFolders, new AssemblyClassLoader(module.OnClassLoaded), module.OnAssemblyLoaded);
                var jarImporter = new JarImporter(options.JarFile, options.LibName, options.ImportStubsOnly, false/*true*/, options.GeneratedCodeFolder, resolver, options.ExcludedPackages, options.UseAutoExcludedPackages);
                foreach (var path in options.References)
                {
                    jarImporter.ImportAssembly(path);
                }
                jarImporter.ImportAssembliesCompleted();
                jarImporter.Import();
            }
            else if (options.WcfProxyInputAssemblies.Any()) // Generate WCF Proxy
            {
                var resolver = new AssemblyResolver(options.ReferenceFolders, null, null);
                var readerParameters = new ReaderParameters(ReadingMode.Immediate) {
                    AssemblyResolver = resolver,
                    SymbolReaderProvider = new SafeSymbolReaderProvider(),
                    ReadSymbols = true
                };
                var assemblies = options.WcfProxyInputAssemblies.Select(x => AssemblyDefinition.ReadAssembly(x, readerParameters)).ToList();
                var proxyTool = new ProxyBuilderTool(assemblies, options.GeneratedProxySourcePath);
                proxyTool.Build();
            }
            else
            {
                // Create namespace converter
                var nsConverter = new NameConverter(options.PackageName, options.RootNamespace);

                // Create manifest file?
                if (options.CreateManifest)
                {
                    ManifestBuilder.CreateManifest(target, options.Assemblies.First(), options.ReferenceFolders, options.PackageName, nsConverter, 
                        options.DebugInfo, options.AppWidgetProviders, options.TargetSdkVersion, options.OutputFolder);
                }
                else
                {
                    // Code compilation?
                    if (options.Assemblies.Any())
                    {
#if DEBUG
                        //Debugger.Launch();
#endif

                        CompileAssembly(options, nsConverter);
                    }
                }

                // Xml compilation
                if (options.CompileResources)
                {
                    if (!CompileResources(options))
                        return false;
                }
            }
            return true;
        }
Пример #6
0
        /// <summary>
        /// Compile an assembly into a dex file.
        /// </summary>
        private static void CompileAssembly(CommandLineOptions options, NameConverter nsConverter)
        {
            // Load resource type usage info file
            var usedTypeNames = LoadResourceTypeUsageInformation(options);


            // Load assemblies
            List<AssemblyDefinition> assemblies = new List<AssemblyDefinition>();
            List<AssemblyDefinition> references= new List<AssemblyDefinition>();

            var dxJarCompiler = options.EnableDxJarCompilation
                ? new DxClassfileMethodBodyCompiler(options.OutputFolder, options.DebugInfo)
                : null;
            Action<ClassSource> jarLoaded = dxJarCompiler != null ? dxJarCompiler.PreloadJar : (Action<ClassSource>)null;

            var module = new XModule();
            var classLoader = new AssemblyClassLoader(module.OnClassLoaded);
            var resolver = new AssemblyResolver(options.ReferenceFolders, classLoader, module.OnAssemblyLoaded);

            // initialize compiler cache in background.
            var ccache = options.EnableCompilerCache ? new DexMethodBodyCompilerCache(options.OutputFolder, resolver.GetFileName)
                                                     : new DexMethodBodyCompilerCache();

            var readerParameters = new ReaderParameters
            {
                AssemblyResolver = resolver,
                SymbolReaderProvider = new SafeSymbolReaderProvider(),
                ReadSymbols = true,
                ReadingMode = ReadingMode.Immediate
            };

            // load assemblies
            var toLoad = options.Assemblies.Select(path => new {path, target = assemblies})
                 .Concat(options.References.Select(path => new {path, target = references}))
                 // Some micro optimizations... 
                 // Our startup is IO bound until we have loaded first assembly from disk.
                 // So just load from smallest to largest.
                 .Select(load => new { load.path, load.target, length = new FileInfo(resolver.ResolvePath(load.path)).Length})
                 .OrderBy(load=>load.length)
                 .ToList();

            using (AssemblyCompiler.Profile("for loading assemblies"))
            {
                toLoad.AsParallel().ForAll(
                //toLoad.ForEach(
                    load =>
                    {
                        var assm = resolver.Load(load.path, readerParameters);
                        lock (load.target) load.target.Add(assm);
                    });
            }

            // Load resources
            Table table;
            using (var stream = new FileStream(options.InputResources, FileMode.Open, FileAccess.Read))
            {
                table = new Table(stream);
            }

            // Create compiler
            var compiler = new AssemblyCompiler(options.CompilationMode, assemblies, references, table, nsConverter,
                                                options.DebugInfo, classLoader, resolver.GetFileName, ccache, 
                                                usedTypeNames, module, options.GenerateSetNextInstructionCode);
            compiler.DxClassfileMethodBodyCompiler = dxJarCompiler;
            using (AssemblyCompiler.Profile("total compilation time", true))
                compiler.Compile();

            ccache.PrintStatistics();

            using (AssemblyCompiler.Profile("saving results"))
                compiler.Save(options.OutputFolder, options.FreeAppsKeyPath);

            
        }
Пример #7
0
        /// <summary>
        /// Compile the given resources into a suitable output folder.
        /// </summary>
        internal bool Compile(List<Tuple<string, ResourceType>> resources, List<string> appWidgetProviderCodeFiles, List<string> references, List<string> referenceFolders, string baseApkPath)
        {
            // Remove temp folder
            if (Directory.Exists(tempFolder))
            {
                Directory.Delete(tempFolder, true);
            }

            // Ensure temp\res folder exists
            var resFolder = Path.Combine(tempFolder, "res");
            Directory.CreateDirectory(resFolder);
            var tempApkPath = Path.Combine(tempFolder, "temp.apk");

            // Compile each resource
            foreach (var resource in resources.Where(x => x.Item2 != ResourceType.Manifest))
            {
                CopyResourceToFolder(tempFolder, resource.Item1, resource.Item2);
            }

            // Extract resources out of library project references
            var resolver = new AssemblyResolver(referenceFolders, null, null);
            foreach (var path in references)
            {
                ExtractLibraryProjectResources(resFolder, path, resolver);
            }

            // Select manifest path
            var manifestPath = resources.Where(x => x.Item2 == ResourceType.Manifest).Select(x => x.Item1).FirstOrDefault();

            // Ensure files exists for the appwidgetproviders
            CreateAppWidgetProviderFiles(tempFolder, manifestPath, appWidgetProviderCodeFiles);

            // Create system ID's resource
            CreateSystemIdsResource(tempFolder);

            // Run aapt
            var args = new[] {
                                 "p",
                                 "-f",
                                 "-S",
                                 resFolder,
                                 "-M",
                                 GetManifestPath(tempFolder, manifestPath, packageName),
                                 "-I",
                                 baseApkPath,
                                 "-F",
                                 tempApkPath
                             };
            var runner = new ProcessRunner(Locations.Aapt, args);
            var exitCode = runner.Run();
            if (exitCode != 0)
            {
                ProcessAaptErrors(runner.Output, tempFolder, resources);
                return false;
            }

            // Unpack compiled resources to base folder.
            Table resourceTable = null;
            using (var apk = new ApkFile(tempApkPath))
            {
                foreach (var name in apk.FileNames)
                {
                    // Extract
                    var data = apk.Load(name);

                    // Save
                    var path = Path.Combine(baseFolder, name);
                    Directory.CreateDirectory(Path.GetDirectoryName(path));
                    File.WriteAllBytes(path, data);

                    // Is resource table? yes -> load it
                    if (name == "resources.arsc")
                    {
                        resourceTable = new Table(new MemoryStream(data));
                    }
                }
            }

            // Create R.cs
            if (!string.IsNullOrEmpty(generatedCodeFolder))
            {
                var codeBuilder = new CreateResourceIdsCode(resourceTable, resources, valuesResourceProcessor.StyleableDeclarations);
                codeBuilder.Generate(generatedCodeFolder, packageName, generatedCodeNamespace, generatedCodeLanguage, lastModified);
            }

            // Create resource type usage info file
            if (!string.IsNullOrEmpty(resourceTypeUsageInformationPath))
            {
                // Ensure folder exists
                var folder = Path.GetDirectoryName(resourceTypeUsageInformationPath);
                if (!Directory.Exists(folder))
                    Directory.CreateDirectory(folder);

                // Create file
                File.WriteAllLines(resourceTypeUsageInformationPath, layoutProcessor.CustomClassNames);                
            }

            return true;
        }
Пример #8
0
        /// <summary>
        /// Extract resources out of library project references
        /// </summary>
        private void ExtractLibraryProjectResources(string folder, string referencePath, AssemblyResolver resolver)
        {
#if DEBUG
            //Debugger.Launch();
#endif
            var parameters = new ReaderParameters { AssemblyResolver = resolver };
            var assembly = resolver.Load(referencePath, parameters);

            // Go over all LibraryProjectReference attributes.
            foreach (var attr in assembly.CustomAttributes.Where(x => (x.AttributeType.Name == AttributeConstants.LibraryProjectReferenceAttributeName) && (x.AttributeType.Namespace == AttributeConstants.Dot42AttributeNamespace)))
            {
                var libPackageName = (string)attr.ConstructorArguments[0].Value;
                var prefix = libPackageName + ".res.";

                foreach (var resource in assembly.MainModule.Resources.OfType<EmbeddedResource>().Where(x => x.Name.StartsWith(prefix)))
                {
                    var name = resource.Name.Substring(prefix.Length);
                    var parts = name.Split(new[] { '.' }, 2);
                    if (parts.Length == 2)
                    {
                        // Export resource to disk
                        var targetPath = Path.Combine(Path.Combine(folder, parts[0]), parts[1]);
                        var outputFolder = Path.GetDirectoryName(targetPath);
                        if (!Directory.Exists(outputFolder))
                            Directory.CreateDirectory(outputFolder);
                        File.WriteAllBytes(targetPath, resource.GetResourceData());

                        // Post process
                        var xmlName = parts[0].Split(new[] { '-' }, 2)[0];
                        var resourceType = ResourceExtensions.GetResourceTypeFromXmlName(xmlName);
                        ProcessResource(targetPath, resourceType);
                    }
                }
            }
        }