Beispiel #1
0
        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));
            }
        }
Beispiel #2
0
        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)));
        }
Beispiel #3
0
        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);
        }
Beispiel #5
0
        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));
            });
        }
Beispiel #10
0
        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))));
        }
Beispiel #11
0
 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));
 }