コード例 #1
0
        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);
        }
コード例 #2
0
        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 }));
        }
コード例 #3
0
 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));
 }
コード例 #4
0
        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 }));
        }
コード例 #5
0
        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);
        }
コード例 #6
0
ファイル: MethodFactory.cs プロジェクト: re-motion/TypePipe
        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));
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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);
        }