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); }