Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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 @@ -409,15 +409,17 @@ private static AssemblyLoadContext GetALC(string assemblyPath)
private sealed class BasicClassFactory : IClassFactory
{
private readonly Guid _classId;

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
private readonly Type _classType;

public BasicClassFactory(Guid clsid, Type classType)
public BasicClassFactory(Guid clsid, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] Type classType)
{
_classId = clsid;
_classType = classType;
}

public static Type GetValidatedInterfaceType(Type classType, ref Guid riid, object? outer)
public static Type GetValidatedInterfaceType([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] Type classType, ref Guid riid, object? outer)
{
Debug.Assert(classType != null);
if (riid == Marshal.IID_IUnknown)
Expand Down Expand Up @@ -516,9 +518,11 @@ private sealed class LicenseClassFactory : IClassFactory2
{
private readonly LicenseInteropProxy _licenseProxy = new LicenseInteropProxy();
private readonly Guid _classId;

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
private readonly Type _classType;

public LicenseClassFactory(Guid clsid, Type classType)
public LicenseClassFactory(Guid clsid, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] Type classType)
{
_classId = clsid;
_classType = classType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,13 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
return m_typeBuilder.GetFields(bindingAttr);
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type? GetInterface(string name, bool ignoreCase)
{
return m_typeBuilder.GetInterface(name, ignoreCase);
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type[] GetInterfaces()
{
return m_typeBuilder.GetInterfaces();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ public override Type MakeArrayType(int rank)
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); }

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type GetInterface(string name, bool ignoreCase) { throw new NotSupportedException(); }

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type[] GetInterfaces() { throw new NotSupportedException(); }

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,11 +397,13 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type GetInterface(string name, bool ignoreCase)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type[] GetInterfaces()
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,7 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetFields(bindingAttr);
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type? GetInterface(string name, bool ignoreCase)
{
if (!IsCreated())
Expand All @@ -845,6 +846,7 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetInterface(name, ignoreCase);
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type[] GetInterfaces()
{
if (m_bakedRuntimeType != null)
Expand Down Expand Up @@ -947,6 +949,9 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetMembers(bindingAttr);
}

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "The GetInterfaces technically requires all interfaces to be preserved" +
"But in this case it acts only on TypeBuilder which is never trimmed (as it's runtime created).")]
public override bool IsAssignableFrom([NotNullWhen(true)] Type? c)
{
if (IsTypeEqual(c, this))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,10 @@ public override Type? BaseType
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); }

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type GetInterface(string name, bool ignoreCase) { throw new NotSupportedException(); }

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type[] GetInterfaces() { throw new NotSupportedException(); }

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,10 @@ private RuntimeConstructorInfo[] PopulateConstructors(Filter filter)
return list.ToArray();
}

[UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've submitted #52535 to see whether we can just delete the problematic code instead.

I think this would only do something if we allowed instance fields on interfaces, but that smells a lot like multiple-inheritance problems, so I don't think we're ever going to allow that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for testing this.

Justification = "Calls to GetInterfaces technically require all interfaces on ReflectedType" +
"But this is not a public API to enumerate reflection items, all the public APIs which do that" +
"should be annotated accordingly.")]
private RuntimeFieldInfo[] PopulateFields(Filter filter)
{
ListBuilder<RuntimeFieldInfo> list = default;
Expand Down Expand Up @@ -983,7 +987,11 @@ private void PopulateLiteralFields(Filter filter, RuntimeType declaringType, ref
}
}

