Beispiel #1
0
        internal IMethod GetMethod(object token, ILType contextType, ILMethod contextMethod, out bool invalidToken)
        {
            string       methodname = null;
            string       typename   = null;
            List <IType> paramList  = null;
            int          hashCode   = token.GetHashCode();
            IMethod      method;

            IType[] genericArguments = null;
            IType   returnType;

            invalidToken = false;
            bool isConstructor = false;

            if (mapMethod.TryGetValue(hashCode, out method))
            {
                return(method);
            }
            IType type = null;

            if (token is Mono.Cecil.MethodReference)
            {
                Mono.Cecil.MethodReference _ref = (token as Mono.Cecil.MethodReference);
                if (_ref.FullName == "System.Void System.Object::.ctor()")
                {
                    mapMethod[hashCode] = null;
                    return(null);
                }
                if (_ref.FullName == "System.Void System.Attribute::.ctor()")
                {
                    mapMethod[hashCode] = null;
                    return(null);
                }
                methodname = _ref.Name;
                var typeDef = _ref.DeclaringType;
                type = GetType(typeDef, contextType, contextMethod);
                if (type == null)
                {
                    throw new KeyNotFoundException("Cannot find type:" + typename);
                }

                if (token is Mono.Cecil.MethodDefinition)
                {
                    var def = _ref as MethodDefinition;
                    isConstructor = def.IsConstructor;
                }
                else
                {
                    isConstructor = methodname == ".ctor";
                }

                if (_ref.IsGenericInstance)
                {
                    GenericInstanceMethod gim = (GenericInstanceMethod)_ref;
                    genericArguments = new IType[gim.GenericArguments.Count];
                    for (int i = 0; i < genericArguments.Length; i++)
                    {
                        if (gim.GenericArguments[i].IsGenericParameter)
                        {
                            invalidToken = true;
                        }
                        var gt = GetType(gim.GenericArguments[i], contextType, contextMethod);
                        if (gt == null)
                        {
                            gt = contextMethod.FindGenericArgument(gim.GenericArguments[i].Name);
                            if (gt == null)//This means it contains unresolved generic arguments, which means it's not searching the generic instance
                            {
                                genericArguments = null;
                                break;
                            }
                            else
                            {
                                genericArguments[i] = gt;
                            }
                        }
                        else
                        {
                            genericArguments[i] = gt;
                        }
                    }
                }

                paramList  = _ref.GetParamList(this, contextType, contextMethod, genericArguments);
                returnType = GetType(_ref.ReturnType, contextType, null);
            }
            else
            {
                throw new NotImplementedException();
                //Mono.Cecil.GenericInstanceMethod gmethod = _def as Mono.Cecil.GenericInstanceMethod;
                //genlist = new MethodParamList(environment, gmethod);
            }

            if (isConstructor)
            {
                method = type.GetConstructor(paramList);
            }
            else
            {
                method = type.GetMethod(methodname, paramList, genericArguments, returnType);
                if (method != null && method.IsGenericInstance)
                {
                    mapMethod[method.GetHashCode()] = method;
                }
            }

            if (method == null)
            {
                if (isConstructor && contextType.FirstCLRBaseType != null && contextType.FirstCLRBaseType is CrossBindingAdaptor && type.TypeForCLR == ((CrossBindingAdaptor)contextType.FirstCLRBaseType).BaseCLRType)
                {
                    method = contextType.BaseType.GetConstructor(paramList);
                    if (method == null)
                    {
                        throw new KeyNotFoundException("Cannot find method:" + methodname);
                    }
                    invalidToken = true;
                    mapMethod[method.GetHashCode()] = method;
                }
                else
                {
                    throw new KeyNotFoundException("Cannot find method:" + methodname);
                }
            }
            if (!invalidToken)
            {
                mapMethod[hashCode] = method;
            }
            return(method);
        }