예제 #1
0
        internal void BuildImplementation(AbcInstance implInstance, IType implType, IMethod ifaceMethod, AbcMethod ifaceAbcMethod)
        {
            if (implInstance == null)
            {
                throw new ArgumentNullException("implInstance");
            }
            if (implInstance.IsInterface)
            {
                return;
            }

            if (implType == null)
            {
                throw new ArgumentNullException("implType");
            }
            if (implType.IsInterface)
            {
                return;
            }

            var impl = implType.FindImplementation(ifaceMethod, true, false);

            if (impl == null)
            {
                throw new InvalidOperationException(
                          string.Format("Unable to find implementation for method {0} in type {1}",
                                        ifaceMethod.FullName, implType.FullName));
            }

            impl = impl.ResolveGenericInstance(implType, ifaceMethod);

            var abcImpl = Build(impl) as AbcMethod;

            // determine whether we should create explicit impl
            if (abcImpl == null || implInstance.IsForeign ||
                ReferenceEquals(impl.DeclaringType, implType) ||
                impl.IsExplicitImplementation ||
                impl.Implements.Any(x => x == ifaceMethod))
            {
                return;
            }

            // do not create explicit impl if interface is implemented in base type
            var iface      = ifaceMethod.DeclaringType;
            var baseIfaces = implType.BaseTypes().SelectMany(x => x.Interfaces.SelectMany(i => i.Interfaces.Append(i)));

            if (baseIfaces.Any(x => ReferenceEquals(x, iface)))
            {
                return;
            }

            if (Equals(abcImpl.TraitName, ifaceAbcMethod.TraitName) ||
                (abcImpl.TraitName != null && ifaceAbcMethod.TraitName != null &&
                 abcImpl.TraitName.IsGlobalName(ifaceAbcMethod.TraitName.NameString) &&
                 HasFlashIfaceName(ifaceAbcMethod)))
            {
                return;
            }

            BuildExplicitImplementation(implInstance, abcImpl, ifaceMethod, ifaceAbcMethod);
        }