Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make TypeComponentsCache trimmable #80726

Merged
merged 2 commits into from
Jan 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ namespace System.Reflection.Runtime.BindingFlagSupport
//==========================================================================================================================
internal sealed class ConstructorPolicies : MemberPolicies<ConstructorInfo>
{
public static readonly ConstructorPolicies Instance = new ConstructorPolicies();

public ConstructorPolicies() : base(MemberTypeIndex.Constructor) { }

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "Reflection implementation")]
public sealed override IEnumerable<ConstructorInfo> GetDeclaredMembers(TypeInfo typeInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ namespace System.Reflection.Runtime.BindingFlagSupport
//==========================================================================================================================
internal sealed class EventPolicies : MemberPolicies<EventInfo>
{
public static readonly EventPolicies Instance = new EventPolicies();

public EventPolicies() : base(MemberTypeIndex.Event) { }

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "Reflection implementation")]
public sealed override IEnumerable<EventInfo> GetDeclaredMembers(TypeInfo typeInfo)
Expand Down Expand Up @@ -67,7 +71,7 @@ public sealed override bool ImplicitlyOverrides(EventInfo? baseMember, EventInfo
{
MethodInfo? baseAccessor = GetAccessorMethod(baseMember!);
MethodInfo? derivedAccessor = GetAccessorMethod(derivedMember!);
return MemberPolicies<MethodInfo>.Default.ImplicitlyOverrides(baseAccessor, derivedAccessor);
return MethodPolicies.Instance.ImplicitlyOverrides(baseAccessor, derivedAccessor);
}

public sealed override bool OkToIgnoreAmbiguity(EventInfo m1, EventInfo m2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ namespace System.Reflection.Runtime.BindingFlagSupport
//==========================================================================================================================
internal sealed class FieldPolicies : MemberPolicies<FieldInfo>
{
public static readonly FieldPolicies Instance = new FieldPolicies();

public FieldPolicies() : base(MemberTypeIndex.Field) { }

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "Reflection implementation")]
public sealed override IEnumerable<FieldInfo> GetDeclaredMembers(TypeInfo typeInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ namespace System.Reflection.Runtime.BindingFlagSupport
//=================================================================================================================
internal abstract class MemberPolicies<M> where M : MemberInfo
{
public MemberPolicies(int index)
{
Index = index;
}

//=================================================================================================================
// Subclasses for specific MemberInfo types must override these:
//=================================================================================================================
Expand Down Expand Up @@ -184,55 +189,11 @@ private static bool GenericMethodAwareAreParameterTypesEqual(Type t1, Type t2)
return false;
}

static MemberPolicies()
{
Type t = typeof(M);
if (t.Equals(typeof(FieldInfo)))
{
MemberTypeIndex = BindingFlagSupport.MemberTypeIndex.Field;
Default = (MemberPolicies<M>)(object)(new FieldPolicies());
}
else if (t.Equals(typeof(MethodInfo)))
{
MemberTypeIndex = BindingFlagSupport.MemberTypeIndex.Method;
Default = (MemberPolicies<M>)(object)(new MethodPolicies());
}
else if (t.Equals(typeof(ConstructorInfo)))
{
MemberTypeIndex = BindingFlagSupport.MemberTypeIndex.Constructor;
Default = (MemberPolicies<M>)(object)(new ConstructorPolicies());
}
else if (t.Equals(typeof(PropertyInfo)))
{
MemberTypeIndex = BindingFlagSupport.MemberTypeIndex.Property; ;
Default = (MemberPolicies<M>)(object)(new PropertyPolicies());
}
else if (t.Equals(typeof(EventInfo)))
{
MemberTypeIndex = BindingFlagSupport.MemberTypeIndex.Event;
Default = (MemberPolicies<M>)(object)(new EventPolicies());
}
else if (t.Equals(typeof(Type)))
{
MemberTypeIndex = BindingFlagSupport.MemberTypeIndex.NestedType;
Default = (MemberPolicies<M>)(object)(new NestedTypePolicies());
}
else
{
Debug.Fail("Unknown MemberInfo type.");
}
}

//
// This is a singleton class one for each MemberInfo category: Return the appropriate one.
//
public static readonly MemberPolicies<M> Default;

//
// This returns a fixed value from 0 to MemberIndex.Count-1 with each possible type of M
// being assigned a unique index (see the MemberTypeIndex for possible values). This is useful
// for converting a type reference to M to an array index or switch case label.
//
public static readonly int MemberTypeIndex;
public int Index { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ namespace System.Reflection.Runtime.BindingFlagSupport
//==========================================================================================================================
internal sealed class MethodPolicies : MemberPolicies<MethodInfo>
{
public static readonly MethodPolicies Instance = new MethodPolicies();

public MethodPolicies() : base(MemberTypeIndex.Method) { }

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "Reflection implementation")]
public sealed override IEnumerable<MethodInfo> GetDeclaredMembers(TypeInfo typeInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ namespace System.Reflection.Runtime.BindingFlagSupport
//==========================================================================================================================
internal sealed class NestedTypePolicies : MemberPolicies<Type>
{
public static readonly NestedTypePolicies Instance = new NestedTypePolicies();

public NestedTypePolicies() : base(MemberTypeIndex.NestedType) { }

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "Reflection implementation")]
public sealed override IEnumerable<Type> GetDeclaredMembers(TypeInfo typeInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ namespace System.Reflection.Runtime.BindingFlagSupport
//==========================================================================================================================
internal sealed class PropertyPolicies : MemberPolicies<PropertyInfo>
{
public static readonly PropertyPolicies Instance = new PropertyPolicies();

public PropertyPolicies() : base(MemberTypeIndex.Property) { }

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "Reflection implementation")]
public sealed override IEnumerable<PropertyInfo> GetDeclaredMembers(TypeInfo typeInfo)
Expand Down Expand Up @@ -54,7 +58,7 @@ public sealed override bool ImplicitlyOverrides(PropertyInfo? baseMember, Proper
{
MethodInfo? baseAccessor = GetAccessorMethod(baseMember!);
MethodInfo? derivedAccessor = GetAccessorMethod(derivedMember!);
return MemberPolicies<MethodInfo>.Default.ImplicitlyOverrides(baseAccessor, derivedAccessor);
return MethodPolicies.Instance.ImplicitlyOverrides(baseAccessor, derivedAccessor);
}

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,10 @@ public QueriedMemberList<M> Filter(Func<M, bool> predicate)
//
// Filter by name and visibility from the ReflectedType.
//
public static QueriedMemberList<M> Create(RuntimeTypeInfo type, string optionalNameFilter, bool ignoreCase)
public static QueriedMemberList<M> Create(MemberPolicies<M> policies, RuntimeTypeInfo type, string optionalNameFilter, bool ignoreCase)
{
RuntimeTypeInfo reflectedType = type;

MemberPolicies<M> policies = MemberPolicies<M>.Default;

NameFilter? nameFilter;
if (optionalNameFilter == null)
nameFilter = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ namespace System.Reflection.Runtime.BindingFlagSupport
//
internal partial struct QueryResult<M> where M : MemberInfo
{
public QueryResult(BindingFlags bindingAttr, QueriedMemberList<M> queriedMembers)
public QueryResult(MemberPolicies<M> policies, BindingFlags bindingAttr, QueriedMemberList<M> queriedMembers)
{
_policies = policies;
_lazyCount = 0;
_bindingAttr = bindingAttr;
_queriedMembers = queriedMembers;
Expand Down Expand Up @@ -114,8 +115,7 @@ public void CopyTo(MemberInfo[] array, int startIndex)
if (match.DeclaringType.Equals(challenger.DeclaringType))
throw new AmbiguousMatchException();

MemberPolicies<M> policies = MemberPolicies<M>.Default;
if (!policies.OkToIgnoreAmbiguity(match, challenger))
if (!_policies.OkToIgnoreAmbiguity(match, challenger))
throw new AmbiguousMatchException();
}
else
Expand All @@ -129,6 +129,7 @@ public void CopyTo(MemberInfo[] array, int startIndex)

private int UnfilteredCount => ((_bindingAttr & BindingFlags.DeclaredOnly) != 0) ? _queriedMembers.DeclaredOnlyCount : _queriedMembers.TotalCount;

private readonly MemberPolicies<M> _policies;
private readonly BindingFlags _bindingAttr;
private int _lazyCount; // Intentionally not marking as volatile. QueryResult is for short-term use within a single method call - no aspiration to be thread-safe.
private QueriedMemberList<M> _queriedMembers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,8 @@ public static bool QualifiesBasedOnParameterCount(this MethodBase methodBase, Bi
// - MethodImpls ignored. (I didn't say it made sense, this is just how the desktop api we're porting behaves.)
// - Implemented interfaces ignores. (I didn't say it made sense, this is just how the desktop api we're porting behaves.)
//
public static M GetImplicitlyOverriddenBaseClassMember<M>(this M member) where M : MemberInfo
public static M GetImplicitlyOverriddenBaseClassMember<M>(this M member, MemberPolicies<M> policies) where M : MemberInfo
{
MemberPolicies<M> policies = MemberPolicies<M>.Default;
bool isVirtual;
bool isNewSlot;
policies.GetMemberAttributes(member, out _, out _, out isVirtual, out isNewSlot);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,17 @@ public sealed override FieldInfo GetFieldFromHandle(RuntimeFieldHandle runtimeFi

public sealed override EventInfo GetImplicitlyOverriddenBaseClassEvent(EventInfo e)
{
return e.GetImplicitlyOverriddenBaseClassMember();
return e.GetImplicitlyOverriddenBaseClassMember(EventPolicies.Instance);
}

public sealed override MethodInfo GetImplicitlyOverriddenBaseClassMethod(MethodInfo m)
{
return m.GetImplicitlyOverriddenBaseClassMember();
return m.GetImplicitlyOverriddenBaseClassMember(MethodPolicies.Instance);
}

public sealed override PropertyInfo GetImplicitlyOverriddenBaseClassProperty(PropertyInfo p)
{
return p.GetImplicitlyOverriddenBaseClassMember();
return p.GetImplicitlyOverriddenBaseClassMember(PropertyPolicies.Instance);
}

private static FieldInfo GetFieldInfo(RuntimeTypeHandle declaringTypeHandle, FieldHandle fieldHandle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public sealed override MethodInfo GetBaseDefinition()

while (true)
{
MethodInfo next = method.GetImplicitlyOverriddenBaseClassMember();
MethodInfo next = method.GetImplicitlyOverriddenBaseClassMember(MethodPolicies.Instance);
if (next == null)
return ((RuntimeMethodInfo)method).WithReflectedTypeSetToDeclaringType;

Expand Down
Loading