public static JavaTypeCollection Parse(AssemblyDefinition assembly, JavaTypeCollection collection) { var types_to_add = new List <JavaTypeModel> (); foreach (var md in assembly.Modules) { foreach (var td in md.Types) { if (!ShouldSkipType(td) && ParseType(td, collection) is JavaTypeModel type) { types_to_add.Add(type); } } } // This needs to be done ordered from least nested to most nested, in order for nesting to work. // That is, 'android.foo.Blah' needs to be added before 'android.foo.Blah.Bar'. // Plus, we may have unnested managed types that are actually nested in Java-land: // ex: IContextMenu and IContextMenuContextMenuItem foreach (var type in types_to_add.OrderBy(t => t.FullName.Count(c => c == '.')).ToArray()) { AddReferenceTypeRecursive(type, collection); } return(collection); }
public static JavaTypeModel?ParseType(TypeDefinition type, JavaTypeCollection collection) { if (!type.IsPublic && !type.IsNested) { return(null); } if (!ShouldImport(type)) { return(null); } var model = type.IsInterface ? (JavaTypeModel?)ParseInterface(type, collection) : ParseClass(type, collection); if (model is null) { return(null); } foreach (var nested in type.NestedTypes) { if (ParseType(nested, collection) is JavaTypeModel nested_model) { model.NestedTypes.Add(nested_model); } } return(model); }
static void AddReferenceTypeRecursive(JavaTypeModel type, JavaTypeCollection collection) { collection.AddReferencedType(type); foreach (var nested in type.NestedTypes) { AddReferenceTypeRecursive(nested, collection); } }
public static void Save(JavaTypeCollection types, string xmlFile) { using (var writer = XmlWriter.Create(xmlFile, new XmlWriterSettings { Encoding = new UTF8Encoding(false, true), Indent = true, OmitXmlDeclaration = true, })) Save(types, writer); }
public static void Save(JavaTypeCollection types, XmlWriter writer) { writer.WriteStartElement("api"); if (types.Platform.HasValue()) { writer.WriteAttributeString("platform", types.Platform); } writer.WriteAttributeString("api-source", "JavaTypeSystem"); foreach (var pkg in types.Packages.Values) { if (!pkg.Types.Any(t => !t.IsReferencedOnly)) { continue; } writer.WriteStartElement("package"); writer.WriteAttributeString("name", pkg.Name); if (pkg.PropertyBag.TryGetValue("merge.SourceFile", out var source)) { writer.WriteAttributeString("merge.SourceFile", source); } if (!string.IsNullOrEmpty(pkg.JniName)) { writer.WriteAttributeString("jni-name", pkg.JniName); } foreach (var type in pkg.Types) { if (type.IsReferencedOnly) { continue; // skip reference only types } SaveType(type, writer); } WriteFullEndElement(writer); } WriteFullEndElement(writer); }
public static JavaClassModel?ParseClass(TypeDefinition type, JavaTypeCollection collection) { // TODO: type parameters? var obs_attr = GetObsoleteAttribute(type.CustomAttributes); var reg_attr = GetRegisterAttribute(type.CustomAttributes); if (reg_attr is null) { return(null); } var encoded_fullname = ((string)reg_attr.ConstructorArguments [0].Value).Replace('/', '.'); var(package, nested_name) = DecodeRegisterJavaFullName(encoded_fullname); var base_jni = GetBaseTypeJni(type); var model = new JavaClassModel( javaPackage: GetOrCreatePackage(collection, package, type.Namespace), javaNestedName: nested_name, javaVisibility: type.IsPublic || type.IsNestedPublic ? "public" : "protected internal", javaAbstract: type.IsAbstract, javaFinal: type.IsSealed, javaBaseType: base_jni.Replace('/', '.').Replace('$', '.'), javaBaseTypeGeneric: base_jni.Replace('/', '.').Replace('$', '.'), javaDeprecated: obs_attr != null ? "deprecated" : "not-deprecated", javaStatic: false, jniSignature: FormatJniSignature(package, nested_name), baseTypeJni: base_jni.HasValue() ? $"L{base_jni};" : string.Empty );; ParseImplementedInterfaces(type, model); foreach (var method in type.Methods.Where(m => !m.IsConstructor)) { if (ParseMethod(method, model) is JavaMethodModel m) { model.Methods.Add(m); } } return(model); }
public static JavaPackage ParsePackage(XElement package, JavaTypeCollection collection) { var pkg = collection.AddPackage( name: package.XGetAttribute("name"), jniName: package.XGetAttribute("jni-name"), managedName: package.XGetAttributeOrNull("managedName") ); if (package.XGetAttribute("merge.SourceFile") is string source && source.HasValue()) { pkg.PropertyBag.Add("merge.SourceFile", source); } foreach (var elem in package.Elements()) { switch (elem.Name.LocalName) { case "class": if (elem.XGetAttributeAsBool("obfuscated")) { continue; } pkg.Types.Add(ParseClass(pkg, elem)); break; case "interface": if (elem.XGetAttributeAsBool("obfuscated")) { continue; } pkg.Types.Add(ParseInterface(pkg, elem)); break; } } return(pkg); }
public static JavaInterfaceModel?ParseInterface(TypeDefinition type, JavaTypeCollection collection) { // TODO: type paramters? var obs_attr = GetObsoleteAttribute(type.CustomAttributes); var reg_attr = GetRegisterAttribute(type.CustomAttributes); if (reg_attr is null) { return(null); } var encoded_fullname = ((string)reg_attr.ConstructorArguments [0].Value); var(package, nested_name) = DecodeRegisterJavaFullName(encoded_fullname); var model = new JavaInterfaceModel( javaPackage: GetOrCreatePackage(collection, package, type.Namespace), javaNestedName: nested_name, javaVisibility: type.IsPublic || type.IsNestedPublic ? "public" : "protected internal", javaDeprecated: obs_attr != null ? "deprecated" : "not-deprecated", javaStatic: false, jniSignature: FormatJniSignature(package, nested_name) ); ParseImplementedInterfaces(type, model); foreach (var method in type.Methods) { if (ParseMethod(method, model) is JavaMethodModel m) { model.Methods.Add(m); } } return(model); }
public void SetupFixture() { api = JavaApiTestHelper.GetLoadedApi(); }
public void SetupFixture() { api = JavaApiTestHelper.GetLoadedApi(); api.ResolveCollection(); }