private void ImplementBaseCallForOverridenMethodOnTarget(MethodDefinition methodDefinitionOnTarget) { Assertion.IsTrue(methodDefinitionOnTarget.DeclaringClass == _targetClassDefinition); var attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual; var md = MethodDeclaration.CreateEquivalent(methodDefinitionOnTarget.MethodInfo); var methodOverride = _type.AddMethod( methodDefinitionOnTarget.FullName, attributes, md, ctx => _nextCallMethodGenerator.CreateBaseCallToNextInChain(ctx, methodDefinitionOnTarget)); _overriddenMethodToImplementationMap.Add(methodDefinitionOnTarget, methodOverride); // If the base type of the emitter (object) already has the method being overridden (ToString, Equals, etc.), mixins could use the base // implementation of the method rather than coming via the next call interface. Therefore, we need to override that base method and point it // towards our next call above. Assertion.IsTrue( _type.BaseType == typeof(object), "This code assumes that only non-generic methods could match on the base type, which holds for object."); // Since object has no generic methods, we can use the exact parameter types to find the equivalent method. var equivalentMethodOnProxyBase = _type.BaseType.GetMethod( methodDefinitionOnTarget.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, methodOverride.GetParameters().Select(p => p.ParameterType).ToArray(), null); if (equivalentMethodOnProxyBase != null && equivalentMethodOnProxyBase.IsVirtual) { _type.GetOrAddOverride(equivalentMethodOnProxyBase) .SetBody(ctx => ctx.DelegateTo(ctx.This, methodOverride)); } }
private MutableMethodInfo AddSimiliarMethod( MutableType mutableType, MethodInfo template, string methodName = null, MethodAttributes vtableLayout = MethodAttributes.NewSlot) { var methodDeclaration = MethodDeclaration.CreateEquivalent(template); return(mutableType.AddMethod( methodName ?? template.Name, MethodAttributes.Public | MethodAttributes.Virtual | vtableLayout, methodDeclaration, ctx => Expression.Default(template.ReturnType))); }
protected MutableMethodInfo AddEquivalentMethod( MutableType mutableType, MethodInfo template, MethodAttributes adjustedAttributes, Func <MethodBodyCreationContext, Expression> bodyProvider = null) { bodyProvider = bodyProvider ?? (ctx => Expression.Default(template.ReturnType)); var methodDeclaration = MethodDeclaration.CreateEquivalent(template); return(mutableType.AddMethod(template.Name, adjustedAttributes, methodDeclaration, bodyProvider)); }
private MethodInfo CreatePublicMethodWrapper(MethodInfo methodToBeWrapped) { var name = "__wrap__" + methodToBeWrapped.Name; var attributes = MethodAttributes.Public | MethodAttributes.HideBySig; var md = MethodDeclaration.CreateEquivalent(methodToBeWrapped); var wrapper = _type.AddMethod(name, attributes, md, ctx => ctx.DelegateTo(ctx.This, methodToBeWrapped)); _attributeGenerator.AddGeneratedMethodWrapperAttribute(wrapper, methodToBeWrapped); return(wrapper); }
public void DefineTypeFacets() { var typeInitializer = _mutableType.AddTypeInitializer(ctx => Expression.Empty()); var instanceInitialization = ExpressionTreeObjectMother.GetSomeExpression(); _mutableType.AddInitialization(ctx => instanceInitialization); var customAttribute = CustomAttributeDeclarationObjectMother.Create(); _mutableType.AddCustomAttribute(customAttribute); var @interface = typeof(IDisposable); _mutableType.AddInterface(@interface); var field = _mutableType.AddField(); var constructor = _mutableType.AddConstructor(); var method = _mutableType.AddMethod(); var property = _mutableType.AddProperty(); var event_ = _mutableType.AddEvent(); using (_mockRepository.Ordered()) { var context = PopulateContext(_generator, 2); _typeBuilderMock.Expect(mock => mock.SetParent(_mutableType.BaseType)); _memberEmitterMock.Expect(mock => mock.AddConstructor(context, typeInitializer)); _initializationBuilderMock.Expect(mock => mock.CreateInitializationMembers(_mutableType)).Return(_fakeInitializationMembers); _proxySerializationEnablerMock.Expect(mock => mock.MakeSerializable(_mutableType, _fakeInitializationMethod)); _typeBuilderMock.Expect(mock => mock.SetCustomAttribute(customAttribute)); _typeBuilderMock.Expect(mock => mock.AddInterfaceImplementation(@interface)); _memberEmitterMock.Expect(mock => mock.AddField(context, field)); _initializationBuilderMock.Expect( mock => mock.WireConstructorWithInitialization(constructor, _fakeInitializationMembers, _proxySerializationEnablerMock)); _memberEmitterMock.Expect(mock => mock.AddConstructor(context, constructor)); _memberEmitterMock.Expect(mock => mock.AddMethod(context, method)); SetupExpectationsForAccessors(_memberEmitterMock, _mutableType.AddedMethods.Except(new[] { method })); _memberEmitterMock.Expect(mock => mock.AddProperty(context, property)); _memberEmitterMock.Expect(mock => mock.AddEvent(context, event_)); } _mockRepository.ReplayAll(); _generator.DefineTypeFacets(); _mockRepository.VerifyAll(); }
private MethodInfo ImplementBaseCallMethod(MethodInfo baseMethod) { Assertion.IsTrue(ReflectionUtility.IsPublicOrProtected(baseMethod)); if (baseMethod.IsAbstract) { var message = string.Format("The given method {0}.{1} is abstract.", baseMethod.DeclaringType.FullName, baseMethod.Name); throw new ArgumentException(message, "baseMethod"); } var attributes = MethodAttributes.Public | MethodAttributes.HideBySig; var name = "__base__" + baseMethod.Name; var md = MethodDeclaration.CreateEquivalent(baseMethod); return(_concreteTarget.AddMethod(name, attributes, md, ctx => ctx.DelegateToBase(baseMethod))); }
public MethodInfo AddOverriddenMethod(MethodInfo overriddenMethod) { ArgumentUtility.CheckNotNull("overriddenMethod", overriddenMethod); var name = overriddenMethod.Name; var attributes = MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual; var md = MethodDeclaration.CreateEquivalent(overriddenMethod); var method = _interfaceType.AddMethod(name, attributes, md, bodyProvider: null); _attributeGenerator.AddOverrideInterfaceMappingAttribute(method, overriddenMethod); _interfaceMethods.Add(overriddenMethod, method); return(method); }
public void Prepare(MutableType mutableType, EventInfo eventInfo) { var eventType = eventInfo.EventHandlerType; var eventInvoke = eventType.GetMethod("Invoke"); var original = Expression.Field( new ThisExpression(mutableType), mutableType.GetField(eventInfo.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)); var broker = Expression.Field( new ThisExpression(mutableType), mutableType.AddField(eventInfo.Name + "Broker", eventType)); var addMethod = mutableType.GetOrAddMutableMethod(eventInfo.GetAddMethod(true)); var removeMethod = mutableType.GetOrAddMutableMethod(eventInfo.GetRemoveMethod(true)); var parameters = eventInvoke.GetParameters().Select(ParameterDeclaration.CreateEquivalent); var invokeMethod = mutableType.AddMethod( "invoke_" + eventInfo.Name, MethodAttributes.Private, eventInvoke.ReturnType, parameters, ctx => Expression.Call(broker, eventInvoke, ctx.Parameters.Cast <Expression>())); var invokeDelegate = new NewDelegateExpression(eventType, new ThisExpression(mutableType.UnderlyingSystemType), invokeMethod); addMethod.SetBody( ctx => Expression.Block( Expression.IfThen( Expression.Equal(broker, Expression.Constant(null, eventType)), Expression.Call(ctx.This, new NonVirtualCallMethodInfoAdapter(addMethod.UnderlyingSystemMethodInfo), invokeDelegate)), Expression.Assign( broker, Expression.Convert(Expression.Call(null, s_combineMethod, new Expression[] { broker, ctx.Parameters.Single() }), eventType)))); removeMethod.SetBody( ctx => Expression.Block( Expression.IfThen( Expression.Equal(broker, Expression.Constant(null, eventType)), Expression.Call(ctx.This, new NonVirtualCallMethodInfoAdapter(addMethod.UnderlyingSystemMethodInfo), invokeDelegate)), Expression.Assign( broker, Expression.Convert(Expression.Call(null, s_combineMethod, new Expression[] { broker, ctx.Parameters.Single() }), eventType)))); }
public static void ImplementGetObjectDataByDelegation( MutableType mutableType, Func <MethodBodyContextBase, bool, Expression> delegatingExpressionFunc) { ArgumentUtility.CheckNotNull("mutableType", mutableType); ArgumentUtility.CheckNotNull("delegatingExpressionFunc", delegatingExpressionFunc); var baseIsISerializable = typeof(ISerializable).IsTypePipeAssignableFrom(mutableType.BaseType); var attributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final; var md = MethodDeclaration.CreateEquivalent(s_getObjectDataMethod); mutableType.AddMethod( s_getObjectDataMethod.Name, attributes, md, ctx => { var baseCall = baseIsISerializable ? ImplementBaseGetObjectDataCall(ctx) : Expression.Empty(); var delegatingExpression = delegatingExpressionFunc(ctx, baseIsISerializable) ?? Expression.Empty(); return(Expression.Block(baseCall, delegatingExpression)); }); }
public void AddInitializations(List <Type> mixinTypes) { ArgumentUtility.CheckNotNull("mixinTypes", mixinTypes); Assertion.IsNotNull(_extensionsField, "AddExtensionsField must be called first."); Assertion.IsNotNull(_extensionsInitializedField, "AddFields must be called first."); Assertion.IsNotNull(_firstField, "AddFields must be called first."); Assertion.IsNotNull(_nextCallProxy, "AddNextCallProxy must be called first."); Assertion.IsNotNull(_mixinArrayInitializerField, "AddFields must be called first."); Assertion.IsNotNull(_extensionsInitializedField, "AddFields must be called first."); _initializationMethod = _concreteTarget.AddMethod( "__InitializeMixins", MethodAttributes.Private, parameters: new[] { new ParameterDeclaration(typeof(bool), "isDeserialization") }, bodyProvider: ctx => ImplementMixinInitalizationMethod(ctx, mixinTypes)); _concreteTarget.AddInitialization( ctx => Expression.Call( ctx.This, _initializationMethod, Expression.Equal(ctx.InitializationSemantics, Expression.Constant(InitializationSemantics.Deserialization)))); }
private void CheckAddMethodThrows(MutableType mutableType, string name, Type returnType, Expression body, string exceptionMessage) { Assert.That( () => mutableType.AddMethod(name, MethodAttributes.Public, returnType, ParameterDeclaration.None, ctx => body), Throws.InvalidOperationException.With.Message.EqualTo(exceptionMessage)); }