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); } } } }