/// <summary> /// Mark all eachable items in argument as such. /// </summary> private static void Walk(ReachableContext context, ClassFile classFile) { // Mark owner classFile.DeclaringClass.MarkReachable(context); // Mark base class classFile.SuperClass.MarkReachable(context); // Mark interfaces if (classFile.Interfaces != null) { foreach (var intf in classFile.Interfaces) { intf.MarkReachable(context); } } // Mark class ctor classFile.Methods.FirstOrDefault(x => x.Name == "<clinit>").MarkReachable(context); // Mark methods of imported classes reachable if (classFile.IsCreatedByLoader) { classFile.Methods.Where(x => x.IsPublic || x.IsProtected).ForEach(x => x.MarkReachable(context)); } // If this is a class that does not have an imported C# wrapper, be safe and include everything from this class. if (!context.HasDexImport(classFile)) { context.MarkAsRoot(classFile); } // Record in context context.RecordReachableType(classFile); }
/// <summary> /// Default ctor /// </summary> protected NestedTypeBuilder(TypeBuilder parent, string parentFullName, ClassFile cf, InnerClass inner) { this.parent = parent; this.parentFullName = parentFullName; this.cf = cf; this.inner = inner; }
protected override Model.NetCustomAttribute CreateDexImportAttribute(ClassFile cf) { var ca = base.CreateDexImportAttribute(cf); ca.Properties.Add(AttributeConstants.DexImportAttributeIgnoreFromJavaName, true); ca.Properties.Add(AttributeConstants.DexImportAttributePriority, 1); return ca; }
/// <summary> /// Load a class by the given name. /// </summary> public bool TryLoadClass(string className, out ClassFile result) { #if DEBUG //Debugger.Launch(); #endif lock (dataLock) { foreach (var assemblyClasses in loadedAssemblies) { JavaClass jClass; if (assemblyClasses.TryGetJavaClass(className, out jClass)) if (jClass != null) { result = jClass.Resolve(this, classLoaded); return (result != null); } DexImport dexImport; if (assemblyClasses.TryGetDexImport(className, out dexImport)) { result = dexImport.Resolve(this, classLoaded, null); return (result != null); } } result = null; return false; } }
/// <summary> /// The given type has been made reachable. /// </summary> /// <returns>True if the class was marked reachable, false otherwise</returns> internal bool IncludeIfNeeded(ReachableContext context, ClassFile javaClass) { if (javaClass.IsReachable) return true; // Already included if (className == null) return false; if (instanceOfCondition.IsInterface) { // Check implements if (Implements(context, javaClass)) { javaClass.MarkReachable(context); return true; } } else { // Check extends if (Extends(javaClass)) { javaClass.MarkReachable(context); return true; } } return false; }
public FieldDefinition(ClassFile cf, FieldAccessFlags accessFlags, string name, string descriptor, string signature) : base(cf, name) { this.accessFlags = accessFlags; this.descriptor = descriptor; fieldType = Descriptors.ParseFieldType(descriptor); Signature = (signature != null) ? Signatures.ParseFieldTypeSignature(signature) : fieldType; }
internal static IEnumerable<NestedTypeBuilder> Create(TypeBuilder parent, string parentFullName, ClassFile cf, InnerClass inner) { if (cf.IsInterface && cf.Fields.Any()) { yield return new NestedInterfaceConstantsTypeBuilder(parent, parentFullName, cf, inner); } yield return new NestedTypeBuilder(parent, parentFullName, cf, inner); }
public MethodDefinition(ClassFile cf, MethodAccessFlags accessFlags, string name, string descriptor, string signature) : base(cf, name) { this.accessFlags = accessFlags; this.descriptor = descriptor; methodDescriptor = Descriptors.ParseMethodDescriptor(descriptor); this.signature = (signature != null) ? Signatures.ParseMethodSignature(signature) : null; }
/// <summary> /// Get's the namespace of the given type after conversion. /// </summary> public string GetConvertedNamespace(ClassFile type) { /*if (type.IsNested) { return GetConvertedNamespace(type.DeclaringType); }*/ return ClassName.JavaClassNameToClrTypeName(type.Package); }
/// <summary> /// Resolve the method into a java method definition. /// </summary> public JavaMethodDefinition Resolve(ClassFile declaringClass) { if (resolved == null) { // Load the class resolved = BuildMethod(declaringClass); } return resolved; }
/// <summary> /// Default ctor /// </summary> public JavaTypeDefinition(XModule module, XTypeDefinition declaringType, ClassFile type) : base(module, declaringType, false, null) { this.type = type; fields = type.Fields.Select(x => new JavaFieldDefinition(this, x)).Cast<XFieldDefinition>().ToList().AsReadOnly(); methods = type.Methods.Select(x => new JavaMethodDefinition(this, x)).Cast<XMethodDefinition>().ToList().AsReadOnly(); nested = type.InnerClasses.Where(x => x.InnerClassFile.DeclaringClass == type).Select(x => new JavaTypeDefinition(module, this, x.InnerClassFile)).Cast<XTypeDefinition>().ToList().AsReadOnly(); interfaces = new List<XTypeReference>(); }
/// <summary> /// Load a class with the given name /// </summary> public bool TryLoadClass(string className, out ClassFile result) { if (loadedClasses.TryGetValue(className, out result)) return true; result = OpenClass(className + ".class"); if (result != null) return true; if (nextClassLoader != null) return nextClassLoader.TryLoadClass(className, out result); return false; }
public AssemblyDefinition GetAssembly(ClassFile classFile) { AssemblyClasses cl; lock(dataLock) cl = loadedAssemblies.SingleOrDefault(c => c.ClassNames.Contains(classFile.ClassName)); if (cl == null) return null; return cl.Assembly; }
/// <summary> /// Create all child nodes /// </summary> protected override void CreateChildNodes() { classDef = Source.OpenClass(FileName); foreach (var field in classDef.Fields.OrderBy(x => x.Name)) { Nodes.Add(new JavaFieldDefinitionNode(field)); } foreach (var method in classDef.Methods.OrderBy(x => x.Name)) { Nodes.Add(new JavaMethodDefinitionNode(method)); } }
/// <summary> /// Try to create a type builder for the given class. /// </summary> internal static bool TryCreateTypeBuilder(ClassFile cf, out TypeBuilder builder) { if (mappedTypeBuilders != null) { IMappedTypeBuilder mappedBuilder; if (mappedTypeBuilders.TryGetValue(cf.ClassName, out mappedBuilder)) { builder = mappedBuilder.Create(cf); return true; } } builder = null; return false; }
/// <summary> /// Resolve the payload into a class file. /// </summary> public ClassFile Resolve(IClassLoader loader, Action<ClassFile> classLoaded) { if (resolved == null) { // Load the class var raw = javaCode.Resolve(loader).GetResource(className + ".class"); resolved = new ClassFile(new MemoryStream(raw), loader); if (classLoaded != null) { classLoaded(resolved); } } return resolved; }
/// <summary> /// Finalize all references now that all types have been created /// </summary> public void Complete(ClassFile declaringClass, TargetFramework target) { if (method == null) return; // Add DexImport attribute var ca = new NetCustomAttribute(null, javaMethod.Name, javaMethod.Descriptor); ca.Properties.Add(AttributeConstants.DexImportAttributeAccessFlagsName, (int)javaMethod.AccessFlags); if (method.HasUnsignedPartner) { ca.Properties.Add(AttributeConstants.DexImportAttributeIgnoreFromJavaName, true); } var signature = (javaMethod.Signature != null) ? javaMethod.Signature.Original : null; if ((signature != null) && (signature != javaMethod.Descriptor)) { ca.Properties.Add(AttributeConstants.DexImportAttributeSignature, signature); } method.CustomAttributes.Add(ca); }
/// <summary> /// Finalize all references now that all types have been created /// </summary> public void Complete(ClassFile declaringClass, TargetFramework target) { if (field == null) return; // Setup field value var cValue = javaField.ConstantValue; // Fixup value if (cValue != null) { if (field.FieldType.IsSingle() && (float.IsPositiveInfinity((float)cValue) || float.IsNegativeInfinity((float)cValue))) cValue = null; if (field.FieldType.IsDouble() && (double.IsPositiveInfinity((double)cValue) || double.IsNegativeInfinity((double)cValue))) cValue = null; } if (cValue != null) { field.DefaultValue = cValue; } else if (field.DeclaringType.IsEnum) { /*field.DefaultValue = field.DeclaringType.Fields.ToList().IndexOf(field); field.Attributes |= FieldAttributes.Literal | FieldAttributes.Static; field.Attributes &= ~FieldAttributes.InitOnly;*/ field.Attributes |= FieldAttributes.InitOnly | FieldAttributes.Static; field.Attributes &= ~FieldAttributes.Literal; } else { field.Attributes &= ~FieldAttributes.Literal; } // Add DexImport attribute var ca = new NetCustomAttribute(null, javaField.Name, javaField.Descriptor); ca.Properties.Add(AttributeConstants.DexImportAttributeAccessFlagsName, (int)javaField.AccessFlags); field.CustomAttributes.Add(ca); }
/// <summary> /// Create a builder /// </summary> public static IEnumerable<TypeBuilder> Create(ClassFile cf, TargetFramework target) { if (!ShouldImplement(cf, target)) yield break; TypeBuilder builder; if (MappedTypeBuilder.TryCreateTypeBuilder(cf, out builder)) { yield return builder; } else { if (cf.IsInterface && cf.Fields.Any()) { yield return new StandardInterfaceConstantsTypeBuilder(cf); } yield return new StandardTypeBuilder(cf); } }
/// <summary> /// Default ctor /// </summary> internal JavaIoEOFExceptionBuilder(ClassFile cf) : base(cf, "System.IO.EndOfStreamException", "java/io/EOFException") { }
/// <summary> /// Gets the class name of the base class relevant for layout.xml. /// </summary> private static string GetLayoutBaseClassName(ClassFile classFile) { while (true) { var className = classFile.ClassName; switch (className) { case SdkConstants.ViewClass: case SdkConstants.ViewGroupClass: return className; case SdkConstants.ObjectClass: return null; } // Go to the base class if (!classFile.TryGetSuperClass(out classFile)) return null; } }
/// <summary> /// Default ctor /// </summary> protected StandardTypeBuilder(ClassFile cf) { this.cf = cf; }
/// <summary> /// Create type attributes /// </summary> protected virtual TypeAttributes GetAttributes(ClassFile cf, bool hasFields) { var result = cf.IsPublic ? TypeAttributes.Public : TypeAttributes.NotPublic; result |= cf.IsInterface ? TypeAttributes.Interface : TypeAttributes.Class; if (cf.IsAbstract) result |= TypeAttributes.Abstract; else if (cf.IsFinal) result |= TypeAttributes.Sealed; return result; }
/// <summary> /// Register the given type in the type map. /// </summary> protected virtual void RegisterType(TargetFramework target, ClassFile classFile, NetTypeDefinition typeDef) { target.TypeNameMap.Add(classFile.ClassName, typeDef); }
/// <summary> /// Read the header /// </summary> internal void ReadHeader(ClassFile cf) { var magic = stream.ReadU4(); if (magic != ClassFile.Magic) { throw new Dot42Exception("Invalid magic"); } cf.MinorVersion = stream.ReadU2(); cf.MajorVersion = stream.ReadU2(); var cpCount = stream.ReadU2(); var cp = new ConstantPool(cpCount, cf.Loader); for (var i = 1; i < cpCount; i++) { var tag = (ConstantPoolTags)stream.ReadU1(); ConstantPoolEntry entry; int tmp; switch (tag) { case ConstantPoolTags.Class: entry = new ConstantPoolClass(cp, stream.ReadU2()); break; case ConstantPoolTags.Fieldref: tmp = stream.ReadU2(); entry = new ConstantPoolFieldRef(cp, tmp, stream.ReadU2()); break; case ConstantPoolTags.Methodref: tmp = stream.ReadU2(); entry = new ConstantPoolMethodRef(cp, tmp, stream.ReadU2()); break; case ConstantPoolTags.InterfaceMethodref: tmp = stream.ReadU2(); entry = new ConstantPoolInterfaceMethodRef(cp, tmp, stream.ReadU2()); break; case ConstantPoolTags.String: entry = new ConstantPoolString(cp, stream.ReadU2()); break; case ConstantPoolTags.Integer: entry = new ConstantPoolInteger(cp, stream.ReadS4()); break; case ConstantPoolTags.Float: entry = new ConstantPoolFloat(cp, stream.ReadF4()); break; case ConstantPoolTags.Long: entry = new ConstantPoolLong(cp, stream.ReadS8()); break; case ConstantPoolTags.Double: entry = new ConstantPoolDouble(cp, stream.ReadF8()); break; case ConstantPoolTags.NameAndType: tmp = stream.ReadU2(); entry = new ConstantPoolNameAndType(cp, tmp, stream.ReadU2()); break; case ConstantPoolTags.Utf8: tmp = stream.ReadU2(); entry = new ConstantPoolUtf8(cp, stream.ReadUTF8(tmp)); break; default: throw new Dot42Exception("Unknown constant pool tag: " + (int)tag); } cp[i] = entry; if ((tag == ConstantPoolTags.Double) || (tag == ConstantPoolTags.Long)) { i++; } } cf.ClassAccessFlags = (ClassAccessFlags)stream.ReadU2(); var index = stream.ReadU2(); cf.ClassName = cp.GetEntry <ConstantPoolClass>(index).Name; index = stream.ReadU2(); cf.SuperClass = (index == 0) ? null : new ObjectTypeReference(cp.GetEntry <ConstantPoolClass>(index).Name, null); // Interfaces var icount = stream.ReadU2(); var interfaces = new string[icount]; for (var i = 0; i < icount; i++) { index = stream.ReadU2(); interfaces[i] = cp.GetEntry <ConstantPoolClass>(index).Name; } cf.Interfaces = interfaces.Select(x => new ObjectTypeReference(x, null)).ToArray(); // Fields var fcount = stream.ReadU2(); for (var i = 0; i < fcount; i++) { var accessFlags = (FieldAccessFlags)stream.ReadU2(); var nameIndex = stream.ReadU2(); var descriptorIndex = stream.ReadU2(); var name = cp.GetEntry <ConstantPoolUtf8>(nameIndex).Value; var descriptor = cp.GetEntry <ConstantPoolUtf8>(descriptorIndex).Value; var field = new FieldDefinition(cf, accessFlags, name, descriptor, null); ReadAttributes(cp, field); cf.Fields.Add(field); } // Methods var mcount = stream.ReadU2(); for (var i = 0; i < mcount; i++) { var accessFlags = (MethodAccessFlags)stream.ReadU2(); var nameIndex = stream.ReadU2(); var descriptorIndex = stream.ReadU2(); var name = cp.GetEntry <ConstantPoolUtf8>(nameIndex).Value; var descriptor = cp.GetEntry <ConstantPoolUtf8>(descriptorIndex).Value; var method = new MethodDefinition(cf, accessFlags, name, descriptor, null); ReadAttributes(cp, method); cf.Methods.Add(method); } // Attributes ReadAttributes(cp, cf); }
/// <summary> /// Default ctor /// </summary> internal JavaLangBooleanBuilder(ClassFile cf) : base(cf, "System.Boolean", "java/lang/Boolean") { }
/// <summary> /// Gets the converted name of the given type. /// </summary> public static string GetConvertedName(ClassFile type) { return ConvertTypeName(type.Name); }
/// <summary> /// Default ctor /// </summary> internal JavaLangNullPointerExceptionBuilder(ClassFile cf) : base(cf, "System.NullReferenceException", "java/lang/NullPointerException") { }
/// <summary> /// Default ctor /// </summary> internal JavaLangOutOfMemoryErrorBuilder(ClassFile cf) : base(cf, "System.OutOfMemoryException", "java/lang/OutOfMemoryError") { }
/// <summary> /// Default ctor /// </summary> protected MemberDefinition(ClassFile cf, string name) { this.cf = cf; this.name = name; }
/// <summary> /// Default ctor /// </summary> internal JavaNetUriBuilder(ClassFile cf) : base(cf, "System.Uri", "java/net/URI") { }
/// <summary> /// Default ctor /// </summary> internal JavaLangMathBuilder(ClassFile cf) : base(cf, "System.Math", "java/lang/Math") { }
/// <summary> /// Is the given class an enum? /// </summary> public static bool IsEnum(this ClassFile cf) { return(cf.IsEnum || ((cf.SuperClass != null) && (cf.SuperClass.ClassName == "java/lang/Enum"))); }