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