コード例 #1
0
        public T[] RemoveOverriddenMembers <T> (IEnumerable <T> members) where T : MemberInfo
        {
            ArgumentUtility.CheckNotNull("members", members);

            // maps the associated methods' base definitions to the most derived member in the list; we adjust this dictionary as we walk the members
            var baseDefinitionsToMostDerivedMembers = new Dictionary <MethodInfo, T> ();

            foreach (var member in members)
            {
                var associatedMethodsForMember = ReflectionUtility.GetAssociatedMethods(member);
                foreach (var associatedMethodForMember in associatedMethodsForMember)
                {
                    // check whether we already have a member for that base definition; if yes, check which one is more derived
                    var baseDefinition = MethodBaseDefinitionCache.GetBaseDefinition(associatedMethodForMember);
                    T   existingMember;
                    if (!baseDefinitionsToMostDerivedMembers.TryGetValue(baseDefinition, out existingMember) || // we have no member for the base definition...
                        existingMember.DeclaringType.IsAssignableFrom(member.DeclaringType)) // the current one is more derived...
                    {
                        baseDefinitionsToMostDerivedMembers[baseDefinition] = member;        // ...so store the current member
                    }
                }
            }

            return(baseDefinitionsToMostDerivedMembers.Values.Distinct().ToArray()); // Distinct required for members that have more than one accessor
        }
コード例 #2
0
        public MutableType(
            MutableType declaringType,
            Type baseType,
            string name,
            string @namespace,
            TypeAttributes attributes,
            IInterfaceMappingComputer interfaceMappingComputer,
            IMutableMemberFactory mutableMemberFactory)
            : base(name, @namespace, attributes, null, EmptyTypes)
        {
            // Base type may be null (for interfaces).
            // Declaring type may be null.
            ArgumentUtility.CheckNotNull("interfaceMappingComputer", interfaceMappingComputer);
            ArgumentUtility.CheckNotNull("mutableMemberFactory", mutableMemberFactory);

            SetDeclaringType(declaringType);
            SetBaseType(baseType);

            _interfaceMappingComputer = interfaceMappingComputer;
            _mutableMemberFactory     = mutableMemberFactory;

            _allMethods = GetAllBaseMethods(baseType);

            _allMethodsIndex = new Dictionary <MethodInfo, int>();
            for (int index = 0; index < _allMethods.Count; index++)
            {
                _allMethodsIndex.Add(MethodBaseDefinitionCache.GetBaseDefinition(_allMethods[index]), index);
            }

            _baseDefinitionsOfAbstractMethods = GetBaseDefinitionsOfAbstractMethods(baseType);
        }
コード例 #3
0
 private void ValidateAccessor(PropertyInfo property, MethodInfo accessor, bool isMixinProperty, string accessorDescription)
 {
     if (isMixinProperty)
     {
         ValidateMixinAccessor(property, accessor);
     }
     else
     {
         ValidateNonMixinAccessor(property, accessor, accessorDescription);
         _validatedMethods.Add(MethodBaseDefinitionCache.GetBaseDefinition(accessor));
     }
 }
コード例 #4
0
        public void GetBaseDefinition_ForStandardMethodInfo_Cached()
        {
            var standardMethodInfoMock = new Mock <MethodInfo> (MockBehavior.Strict);

            var fakeMethodDefinition = ReflectionObjectMother.GetSomeMethod();

            standardMethodInfoMock.Setup(mock => mock.GetBaseDefinition()).Returns(fakeMethodDefinition).Verifiable();

            var result1 = MethodBaseDefinitionCache.GetBaseDefinition(standardMethodInfoMock.Object);
            var result2 = MethodBaseDefinitionCache.GetBaseDefinition(standardMethodInfoMock.Object);

            standardMethodInfoMock.Verify();

            Assert.That(result1, Is.SameAs(fakeMethodDefinition));
            Assert.That(result2, Is.SameAs(fakeMethodDefinition));
        }
コード例 #5
0
        public void GetBaseDefinition_ForStandardMethodInfo_Cached()
        {
            var standardMethodInfoMock = MockRepository.GenerateStrictMock <MethodInfo>();

            var fakeMethodDefinition = ReflectionObjectMother.GetSomeMethod();

            standardMethodInfoMock.Expect(mock => mock.GetBaseDefinition()).Return(fakeMethodDefinition).Repeat.Once();

            var result1 = MethodBaseDefinitionCache.GetBaseDefinition(standardMethodInfoMock);
            var result2 = MethodBaseDefinitionCache.GetBaseDefinition(standardMethodInfoMock);

            standardMethodInfoMock.VerifyAllExpectations();

            Assert.That(result1, Is.SameAs(fakeMethodDefinition));
            Assert.That(result2, Is.SameAs(fakeMethodDefinition));
        }
