Esempio n. 1
0
		private static void CheckMethodCompatibility(MethodBase method)
		{
			var sigTypes = method.GetParameters().Select(p => p.ParameterType).Concat(new[] { method.GetReturnType() });
			if (sigTypes.Any(sigType =>
			{
				while (sigType.IsByRef || sigType.IsArray)
					sigType = sigType.GetElementType();
				return sigType == typeof(TypedReference);
			}))
				throw new MockException("Mocking methods with TypedReference in their signature is not supported.");

			if (method.GetReturnType().IsByRef)
				throw new MockException("Cannot mock method with by-ref return value.");

			if (method.CallingConvention == CallingConventions.VarArgs)
				throw new MockException("Cannot mock method with __arglist.");
		}
        internal override int GetMemberRefToken(MethodBase methodInfo, Type[] optionalParameterTypes) {
            Type[] parameterTypes;

            if (optionalParameterTypes != null)
                if ((methodInfo.CallingConvention & CallingConventions.VarArgs) == 0)
                     
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention"));
                
            if (!(methodInfo is RuntimeMethodInfo) && DynamicMethod.AsDynamicMethod(methodInfo) == null)
                throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "methodInfo");               

            ParameterInfo[] paramInfo = methodInfo.GetParametersNoCopy();
            if (paramInfo != null && paramInfo.Length != 0) {
                parameterTypes = new Type[paramInfo.Length];
                for (int i = 0; i < paramInfo.Length; i++) {
                    parameterTypes[i] = paramInfo[i].ParameterType;
                }
            }
            else
                parameterTypes = null;

            SignatureHelper sig = GetMemberRefSignature(methodInfo.CallingConvention,
                                                     methodInfo.GetReturnType(),
                                                     parameterTypes,
                                                     optionalParameterTypes);
            return m_scope.GetTokenFor(new VarArgMethod(methodInfo as MethodInfo, sig));
        }
        internal virtual int GetMemberRefToken(MethodBase method, Type[] optionalParameterTypes)
        {
            Type[] parameterTypes;
            Type returnType;
            int tkParent;
            ModuleBuilder modBuilder = (ModuleBuilder)m_methodBuilder.Module;
            int cGenericParameters = 0;

            if (method.IsGenericMethod)
            {
                if (!method.IsGenericMethodDefinition)
                    throw new InvalidOperationException();
            
                cGenericParameters = method.GetGenericArguments().Length;
            }

            if (optionalParameterTypes != null)
            {
                if ((method.CallingConvention & CallingConventions.VarArgs) == 0)
                {
                    // Client should not supply optional parameter in default calling convention
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention"));
                }
            }

            if (method.DeclaringType.IsGenericType)
            {
                MethodBase methDef = null; // methodInfo = G<Foo>.M<Bar> ==> methDef = G<T>.M<S>
                
                if (method is MethodOnTypeBuilderInstantiation)
                {
                    methDef = (method as MethodOnTypeBuilderInstantiation).m_method;
                }
                else if (method is ConstructorOnTypeBuilderInstantiation)
                {
                    methDef = (method as ConstructorOnTypeBuilderInstantiation).m_ctor;
                }
                else if (method is MethodBuilder || method is ConstructorBuilder)
                {
                    // methodInfo must be GenericMethodDefinition; trying to emit G<?>.M<S>
                    methDef = method;
                }
                else if (method.IsGenericMethod)
                {
                    methDef = ((MethodInfo)method).GetGenericMethodDefinition();
                    methDef = methDef.Module.ResolveMethod(
                        methDef.MetadataTokenInternal, 
                        methDef.GetGenericArguments(), 
                        methDef.DeclaringType != null ? methDef.DeclaringType.GetGenericArguments() : null) as MethodBase;
                }
                else
                {
                    methDef = method;
                    methDef = method.Module.ResolveMethod(
                        method.MetadataTokenInternal, 
                        null, 
                        methDef.DeclaringType != null ? methDef.DeclaringType.GetGenericArguments() : null) as MethodBase;
                }

                parameterTypes = methDef.GetParameterTypes();
                returnType = methDef.GetReturnType();
            }
            else
            {
                parameterTypes = method.GetParameterTypes();
                returnType = method.GetReturnType();
            }

            if (method.DeclaringType.IsGenericType)
            {
                int length;
                byte[] sig = SignatureHelper.GetTypeSigToken(modBuilder, method.DeclaringType).InternalGetSignature(out length);
                tkParent = modBuilder.InternalGetTypeSpecTokenWithBytes(sig, length);
            }
            else if (method.Module != modBuilder)
            {                
                // Use typeRef as parent because the method's declaringType lives in a different assembly                
                tkParent = modBuilder.GetTypeToken(method.DeclaringType).Token;
            }
            else
            {
                // Use methodDef as parent because the method lives in this assembly and its declaringType has no generic arguments
                if (method is MethodInfo)
                    tkParent = modBuilder.GetMethodToken(method as MethodInfo).Token;
                else
                    tkParent = modBuilder.GetConstructorToken(method as ConstructorInfo).Token;
            }

            int sigLength;
            byte[] sigBytes = GetMemberRefSignature(
                method.CallingConvention, returnType, parameterTypes, 
                optionalParameterTypes, cGenericParameters).InternalGetSignature(out sigLength); 

            return modBuilder.InternalGetMemberRefFromSignature(tkParent, method.Name, sigBytes, sigLength);
        }