예제 #1
0
 private void ImplementBaseCallForRequirement(RequiredMethodDefinition requiredMethod)
 {
     if (requiredMethod.ImplementingMethod.DeclaringClass == _targetClassDefinition)
     {
         ImplementBaseCallForRequirementOnTarget(requiredMethod);
     }
     else
     {
         ImplementBaseCallForRequirementOnMixin(requiredMethod);
     }
 }
예제 #2
0
        public void BaseMethods()
        {
            TargetClassDefinition targetClass = DefinitionObjectMother.GetActiveTargetClassDefinition(typeof(BaseType3));

            RequiredNextCallTypeDefinition req1 = targetClass.RequiredNextCallTypes[typeof(IBaseType31)];

            Assert.That(req1.Methods.Count, Is.EqualTo(typeof(IBaseType31).GetMembers().Length));

            RequiredMethodDefinition member1 = req1.Methods[typeof(IBaseType31).GetMethod("IfcMethod")];

            Assert.That(member1.FullName, Is.EqualTo("Remotion.Mixins.UnitTests.Core.TestDomain.IBaseType31.IfcMethod"));
            Assert.That(member1.DeclaringRequirement, Is.SameAs(req1));
            Assert.That(member1.Parent, Is.SameAs(req1));

            Assert.That(member1.InterfaceMethod, Is.EqualTo(typeof(IBaseType31).GetMethod("IfcMethod")));
            Assert.That(member1.ImplementingMethod, Is.EqualTo(targetClass.Methods[typeof(BaseType3).GetMethod("IfcMethod")]));

            RequiredNextCallTypeDefinition req2 = targetClass.RequiredNextCallTypes[typeof(IBT3Mixin4)];

            Assert.That(req2.Methods.Count, Is.EqualTo(typeof(IBT3Mixin4).GetMembers().Length));

            RequiredMethodDefinition member2 = req2.Methods[typeof(IBT3Mixin4).GetMethod("Foo")];

            Assert.That(member2.FullName, Is.EqualTo("Remotion.Mixins.UnitTests.Core.TestDomain.IBT3Mixin4.Foo"));
            Assert.That(member2.DeclaringRequirement, Is.SameAs(req2));
            Assert.That(member2.Parent, Is.SameAs(req2));

            Assert.That(member2.InterfaceMethod, Is.EqualTo(typeof(IBT3Mixin4).GetMethod("Foo")));
            Assert.That(member2.ImplementingMethod, Is.EqualTo(targetClass.Mixins[typeof(BT3Mixin4)].Methods[typeof(BT3Mixin4).GetMethod("Foo")]));

            using (MixinConfiguration.BuildFromActive().ForClass <BaseType3> ().Clear().AddMixins(typeof(BT3Mixin7Base), typeof(BT3Mixin4)).EnterScope())
            {
                TargetClassDefinition targetClass2 = DefinitionObjectMother.GetActiveTargetClassDefinition(typeof(BaseType3));

                RequiredNextCallTypeDefinition req3 = targetClass2.RequiredNextCallTypes[typeof(ICBaseType3BT3Mixin4)];
                Assert.That(req3.Methods.Count, Is.EqualTo(0));

                req3 = targetClass2.RequiredNextCallTypes[typeof(ICBaseType3)];
                Assert.That(req3.Methods.Count, Is.EqualTo(0));

                req3 = targetClass2.RequiredNextCallTypes[typeof(IBaseType31)];
                Assert.That(req3.Methods.Count, Is.EqualTo(1));

                req3 = targetClass2.RequiredNextCallTypes[typeof(IBT3Mixin4)];
                Assert.That(req3.Methods.Count, Is.EqualTo(1));

                RequiredMethodDefinition member3 = req3.Methods[typeof(IBT3Mixin4).GetMethod("Foo")];
                Assert.That(member3, Is.Not.Null);
                Assert.That(member3.ImplementingMethod, Is.EqualTo(targetClass2.Mixins[typeof(BT3Mixin4)].Methods[typeof(BT3Mixin4).GetMethod("Foo")]));
            }
        }
