예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
            }
        }