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