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));
            }
        }
 public void CreateEquivalent_MethodInstantiation()
 {
     Assert.That(
         () => MethodDeclaration.CreateEquivalent(ReflectionObjectMother.GetSomeMethodInstantiation()),
         Throws.ArgumentException
         .With.ArgumentExceptionMessageEqualTo(
             "The specified method must be either a non-generic method or a generic method definition; it cannot be a method instantiation.",
             "method"));
 }
Beispiel #3
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 #4
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);
        }
        private MutableMethodInfo CreateMethod(
            MutableType declaringType,
            MethodInfo template,
            string name,
            MethodAttributes attributes,
            Func <MethodBodyCreationContext, Expression> bodyProvider)
        {
            var md = MethodDeclaration.CreateEquivalent(template);

            return(_methodFactory.CreateMethod(
                       declaringType, name, attributes, md.GenericParameters, md.ReturnTypeProvider, md.ParameterProvider, bodyProvider));
        }
Beispiel #7
0
        private MethodInfo CreateNonVirtualCallTrampoline(CodeGenerationContext context, MethodInfo method, string trampolineName)
        {
            var methodDeclaration = MethodDeclaration.CreateEquivalent(method);
            var trampoline        = context.MutableType.AddMethod(
                trampolineName,
                MethodAttributes.Private,
                methodDeclaration,
                ctx => Expression.Call(ctx.This, NonVirtualCallMethodInfoAdapter.Adapt(method), ctx.Parameters.Cast <Expression>()));

            _memberEmitter.AddMethod(context, trampoline);

            return(trampoline);
        }
Beispiel #8
0
        public void GetAttributeFlagsImpl_AbstractCache_Updated_WhenAddingNonAbstractMethod_ThatOverridesAbstractMethod()
        {
            var proxyType = MutableTypeObjectMother.Create(baseType: typeof(AbstractTypeBase));

            Assert.That(proxyType.IsAbstract, Is.True);

            proxyType
            .AddMethod(
                "AbstractMethod1",
                MethodAttributes.Public | MethodAttributes.Virtual,
                MethodDeclaration.CreateEquivalent(NormalizingMemberInfoFromExpressionUtility.GetMethod((AbstractTypeBase t) => t.AbstractMethod1())),
                bodyProvider: c => Expression.Default(c.ReturnType));
            Assert.That(proxyType.IsAbstract, Is.False);
        }
        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 void AddMethod_MethodDeclaration()
        {
            var method =
                NormalizingMemberInfoFromExpressionUtility.GetGenericMethodDefinition((DomainType obj) => obj.MethodDeclaration <MemoryStream> (null));
            var declaration = MethodDeclaration.CreateEquivalent(method);
            var type        = AssembleType <DomainType> (p => p.AddMethod("GenericMethod", MethodAttributes.Public, declaration, ctx => Expression.Empty()));

            var genericMethod    = type.GetMethod("GenericMethod");
            var genericParameter = genericMethod.GetGenericArguments().Single();

            Assert.That(
                genericParameter.GenericParameterAttributes,
                Is.EqualTo(GenericParameterAttributes.ReferenceTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint));
            Assert.That(genericParameter.GetGenericParameterConstraints(), Is.EquivalentTo(new[] { typeof(object), typeof(IDisposable) }));
        }
        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);
        }
Beispiel #12
0
        public void ImplementFully_BecomesConcrete()
        {
            var type = AssembleType <AbstractTypeWithOneMethod> (
                proxyType =>
            {
                Assert.That(proxyType.IsAbstract, Is.True);

                var abstractBaseMethod = NormalizingMemberInfoFromExpressionUtility.GetMethod((AbstractTypeWithOneMethod obj) => obj.Method());
                var method             = proxyType.AddMethod(
                    abstractBaseMethod.Name,
                    MethodAttributes.Public | MethodAttributes.Virtual,
                    MethodDeclaration.CreateEquivalent(abstractBaseMethod),
                    ctx => Expression.Empty());
                Assert.That(method.IsAbstract, Is.False);

                Assert.That(proxyType.IsAbstract, Is.False);
            });

            Assert.That(type.IsAbstract, Is.False);
        }
        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 CreateEquivalent()
        {
            var method = GetType().GetMethod("Method");

            var decl = MethodDeclaration.CreateEquivalent(method);

            var context = new GenericParameterContext(new[] { ReflectionObjectMother.GetSomeType(), ReflectionObjectMother.GetSomeOtherType() });

            Assert.That(decl.GenericParameters, Has.Count.EqualTo(3));
            GenericParameterDeclarationTest.CheckGenericParameter(
                decl.GenericParameters[0],
                context,
                "TRet",
                GenericParameterAttributes.DefaultConstructorConstraint,
                expectedConstraints: new[] { typeof(IDisposable) });
            GenericParameterDeclarationTest.CheckGenericParameter(
                decl.GenericParameters[1],
                context,
                "TArg",
                GenericParameterAttributes.None,
                typeof(List <>).MakeGenericType(context.GenericParameters[1]),
                context.GenericParameters[0],
                typeof(IList <>).MakeGenericType(context.GenericParameters[1]));
            GenericParameterDeclarationTest.CheckGenericParameter(
                decl.GenericParameters[2],
                context,
                "TValue",
                GenericParameterAttributes.NotNullableValueTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint);

            var returnType = decl.ReturnTypeProvider(context);

            Assert.That(returnType, Is.SameAs(context.GenericParameters[0]));

            var parameters = decl.ParameterProvider(context).ToList();

            Assert.That(parameters, Has.Count.EqualTo(2));
            ParameterDeclarationTest.CheckParameter(parameters[0], typeof(int).MakeByRefType(), "i", ParameterAttributes.Out);
            ParameterDeclarationTest.CheckParameter(parameters[1], context.GenericParameters[1], "t", ParameterAttributes.None);
        }
 public void CreateEquivalent_MethodInstantiation()
 {
     MethodDeclaration.CreateEquivalent(ReflectionObjectMother.GetSomeMethodInstantiation());
 }