diff --git a/src/WinRT.Runtime/ApiCompatBaseline.txt b/src/WinRT.Runtime/ApiCompatBaseline.txt index c7584cc04..dcf5bea51 100644 --- a/src/WinRT.Runtime/ApiCompatBaseline.txt +++ b/src/WinRT.Runtime/ApiCompatBaseline.txt @@ -21,4 +21,5 @@ CannotRemoveAttribute : Attribute 'WinRT.ObjectReferenceWrapperAttribute' exists CannotRemoveAttribute : Attribute 'WinRT.ObjectReferenceWrapperAttribute' exists on 'WinRT.IInspectable' in the contract but not the implementation. MembersMustExist : Member 'protected void Microsoft.UI.Xaml.LayoutCycleException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract. MembersMustExist : Member 'protected void Microsoft.UI.Xaml.Automation.ElementNotAvailableException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract. -Total Issues: 122 +CannotChangeAttribute : Attribute 'System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute' on 'WinRT.WindowsRuntimeHelperTypeAttribute.HelperType' changed from '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes)]' in the contract to '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)]' in the implementation. +Total Issues: 123 diff --git a/src/WinRT.Runtime/AttributeMessages.net5.cs b/src/WinRT.Runtime/AttributeMessages.net5.cs index 91dc012ae..04eda9fa3 100644 --- a/src/WinRT.Runtime/AttributeMessages.net5.cs +++ b/src/WinRT.Runtime/AttributeMessages.net5.cs @@ -10,6 +10,11 @@ internal static class AttributeMessages /// public const string GenericDeprecatedMessage = "This method is deprecated and will be removed in a future release."; + /// + /// Message for a generic annotation for a method using . + /// + public const string GenericRequiresUnreferencedCodeMessage = "This method is not trim-safe, and is only supported for use when not using trimming (or AOT)."; + /// /// Message for marshalling or generic code requiring . /// diff --git a/src/WinRT.Runtime/Attributes.cs b/src/WinRT.Runtime/Attributes.cs index 2d332a5cb..be07a166e 100644 --- a/src/WinRT.Runtime/Attributes.cs +++ b/src/WinRT.Runtime/Attributes.cs @@ -97,7 +97,7 @@ public WindowsRuntimeHelperTypeAttribute() public WindowsRuntimeHelperTypeAttribute( #if NET - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] #endif Type helperType) { @@ -105,7 +105,7 @@ public WindowsRuntimeHelperTypeAttribute( } #if NET - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] #endif public Type HelperType { get; } } diff --git a/src/WinRT.Runtime/ComWrappersSupport.cs b/src/WinRT.Runtime/ComWrappersSupport.cs index f805baa28..8bbda9a01 100644 --- a/src/WinRT.Runtime/ComWrappersSupport.cs +++ b/src/WinRT.Runtime/ComWrappersSupport.cs @@ -159,7 +159,6 @@ public static void RegisterHelperType( Type type, #if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] #endif Type helperType) => TypeExtensions.HelperTypeCache.TryAdd(type, helperType); diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index 88904706e..7ef7247ad 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -1375,7 +1375,6 @@ struct MarshalInterface #if NET [DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicFields | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicMethods)] #endif private static Type _HelperType; @@ -1383,7 +1382,6 @@ struct MarshalInterface #if NET [DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicFields | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicMethods)] #endif private static Type HelperType => _HelperType ??= typeof(T).GetHelperType(); diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt index 93601c34a..8079ba1ea 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt @@ -215,4 +215,6 @@ TypesMustExist : Type 'ABI.WinRT.Interop.EventSource' does not exist TypesMustExist : Type 'ABI.WinRT.Interop.EventSourceState' does not exist in the reference but it does exist in the implementation. TypesMustExist : Type 'ABI.WinRT.Interop.EventHandlerEventSource' does not exist in the reference but it does exist in the implementation. TypesMustExist : Type 'ABI.WinRT.Interop.EventHandlerEventSource' does not exist in the reference but it does exist in the implementation. -Total Issues: 217 +CannotChangeAttribute : Attribute 'System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute' on 'WinRT.WindowsRuntimeHelperTypeAttribute.HelperType' changed from '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)]' in the implementation to '[DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes)]' in the reference. +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute' exists on 'WinRT.TypeExtensions.FindVftblType(System.Type)' in the implementation but not the reference. +Total Issues: 219 diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index 96a68f684..66de64b61 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -120,7 +120,6 @@ private static void RegisterCustomAbiTypeMapping( #if NET [DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] #endif Type abiType, @@ -143,7 +142,6 @@ private static void RegisterCustomTypeToHelperTypeMapping( #if NET [DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] #endif Type helperType) @@ -164,7 +162,6 @@ private static void RegisterCustomTypeToHelperTypeMappingNoLock( #if NET [DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] #endif Type helperType) @@ -177,7 +174,6 @@ private static void RegisterCustomAbiTypeMappingNoLock( #if NET [DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] #endif Type abiType, @@ -200,7 +196,6 @@ private static void RegisterCustomAbiTypeMapping( #if NET [DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] #endif Type abiType) @@ -221,7 +216,6 @@ private static void RegisterCustomAbiTypeMappingNoLock( #if NET [DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] #endif Type abiType) @@ -233,7 +227,6 @@ private static void RegisterCustomAbiTypeMappingNoLock( #if NET [return: DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] #endif public static Type FindCustomHelperTypeMapping(Type publicType, bool filterToRuntimeClass = false) diff --git a/src/WinRT.Runtime/TypeExtensions.cs b/src/WinRT.Runtime/TypeExtensions.cs index 2cd70aa5f..def3b4f2f 100644 --- a/src/WinRT.Runtime/TypeExtensions.cs +++ b/src/WinRT.Runtime/TypeExtensions.cs @@ -21,7 +21,6 @@ static class TypeExtensions #if NET [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] [SuppressMessage("Trimming", "IL2073", Justification = "Matching trimming annotations are used at all callsites registering helper types present in the cache.")] #endif @@ -29,7 +28,6 @@ public static Type FindHelperType(this Type type) { #if NET [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] #endif static Type FindHelperTypeNoCache(Type type) @@ -76,7 +74,7 @@ static Type FindHelperTypeNoCache(Type type) #if NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "No members of the generic type are dynamically accessed other than for the attributes on it.")] - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)] + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] #endif static Type GetHelperTypeFromAttribute(WindowsRuntimeHelperTypeAttribute helperTypeAtribute, Type type) { @@ -119,8 +117,7 @@ static Type FindHelperTypeFallback(Type type) } #if NET - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicNestedTypes | + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] #endif public static Type GetHelperType(this Type type) @@ -140,13 +137,10 @@ public static Type GetGuidType(this Type type) } #if NET - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] -#endif - public static Type FindVftblType( -#if NET - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes)] + [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "The fallback path is not AOT-safe by design (to avoid annotations).")] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The fallback path is not trim-safe by design (to avoid annotations).")] #endif - this Type helperType) + public static Type FindVftblType(this Type helperType) { #if NET if (!RuntimeFeature.IsDynamicCodeCompiled) @@ -155,23 +149,49 @@ public static Type FindVftblType( } #endif - Type vftblType = helperType.GetNestedType("Vftbl"); - if (vftblType is null) - { - return null; - } - if (helperType.IsGenericType && vftblType is object) +#if NET8_0_OR_GREATER + [RequiresDynamicCode(AttributeMessages.MarshallingOrGenericInstantiationsRequiresDynamicCode)] +#endif +#if NET + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.IAsyncActionWithProgress`1+Vftbl", "Microsoft.Windows.SDK.NET")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.IAsyncOperationWithProgress`2+Vftbl", "Microsoft.Windows.SDK.NET")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.IAsyncOperation`1+Vftbl", "Microsoft.Windows.SDK.NET")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.Collections.IMapChangedEventArgs`1+Vftbl", "Microsoft.Windows.SDK.NET")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.Collections.IObservableMap`2+Vftbl", "Microsoft.Windows.SDK.NET")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.Windows.Foundation.Collections.IObservableVector`1+Vftbl", "Microsoft.Windows.SDK.NET")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.EventHandler`1+Vftbl", "WinRT.Runtime")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.KeyValuePair`2+Vftbl", "WinRT.Runtime")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IEnumerable`1+Vftbl", "WinRT.Runtime")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IEnumerator`1+Vftbl", "WinRT.Runtime")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IList`1+Vftbl", "WinRT.Runtime")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IReadOnlyList`1+Vftbl", "WinRT.Runtime")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IDictionary`2+Vftbl", "WinRT.Runtime")] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "ABI.System.Collections.Generic.IReadOnlyDictionary`2+Vftbl", "WinRT.Runtime")] + [RequiresUnreferencedCode(AttributeMessages.GenericRequiresUnreferencedCodeMessage)] +#endif + static Type FindVftblTypeFallback(Type helperType) { -#pragma warning disable IL3050 // https://github.com/dotnet/runtime/issues/97273 - vftblType = vftblType.MakeGenericType(helperType.GetGenericArguments()); -#pragma warning restore IL3050 + Type vftblType = helperType.GetNestedType("Vftbl"); + if (vftblType is null) + { + return null; + } + if (helperType.IsGenericType) + { + vftblType = vftblType.MakeGenericType(helperType.GetGenericArguments()); + } + return vftblType; } - return vftblType; + + return FindVftblTypeFallback(helperType); } +#if NET + [SuppressMessage("Trimming", "IL2075", Justification = "The path using vtable types is a fallback and is not trim-safe by design.")] +#endif internal static IntPtr GetAbiToProjectionVftblPtr( #if NET - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] #endif this Type helperType) {