private void AddOverrider(MethodInfo method, Reference invocationHandler) { var overrider = _emitter.CreateMethod(method.Name, MethodAttributes.Public | MethodAttributes.Virtual, method); overrider.AddCustomAttribute(new CustomAttributeBuilder(s_attributeConstructor, new object[0])); Reference targetReference = GetTargetReference(); Expression overriddenMethodToken = new MethodTokenExpression(method); LocalReference argsLocal = CopyArgumentsToLocalVariable(overrider); Expression baseMethodInvoker = GetBaseInvokerExpression(method); TypeReference handlerReference = new TypeReferenceWrapper(invocationHandler, typeof(MethodInvocationHandler)); Expression[] handlerArgs = new Expression[] { targetReference.ToExpression(), overriddenMethodToken, argsLocal.ToExpression(), baseMethodInvoker }; Expression handlerInvocation = new VirtualMethodInvocationExpression(handlerReference, s_handlerInvokeMethod, handlerArgs); if (method.ReturnType != typeof(void)) { overrider.ImplementByReturning(new ConvertExpression(method.ReturnType, typeof(object), handlerInvocation)); } else { overrider.AddStatement(new ExpressionStatement(handlerInvocation)); overrider.AddStatement(new PopStatement()); overrider.ImplementByReturningVoid(); } }
public void CustomAddMethod() { CustomEventEmitter eventEmitter = _classEmitter.CreateEvent("CustomAddMethod", EventKind.Static, typeof(EventHandler)); eventEmitter.AddMethod = _classEmitter.CreateMethod( "CustomAdd", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new [] { typeof(EventHandler) }); }
public void CreateMethod_CopyParametersAndReturnTypeOutRef() { var classEmitter = new CustomClassEmitter(Scope, "CreateMethod_CopyParametersAndReturnTypeOutRef", typeof(object)); var method = classEmitter.CreateMethod( "MethodWithOutRef", MethodAttributes.Public, typeof(ClassWithAllKindsOfMembers).GetMethod("MethodWithOutRef")); method.AddStatement(new AssignStatement(new IndirectReference(method.ArgumentReferences[0]), NullExpression.Instance)); method.ImplementByReturningDefault(); object instance = Activator.CreateInstance(classEmitter.BuildType()); MethodInfo builtMethod = instance.GetType().GetMethod("MethodWithOutRef"); Assert.That(builtMethod.ReturnType, Is.EqualTo(typeof(void))); ParameterInfo[] parameters = builtMethod.GetParameters(); Assert.That(parameters.Length, Is.EqualTo(2)); Assert.That(parameters[0].ParameterType, Is.EqualTo(typeof(string).MakeByRefType())); Assert.That(parameters[0].ParameterType.IsByRef, Is.True); Assert.That(parameters[0].IsOut, Is.True); Assert.That(parameters[0].IsIn, Is.False); Assert.That(parameters[1].ParameterType, Is.EqualTo(typeof(int).MakeByRefType())); Assert.That(parameters[1].ParameterType.IsByRef, Is.True); Assert.That(parameters[1].IsOut, Is.False); Assert.That(parameters[1].IsIn, Is.False); var arguments = new object[] { "foo", 5 }; builtMethod.Invoke(instance, arguments); Assert.That(arguments[0], Is.EqualTo(null)); Assert.That(arguments[1], Is.EqualTo(5)); }
private static MethodInfo DefineEquivalentInterfaceMethod(CustomClassEmitter emitter, MethodInfo method) { var interfaceMethod = emitter.CreateMethod( method.Name, MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual, method); return(interfaceMethod.MethodBuilder); }
public void CreateStaticMethod() { var classEmitter = new CustomClassEmitter(Scope, "CreateStaticMethod", typeof(object)); var method = classEmitter.CreateMethod("Check", MethodAttributes.Public | MethodAttributes.Static, typeof(string), new Type[0]); method.AddStatement(new ReturnStatement(new ConstReference("stat"))); Type t = classEmitter.BuildType(); Assert.That(t.GetMethod("Check").Invoke(null, null), Is.EqualTo("stat")); }
public void CreateMethod() { var classEmitter = new CustomClassEmitter(Scope, "CreateMethod", typeof(object)); var method = classEmitter.CreateMethod("Check", MethodAttributes.Public, typeof(string), new Type[0]); method.AddStatement(new ReturnStatement(new ConstReference("ret"))); object instance = Activator.CreateInstance(classEmitter.BuildType()); Assert.That(instance.GetType().GetMethod("Check").Invoke(instance, null), Is.EqualTo("ret")); }
/// <summary> /// Adds a forwarding method to the proxy based on the passed <see cref="MethodInfo"/>, using the passed <see cref="MethodAttributes"/>. /// </summary> /// <remarks> /// Note that this works for interface methods only, if the <see cref="MethodInfo"/> comes from the interface, not the /// type implementing the interface. /// </remarks> public IMethodEmitter AddForwardingMethodFromClassOrInterfaceMethodInfoCopy(MethodInfo methodInfo, MethodAttributes methodAttributes) { ArgumentUtility.CheckNotNull("methodInfo", methodInfo); IMethodEmitter methodEmitter; if (methodInfo.DeclaringType.IsInterface) { methodEmitter = _classEmitter.CreateMethodOverrideOrInterfaceImplementation( methodInfo, true, methodAttributes & MethodAttributes.MemberAccessMask); } else { // Note: Masking the attributes with MethodAttributes.MemberAccessMask below, would remove // desired attributes such as Final, Virtual and HideBySig. methodEmitter = _classEmitter.CreateMethod(methodInfo.Name, methodAttributes, methodInfo); } ImplementForwardingMethod(methodInfo, methodEmitter); // TODO: Test return type return(methodEmitter); }
public void CreateMethod_CopyParametersAndReturnTypeSimple() { var classEmitter = new CustomClassEmitter(Scope, "CreateMethod_CopyParametersAndReturnTypeSimple", typeof(object)); var method = classEmitter.CreateMethod( "SimpleClone", MethodAttributes.Public, typeof(object).GetMethod("Equals", new[] { typeof(object) })); method.ImplementByReturningDefault(); Type t = classEmitter.BuildType(); MethodInfo builtMethod = t.GetMethod("SimpleClone"); Assert.That(builtMethod.ReturnType, Is.EqualTo(typeof(bool))); ParameterInfo[] parameters = builtMethod.GetParameters(); Assert.That(parameters.Length, Is.EqualTo(1)); Assert.That(parameters[0].ParameterType, Is.EqualTo(typeof(object))); }
public void CreateMethod_CopyParametersAndReturnTypeGeneric() { var classEmitter = new CustomClassEmitter(Scope, "CreateMethod_CopyParametersAndReturnTypeGeneric", typeof(object)); var method = classEmitter.CreateMethod( "SimpleClone", MethodAttributes.Public, typeof(ClassWithConstrainedGenericMethod).GetMethod("GenericMethod")); method.ImplementByReturningDefault(); Type t = classEmitter.BuildType(); MethodInfo builtMethod = t.GetMethod("SimpleClone"); Assert.That(builtMethod.ReturnType, Is.EqualTo(typeof(string))); ParameterInfo[] parameters = builtMethod.GetParameters(); Assert.That(parameters.Length, Is.EqualTo(3)); Assert.That(parameters[0].ParameterType.IsGenericParameter, Is.True); Assert.That(parameters[0].ParameterType.DeclaringMethod, Is.EqualTo(builtMethod)); Assert.That(parameters[0].ParameterType.GenericParameterAttributes, Is.EqualTo(GenericParameterAttributes.None)); Type[] constraints = parameters[0].ParameterType.GetGenericParameterConstraints(); Assert.That(constraints.Length, Is.EqualTo(1)); Assert.That(constraints[0], Is.EqualTo(typeof(IConvertible))); Assert.That(parameters[1].ParameterType.IsGenericParameter, Is.True); Assert.That(parameters[1].ParameterType.DeclaringMethod, Is.EqualTo(builtMethod)); Assert.That(parameters[1].ParameterType.GenericParameterAttributes, Is.EqualTo(GenericParameterAttributes.NotNullableValueTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint)); constraints = parameters[1].ParameterType.GetGenericParameterConstraints(); Assert.That(constraints.Length, Is.EqualTo(1)); Assert.That(constraints[0], Is.EqualTo(typeof(ValueType))); Assert.That(parameters[2].ParameterType.IsGenericParameter, Is.True); Assert.That(parameters[2].ParameterType.DeclaringMethod, Is.EqualTo(builtMethod)); Assert.That(parameters[2].ParameterType.GenericParameterAttributes, Is.EqualTo(GenericParameterAttributes.None)); constraints = parameters[2].ParameterType.GetGenericParameterConstraints(); Assert.That(constraints.Length, Is.EqualTo(1)); Assert.That(constraints[0], Is.EqualTo(parameters[0].ParameterType)); }