/// <summary> /// Default ctor /// </summary> internal MethodRenamer(TargetFramework target) { // Build groups foreach (var method in target.MethodMap.AllMethods.Where(x => !(x.IsStatic || x.IsConstructor))) { if (method.MethodGroup != null) continue; var possibleGroups = method.Overrides.Select(x => x.MethodGroup).Where(x => x != null).Distinct().ToList(); while (possibleGroups.Count > 1) { var sourceIndex = possibleGroups.Count - 1; possibleGroups[0].MergeFrom(possibleGroups[sourceIndex]); possibleGroups.RemoveAt(sourceIndex); } var group = possibleGroups.SingleOrDefault(); if (group == null) { // Create new group group = new MethodGroup(method.Name); groups.Add(group); } // Add method to group group.Add(method); // Add all overrides to group group.AddRange(method.Overrides); } }
/// <summary> /// Implement members and setup references now that all types have been created /// </summary> public override void Implement(TargetFramework target) { base.Implement(target); TypeDefinition.IsStruct = true; //var field = new NetFieldDefinition { FieldType = GetValueType(target), Name = "m_value", Attributes = FieldAttributes.Private }; //TypeDefinition.Fields.Add(field); }
/// <summary> /// Called in the finalize phase of the type builder. /// </summary> public void Finalize(TargetFramework target, MethodRenamer methodRenamer) { FixOverridenProperties(methodRenamer, target); RemoveDuplicateProperties(); RemoveClashingProperties(); FixPropertyFinalState(); }
/// <summary> /// Resolve the given java based type reference to a Cecil based type reference. /// </summary> internal static NetTypeReference Resolve(this TypeReference jRef, TargetFramework target, IBuilderGenericContext gcontext, bool convertSignedBytes) { NetTypeReference result; if (TryResolve(jRef, target, gcontext, convertSignedBytes, out result)) return result; throw new ArgumentException(string.Format("Unknown java type ref. {0}", jRef)); }
/// <summary> /// Implement members and setup references now that all types have been created /// </summary> public override void Implement(TargetFramework target) { base.Implement(target); TypeDefinition.IsStruct = true; //TypeDefinition.ClassSize = 1; //TypeDefinition.PackingSize = 0; }
/// <summary> /// Gets a mapping /// </summary> public NetTypeReference GetType(ObjectTypeReference javaTypeRef, TargetFramework target, IBuilderGenericContext gcontext) { NetTypeReference result; if (TryGetType(javaTypeRef, target, gcontext, out result)) return result; //var names = map.Keys.OrderBy(x => x).ToArray(); throw new ArgumentException(string.Format("{0} not found", javaTypeRef)); }
/// <summary> /// Should the given method be implemented? /// </summary> protected override bool ShouldImplement(MethodDefinition method, TargetFramework target) { if (method.Name == "getLong") { if (method.Descriptor == "(Ljava/lang/String;Ljava/lang/Long;)Ljava/lang/Long;") return false; } return base.ShouldImplement(method, target); }
/// <summary> /// Update names where needed /// </summary> public override void FinalizeNames(TargetFramework target, MethodRenamer methodRenamer) { // Make sure there is no name class with other members var prefix = "Java"; var postfix = 0; while ((typeDef.DeclaringType != null) && (typeDef.DeclaringType.Methods.Any(x => x.Name == typeDef.Name))) { typeDef.Name = prefix + typeDef.Name; if (postfix > 0) typeDef.Name += postfix; prefix = ""; postfix++; } FinalizeNames(typeDef, target, methodRenamer); }
/// <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); }
/// <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> /// Resolve the given java based type reference to a Cecil based type reference. /// </summary> internal static bool TryResolve(this TypeReference jRef, TargetFramework target, IBuilderGenericContext gcontext, bool convertSignedBytes, out NetTypeReference result) { result = null; if (jRef.IsArray) { var aType = (ArrayTypeReference) jRef; NetTypeReference elementType; if (!aType.ElementType.TryResolve(target, gcontext, convertSignedBytes, out elementType)) return false; result = new NetArrayType(elementType); return true; } if (jRef.IsVoid) { result = target.TypeNameMap.GetByType(typeof(void)); return true; } if (jRef.IsBaseType) { var bType = (BaseTypeReference) jRef; result = target.TypeNameMap.GetByType(bType.GetClrType(convertSignedBytes)); return true; } if (jRef.IsObjectType) { return TryResolveObjectType((ObjectTypeReference) jRef, target, gcontext, out result); } if (jRef.IsTypeVariable) { var tRef = (TypeVariableReference) jRef; if (gcontext.TryResolveTypeParameter(tRef.ClassName, target, out result)) return true; result = target.TypeNameMap.Object; // Hack for incorrect behaving java classes return true; } return false; //throw new ArgumentException(string.Format("Unknown java type ref. {0}", jRef)); }
/// <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> /// Resolve the given java based type reference to a Cecil based type reference. /// </summary> private static bool TryResolveObjectType(ObjectTypeReference jRef, TargetFramework target, IBuilderGenericContext gcontext, out NetTypeReference result) { var objecType = jRef; switch (objecType.ClassName) { case "java/lang/Exception": case "java/lang/Throwable": result = target.TypeNameMap.GetByType(typeof(Exception)); return true; case "java/lang/Boolean": case "java/lang/Byte": case "java/lang/Character": case "java/lang/Double": case "java/lang/Float": case "java/lang/Integer": case "java/lang/Long": case "java/lang/Short": result = new NetNullableType(target.TypeNameMap.GetType(objecType, target, gcontext)); return true; default: return target.TypeNameMap.TryGetType(objecType, target, gcontext, out result); } }
/// <summary> /// Create a type defrinition for the given class file and all inner classes. /// </summary> public override void CreateType(NetTypeDefinition declaringType, NetModule module, TargetFramework target) { if (declaringType == null) throw new ArgumentNullException("declaringType"); docClass = target.GetXmlClass(cf); var name = NameConverter.UpperCamelCase(inner.IsAnonymous ? cf.Name : inner.Name); name = CreateTypeName(declaringType, cf, name, null); var finalFullName = parentFullName + "/" + name; var attributes = GetAttributes(cf); typeDef = new NetTypeDefinition(cf, target, module.Scope) { Name = name, Attributes = attributes }; typeDef.OriginalJavaClassName = cf.ClassName; typeDef.Description = (docClass != null) ? docClass.Description : null; parent.AddNestedType(typeDef, "", module, ref finalFullName); // Prepare generics CreateGenericParameters(cf, typeDef); // Add mapping RegisterType(target, cf, typeDef); CreateNestedTypes(cf, typeDef, finalFullName, module, target); }
/// <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> /// Resolve the given generic parameter into a type reference. /// </summary> protected override bool TryResolveTypeParameter(string name, TargetFramework target, out NetTypeReference type) { if (!AddGenericParameters) { if (cf.Signature.TypeParameters.Any(x => x.Name == name)) { type = target.TypeNameMap.Object; return true; } } var result = typeDef.GenericParameters.FirstOrDefault(x => x.Name == name); if (result != null) { type = result; return true; } // This is a hack for non-behaving java classes type = target.TypeNameMap.Object; return false; }
/// <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> /// Should the given field be implemented? /// </summary> protected internal override bool ShouldImplement(FieldDefinition field, TargetFramework target) { if (cf.IsInterface) return false; return base.ShouldImplement(field, target); }
/// <summary> /// Implement members and setup references now that all types have been created /// </summary> public override void Implement(TargetFramework target) { Implement(cf, typeDef, cf.IsEnum(), (this is IInterfaceConstantsTypeBuilder), target); base.Implement(target); }
/// <summary> /// Gets the type of the value field /// </summary> protected virtual NetTypeReference GetValueType(TargetFramework target) { return target.TypeNameMap.GetByJavaClassName(ClassName); }
/// <summary> /// Create the field in the given type /// </summary> public void Create(NetTypeDefinition declaringType, TargetFramework target) { // Do not add private fields if ((javaField.AccessFlags & FieldAccessFlags.Private) != 0) return; // Find documentation var docClass = declaringTypeBuilder.Documentation; docField = (docClass != null) ? docClass.Fields.FirstOrDefault(x => x.Name == javaField.Name) : null; //var fieldType = declaringType.IsEnum ? target.TypeNameMap.GetByType(typeof(int)) : javaField.Signature.Resolve(target, declaringTypeBuilder); NetTypeReference fieldType; if (!javaField.Signature.TryResolve(target, declaringTypeBuilder, false, out fieldType)) return; //var fieldTypeIsValueType = declaringType.IsEnum ? true : javaField.FieldType. var name = declaringTypeBuilder.GetFieldName(javaField); field = new NetFieldDefinition(); field.Name = name; field.OriginalJavaName = javaField.Name; field.FieldType = fieldType; field.Attributes = GetAttributes(javaField, false); field.Description = (docField != null) ? docField.Description : null; declaringType.Fields.Add(field); }
/// <summary> /// Implement interface members /// </summary> public override void Finalize(TargetFramework target, FinalizeStates state) { Finalize(typeDef, target, state); base.Finalize(target, state); }
/// <summary> /// Create a type definition for the given class file and all inner classes. /// </summary> public override void CreateType(NetTypeDefinition declaringType, NetModule module, TargetFramework target) { if (declaringType != null) throw new ArgumentException("Declaring type should be null"); docClass = target.GetXmlClass(cf); var fullName = GetFullName(); var dotIndex = fullName.LastIndexOf('.'); var ns = (dotIndex > 0) ? ConvertNamespace(fullName, dotIndex) : String.Empty; var name = (dotIndex > 0) ? NameConverter.UpperCamelCase(fullName.Substring(dotIndex + 1)) : fullName; name = CreateTypeName(null, cf, name, ns); typeDef = new NetTypeDefinition(cf, target, module.Scope); typeDef.Name = name; typeDef.Namespace = ns; typeDef.OriginalJavaClassName = cf.ClassName; typeDef.Attributes = GetAttributes(cf, cf.Fields.Any()); typeDef.IgnoreGenericArguments = !AddGenericParameters; typeDef.Description = (docClass != null) ? docClass.Description : null; module.Types.Add(typeDef); // Prepare generics CreateGenericParameters(cf, typeDef); // Add mapping var finalFullName = string.IsNullOrEmpty(ns) ? name : ns + "." + name; RegisterType(target, cf, typeDef); CreateNestedTypes(cf, typeDef, finalFullName, module, target); }
/// <summary> /// Implement members and setup references now that all types have been created /// </summary> public override void Implement(TargetFramework target) { TypeDefinition.IsStruct = true; base.Implement(target); }
protected override bool ShouldImplement(MethodDefinition method, TargetFramework target) { if (method.Name == "clone") return false; return base.ShouldImplement(method, target); }
/// <summary> /// Called in the finalize phase of the type builder. /// </summary> public void Finalize(TargetFramework target, FinalizeStates state) { if (field == null) return; if (state == FinalizeStates.FixTypes) { field.EnsureVisibility(); field.LimitVisibility(); } }
/// <summary> /// Update names where needed /// </summary> public override void FinalizeNames(TargetFramework target, MethodRenamer methodRenamer) { FinalizeNames(typeDef, target, methodRenamer); }
/// <summary> /// Make sure that base types are visible. /// </summary> public override void FinalizeVisibility(TargetFramework target) { typeDef.EnsureVisibility(); }
/// <summary> /// Gets the type of the value field /// </summary> protected override NetTypeReference GetValueType(TargetFramework target) { return target.TypeNameMap.GetByType(typeof(IntPtr)); }
/// <summary> /// Fix base type relations. /// </summary> protected override void FixBaseType(NetTypeDefinition typeDef, TargetFramework target) { if ((typeDef.BaseType != null) && (typeDef.BaseType.FullName == "Java.Lang.Number")) typeDef.BaseType = null; base.FixBaseType(typeDef, target); }