示例#1
0
        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));
        }