| File: Linker\InterfaceImplementor.cs | Web Access |
| Project: src\runtime\src\tools\illink\src\linker\Mono.Linker.csproj (illink) |
// Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using Mono.Cecil; namespace Mono.Linker { public class InterfaceImplementor { /// <summary> /// The type that implements <see cref="InterfaceImplementor.InterfaceType"/>. /// </summary> public TypeDefinition Implementor { get; } /// <summary> /// The .interfaceimpl on <see cref="InterfaceImplementor.Implementor"/>that points to <see cref="InterfaceImplementor.InterfaceType"/> /// </summary> public InterfaceImplementation InterfaceImplementation { get; } /// <summary> /// The type of the interface that is implemented by <see cref="InterfaceImplementor.Implementor"/> /// </summary> public TypeDefinition InterfaceType { get; } public InterfaceImplementor(TypeDefinition implementor, InterfaceImplementation interfaceImplementation, TypeDefinition interfaceType, IMetadataResolver resolver) { Implementor = implementor; InterfaceImplementation = interfaceImplementation; InterfaceType = interfaceType; Debug.Assert(resolver.Resolve(interfaceImplementation.InterfaceType) == interfaceType); } public static InterfaceImplementor Create(TypeDefinition implementor, TypeDefinition interfaceType, IMetadataResolver resolver) { foreach (InterfaceImplementation iface in implementor.Interfaces) { if (resolver.Resolve(iface.InterfaceType) == interfaceType) { return new InterfaceImplementor(implementor, iface, interfaceType, resolver); } } Queue<TypeDefinition> ifacesToCheck = new(); ifacesToCheck.Enqueue(implementor); while (ifacesToCheck.Count > 0) { var currentIface = ifacesToCheck.Dequeue(); foreach (InterfaceImplementation ifaceImpl in currentIface.Interfaces) { var iface = resolver.Resolve(ifaceImpl.InterfaceType); if (iface == interfaceType) { return new InterfaceImplementor(implementor, ifaceImpl, interfaceType, resolver); } ifacesToCheck.Enqueue(iface); } } throw new InvalidOperationException($"Type '{implementor.FullName}' does not implement interface '{interfaceType.FullName}' directly or through any interfaces"); } } }