コード例 #6
0
        private void UpdateAbstractMethods(MutableMethodInfo method)
        {
            var baseDefinition          = MethodBaseDefinitionCache.GetBaseDefinition(method);
            var explicitBaseDefinitions = method.AddedExplicitBaseDefinitions;

            if (method.IsAbstract)
            {
                _baseDefinitionsOfAbstractMethods.Add(baseDefinition);
                _baseDefinitionsOfAbstractMethods.UnionWith(explicitBaseDefinitions);
            }
            else
            {
                _baseDefinitionsOfAbstractMethods.Remove(baseDefinition);
                _baseDefinitionsOfAbstractMethods.ExceptWith(explicitBaseDefinitions);
            }
        }
コード例 #7
0
        private void UpdateAllMethods(MutableMethodInfo method)
        {
            var overriddenBaseDefinition = MethodBaseDefinitionCache.GetBaseDefinition(method);
            int existingIndex;

            if (_allMethodsIndex.TryGetValue(overriddenBaseDefinition, out existingIndex))
            {
                // Remove overridden methods.
                _allMethods[existingIndex] = null;
                _allMethodsIndex.Remove(overriddenBaseDefinition);
            }
            _allMethods.Add(method);
            int newMethodIndex = _allMethods.Count - 1;

            _allMethodsIndex.Add(method, newMethodIndex);
        }
コード例 #8
0
        /// <summary>
        /// Adds an explicit base definition, i.e., a root <see cref="MethodInfo"/> explicitly overridden by this <see cref="MethodInfo"/>.
        /// </summary>
        /// <param name="overriddenMethodBaseDefinition">The overridden method base definition.</param>
        /// <remarks>
        /// This method does not affect <see cref="GetBaseDefinition"/> or <see cref="BaseMethod"/>, both of which only return implicitly overridden
        /// methods. Methods can override both a single method implicitly and multiple methods explicitly.
        /// </remarks>
        public void AddExplicitBaseDefinition(MethodInfo overriddenMethodBaseDefinition)
        {
            ArgumentUtility.CheckNotNull("overriddenMethodBaseDefinition", overriddenMethodBaseDefinition);

            if (!IsVirtual)
            {
                // TODO 4695: Adapt message
                var message = string.Format("Cannot add an explicit base definition to the non-virtual method '{0}'.", Name);
                throw new NotSupportedException(message);
            }

            if (!overriddenMethodBaseDefinition.IsVirtual || overriddenMethodBaseDefinition.IsFinal)
            {
                throw new ArgumentException("Method must be virtual and non-final.", "overriddenMethodBaseDefinition");
            }

            if (!MethodSignature.AreEqual(this, overriddenMethodBaseDefinition))
            {
                throw new ArgumentException("Method signatures must be equal.", "overriddenMethodBaseDefinition");
            }

            if (!overriddenMethodBaseDefinition.DeclaringType.IsTypePipeAssignableFrom(DeclaringType))
            {
                throw new ArgumentException("The overridden method must be from the same type hierarchy.", "overriddenMethodBaseDefinition");
            }

            if (MethodBaseDefinitionCache.GetBaseDefinition(overriddenMethodBaseDefinition) != overriddenMethodBaseDefinition)
            {
                throw new ArgumentException(
                          "The given method must be a root method definition. (Use GetBaseDefinition to get a root method.)",
                          "overriddenMethodBaseDefinition");
            }

            // TODO: check all mutable methods not just the current one
            if (_addedExplicitBaseDefinitions.Contains(overriddenMethodBaseDefinition))
            {
                throw new InvalidOperationException("The given method has already been added to the list of explicit base definitions.");
            }

            _addedExplicitBaseDefinitions.Add(overriddenMethodBaseDefinition);
            if (ExplicitBaseDefinitionAdded != null)
            {
                ExplicitBaseDefinitionAdded(this, new ExplicitBaseDefinitionsAddedEventArgs(overriddenMethodBaseDefinition));
            }
        }
