Skip to content
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 @@ -411,15 +411,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 @@ -519,9 +521,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,14 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
return m_typeBuilder.GetFields(bindingAttr);
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
[return: 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,13 @@ public override Type MakeArrayType(int rank)
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); }

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2063:UnrecognizedReflectionPattern",
Justification = "Linker doesn't recognize always throwing method. https://github.com/mono/linker/issues/2025")]
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,16 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2063:UnrecognizedReflectionPattern",
Justification = "Linker doesn't recognize always throwing method. https://github.com/mono/linker/issues/2025")]
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,8 @@ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetFields(bindingAttr);
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public override Type? GetInterface(string name, bool ignoreCase)
{
if (!IsCreated())
Expand All @@ -845,6 +847,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 +950,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,13 @@ public override Type? BaseType
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); }

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2063:UnrecognizedReflectionPattern",
Justification = "Linker doesn't recognize always throwing method. https://github.com/mono/linker/issues/2025")]
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,8 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType)
return match;
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
[return: 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 @@ -43,5 +43,11 @@
<property name="Scope">member</property>
<property name="Target">M:Microsoft.Extensions.Configuration.ConfigurationBinder.GetAllProperties(System.Type)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2070</argument>
<property name="Scope">member</property>
<property name="Target">M:Microsoft.Extensions.Configuration.ConfigurationBinder.FindOpenGenericInterface(System.Type,System.Type)</property>
</attribute>
</assembly>
</linker>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<ItemGroup>
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\DynamicallyAccessedMembersAttribute.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\DynamicallyAccessedMemberTypes.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public static IServiceCollection PostConfigureAll<TOptions>(this IServiceCollect

private static IEnumerable<Type> FindConfigurationServices(Type type)
{
foreach (Type t in type.GetInterfaces())
foreach (Type t in GetInterfacesOnType(type))
{
if (t.IsGenericType)
{
Expand All @@ -159,6 +159,16 @@ private static IEnumerable<Type> FindConfigurationServices(Type type)
}
}
}

// Extracted the suppression to a local function as trimmer currently doesn't handle suppressions
// on iterator methods correctly.
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification="This method only looks for interfaces referenced in its code. " +
"The trimmer will keep the interface and thus all of its implementations in that case. " +
"The call to GetInterfaces may return less results in trimmed apps, but it will " +
"include the interfaces this method looks for if they should be there.")]
static Type[] GetInterfacesOnType(Type t)
=> t.GetInterfaces();
}

private static void ThrowNoConfigServices(Type type) =>
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
Loading