public InterType(TypeReference typeRef, List <InterGenericArgument> genericArgs, IResolver resolver, Func <InterType, bool> register) { this.typeRef = typeRef; genericArgs = genericArgs ?? InterGenericArgument.EmptyGenericArgsList; this.primitiveType = PrimitiveType.None; this.IsArray = typeRef.IsArray; this.IsByRef = typeRef.IsByReference; if (this.IsArray) { this.arrayRank = ((ArrayType)typeRef).Rank; this.dimensions = ((ArrayType)typeRef).Dimensions.ToArray(); } if ((IsArray) || (IsByRef)) { this.elementType = resolver.Resolve(((TypeSpecification)typeRef).ElementType, genericArgs); register(this); return; } if (typeRef.IsGenericParameter) { GenericParameter gp = (GenericParameter)typeRef; register(genericArgs.Where(A => ((A.Position == gp.Position) && (Utils.CecilGenericOwnerToC2JGenericOwner(gp.Type) == A.Owner))).FirstOrDefault().Type); return; } TypeDefinition typeDef = typeRef.Resolve(); CustomAttribute typeMapCustomAttr = typeDef.CustomAttributes.Where(A => A.AttributeType.FullName == ClassNames.TypeMapAttribute).FirstOrDefault(); CustomAttribute javaBoxTypeMapCustomAttr = typeDef.CustomAttributes.Where(A => A.AttributeType.FullName == ClassNames.JavaBoxTypeMapAttribute).FirstOrDefault(); CustomAttribute interfacesMapCustomAttr = typeDef.CustomAttributes.Where(A => A.AttributeType.FullName == ClassNames.InterfacesMapAttribute).FirstOrDefault(); if ((interfacesMapCustomAttr == null) && (Program.BoxType == BoxingType.Java)) { interfacesMapCustomAttr = typeDef.CustomAttributes.Where(A => A.AttributeType.FullName == ClassNames.JavaBoxedInterfacesMapAttribute).FirstOrDefault(); } if ((typeMapCustomAttr == null) && (javaBoxTypeMapCustomAttr != null) && (Program.BoxType == BoxingType.Java)) { typeMapCustomAttr = javaBoxTypeMapCustomAttr; } if (typeMapCustomAttr != null) { InterType realType = resolver.Resolve(typeMapCustomAttr.ConstructorArguments[0].Value as TypeReference, genericArgs); register(realType); if ((interfacesMapCustomAttr != null) && (realType.InterfacesMap == null)) { TypeReference mapRef = interfacesMapCustomAttr.ConstructorArguments[0].Value as TypeReference; TypeDefinition mapDef = mapRef.Resolve(); mapDef.Methods.Where(M => M.Name == ClassNames.InterfacesMapGetAdapterMethodName).ForEach(M => resolver.Resolve(M, genericArgs)); realType.interfacesMap = resolver.Resolve(mapRef, genericArgs); } return; } this.IsPublic = typeDef.IsPublic; this.IsNested = typeDef.IsNested; this.IsNestedPublic = typeDef.IsNestedPublic | typeDef.IsNestedFamilyAndAssembly | typeDef.IsNestedFamilyOrAssembly | typeDef.IsNestedAssembly; this.IsNestedProtected = typeDef.IsNestedFamily | typeDef.IsNestedFamilyAndAssembly | typeDef.IsNestedFamilyOrAssembly; this.IsNestedPrivate = typeDef.IsNestedPrivate; this.IsAbstract = typeDef.IsAbstract; this.IsSealed = typeDef.IsSealed; this.IsInterface = typeDef.IsInterface; this.IsValueType = typeDef.IsValueType && !typeDef.IsPrimitive && !typeDef.IsEnum; this.IsEnum = typeDef.IsEnum; this.nameSpace = typeRef.Namespace; this.name = typeRef.Name; if (typeDef.HasGenericParameters) { GenericInstanceType git = typeRef as GenericInstanceType; for (int i = 0; i < typeDef.GenericParameters.Count; i++) { GenericParameter gp = typeDef.GenericParameters[i]; TypeReference genericArg = null; if (git != null) { genericArg = git.GenericArguments[i]; } if (genericArg is GenericParameter) { gp = (GenericParameter)genericArg; genericArg = null; } InterType resolvedGenericArg = null; if (genericArg == null) { var resolvedInterGenericArg = genericArgs.Where(G => G.Owner == Utils.CecilGenericOwnerToC2JGenericOwner(gp.Type) && G.Position == gp.Position); if (resolvedInterGenericArg.Count() > 0) { resolvedGenericArg = resolvedInterGenericArg.First().Type; } } if (resolvedGenericArg != null) { this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Type, i, resolvedGenericArg)); } else if (genericArg != null) { this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Type, i, resolver.Resolve(genericArg, genericArgs))); } else { Messages.Message(MessageCode.CantResolveGenericParameter, gp.ToString(), typeRef.ToString()); this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Type, i, resolver.Resolve(ClassNames.ObjectTypeName))); } } string genericsSufix = "<" + string.Join(",", this.genericArgs.Select(G => G.Type.Fullname)) + ">"; this.name = this.name + "_GIT_" + resolver.GetGenericsArgsIndex(genericsSufix).ToString(); } if (this.IsNested) { this.declType = resolver.Resolve(typeRef.DeclaringType, this.genericArgs); this.name = this.declType.Name + '/' + this.name; this.nameSpace = this.declType.NameSpace; if (this.declType.NestedClasses.Where(T => T.Fullname == this.Fullname).Count() == 0) { this.declType.NestedClasses.Add(this); } } Attributes.FromJavaAttribute fromJavaAttr = null; CustomAttribute fromJavaCustromAttr = typeDef.CustomAttributes.Where(A => A.AttributeType.FullName == ClassNames.FromJavaAttribute).FirstOrDefault(); if (fromJavaCustromAttr != null) { fromJavaAttr = (Attributes.FromJavaAttribute) typeof(Attributes.FromJavaAttribute).InvokeMember("", System.Reflection.BindingFlags.CreateInstance, null, null, fromJavaCustromAttr.ConstructorArguments.Select(A => A.Value).ToArray()); this.IsFromJava = true; if (fromJavaAttr.JavaName != null) { int delimer = fromJavaAttr.JavaName.LastIndexOf('.'); nameSpace = fromJavaAttr.JavaName.Substring(0, delimer); name = fromJavaAttr.JavaName.Substring(delimer + 1); } } if (!register(this)) { return; } if (typeDef.BaseType != null) { this.baseType = resolver.Resolve(typeDef.BaseType, this.genericArgs); } foreach (TypeReference i in typeDef.Interfaces) { this.interfaces.Add(resolver.Resolve(i, this.genericArgs)); } if (typeDef.BaseType != null) { this.IsDelegate = typeDef.BaseType.FullName == ClassNames.MulticastDelegateTypeName; if ((typeDef.BaseType.FullName == ClassNames.DelegateTypeName) && (typeDef.FullName != ClassNames.MulticastDelegateTypeName)) { this.IsDelegate = true; } } else { this.IsDelegate = false; } if (this.IsEnum) { elementType = resolver.Resolve(typeDef.Fields.Where(F => F.Name == ClassNames.EnumValueFieldName).FirstOrDefault() .FieldType, genericArgs); } if (typeDef != null) { Special(typeDef, resolver); } }
public InterMethod(MethodReference methodRef, List <InterGenericArgument> genericArgs, IResolver resolver, Action <InterMethod> onFounded) { originalName = methodRef.Name; genericArgs = genericArgs ?? InterGenericArgument.EmptyGenericArgsList; MethodDefinition methodDef = methodRef.Resolve(); CustomAttribute methodMapCustomAttr = null; if (methodDef != null) { methodMapCustomAttr = methodDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.MethodMapAttribute).FirstOrDefault(); if ((methodMapCustomAttr == null) && (Program.BoxType == BoxingType.Java)) { methodMapCustomAttr = methodDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.JavaBoxMethodMapAttribute).FirstOrDefault(); } } declType = resolver.Resolve(methodRef.DeclaringType, genericArgs); #region Mapping if (methodMapCustomAttr != null) { TypeReference realDeclType = methodMapCustomAttr.ConstructorArguments[0].Value as TypeReference; TypeDefinition realDeclTypeDef = realDeclType.Resolve(); string mappedName = (string)methodMapCustomAttr.ConstructorArguments[1].Value; MethodDefinition md = null; int paramsOffset = 0; if ((methodMapCustomAttr.ConstructorArguments.Count > 2) && ((bool)methodMapCustomAttr.ConstructorArguments[2].Value)) { paramsOffset = 1; } foreach (var method in realDeclTypeDef.Methods) { if (method.Name != mappedName) { continue; } if (method.HasGenericParameters != methodDef.HasGenericParameters) { continue; } if (method.HasGenericParameters && method.GenericParameters.Count != methodDef.GenericParameters.Count) { continue; } if (!Utils.AreSame(method.ReturnType, methodDef.ReturnType)) { continue; } if (paramsOffset == 0) { if ((!method.HasParameters) && (methodDef.HasParameters)) { md = method; break; } } else { if (!method.HasParameters) { continue; } if ((!methodRef.HasParameters) && (method.Parameters.Count == 1)) { md = method; break; } } if (!Utils.AreSame(method.Parameters, methodDef.Parameters, paramsOffset)) { continue; } md = method; break; } if (md == null) { throw new Exception(); //TODO: mapping error } MethodReference newMethodRef = md; if (methodRef is GenericInstanceMethod) { GenericInstanceMethod oldGIM = (GenericInstanceMethod)methodRef; GenericInstanceMethod newGIM = new GenericInstanceMethod(newMethodRef); oldGIM.GenericArguments.ForEach(T => newGIM.GenericArguments.Add(T)); newMethodRef = newGIM; } onFounded(resolver.Resolve(newMethodRef, genericArgs)); return; } else #endregion { name = methodRef.Name; } genericArgs.AddRange(declType.GenericArguments); if ((methodDef ?? methodRef).HasGenericParameters) { GenericInstanceMethod gim = methodRef as GenericInstanceMethod; for (int i = 0; i < (methodDef ?? methodRef).GenericParameters.Count; i++) { GenericParameter gp = (methodDef ?? methodRef).GenericParameters[i]; TypeReference genericArg = null; if (gim != null) { genericArg = gim.GenericArguments[i]; } if (genericArg is GenericParameter) { gp = (GenericParameter)genericArg; genericArg = null; } InterType resolvedGenericArg = null; if (genericArg == null) { var resolvedInterGenericArg = genericArgs.Where(G => G.Owner == Utils.CecilGenericOwnerToC2JGenericOwner(gp.Type) && G.Position == gp.Position); if (resolvedInterGenericArg.Count() > 0) { resolvedGenericArg = resolvedInterGenericArg.First().Type; } } if (resolvedGenericArg != null) { this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Method, i, resolvedGenericArg)); } else if (genericArg != null) { this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Method, i, resolver.Resolve(genericArg, genericArgs))); } else { Messages.Message(MessageCode.CantResolveGenericParameter, gp.ToString(), methodRef.ToString()); this.genericArgs.Add(new InterGenericArgument(GenericArgumentOwnerType.Method, i, resolver.Resolve(ClassNames.ObjectTypeName))); } } string genericsSufix = "<" + string.Join(",", this.genericArgs.Select(G => G.Type.Fullname)) + ">"; this.name = this.name + "_GIM_" + resolver.GetGenericsArgsIndex(genericsSufix).ToString(); } if (methodDef != null) { CustomAttribute fromJavaCustomAttr = methodDef.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.FromJavaAttribute).FirstOrDefault(); if (fromJavaCustomAttr != null) { FromJava = true; if (fromJavaCustomAttr.ConstructorArguments.Count > 0) { name = fromJavaCustomAttr.ConstructorArguments[0].Value.ToString(); } } } if (methodRef.HasThis) { thisParam = new InterParameter(0, declType, "this"); } this.returnParam = new InterParameter(-1, resolver.Resolve(methodRef.ReturnType, this.FullGenericArguments), "return", methodRef.MethodReturnType.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.BoxedAttribute).Count() > 0, methodRef.MethodReturnType.CustomAttributes.Where(C => C.AttributeType.FullName == ClassNames.JavaBoxedAttribute).Count() > 0); foreach (ParameterDefinition paramDef in methodRef.Parameters) { if (paramDef.ParameterType.IsSentinel) { break; } parameters.Add(new InterParameter(paramDef, this.FullGenericArguments, resolver)); } if (methodDef != null) { if (methodDef.HasBody) { body = methodDef.Body; } IsPublic = methodDef.IsPublic || methodDef.IsAssembly; IsProtected = methodDef.IsFamily || methodDef.IsFamilyAndAssembly || methodDef.IsFamilyOrAssembly; IsPrivate = methodDef.IsPrivate; IsAbstract = methodDef.IsAbstract; IsFinal = methodDef.IsFinal; IsVirtual = methodDef.IsVirtual; IsNewSlot = methodDef.IsNewSlot; IsStatic = methodDef.IsStatic; IsSynchronized = methodDef.IsSynchronized; IsConstructor = methodDef.IsConstructor; IsVarArg = methodDef.CallingConvention == MethodCallingConvention.VarArg; HasThis = methodDef.HasThis; HasBody = methodDef.HasBody; foreach (MethodReference overridedMethod in methodDef.Overrides) { overrides.Add(resolver.Resolve(overridedMethod, this.FullGenericArguments)); } } else { IsPublic = true; IsFinal = true; HasThis = methodRef.HasThis; IsStatic = !methodRef.HasThis; } if ((!IsConstructor) && (!declType.IsDelegate)) { //TODO: change params in ctors var changedParams = parameters.Where(P => ((P.Type.IsEnum) || ((P.Type.IsPrimitive) && (Utils.IsUnsigned(P.Type.PrimitiveType))))); if (changedParams.Count() > 0) { name += "$" + string.Join("_", changedParams.Select(P => P.Index + P.Type.Fullname)); } } InterMethod thisFromDecl = declType.Methods.Where(M => M.Equals(this)).FirstOrDefault(); if (thisFromDecl != null) { onFounded(thisFromDecl); } }