コード例 #9
0
        public MutableMethodInfo GetOrCreateOverride(MutableType declaringType, MethodInfo overriddenMethod, out bool isNewlyCreated)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNull("overriddenMethod", overriddenMethod);
            Assertion.IsNotNull(overriddenMethod.DeclaringType);

            if (!overriddenMethod.IsVirtual)
            {
                throw new ArgumentException("Only virtual methods can be overridden.", "overriddenMethod");
            }

            CheckIsNotMethodInstantiation(overriddenMethod, "overriddenMethod");

            if (!declaringType.IsSubclassOf(overriddenMethod.DeclaringType))
            {
                var message = string.Format("Method is declared by type '{0}' outside of the proxy base class hierarchy.", overriddenMethod.DeclaringType.Name);
                throw new ArgumentException(message, "overriddenMethod");
            }

            var baseDefinition          = MethodBaseDefinitionCache.GetBaseDefinition(overriddenMethod);
            var existingMutableOverride = _relatedMethodFinder.GetOverride(baseDefinition, declaringType.AddedMethods);

            if (existingMutableOverride != null)
            {
                isNewlyCreated = false;
                return(existingMutableOverride);
            }
            isNewlyCreated = true;

            var baseMethod   = _relatedMethodFinder.GetMostDerivedOverride(baseDefinition, declaringType.BaseType);
            var bodyProvider = CreateBodyProvider(baseMethod);

            var needsExplicitOverride = _relatedMethodFinder.IsShadowed(baseDefinition, declaringType.GetAllMethods());

            if (needsExplicitOverride)
            {
                return(PrivateCreateExplicitOverrideAllowAbstract(declaringType, baseDefinition, bodyProvider));
            }

            var attributes = MethodOverrideUtility.GetAttributesForImplicitOverride(baseMethod);

            return(CreateMethod(declaringType, baseMethod, baseMethod.Name, attributes, bodyProvider));
        }
コード例 #10
0
        public void GetBaseDefinition_ForCustomMethodInfo_NotCached()
        {
            var customMethodInfoMock = new Mock <CustomMethodInfo> (
                MockBehavior.Strict, ReflectionObjectMother.GetSomeType(), "method", MethodAttributes.Public, null, Type.EmptyTypes);

            var fakeMethodDefinition1 = ReflectionObjectMother.GetSomeMethod();
            var fakeMethodDefinition2 = ReflectionObjectMother.GetSomeMethod();

            var sequence = new MockSequence();

            customMethodInfoMock.InSequence(sequence).Setup(mock => mock.GetBaseDefinition()).Returns(fakeMethodDefinition1);
            customMethodInfoMock.InSequence(sequence).Setup(mock => mock.GetBaseDefinition()).Returns(fakeMethodDefinition2);

            var result1 = MethodBaseDefinitionCache.GetBaseDefinition(customMethodInfoMock.Object);
            var result2 = MethodBaseDefinitionCache.GetBaseDefinition(customMethodInfoMock.Object);

            customMethodInfoMock.Verify();

            Assert.That(result1, Is.SameAs(fakeMethodDefinition1));
            Assert.That(result2, Is.SameAs(fakeMethodDefinition2));
        }
コード例 #11
0
        public void GetBaseDefinition_ForCustomMethodInfo_NotCached()
        {
            var customMethodInfoMock = MockRepository.GenerateStrictMock <CustomMethodInfo> (
                ReflectionObjectMother.GetSomeType(), "method", MethodAttributes.Public, null, Type.EmptyTypes);

            var fakeMethodDefinition1 = ReflectionObjectMother.GetSomeMethod();

            customMethodInfoMock.Expect(mock => mock.GetBaseDefinition()).Return(fakeMethodDefinition1).Repeat.Once();

            var fakeMethodDefinition2 = ReflectionObjectMother.GetSomeMethod();

            customMethodInfoMock.Expect(mock => mock.GetBaseDefinition()).Return(fakeMethodDefinition2).Repeat.Once();

            var result1 = MethodBaseDefinitionCache.GetBaseDefinition(customMethodInfoMock);
            var result2 = MethodBaseDefinitionCache.GetBaseDefinition(customMethodInfoMock);

            customMethodInfoMock.VerifyAllExpectations();

            Assert.That(result1, Is.SameAs(fakeMethodDefinition1));
            Assert.That(result2, Is.SameAs(fakeMethodDefinition2));
        }
コード例 #12
0
        private void ValidateRemainingMethods(Type currentType)
        {
            foreach (MethodInfo method in currentType.GetMethods(_declaredInfrastructureBindingFlags))
            {
                if (method.IsAbstract && !_validatedMethods.Contains(MethodBaseDefinitionCache.GetBaseDefinition(method)))
                {
                    throw new NonInterceptableTypeException(
                              string.Format(
                                  "Cannot instantiate type {0} as its member {1} (on type {2}) is abstract (and not an automatic property).",
                                  _baseType.FullName,
                                  method.Name,
                                  currentType.Name),
                              _baseType);
                }

                _validatedMethods.Add(MethodBaseDefinitionCache.GetBaseDefinition(method));
            }

            if (currentType.BaseType != null)
            {
                ValidateRemainingMethods(currentType.BaseType);
            }
        }
コード例 #13
0
 public override MethodInfo GetBaseDefinition()
 {
     return(_baseMethod != null?MethodBaseDefinitionCache.GetBaseDefinition(_baseMethod) : this);
 }
コード例 #14
0
 public override MethodInfo GetBaseDefinition()
 {
     return(MethodBaseDefinitionCache.GetBaseDefinition(InnerMethod));
 }