/// <summary> /// Parse a signature containing a single ClassTypeSignature. /// </summary> private static TypeReference ParseClassTypeSignature(string signature, ref int index) { var code = signature[index++]; if (code != 'L') { throw new InvalidSignatureException(signature); } // Object class var end = signature.IndexOfAny(new[] { '.', '<', ';' }, index); if (end < 0) { throw new InvalidDescriptorException(signature); } var name = signature.Substring(index, end - index); index = end; List <TypeArgument> arguments = null; if (signature[index] == '<') { // Add type arguments arguments = ParseTypeArguments(signature, ref index); } var result = new ObjectTypeReference(name, arguments); // Parse suffixes while (signature[index] == '.') { index++; end = signature.IndexOfAny(new[] { '.', '<', ';' }, index); if (end < 0) { throw new InvalidDescriptorException(signature); } var identifier = signature.Substring(index, end - index); index = end; arguments = null; if (signature[index] == '<') { arguments = ParseTypeArguments(signature, ref index); } name = name + "$" + identifier; result = new ObjectTypeReference(name, arguments, result); } // ';' expected if (signature[index] != ';') { throw new InvalidSignatureException(signature); } index++; return(result); }
/// <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)); }
public override void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage) { if (_baseFieldBuilder.dfield == null) return; // can't create udater for static fields. if (field.IsStatic) return; var updaterType = GetAtomicFieldUpdaterType(field.FieldType); if (updaterType == null) return; var fullUpdateTypeName = "Java.Util.Concurrent.Atomic." + updaterType; // create matching xField. Note: this seems to be a hack. what to do? var objType = new ObjectTypeReference(fullUpdateTypeName, new TypeArgument[0]); var javaTypeReference = new XBuilder.JavaTypeReference(Compiler.Module, objType, objType.ClassName); var basexField = _baseFieldBuilder.xField; var basedField = _baseFieldBuilder.dfield; var fieldName = basedField.Name + NameConstants.Atomic.FieldUpdaterPostfix; var xflags = XSyntheticFieldFlags.Static | XSyntheticFieldFlags.ReadOnly; if (basedField.IsProtected) xflags |= XSyntheticFieldFlags.Protected; if (basedField.IsPrivate) xflags |= XSyntheticFieldFlags.Private; var xAtomicField = XSyntheticFieldDefinition.Create(basexField.DeclaringType, xflags, fieldName, javaTypeReference); xField = xAtomicField; // create dfield. dfield = new DexLib.FieldDefinition { Name = fieldName, IsStatic = true, IsFinal = true, IsSynthetic = true, // same access as the original field. IsPublic = basedField.IsPublic, IsPrivate = basedField.IsPrivate, IsProtected = basedField.IsProtected, }; AddFieldToDeclaringClass(declaringClass, dfield, targetPackage); targetPackage.NameConverter.Record(xField, dfield); }
/// <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> /// Default ctor /// </summary> public ObjectTypeReference(string className, IEnumerable<TypeArgument> arguments, ObjectTypeReference prefix = null) { this.className = className; this.prefix = prefix; this.arguments = (arguments != null) ? arguments.ToList() : null; }
/// <summary> /// Default ctor /// </summary> public ObjectTypeReference(string className, IEnumerable <TypeArgument> arguments, ObjectTypeReference prefix = null) { this.className = className; this.prefix = prefix; this.arguments = (arguments != null) ? arguments.ToList() : null; }
/// <summary> /// Gets a mapping /// </summary> public bool TryGetType(ObjectTypeReference javaTypeRef, TargetFramework target, IBuilderGenericContext gcontext, out NetTypeReference result) { NetTypeDefinition typeDef; if (TryGetByJavaClassName(javaTypeRef.ClassName, out typeDef)) { // Custom /*if (typeDef.FullName.StartsWith("System.Type")) { }*/ // Create result if (!javaTypeRef.Arguments.Any() && (typeDef.GenericParameters.Count == 0)) { // Normal non-generic type result = typeDef; return true; } if (typeDef.IgnoreGenericArguments) { // Force use as normal type result = typeDef; return true; } // Generic type is used as non-generic? NetTypeReference declaringType = null; if (javaTypeRef.Prefix != null) { TryGetType(javaTypeRef.Prefix, target, gcontext, out declaringType); } var git = new NetGenericInstanceType(typeDef, declaringType); if (!javaTypeRef.Arguments.Any() && (typeDef.GenericParameters.Count > 0)) { // Add "object" arguments foreach (var tp in typeDef.GenericParameters) { git.AddGenericArgument(Object, this); } result = git; return true; } if (javaTypeRef.Arguments.Count() != typeDef.GenericParameters.Count) { if ((resolver == null) || (typeDef.GenericParameters.Count != 0) || (!resolver.AcceptLackOfGenericParameters)) { throw new ArgumentException(string.Format("Mismatch between generic parameter count and generic argument count in {0}", javaTypeRef)); } if ((resolver != null) && (resolver.AcceptLackOfGenericParameters) && (typeDef.GenericParameters.Count == 0)) { result = typeDef; return true; } } // Type with generic arguments foreach (var typeArg in javaTypeRef.Arguments) { NetTypeReference arg; if (typeArg.IsAny) { arg = Object; } else { if (!typeArg.Signature.TryResolve(target, gcontext, false, out arg)) { arg = Object; //result = null; //return false; } } git.AddGenericArgument(arg, this); } result = git; return true; } #if DEBUG var names = map.Keys.OrderBy(x => x).ToArray(); #endif //throw new ArgumentException(string.Format("{0} not found", javaTypeRef)); result = null; return false; }
/// <summary> /// Default ctor /// </summary> public JavaTypeReference(XModule module, ObjectTypeReference type, string javaClassName) : base(module, false, null) { this.type = type; this.javaClassName = javaClassName; }
/// <summary> /// Create the method in the given type /// </summary> public void Create(NetTypeDefinition declaringType, TargetFramework target) { try { // Do not add private methods if (javaMethod.IsPrivate) { if (javaMethod.Name != "<init>") { return; } } // Do not add useless bridges methods if (javaMethod.IsBridge) { var targetMethod = javaMethod.DeclaringClass.Methods.FirstOrDefault(x => javaMethod.IsBridgeFor(x)); /*if (javaMethod.DeclaringClass.Methods.Any(x => (x != javaMethod) && (x.Name == javaMethod.Name) && (x.Parameters.Count == javaMethod.Parameters.Count) && (x.Descriptor != javaMethod.Descriptor)))*/ if (targetMethod != null) { if (!(targetMethod.IsAbstract && !javaMethod.IsAbstract)) { return; } } } // We're using a dummy return type first. // Otherwise we cannot resolve generic return types. var signature = javaMethod.Signature; var nameInfo = declaringTypeBuilder.GetMethodName(javaMethod); var name = nameInfo.Name; if (nameInfo.IsConstructor) { method = new NetMethodDefinition(".ctor", javaMethod, declaringType, target, convertSignedBytes, "MethodBuilder.Create") { AccessFlags = (int) javaMethod.AccessFlags, EditorBrowsableState = nameInfo.EditorBrowsableState }; } else if (nameInfo.IsDeconstructor) { method = new NetMethodDefinition("Finalize", javaMethod, declaringType, target, convertSignedBytes, "MethodBuilder.Create") { AccessFlags = (int) javaMethod.AccessFlags, EditorBrowsableState = EditorBrowsableState.Always, IsDeconstructor = true }; } else { method = new NetMethodDefinition(name, javaMethod, declaringType, target, convertSignedBytes, "MethodBuilder.Create") { AccessFlags = (int) javaMethod.AccessFlags, EditorBrowsableState = nameInfo.EditorBrowsableState }; foreach (var typeParam in signature.TypeParameters) { method.GenericParameters.Add( new NetGenericParameter( TypeBuilder.GetMethodGenericParameterName(declaringType, typeParam.Name), typeParam.Name, method)); } var javaReturnType = signature.ReturnType; NetTypeReference returnType; if (!javaReturnType.TryResolve(target, this, convertSignedBytes, out returnType)) { method = null; return; } method.ReturnType = returnType; } method.OriginalJavaName = javaMethod.Name; // Find documentation var docClass = declaringTypeBuilder.Documentation; if (docClass != null) { // Look for matches by name and parameter count first. // If there is more then 1 match, we look to the parameter types. var model = target.XmlModel; var matches = docClass.Methods.Where(x => Matches(x, false, model)).ToList(); if (matches.Count == 1) { docMethod = matches[0]; } else if (matches.Count > 0) { docMethod = matches.FirstOrDefault(x => Matches(x, true, model)); } } method.Attributes = declaringTypeBuilder.GetMethodAttributes(javaMethod, GetAttributes(declaringType, method, javaMethod, name, target.TypeNameMap)); var paramIndex = 0; foreach (var iterator in signature.Parameters) { var paramType = iterator; if (paramType.IsJavaLangVoid()) { paramType = new ObjectTypeReference("java/lang/Object", null); } NetTypeReference resolvedParamType; if (!paramType.TryResolve(target, this, convertSignedBytes, out resolvedParamType)) { method = null; return; // Sometimes public methods used parameters with internal types } var docParam = (docMethod != null) ? docMethod.Parameters.ElementAtOrDefault(method.Parameters.Count) : null; var paramName = MakeParameterNameUnique(CreateParameterName(resolvedParamType, docParam, target), method); var isParams = javaMethod.IsVarArgs && (paramIndex == signature.Parameters.Count - 1); method.Parameters.Add(new NetParameterDefinition(paramName, resolvedParamType, isParams)); paramIndex++; } method.Description = (docMethod != null) ? docMethod.Description : null; declaringType.Methods.Add(method); if (!convertSignedBytes) { target.MethodMap.Add(javaMethod, method); } } catch (ClassNotFoundException ex) { Console.WriteLine("Class {0} not found in {1}", ex.ClassName, javaMethod.Descriptor); method = null; } }
/// <summary> /// Convert an Java type reference to an XTypeReference. /// </summary> public static XTypeReference AsTypeReference(XModule module, string className, XTypeUsageFlags usageFlags) { var objectType = new ObjectTypeReference(className, null); return AsTypeReference(module, objectType, usageFlags); }
/// <summary> /// Convert an Java type reference to an XTypeReference. /// </summary> public static XTypeReference AsTypeReference(XModule module, ClassFile classFile, XTypeUsageFlags usageFlags) { if (classFile == null) return null; var objectType = new ObjectTypeReference(classFile.ClassName, null); return AsTypeReference(module, objectType, usageFlags); }
/// <summary> /// Parse a signature containing a single ClassTypeSignature. /// </summary> private static TypeReference ParseClassTypeSignature(string signature, ref int index) { var code = signature[index++]; if (code != 'L') { throw new InvalidSignatureException(signature); } // Object class var end = signature.IndexOfAny(new[] { '.', '<', ';' }, index); if (end < 0) throw new InvalidDescriptorException(signature); var name = signature.Substring(index, end - index); index = end; List<TypeArgument> arguments = null; if (signature[index] == '<') { // Add type arguments arguments = ParseTypeArguments(signature, ref index); } var result = new ObjectTypeReference(name, arguments); // Parse suffixes while (signature[index] == '.') { index++; end = signature.IndexOfAny(new[] { '.', '<', ';' }, index); if (end < 0) throw new InvalidDescriptorException(signature); var identifier = signature.Substring(index, end - index); index = end; arguments = null; if (signature[index] == '<') { arguments = ParseTypeArguments(signature, ref index); } name = name + "$" + identifier; result = new ObjectTypeReference(name, arguments, result); } // ';' expected if (signature[index] != ';') throw new InvalidSignatureException(signature); index++; return result; }