예제 #1
0
        public void ManualRegistrationTest()
        {
            Assert.AreEqual(false, RuntimeClass.GetAllClasses().Any(x => x.Name == Runtime.GetExportedClassName <ManualRegisteredClass>()));

            Assert.AreEqual(false, Runtime.IsClassExportedByRuntime(Runtime.GetExportedClass <ManualRegisteredClass>()));
            Runtime.ExportClass(typeof(ManualRegisteredClass));
            Assert.AreEqual(true, Runtime.IsClassExportedByRuntime(Runtime.GetExportedClass <ManualRegisteredClass>()));

            var proxy = Runtime.CreateInstance <ManualRegisteredClass>("init");
        }
예제 #2
0
        public static void Dump(string profileName)
        {
            if (!ProxyBuilder.IsRunningOnMacintosh)
            {
                return;
            }

            // load classes from specified frameworks
            foreach (var setting in Settings.Frameworks)
            {
                setting.Path = setting.Path ?? string.Format("/System/Library/Frameworks/{0}.framework/{0}", setting.Name);

                Console.WriteLine("Loading library {0}..", setting.Path);

                NativeMethods.dlopen(setting.Path, 0x1);
            }

            var result = new ObjectiveCRuntimeInfo {
                OSVersion = Runtime.Version.ToString()
            };
            var libraries = new Dictionary <string, ObjectiveCRuntimeInfo.LibraryInfo>();

            var dumpedMethods = new HashSet <string>();

            Action <string> createLibary = (libraryName) =>
            {
                if (!libraries.ContainsKey(libraryName))
                {
                    libraries[libraryName]      = new ObjectiveCRuntimeInfo.LibraryInfo();
                    libraries[libraryName].Path = libraryName;
                }
            };

            foreach (var @class in RuntimeClass.GetAllClasses())
            {
                var className = @class.Name;

                if (!ClassExcludeFilters.All(x => !x.IsMatch(className)) || !ClassIncludeFilters.Any(x => x.IsMatch(className)))
                {
                    continue;
                }

                if (Runtime.IsInternalProxyClass(@class))
                {
                    continue;
                }

                var classSetting = new ObjectiveCRuntimeInfo.ClassInfo {
                    Name = className
                };

                var libraryName = @class.DeclaringImage;

                // for generated classes
                if (libraryName == null)
                {
                    var baseImage = "/usr/lib/libobjc.A.dylib";

                    foreach (var item in @class.BaseClass.BaseHierarchy)
                    {
                        if (item.DeclaringImage == null)
                        {
                            continue;
                        }

                        baseImage = item.DeclaringImage;
                        break;
                    }
                    libraryName = baseImage;
                }

                createLibary(libraryName);

                if (@class.BaseClass != RuntimeClass.Null)
                {
                    classSetting.BaseClassName = @class.BaseClass.Name;
                }

                dumpedMethods.Clear();
                foreach (var method in @class.Methods)
                {
                    var methodName    = method.Name;
                    var methodLibrary = method.DeclaringImage;

                    if (!MethodExcludeFilters.All(x => !x.IsMatch(methodName)) || dumpedMethods.Contains(methodName))
                    {
                        continue;
                    }

                    dumpedMethods.Add(methodName);

                    if (methodLibrary != libraryName)
                    {
                        createLibary(methodLibrary);

                        var extensionsClass = libraries[methodLibrary].Extensions.FirstOrDefault(x => x.Name == className);
                        if (extensionsClass == null)
                        {
                            extensionsClass = new ObjectiveCRuntimeInfo.ClassInfo {
                                Name = className
                            };
                            libraries[methodLibrary].Extensions.Add(extensionsClass);
                        }

                        extensionsClass.InstanceMethods.Add(new ObjectiveCRuntimeInfo.MethodInfo {
                            Name = method.Name, Encoding = method.Encoding
                        });
                        continue;
                    }

                    classSetting.InstanceMethods.Add(new ObjectiveCRuntimeInfo.MethodInfo {
                        Name = method.Name, Encoding = method.Encoding
                    });
                }

                foreach (var property in @class.Properties)
                {
                    classSetting.Properties = classSetting.Properties ?? new List <ObjectiveCRuntimeInfo.PropertyInfo>();
                    classSetting.Properties.Add(new ObjectiveCRuntimeInfo.PropertyInfo {
                        Name = property.Name, Encoding = property.Attributes
                    });
                }

                dumpedMethods.Clear();
                foreach (var method in @class.MetaClass.Methods)
                {
                    var methodName    = method.Name;
                    var methodLibrary = method.DeclaringImage;

                    if (!MethodExcludeFilters.All(x => !x.IsMatch(methodName)) || dumpedMethods.Contains(methodName))
                    {
                        continue;
                    }

                    dumpedMethods.Add(methodName);

                    if (methodLibrary != libraryName)
                    {
                        createLibary(methodLibrary);

                        var extensionsClass = libraries[methodLibrary].Extensions.FirstOrDefault(x => x.Name == className);
                        if (extensionsClass == null)
                        {
                            extensionsClass = new ObjectiveCRuntimeInfo.ClassInfo {
                                Name = className
                            };
                            libraries[methodLibrary].Extensions.Add(extensionsClass);
                        }

                        extensionsClass.ClassMethods.Add(new ObjectiveCRuntimeInfo.MethodInfo {
                            Name = method.Name, Encoding = method.Encoding
                        });
                        continue;
                    }

                    classSetting.ClassMethods.Add(new ObjectiveCRuntimeInfo.MethodInfo {
                        Name = methodName, Encoding = method.Encoding
                    });
                }

                libraries[libraryName].Classes.Add(classSetting);
            }

            result.Libraries = libraries.Select(x => x.Value).OrderBy(x => x.Path).ToList();

            foreach (var library in result.Libraries)
            {
                library.Classes = library.Classes.OrderBy(x => x.Name).ToList();

                foreach (var @class in library.Classes)
                {
                    @class.ClassMethods    = @class.ClassMethods.OrderBy(x => x.Name).ToList();
                    @class.InstanceMethods = @class.InstanceMethods.OrderBy(x => x.Name).ToList();

                    if (@class.Properties != null)
                    {
                        @class.Properties = @class.Properties.OrderBy(x => x.Name).ToList();
                    }
                }
            }

            using (var file = new StreamWriter(string.Format(OutputFilename, profileName)))
                new XmlSerializer(result.GetType()).Serialize(file, result);

            Console.WriteLine("Dump information:");
            Console.WriteLine(" {0} libraries", result.Libraries.Count);
            Console.WriteLine(" {0} classes", result.Libraries.Sum(x => x.Classes.Count));
            Console.WriteLine(" {0} methods", result.Libraries.SelectMany(x => x.Classes).Sum(x => x.ClassMethods.Count + x.InstanceMethods.Count));
            Console.WriteLine(" {0} properties", result.Libraries.SelectMany(x => x.Classes).Sum(x => x.Properties == null ? 0 : x.Properties.Count));
        }