예제 #1
0
        private Expression CreateInitializationBody(MethodBodyCreationContext ctx, InstanceInitialization initialization)
        {
            var replacements = new Dictionary <Expression, Expression> {
                { initialization.Semantics, ctx.Parameters[0] }
            };
            var initializations = initialization.Expressions.Select(e => e.Replace(replacements));

            return(Expression.Block(typeof(void), initializations));
        }
예제 #2
0
        private Expression GetMethodBody(
            MutableType declaringType,
            MethodAttributes attributes,
            Func <MethodBodyCreationContext, Expression> bodyProvider,
            MethodSignatureItems signatureItems,
            MethodInfo baseMethod)
        {
            var parameterExpressions = signatureItems.ParameterDeclarations.Select(pd => pd.Expression);
            var isStatic             = attributes.IsSet(MethodAttributes.Static);
            var context = new MethodBodyCreationContext(
                declaringType, isStatic, parameterExpressions, signatureItems.GenericParameters.Cast <Type>(), signatureItems.ReturnType, baseMethod);
            var body = bodyProvider == null ? null : BodyProviderUtility.GetTypedBody(signatureItems.ReturnType, bodyProvider, context);

            return(body);
        }
예제 #3
0
        private Expression ImplementMixinInitalizationMethod(MethodBodyCreationContext ctx, List <Type> mixinTypes)
        {
            // if (!__extensionsInitialized) {
            //   __extensionsInitialized = true;
            //   <set first call proxy>;
            //   if (isDeserialization)
            //     <check deserialzed mixin instances>;
            //   else
            //     <create mixin instances>;
            //   <initialize mixins>(isDeserialization);
            // }

            return(Expression.IfThen(
                       Expression.Not(_extensionsInitializedField),
                       Expression.Block(
                           Expression.Assign(_extensionsInitializedField, Expression.Constant(true)),
                           ImplementSettingFirstNextCallProxy(ctx.This),
                           Expression.IfThenElse(
                               ctx.Parameters[0],
                               ImplementCheckingDeserializedMixinInstances(),
                               ImplementCreatingMixinInstances()),
                           ImplementInitializingMixins(ctx.This, mixinTypes, ctx.Parameters[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);
        }
예제 #5
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);
        }