Example #1
0
        void MapInterfaceMethodsInTypeHierarchy(TypeDefinition type)
        {
            if (!type.HasInterfaces)
            {
                return;
            }

            // Foreach interface and for each newslot virtual method on the interface, try
            // to find the method implementation and record it.
            foreach (var interfaceImpl in type.GetInflatedInterfaces())
            {
                foreach (MethodReference interfaceMethod in interfaceImpl.InflatedInterface.GetMethods())
                {
                    MethodDefinition resolvedInterfaceMethod = interfaceMethod.Resolve();
                    if (resolvedInterfaceMethod == null)
                    {
                        continue;
                    }

                    // TODO-NICE: if the interface method is implemented explicitly (with an override),
                    // we shouldn't need to run the below logic. This results in linker potentially
                    // keeping more methods than needed.

                    if (!resolvedInterfaceMethod.IsVirtual ||
                        resolvedInterfaceMethod.IsFinal ||
                        !resolvedInterfaceMethod.IsNewSlot)
                    {
                        continue;
                    }

                    // Try to find an implementation with a name/sig match on the current type
                    MethodDefinition exactMatchOnType = TryMatchMethod(type, interfaceMethod);
                    if (exactMatchOnType != null)
                    {
                        AnnotateMethods(resolvedInterfaceMethod, exactMatchOnType);
                        continue;
                    }

                    // Next try to find an implementation with a name/sig match in the base hierarchy
                    var @base = GetBaseMethodInTypeHierarchy(type, interfaceMethod);
                    if (@base != null)
                    {
                        AnnotateMethods(resolvedInterfaceMethod, @base, interfaceImpl.OriginalImpl);
                        continue;
                    }

                    // Look for a default implementation last.
                    foreach (var defaultImpl in GetDefaultInterfaceImplementations(type, resolvedInterfaceMethod))
                    {
                        Annotations.AddDefaultInterfaceImplementation(resolvedInterfaceMethod, type, defaultImpl);
                    }
                }
            }
        }