|
// 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.Generic;
using ILLink.Shared.TypeSystemProxy;
using Mono.Cecil;
namespace Mono.Linker
{
sealed class TypeHierarchyCache
{
[Flags]
private enum HierarchyFlags
{
IsSystemType = 0x01,
IsSystemReflectionIReflect = 0x02,
}
readonly Dictionary<TypeDefinition, HierarchyFlags> _cache = new Dictionary<TypeDefinition, HierarchyFlags> ();
readonly LinkContext context;
public TypeHierarchyCache (LinkContext context)
{
this.context = context;
}
private HierarchyFlags GetFlags (TypeDefinition resolvedType)
{
if (_cache.TryGetValue (resolvedType, out var flags)) {
return flags;
}
if (resolvedType.Name == "IReflect" && resolvedType.Namespace == "System.Reflection") {
flags |= HierarchyFlags.IsSystemReflectionIReflect;
}
TypeDefinition? baseType = resolvedType;
while (baseType != null) {
if (baseType.IsTypeOf (WellKnownType.System_Type)) {
flags |= HierarchyFlags.IsSystemType;
}
if (baseType.HasInterfaces) {
foreach (var iface in baseType.Interfaces) {
if (iface.InterfaceType.Name == "IReflect" && iface.InterfaceType.Namespace == "System.Reflection") {
flags |= HierarchyFlags.IsSystemReflectionIReflect;
}
}
}
baseType = context.TryResolve (baseType.BaseType);
}
if (resolvedType != null)
_cache.Add (resolvedType, flags);
return flags;
}
public bool IsSystemType (TypeDefinition type)
{
return (GetFlags (type) & HierarchyFlags.IsSystemType) != 0;
}
public bool IsSystemReflectionIReflect (TypeDefinition type)
{
return (GetFlags (type) & HierarchyFlags.IsSystemReflectionIReflect) != 0;
}
}
}
|