private InterfaceMapping CreateForAdded(MutableType mutableType, Type interfaceType) { // Only public virtual methods may implicitly implement interfaces, ignore shadowed methods. (ECMA-335, 6th edition, II.12.2) var implementationCandidates = mutableType .GetAllMethods().Where(m => m.IsPublic && !m.IsStatic) // Optimization: Don't use GetMethods(BindingFlags). .Where(m => m.IsVirtual) .ToLookup(m => new { m.Name, Signature = MethodSignature.Create(m) }); var interfaceMethods = interfaceType.GetMethods(); var targetMethods = interfaceMethods .Select(m => GetMostDerivedOrDefault(implementationCandidates[new { m.Name, Signature = MethodSignature.Create(m) }])) .ToArray(); return(new InterfaceMapping { InterfaceType = interfaceType, TargetType = mutableType, InterfaceMethods = interfaceMethods, TargetMethods = targetMethods }); }
private void CallAndCheckGetOrAddOverride( MethodInfo baseDefinition, MethodInfo inputMethod, MethodInfo baseMethod, bool isBaseDefinitionShadowed, string expectedParameterName, IEnumerable <MethodInfo> expectedAddedExplicitBaseDefinitions, string expectedOverrideMethodName, MethodAttributes expectedOverrideAttributes, MutableType mutableType = null, bool skipBodyProviderCheck = false) { mutableType = mutableType ?? _mutableType; _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(isBaseDefinitionShadowed) .Verifiable(); var fakeResult = SetupExpectationsForCreateMethod( _methodFactoryMock, mutableType, baseMethod, expectedParameterName, expectedOverrideMethodName, expectedOverrideAttributes, skipBodyProviderCheck); var result = _factory.GetOrCreateOverride(mutableType, inputMethod, out _isNewlyCreated); _methodFactoryMock.Verify(); _relatedMethodFinderMock.Verify(); Assert.That(_isNewlyCreated, Is.True); Assert.That(result, Is.SameAs(fakeResult)); Assert.That(result.AddedExplicitBaseDefinitions, Is.EqualTo(expectedAddedExplicitBaseDefinitions)); }
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)); }