예제 #3
0
        // Required base call method implemented by extension -> either as an overridde or not
        // If an overridde, delegate to next in chain, else simply delegate to the extension implementing it field
        private void ImplementBaseCallForRequirementOnMixin(RequiredMethodDefinition requiredMethod)
        {
            var methodImplementation = _type.AddExplicitOverride(requiredMethod.InterfaceMethod, ctx => Expression.Default(ctx.ReturnType));

            if (requiredMethod.ImplementingMethod.Base == null) // this is not an override, call method directly on extension
            {
                methodImplementation.SetBody(ctx => _nextCallMethodGenerator.CreateBaseCallToTarget(ctx, requiredMethod.ImplementingMethod));
            }
            else // this is an override, go to next in chain
            {
                // a base call for this has already been implemented as an overriden method, but we explicitly implement the call chains anyway: it's
                // slightly easier and better for performance
                Assertion.IsTrue(_overriddenMethodToImplementationMap.ContainsKey(requiredMethod.ImplementingMethod.Base));
                methodImplementation.SetBody(ctx => _nextCallMethodGenerator.CreateBaseCallToNextInChain(ctx, requiredMethod.ImplementingMethod.Base));
            }
        }
예제 #4
0
        // Required base call method implemented by "this" -> either overridden or not
        // If overridden, delegate to next in chain, else simply delegate to "this" field
        private void ImplementBaseCallForRequirementOnTarget(RequiredMethodDefinition requiredMethod)
        {
            var methodImplementation = _type.AddExplicitOverride(requiredMethod.InterfaceMethod, ctx => Expression.Default(ctx.ReturnType));

            if (requiredMethod.ImplementingMethod.Overrides.Count == 0) // this is not an overridden method, call method directly on _this
            {
                methodImplementation.SetBody(ctx => _nextCallMethodGenerator.CreateBaseCallToTarget(ctx, requiredMethod.ImplementingMethod));
            }
            else // this is an override, go to next in chain
            {
                // a base call for this might already have been implemented as an overriden method, but we explicitly implement the call chains anyway: it's
                // slightly easier and better for performance
                Assertion.IsFalse(_targetClassDefinition.Methods.ContainsKey(requiredMethod.InterfaceMethod));
                methodImplementation.SetBody(ctx => _nextCallMethodGenerator.CreateBaseCallToNextInChain(ctx, requiredMethod.ImplementingMethod));
            }
        }
        private static void CheckRequiredMethods(RequirementDefinitionBase requirement, ClassDefinitionBase implementer, string memberPrefix)
        {
            BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

            Assert.That(requirement.Methods.Count, Is.EqualTo(5));

            RequiredMethodDefinition method = requirement.Methods[typeof(IMixinRequiringAllMembersRequirements).GetMethod("Method", bf)];

            Assert.That(method, Is.Not.Null);
            Assert.That(method.InterfaceMethod, Is.EqualTo(typeof(IMixinRequiringAllMembersRequirements).GetMethod("Method", bf)));
            Assert.That(method.ImplementingMethod, Is.SameAs(implementer.Methods[implementer.Type.GetMethod(memberPrefix + "Method", bf)]));

            RequiredMethodDefinition propertyGetter = requirement.Methods[typeof(IMixinRequiringAllMembersRequirements).GetMethod("get_Property", bf)];

            Assert.That(propertyGetter, Is.Not.Null);
            Assert.That(propertyGetter.InterfaceMethod, Is.EqualTo(typeof(IMixinRequiringAllMembersRequirements).GetMethod("get_Property", bf)));
            Assert.That(propertyGetter.ImplementingMethod, Is.SameAs(implementer.Properties[implementer.Type.GetProperty(memberPrefix + "Property", bf)].GetMethod));

            RequiredMethodDefinition propertySetter = requirement.Methods[typeof(IMixinRequiringAllMembersRequirements).GetMethod("set_Property", bf)];

            Assert.That(propertySetter, Is.Not.Null);
            Assert.That(propertySetter.InterfaceMethod, Is.EqualTo(typeof(IMixinRequiringAllMembersRequirements).GetMethod("set_Property", bf)));
            Assert.That(propertySetter.ImplementingMethod, Is.SameAs(implementer.Properties[implementer.Type.GetProperty(memberPrefix + "Property", bf)].SetMethod));

            RequiredMethodDefinition eventAdder = requirement.Methods[typeof(IMixinRequiringAllMembersRequirements).GetMethod("add_Event", bf)];

            Assert.That(eventAdder, Is.Not.Null);
            Assert.That(eventAdder.InterfaceMethod, Is.EqualTo(typeof(IMixinRequiringAllMembersRequirements).GetMethod("add_Event", bf)));
            Assert.That(eventAdder.ImplementingMethod, Is.SameAs(implementer.Events[implementer.Type.GetEvent(memberPrefix + "Event", bf)].AddMethod));

            RequiredMethodDefinition eventRemover = requirement.Methods[typeof(IMixinRequiringAllMembersRequirements).GetMethod("remove_Event", bf)];

            Assert.That(eventRemover, Is.Not.Null);
            Assert.That(eventRemover.InterfaceMethod, Is.EqualTo(typeof(IMixinRequiringAllMembersRequirements).GetMethod("remove_Event", bf)));
            Assert.That(eventRemover.ImplementingMethod, Is.SameAs(implementer.Events[implementer.Type.GetEvent(memberPrefix + "Event", bf)].RemoveMethod));
        }
 public void Visit(RequiredMethodDefinition requiredMethod)
 {
     ArgumentUtility.CheckNotNull("requiredMethod", requiredMethod);
     CheckRules(_requiredMethodRules, requiredMethod);
 }
