public void SetUp() { _relatedMethodFinderMock = new Mock <IRelatedMethodFinder> (MockBehavior.Strict); _methodFactoryMock = new Mock <IMethodFactory> (MockBehavior.Strict); _factory = new MethodOverrideFactory(_relatedMethodFinderMock.Object, _methodFactoryMock.Object); _mutableType = MutableTypeObjectMother.Create(name: "MyAbcType", baseType: typeof(DomainType)); _noGenericParameters = new GenericParameterContext(Type.EmptyTypes); }
public void CreateExplicitOverride_Generic() { var method = typeof(DomainType).GetMethod("GenericMethod"); Func <MethodBodyCreationContext, Expression> bodyProvider = ctx => null; var fakeResult = CreateFakeGenericMethod(); _methodFactoryMock .Setup( mock => mock.CreateMethod( _mutableType, "Remotion.TypePipe.UnitTests.MutableReflection.Implementation.MemberFactory.MethodOverrideFactoryTest.DomainType.GenericMethod", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.HideBySig, It.IsAny <IEnumerable <GenericParameterDeclaration> >(), It.IsAny <Func <GenericParameterContext, Type> >(), It.IsAny <Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > >(), bodyProvider)) .Returns(fakeResult) .Callback( ( MutableType declaringType, string nameArgument, MethodAttributes attributes, IEnumerable <GenericParameterDeclaration> genericParameters, Func <GenericParameterContext, Type> returnTypeProvider, Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > parameterProvider, Func <MethodBodyCreationContext, Expression> bodyProviderArg) => { var fakeGenericParameter = ReflectionObjectMother.GetSomeType(); var genericParameterContext = new GenericParameterContext(new[] { fakeGenericParameter }); var returnType = returnTypeProvider(genericParameterContext); var parameters = parameterProvider(genericParameterContext).ToList(); var genericParameter = genericParameters.Single(); Assert.That(genericParameter.Name, Is.EqualTo("TPar")); Assert.That(genericParameter.Attributes, Is.EqualTo(GenericParameterAttributes.DefaultConstructorConstraint)); Assert.That( genericParameter.ConstraintProvider(genericParameterContext), Is.EqualTo(new[] { typeof(DomainType), typeof(IDisposable) })); Assert.That(returnType, Is.SameAs(fakeGenericParameter)); ParameterDeclarationTest.CheckParameter(parameters[0], typeof(int), "arg1", ParameterAttributes.None); ParameterDeclarationTest.CheckParameter(parameters[1], fakeGenericParameter, "arg2", ParameterAttributes.None); }) .Verifiable(); var result = _factory.CreateExplicitOverride(_mutableType, method, bodyProvider); _methodFactoryMock.Verify(); Assert.That(result, Is.SameAs(fakeResult)); Assert.That(result.AddedExplicitBaseDefinitions, Is.EqualTo(new[] { method })); }
public static void CheckGenericParameter( GenericParameterDeclaration genericParameter, GenericParameterContext genericParameterContext, string expectedName, GenericParameterAttributes expectedAttributes, params Type[] expectedConstraints) { Assert.That(genericParameter, Is.Not.Null); Assert.That(genericParameter.Name, Is.EqualTo(expectedName)); Assert.That(genericParameter.Attributes, Is.EqualTo(expectedAttributes)); Assert.That(genericParameter.ConstraintProvider(genericParameterContext), Is.EqualTo(expectedConstraints)); }
public void CreateExplicitOverride_Generic() { var method = typeof(DomainType).GetMethod("GenericMethod"); Func <MethodBodyCreationContext, Expression> bodyProvider = ctx => null; var fakeResult = CreateFakeGenericMethod(); _methodFactoryMock .Expect( mock => mock.CreateMethod( Arg.Is(_mutableType), Arg.Is("Remotion.TypePipe.UnitTests.MutableReflection.Implementation.MemberFactory.MethodOverrideFactoryTest.DomainType.GenericMethod"), Arg.Is(MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.HideBySig), Arg <IEnumerable <GenericParameterDeclaration> > .Is.Anything, Arg <Func <GenericParameterContext, Type> > .Is.Anything, Arg <Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > > .Is.Anything, Arg.Is(bodyProvider))) .Return(fakeResult) .WhenCalled( mi => { var fakeGenericParameter = ReflectionObjectMother.GetSomeType(); var genericParameterContext = new GenericParameterContext(new[] { fakeGenericParameter }); var genericParameters = (IEnumerable <GenericParameterDeclaration>)mi.Arguments[3]; var returnType = ((Func <GenericParameterContext, Type>)mi.Arguments[4])(genericParameterContext); var parameters = ((Func <GenericParameterContext, IEnumerable <ParameterDeclaration> >)mi.Arguments[5])(genericParameterContext).ToList(); var genericParameter = genericParameters.Single(); Assert.That(genericParameter.Name, Is.EqualTo("TPar")); Assert.That(genericParameter.Attributes, Is.EqualTo(GenericParameterAttributes.DefaultConstructorConstraint)); Assert.That(genericParameter.ConstraintProvider(genericParameterContext), Is.EqualTo(new[] { typeof(DomainType), typeof(IDisposable) })); Assert.That(returnType, Is.SameAs(fakeGenericParameter)); ParameterDeclarationTest.CheckParameter(parameters[0], typeof(int), "arg1", ParameterAttributes.None); ParameterDeclarationTest.CheckParameter(parameters[1], fakeGenericParameter, "arg2", ParameterAttributes.None); }); var result = _factory.CreateExplicitOverride(_mutableType, method, bodyProvider); _methodFactoryMock.VerifyAllExpectations(); Assert.That(result, Is.SameAs(fakeResult)); Assert.That(result.AddedExplicitBaseDefinitions, Is.EqualTo(new[] { method })); }
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); }
private MethodSignatureItems GetMethodSignatureItems( MutableType declaringType, IEnumerable <GenericParameterDeclaration> genericParameters, Func <GenericParameterContext, Type> returnTypeProvider, Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > parameterProvider) { var genericParameterDeclarations = genericParameters.ToList(); var genericParams = genericParameterDeclarations .Select((p, i) => new MutableGenericParameter(i, p.Name, declaringType.Namespace, p.Attributes)).ToList(); var genericParameterContext = new GenericParameterContext(genericParams.Cast <Type>()); foreach (var paraAndDecl in genericParams.Zip(genericParameterDeclarations, (p, d) => new { Parameter = p, Declaration = d })) { paraAndDecl.Parameter.SetGenericParameterConstraints(paraAndDecl.Declaration.ConstraintProvider(genericParameterContext)); } var returnType = ProviderUtility.GetNonNullValue(returnTypeProvider, genericParameterContext, "returnTypeProvider"); var parameters = ProviderUtility.GetNonNullValue(parameterProvider, genericParameterContext, "parameterProvider").ToList(); return(new MethodSignatureItems(genericParams, returnType, parameters)); }
public void GetOrCreateOverride_BaseMethod_ImplicitOverride_Generic() { var baseDefinition = typeof(DomainType).GetMethod("GenericMethod"); var inputMethod = baseDefinition; var baseMethod = baseDefinition; _relatedMethodFinderMock .Setup(mock => mock.GetOverride(baseDefinition, _mutableType.AddedMethods)).Returns((MutableMethodInfo)null).Verifiable(); _relatedMethodFinderMock .Setup(mock => mock.GetMostDerivedOverride(baseDefinition, _mutableType.BaseType)).Returns(baseMethod).Verifiable(); _relatedMethodFinderMock .Setup( mock => mock.IsShadowed( baseDefinition, It.Is <IEnumerable <MethodInfo> > (shadowingCandidates => shadowingCandidates.IsEquivalent(_mutableType.GetAllMethods())))) .Returns(false) .Verifiable(); var fakeResult = CreateFakeGenericMethod(); _methodFactoryMock .Setup( mock => mock.CreateMethod( _mutableType, "GenericMethod", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot | MethodAttributes.HideBySig, It.IsAny <IEnumerable <GenericParameterDeclaration> >(), It.IsAny <Func <GenericParameterContext, Type> >(), It.IsAny <Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > >(), It.IsAny <Func <MethodBodyCreationContext, Expression> >())) .Returns(fakeResult) .Callback( ( MutableType declaringType, string name, MethodAttributes attributes, IEnumerable <GenericParameterDeclaration> genericParameters, Func <GenericParameterContext, Type> returnTypeProvider, Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > parameterProvider, Func <MethodBodyCreationContext, Expression> bodyProvider) => { var fakeGenericParameter = typeof(TypeThatCompliesWithConstraints); var genericParameterContext = new GenericParameterContext(new[] { fakeGenericParameter }); var returnType = returnTypeProvider(genericParameterContext); var parameters = parameterProvider(genericParameterContext).ToList(); var genericParameter = genericParameters.Single(); Assert.That(genericParameter.Name, Is.EqualTo("TPar")); Assert.That(genericParameter.Attributes, Is.EqualTo(GenericParameterAttributes.DefaultConstructorConstraint)); Assert.That( genericParameter.ConstraintProvider(genericParameterContext), Is.EqualTo(new[] { typeof(DomainType), typeof(IDisposable) })); Assert.That(returnType, Is.SameAs(fakeGenericParameter)); ParameterDeclarationTest.CheckParameter(parameters[0], typeof(int), "arg1", ParameterAttributes.None); ParameterDeclarationTest.CheckParameter(parameters[1], fakeGenericParameter, "arg2", ParameterAttributes.None); var parameterExpressions = parameters.Select(p => p.Expression).ToList(); var bodyContext = new MethodBodyCreationContext( _mutableType, false, parameterExpressions, new[] { fakeGenericParameter }, returnType, baseMethod); var body = bodyProvider(bodyContext); var expectedBody = Expression.Call( bodyContext.This, baseMethod.MakeTypePipeGenericMethod(fakeGenericParameter), parameterExpressions); ExpressionTreeComparer.CheckAreEqualTrees(expectedBody, body); }) .Verifiable(); var result = _factory.GetOrCreateOverride(_mutableType, inputMethod, out _isNewlyCreated); _relatedMethodFinderMock.Verify(); _methodFactoryMock.Verify(); Assert.That(result, Is.SameAs(fakeResult)); Assert.That(_isNewlyCreated, Is.True); }
public void CreateMethod() { var name = "Method"; var attributes = MethodAttributes.Public; var baseConstraint = ReflectionObjectMother.GetSomeClassType(); var interfaceConstraint = ReflectionObjectMother.GetSomeInterfaceType(); GenericParameterContext genericParameterContext = null; Type firstGenericParameter = null; Func <GenericParameterContext, IEnumerable <Type> > constraintProvider = ctx => { genericParameterContext = ctx; Assert.That(ctx.GenericParameters, Has.Count.EqualTo(2)); Assert.That(ctx.GenericParameters[1].GenericParameterPosition, Is.EqualTo(1)); firstGenericParameter = ctx.GenericParameters[0]; Assert.That(firstGenericParameter.DeclaringMethod, Is.Null); Assert.That(firstGenericParameter.GenericParameterPosition, Is.EqualTo(0)); Assert.That(firstGenericParameter.Name, Is.EqualTo("T1")); Assert.That(firstGenericParameter.Namespace, Is.EqualTo(_mutableType.Namespace)); Assert.That(firstGenericParameter.GenericParameterAttributes, Is.EqualTo(GenericParameterAttributes.Covariant)); return(new[] { baseConstraint, interfaceConstraint }.AsOneTime()); }; var genericParameters = new[] { GenericParameterDeclarationObjectMother.Create("T1", GenericParameterAttributes.Covariant, constraintProvider), GenericParameterDeclarationObjectMother.Create() }; var returnType = typeof(IComparable); Func <GenericParameterContext, Type> returnTypeProvider = ctx => { Assert.That(ctx, Is.Not.Null.And.SameAs(genericParameterContext)); return(returnType); }; var parameter = ParameterDeclarationObjectMother.Create(name: "paramName"); Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > parameterProvider = ctx => { Assert.That(ctx, Is.Not.Null.And.SameAs(genericParameterContext)); return(new[] { parameter }.AsOneTime()); }; var fakeBody = ExpressionTreeObjectMother.GetSomeExpression(typeof(int)); Func <MethodBodyCreationContext, Expression> bodyProvider = ctx => { Assert.That(ctx.This.Type, Is.SameAs(_mutableType)); Assert.That(ctx.Parameters.Single().Name, Is.EqualTo("paramName")); Assert.That(ctx.IsStatic, Is.False); Assert.That(ctx.GenericParameters, Is.EqualTo(genericParameterContext.GenericParameters)); Assert.That(ctx.ReturnType, Is.SameAs(returnType)); Assert.That(ctx.HasBaseMethod, Is.False); return(fakeBody); }; var method = _factory.CreateMethod( _mutableType, name, attributes, genericParameters.AsOneTime(), returnTypeProvider, parameterProvider, bodyProvider); Assert.That(method.DeclaringType, Is.SameAs(_mutableType)); Assert.That(method.Name, Is.EqualTo(name)); Assert.That(method.Attributes, Is.EqualTo(attributes)); Assert.That(method.ReturnType, Is.SameAs(returnType)); Assert.That(method.BaseMethod, Is.Null); var returnParameter = method.ReturnParameter; Assertion.IsNotNull(returnParameter); Assert.That(returnParameter.Position, Is.EqualTo(-1)); Assert.That(returnParameter.Name, Is.Null); Assert.That(returnParameter.ParameterType, Is.SameAs(returnType)); Assert.That(returnParameter.Attributes, Is.EqualTo(ParameterAttributes.None)); Assert.That(method.GetGenericArguments(), Has.Length.EqualTo(2)); var actualFirstGenericParameter = method.GetGenericArguments()[0]; Assert.That(actualFirstGenericParameter, Is.SameAs(firstGenericParameter)); Assert.That(actualFirstGenericParameter.DeclaringMethod, Is.SameAs(method)); Assert.That(actualFirstGenericParameter.GetGenericParameterConstraints(), Is.EqualTo(new[] { baseConstraint, interfaceConstraint })); Assert.That(method.GetParameters().Single().Name, Is.EqualTo(parameter.Name)); var expectedBody = Expression.Convert(fakeBody, returnType); ExpressionTreeComparer.CheckAreEqualTrees(expectedBody, method.Body); }
public void GetOrCreateOverride_BaseMethod_ImplicitOverride_Generic() { var baseDefinition = typeof(DomainType).GetMethod("GenericMethod"); var inputMethod = baseDefinition; var baseMethod = baseDefinition; _relatedMethodFinderMock.Expect(mock => mock.GetOverride(baseDefinition, _mutableType.AddedMethods)).Return(null); _relatedMethodFinderMock.Expect(mock => mock.GetMostDerivedOverride(baseDefinition, _mutableType.BaseType)).Return(baseMethod); _relatedMethodFinderMock .Expect(mock => mock.IsShadowed(Arg.Is(baseDefinition), Arg <IEnumerable <MethodInfo> > .List.Equivalent(_mutableType.GetAllMethods()))) .Return(false); var fakeResult = CreateFakeGenericMethod(); _methodFactoryMock .Expect( mock => mock.CreateMethod( Arg.Is(_mutableType), Arg.Is("GenericMethod"), Arg.Is(MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot | MethodAttributes.HideBySig), Arg <IEnumerable <GenericParameterDeclaration> > .Is.Anything, Arg <Func <GenericParameterContext, Type> > .Is.Anything, Arg <Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > > .Is.Anything, Arg <Func <MethodBodyCreationContext, Expression> > .Is.Anything)) .Return(fakeResult) .WhenCalled( mi => { var fakeGenericParameter = typeof(TypeThatCompliesWithConstraints); var genericParameterContext = new GenericParameterContext(new[] { fakeGenericParameter }); var genericParameters = (IEnumerable <GenericParameterDeclaration>)mi.Arguments[3]; var returnType = ((Func <GenericParameterContext, Type>)mi.Arguments[4])(genericParameterContext); var parameters = ((Func <GenericParameterContext, IEnumerable <ParameterDeclaration> >)mi.Arguments[5])(genericParameterContext).ToList(); var genericParameter = genericParameters.Single(); Assert.That(genericParameter.Name, Is.EqualTo("TPar")); Assert.That(genericParameter.Attributes, Is.EqualTo(GenericParameterAttributes.DefaultConstructorConstraint)); Assert.That(genericParameter.ConstraintProvider(genericParameterContext), Is.EqualTo(new[] { typeof(DomainType), typeof(IDisposable) })); Assert.That(returnType, Is.SameAs(fakeGenericParameter)); ParameterDeclarationTest.CheckParameter(parameters[0], typeof(int), "arg1", ParameterAttributes.None); ParameterDeclarationTest.CheckParameter(parameters[1], fakeGenericParameter, "arg2", ParameterAttributes.None); var parameterExpressions = parameters.Select(p => p.Expression).ToList(); var bodyContext = new MethodBodyCreationContext( _mutableType, false, parameterExpressions, new[] { fakeGenericParameter }, returnType, baseMethod); var body = ((Func <MethodBodyCreationContext, Expression>)mi.Arguments[6])(bodyContext); var expectedBody = Expression.Call( bodyContext.This, baseMethod.MakeTypePipeGenericMethod(fakeGenericParameter), parameterExpressions.Cast <Expression>()); ExpressionTreeComparer.CheckAreEqualTrees(expectedBody, body); }); var result = _factory.GetOrCreateOverride(_mutableType, inputMethod, out _isNewlyCreated); _relatedMethodFinderMock.VerifyAllExpectations(); _methodFactoryMock.VerifyAllExpectations(); Assert.That(result, Is.SameAs(fakeResult)); Assert.That(_isNewlyCreated, Is.True); }