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 }
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); }
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)); } }
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)); }
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)); }
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); } }
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); }
/// <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)); } }
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)); }
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)); }
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)); }
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); } }
public override MethodInfo GetBaseDefinition() { return(_baseMethod != null?MethodBaseDefinitionCache.GetBaseDefinition(_baseMethod) : this); }
public override MethodInfo GetBaseDefinition() { return(MethodBaseDefinitionCache.GetBaseDefinition(InnerMethod)); }