예제 #7
0
 private void ImplementRequiredDuckMethod(RequiredMethodDefinition requiredMethod)
 {
     _concreteTarget.AddExplicitOverride(
         requiredMethod.InterfaceMethod,
         ctx => Expression.Call(ctx.This, requiredMethod.ImplementingMethod.MethodInfo, ctx.Parameters.Cast <Expression>()));
 }
        public void DefaultConfiguration_EverythingIsVisitedOnce()
        {
            var activeConfiguration = MixinConfiguration.ActiveConfiguration;

            ValidationLogData log;

            using (MixinConfiguration.BuildNew().EnterScope())
            {
                log = activeConfiguration.Validate();
            }

            var validationResults  = log.GetResults();
            var visitedDefinitions = new HashSet <IVisitableDefinition>();

            foreach (ValidationResult result in validationResults)
            {
                var definition = result.ValidatedDefinition;
                Assert.That(visitedDefinitions.Contains(definition), Is.False, definition.ToString());
                visitedDefinitions.Add(definition);
            }

            TargetClassDefinition bt1 = DefinitionObjectMother.GetActiveTargetClassDefinition(typeof(BaseType1));

            AssertVisitedEquivalent(validationResults, bt1);
            TargetClassDefinition bt3 = DefinitionObjectMother.GetActiveTargetClassDefinition(typeof(BaseType3));

            AssertVisitedEquivalent(validationResults, bt3);
            TargetClassDefinition bt6 = DefinitionObjectMother.GetActiveTargetClassDefinition(typeof(BaseType6));

            AssertVisitedEquivalent(validationResults, bt6);
            TargetClassDefinition btWithAdditionalDependencies =
                DefinitionObjectMother.GetActiveTargetClassDefinition(typeof(TargetClassWithAdditionalDependencies));

            AssertVisitedEquivalent(validationResults, btWithAdditionalDependencies);
            TargetClassDefinition targetWithSuppressAttribute =
                DefinitionObjectMother.GetActiveTargetClassDefinition(typeof(TargetClassSuppressingBT1Attribute));

            AssertVisitedEquivalent(validationResults, targetWithSuppressAttribute);
            TargetClassDefinition targetWithNonIntroducedAttribute =
                DefinitionObjectMother.GetActiveTargetClassDefinition(typeof(TargetClassWithMixinNonIntroducingSimpleAttribute));

            AssertVisitedEquivalent(validationResults, targetWithSuppressAttribute);
            TargetClassDefinition targetClassWinningOverMixinAddingBT1AttributeToMember =
                DefinitionObjectMother.GetActiveTargetClassDefinition(typeof(TargetClassWinningOverMixinAddingBT1AttributeToMember));

            AssertVisitedEquivalent(validationResults, targetClassWinningOverMixinAddingBT1AttributeToMember);

            MixinDefinition bt1m1 = bt1.Mixins[typeof(BT1Mixin1)];

            AssertVisitedEquivalent(validationResults, bt1m1);
            MixinDefinition bt1m2 = bt1.Mixins[typeof(BT1Mixin2)];

            AssertVisitedEquivalent(validationResults, bt1m2);
            MixinDefinition bt3m1 = bt3.Mixins[typeof(BT3Mixin1)];

            AssertVisitedEquivalent(validationResults, bt3m1);
            MixinDefinition bt3m2 = bt3.Mixins[typeof(BT3Mixin2)];

            AssertVisitedEquivalent(validationResults, bt3m2);
            MixinDefinition bt3m3 = bt3.GetMixinByConfiguredType(typeof(BT3Mixin3 <,>));

            AssertVisitedEquivalent(validationResults, bt3m3);
            MixinDefinition bt3m4 = bt3.Mixins[typeof(BT3Mixin4)];

            AssertVisitedEquivalent(validationResults, bt3m4);
            MixinDefinition bt3m5 = bt3.Mixins[typeof(BT3Mixin5)];

            AssertVisitedEquivalent(validationResults, bt3m5);
            MixinDefinition mixinWithSuppressedAttribute = targetWithSuppressAttribute.Mixins[typeof(MixinAddingBT1Attribute)];

            AssertVisitedEquivalent(validationResults, mixinWithSuppressedAttribute);
            MixinDefinition mixinWithNonIntroducedAttribute = targetWithNonIntroducedAttribute.Mixins[typeof(MixinNonIntroducingSimpleAttribute)];

            AssertVisitedEquivalent(validationResults, mixinWithNonIntroducedAttribute);

            MethodDefinition m1 = bt1.Methods[typeof(BaseType1).GetMethod("VirtualMethod", Type.EmptyTypes)];

            AssertVisitedEquivalent(validationResults, m1);
            MethodDefinition m2 = bt1.Methods[typeof(BaseType1).GetMethod("VirtualMethod", new[] { typeof(string) })];

            AssertVisitedEquivalent(validationResults, m2);
            MethodDefinition m3 = bt1m1.Methods[typeof(BT1Mixin1).GetMethod("VirtualMethod")];

            AssertVisitedEquivalent(validationResults, m3);
            MethodDefinition m4 = bt1m1.Methods[typeof(BT1Mixin1).GetMethod("IntroducedMethod")];

            AssertVisitedEquivalent(validationResults, m4);
            MethodDefinition memberWinningOverMixinAddingAttribute =
                targetClassWinningOverMixinAddingBT1AttributeToMember.Methods[
                    typeof(TargetClassWinningOverMixinAddingBT1AttributeToMember).GetMethod("VirtualMethod")];

            AssertVisitedEquivalent(validationResults, memberWinningOverMixinAddingAttribute);

            PropertyDefinition p1 = bt1.Properties[typeof(BaseType1).GetProperty("VirtualProperty")];

            AssertVisitedEquivalent(validationResults, p1);
            MethodDefinition m5 = p1.GetMethod;

            AssertVisitedEquivalent(validationResults, m5);
            MethodDefinition m6 = p1.SetMethod;

            AssertVisitedEquivalent(validationResults, m6);
            PropertyDefinition p2 = bt1m1.Properties[typeof(BT1Mixin1).GetProperty("VirtualProperty")];

            AssertVisitedEquivalent(validationResults, p2);

            EventDefinition e1 = bt1.Events[typeof(BaseType1).GetEvent("VirtualEvent")];

            AssertVisitedEquivalent(validationResults, e1);
            MethodDefinition m7 = e1.AddMethod;

            AssertVisitedEquivalent(validationResults, m7);
            MethodDefinition m8 = e1.RemoveMethod;

            AssertVisitedEquivalent(validationResults, m8);
            EventDefinition e2 = bt1m1.Events[typeof(BT1Mixin1).GetEvent("VirtualEvent")];

            AssertVisitedEquivalent(validationResults, e2);

            InterfaceIntroductionDefinition i1 = bt1m1.InterfaceIntroductions[typeof(IBT1Mixin1)];

            AssertVisitedEquivalent(validationResults, i1);
            MethodIntroductionDefinition im1 = i1.IntroducedMethods[typeof(IBT1Mixin1).GetMethod("IntroducedMethod")];

            AssertVisitedEquivalent(validationResults, im1);
            PropertyIntroductionDefinition im2 = i1.IntroducedProperties[typeof(IBT1Mixin1).GetProperty("IntroducedProperty")];

            AssertVisitedEquivalent(validationResults, im2);
            EventIntroductionDefinition im3 = i1.IntroducedEvents[typeof(IBT1Mixin1).GetEvent("IntroducedEvent")];

            AssertVisitedEquivalent(validationResults, im3);

            AttributeDefinition a1 = bt1.CustomAttributes.GetFirstItem(typeof(BT1Attribute));

            AssertVisitedEquivalent(validationResults, a1);
            AttributeDefinition a2 = bt1m1.CustomAttributes.GetFirstItem(typeof(BT1M1Attribute));

            AssertVisitedEquivalent(validationResults, a2);
            AttributeDefinition a3 = m1.CustomAttributes.GetFirstItem(typeof(BT1Attribute));

            AssertVisitedEquivalent(validationResults, a3);
            AttributeDefinition a4 = p1.CustomAttributes.GetFirstItem(typeof(BT1Attribute));

            AssertVisitedEquivalent(validationResults, a4);
            AttributeDefinition a5 = e1.CustomAttributes.GetFirstItem(typeof(BT1Attribute));

            AssertVisitedEquivalent(validationResults, a5);
            AttributeDefinition a6 = im1.ImplementingMember.CustomAttributes.GetFirstItem(typeof(BT1M1Attribute));

            AssertVisitedEquivalent(validationResults, a6);
            AttributeDefinition a7 = im2.ImplementingMember.CustomAttributes.GetFirstItem(typeof(BT1M1Attribute));

            AssertVisitedEquivalent(validationResults, a7);
            AttributeDefinition a8 = im3.ImplementingMember.CustomAttributes.GetFirstItem(typeof(BT1M1Attribute));

            AssertVisitedEquivalent(validationResults, a8);

            AttributeIntroductionDefinition ai1 = bt1.ReceivedAttributes.GetFirstItem(typeof(BT1M1Attribute));

            AssertVisitedEquivalent(validationResults, ai1);
            AttributeIntroductionDefinition ai2 = m1.ReceivedAttributes.GetFirstItem(typeof(BT1M1Attribute));

            AssertVisitedEquivalent(validationResults, ai2);

            RequiredNextCallTypeDefinition bc1 = bt3.RequiredNextCallTypes[typeof(IBaseType34)];

            AssertVisitedEquivalent(validationResults, bc1);
            RequiredMethodDefinition bcm1 = bc1.Methods[typeof(IBaseType34).GetMethod("IfcMethod")];

            AssertVisitedEquivalent(validationResults, bcm1);

            RequiredTargetCallTypeDefinition ft1 = bt3.RequiredTargetCallTypes[typeof(IBaseType32)];

            AssertVisitedEquivalent(validationResults, ft1);
            RequiredMethodDefinition fm1 = ft1.Methods[typeof(IBaseType32).GetMethod("IfcMethod")];

            AssertVisitedEquivalent(validationResults, fm1);

            RequiredMixinTypeDefinition rmt1 = btWithAdditionalDependencies.RequiredMixinTypes[typeof(IMixinWithAdditionalClassDependency)];

            AssertVisitedEquivalent(validationResults, rmt1);
            RequiredMixinTypeDefinition rmt2 = btWithAdditionalDependencies.RequiredMixinTypes[typeof(MixinWithNoAdditionalDependency)];

            AssertVisitedEquivalent(validationResults, rmt2);

            ComposedInterfaceDependencyDefinition cid1 = bt6.ComposedInterfaceDependencies[typeof(ICBT6Mixin1)];

            AssertVisitedEquivalent(validationResults, cid1);

            TargetCallDependencyDefinition td1 = bt3m1.TargetCallDependencies[typeof(IBaseType31)];

            AssertVisitedEquivalent(validationResults, td1);

            NextCallDependencyDefinition bd1 = bt3m1.NextCallDependencies[typeof(IBaseType31)];

            AssertVisitedEquivalent(validationResults, bd1);

            MixinDependencyDefinition md1 =
                btWithAdditionalDependencies.Mixins[typeof(MixinWithAdditionalClassDependency)].MixinDependencies[typeof(MixinWithNoAdditionalDependency)];

            AssertVisitedEquivalent(validationResults, md1);

            SuppressedAttributeIntroductionDefinition suppressedAttribute1 =
                mixinWithSuppressedAttribute.SuppressedAttributeIntroductions.GetFirstItem(typeof(BT1Attribute));

            AssertVisitedEquivalent(validationResults, suppressedAttribute1);

            NonAttributeIntroductionDefinition nonIntroducedAttribute1 =
                mixinWithNonIntroducedAttribute.NonAttributeIntroductions.GetFirstItem(typeof(SimpleAttribute));

            AssertVisitedEquivalent(validationResults, nonIntroducedAttribute1);
            NonAttributeIntroductionDefinition nonIntroducedAttribute2 = memberWinningOverMixinAddingAttribute.Overrides[0].NonAttributeIntroductions[0];

            AssertVisitedEquivalent(validationResults, nonIntroducedAttribute2);
        }