private void AddSpecialInterface(ref ListBuilder<RuntimeType> list, Filter filter, RuntimeType iList, bool addSubInterface)
private void AddSpecialInterface(
ref ListBuilder<RuntimeType> list,
Filter filter,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] RuntimeType iList,
bool addSubInterface)
{
if (iList.IsAssignableFrom(ReflectedType))
{
Expand All @@ -1003,6 +1011,10 @@ private void AddSpecialInterface(ref ListBuilder<RuntimeType> list, Filter filte
}
}

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2065:UnrecognizedReflectionPattern",
Justification = "Calls to GetInterfaces technically require all interfaces on ReflectedType" +
"But this is not a public API to enumerate reflection items, all the public APIs which do that" +
"should be annotated accordingly.")]
private RuntimeType[] PopulateInterfaces(Filter filter)
{
ListBuilder<RuntimeType> list = default;
Expand Down Expand Up @@ -2611,6 +2623,7 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
return GetFieldCandidates(null, bindingAttr, false).ToArray();
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type[] GetInterfaces()
{
RuntimeType[] candidates = Cache.GetInterfaceList(MemberListType.All, null);
Expand Down Expand Up @@ -2903,6 +2916,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType)
return match;
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type? GetInterface(string fullname, bool ignoreCase)
{
if (fullname is null) throw new ArgumentNullException(nameof(fullname));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ Namespace Microsoft.VisualBasic.CompilerServices
Debug.Assert(TypeCode.String = 18, "wrong value!")
End Sub

<RequiresUnreferencedCode("Calls ClassifyUserDefinedConversion")>
<RequiresUnreferencedCode("Calls ClassifyUserDefinedConversion and ClassifyPredefinedConversion")>
Friend Shared Function ClassifyConversion(ByVal targetType As System.Type, ByVal sourceType As System.Type, ByRef operatorMethod As Method) As ConversionClass
'This function classifies the nature of the conversion from the source type to the target
'type. If such a conversion requires a user-defined conversion, it will be supplied as an
Expand Down Expand Up @@ -205,6 +205,7 @@ Namespace Microsoft.VisualBasic.CompilerServices
Return s_conversionTable(targetTypeCode)(sourceTypeCode)
End Function

<RequiresUnreferencedCode("Calls GetInterfaceConstraints but does so recursively on various types")>
Friend Shared Function ClassifyPredefinedCLRConversion(ByVal targetType As System.Type, ByVal sourceType As System.Type) As ConversionClass
' This function classifies all intrinsic CLR conversions, such as inheritance,
' implementation, and array covariance.
Expand Down Expand Up @@ -355,6 +356,7 @@ Namespace Microsoft.VisualBasic.CompilerServices

End Function

<RequiresUnreferencedCode("Calls ClassifyPredefinedCLRConversion")>
Private Shared Function ClassifyCLRArrayToInterfaceConversion(ByVal targetInterface As System.Type, ByVal sourceArrayType As System.Type) As ConversionClass

Debug.Assert(IsInterface(targetInterface), "Non-Interface type unexpected!!!")
Expand Down Expand Up @@ -424,6 +426,7 @@ Namespace Microsoft.VisualBasic.CompilerServices
End Function


<RequiresUnreferencedCode("Calls ClassifyPredefinedCLRConversion")>
Private Shared Function ClassifyCLRConversionForArrayElementTypes(ByVal targetElementType As System.Type, ByVal sourceElementType As System.Type) As ConversionClass

' The element types must either be the same or
Expand Down Expand Up @@ -467,6 +470,7 @@ Namespace Microsoft.VisualBasic.CompilerServices
End Function


<RequiresUnreferencedCode("Calls ClassifyPredefinedCLRConversion")>
Friend Shared Function ClassifyPredefinedConversion(ByVal targetType As System.Type, ByVal sourceType As System.Type) As ConversionClass
' This function classifies all intrinsic language conversions, such as inheritance,
' implementation, array covariance, and conversions between intrinsic types.
Expand Down Expand Up @@ -553,6 +557,7 @@ Namespace Microsoft.VisualBasic.CompilerServices
Return result
End Function

<RequiresUnreferencedCode("Calls ClassifyPredefinedConversion")>
Private Shared Function Encompasses(ByVal larger As System.Type, ByVal smaller As System.Type) As Boolean
'Definition: LARGER is said to encompass SMALLER if SMALLER widens to or is LARGER.

Expand All @@ -564,6 +569,7 @@ Namespace Microsoft.VisualBasic.CompilerServices
Return result = ConversionClass.Widening OrElse result = ConversionClass.Identity
End Function

<RequiresUnreferencedCode("Calls ClassifyPredefinedConversion")>
Private Shared Function NotEncompasses(ByVal larger As System.Type, ByVal smaller As System.Type) As Boolean
'Definition: LARGER is said to not encompass SMALLER if SMALLER narrows to or is LARGER.

Expand All @@ -575,7 +581,7 @@ Namespace Microsoft.VisualBasic.CompilerServices
Return result = ConversionClass.Narrowing OrElse result = ConversionClass.Identity
End Function


<RequiresUnreferencedCode("Calls Encompasses")>
Private Shared Function MostEncompassing(ByVal types As List(Of System.Type)) As System.Type
'Given a set TYPES, determine the most encompassing type. An element
'CANDIDATE of TYPES is said to be most encompassing if no other element of
Expand All @@ -601,7 +607,7 @@ Namespace Microsoft.VisualBasic.CompilerServices
Return maxEncompassing
End Function


<RequiresUnreferencedCode("Calls Encompasses")>
Private Shared Function MostEncompassed(ByVal types As List(Of System.Type)) As System.Type
'Given a set TYPES, determine the most encompassed type. An element
'CANDIDATE of TYPES is said to be most encompassed if CANDIDATE encompasses
Expand Down Expand Up @@ -687,6 +693,7 @@ Namespace Microsoft.VisualBasic.CompilerServices
operatorList.Add(operatorToInsert)
End Sub

<RequiresUnreferencedCode("Calls ClassifyPredefinedConversion")>
Private Shared Function ResolveConversion(
ByVal targetType As System.Type,
ByVal sourceType As System.Type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ nextcandidate:
Return False
End Function

<RequiresUnreferencedCode("Calls GetInterfaces on argument type recursively")>
Private Shared Function InferTypeArgumentsFromArgument(
ByVal argumentType As Type,
ByVal parameterType As Type,
Expand Down Expand Up @@ -1104,6 +1105,7 @@ RetryInference:
End Function


<RequiresUnreferencedCode("Calls InferTypeArgumentsFromArgument")>
Private Shared Function InferTypeArgumentsFromArgumentDirectly(
ByVal argumentType As Type,
ByVal parameterType As Type,
Expand Down Expand Up @@ -1296,6 +1298,7 @@ RetryInference:

End Function

<RequiresUnreferencedCode("Calls InferTypArgumentsFromArgument")>
Friend Shared Function InferTypeArgumentsFromArgument(
ByVal targetProcedure As Method,
ByVal argument As Object,
Expand Down Expand Up @@ -1839,6 +1842,7 @@ skipargument:
Return
End Sub

<RequiresUnreferencedCode("Calls InferTypeArgumentsFromArgument")>
Private Shared Function InferTypeArguments(
ByVal targetProcedure As Method,
ByVal arguments As Object(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,8 @@ Namespace Microsoft.VisualBasic.CompilerServices
Return False
End Function
#End If
<UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification:="Calls GetInterfaces but only looks for existing interface type by reference equality. Trimmer guarantees that if the interface type is kept it is also kept on all the types which implement it.")>
Friend Shared Function [Implements](ByVal implementor As System.Type, ByVal [interface] As System.Type) As Boolean

Debug.Assert(Not IsInterface(implementor), "interfaces can't implement, so why call this?")
Expand All @@ -439,6 +441,8 @@ Namespace Microsoft.VisualBasic.CompilerServices

End Function

<UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification:="Calls GetInterfaces but only looks for existing interface type by reference equality. Trimmer guarantees that if the interface type is kept it is also kept on all the types which implement it.")>
Friend Shared Function IsOrInheritsFrom(ByVal derived As System.Type, ByVal base As System.Type) As Boolean
Debug.Assert((Not derived.IsByRef) AndAlso (Not derived.IsPointer))
Debug.Assert((Not base.IsByRef) AndAlso (Not base.IsPointer))
Expand Down Expand Up @@ -514,7 +518,7 @@ Namespace Microsoft.VisualBasic.CompilerServices
Return type.GetGenericArguments
End Function

Friend Shared Function GetInterfaceConstraints(ByVal genericParameter As Type) As Type()
Friend Shared Function GetInterfaceConstraints(<DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)> ByVal genericParameter As Type) As Type()
'Returns the interface constraints for the type parameter.
Debug.Assert(IsGenericParameter(genericParameter), "expected type parameter")
Return System.Linq.Enumerable.ToArray(genericParameter.GetInterfaces)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,14 @@ public static bool IsValidInstanceType(MemberInfo member, Type instanceType)
// been boxed or not.
if (targetType.IsInterface)
{
foreach (Type interfaceType in instanceType.GetInterfaces())
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "The targetType must be preserved (since we have an instance of it here)," +
"So if it's an interface that interface will be preserved everywhere" +
"So if it was implemented by the instanceType, it will be kept even after trimming." +
"The fact that GetInterfaces may return fewer interfaces doesn't matter as long" +
"as it returns the one we're looking for.")]
static Type[] GetTypeInterfaces(Type instanceType) => instanceType.GetInterfaces();
foreach (Type interfaceType in GetTypeInterfaces(instanceType))
{
if (AreReferenceAssignable(targetType, interfaceType))
{
Expand Down Expand Up @@ -799,25 +806,16 @@ private static bool IsImplicitNullableConversion(Type source, Type destination)

public static Type? FindGenericType(Type definition, Type? type)
{
// For now this helper doesn't support interfaces
Debug.Assert(!definition.IsInterface);

while (type is not null && type != typeof(object))
{
if (type.IsConstructedGenericType && AreEquivalent(type.GetGenericTypeDefinition(), definition))
{
return type;
}

if (definition.IsInterface)
{
foreach (Type itype in type.GetInterfaces())
{
Type? found = FindGenericType(definition, itype);
if (found != null)
{
return found;
}
}
}

type = type.BaseType;
}

Expand Down
Loading