diff --git a/src/SourceGenerators/Uno.UI.SourceGenerators/BindableTypeProviders/BindableTypeProvidersGenerationTask.cs b/src/SourceGenerators/Uno.UI.SourceGenerators/BindableTypeProviders/BindableTypeProvidersGenerationTask.cs
index 51ad7abef74f..12986efd5d3a 100644
--- a/src/SourceGenerators/Uno.UI.SourceGenerators/BindableTypeProviders/BindableTypeProvidersGenerationTask.cs
+++ b/src/SourceGenerators/Uno.UI.SourceGenerators/BindableTypeProviders/BindableTypeProvidersGenerationTask.cs
@@ -302,6 +302,7 @@ where field.IsStatic
writer.AppendLineIndented("[global::System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Justification=\"Must be ignored even if generated code is checked.\")]");
writer.AppendLineIndented("[global::System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1506:AvoidExcessiveClassCoupling\", Justification = \"Must be ignored even if generated code is checked.\")]");
writer.AppendLineIndented("[global::System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Maintainability\", \"CA1505:AvoidUnmaintainableCode\", Justification = \"Must be ignored even if generated code is checked.\")]");
+ writer.AppendLineIndented("[global::System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage(\"Trimming\", \"IL2111\", Justification = \"`typeof(Type)` emits IL2111 because of `Type.TypeInitializer`, which is not used.\")]");
using (writer.BlockInvariant("internal static global::Uno.UI.DataBinding.IBindableType Build(global::Uno.UI.DataBinding.BindableType parent)"))
{
RegisterHintMethod($"MetadataBuilder_{typeInfo.Index:000}", ownerType, "Uno.UI.DataBinding.IBindableType Build(Uno.UI.DataBinding.BindableType)");
diff --git a/src/Uno.UI/DataBinding/BindableProperty.cs b/src/Uno.UI/DataBinding/BindableProperty.cs
index 852e7ec0a8b7..373079d0f8f9 100644
--- a/src/Uno.UI/DataBinding/BindableProperty.cs
+++ b/src/Uno.UI/DataBinding/BindableProperty.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -24,7 +25,11 @@ public BindableProperty(DependencyProperty property)
///
/// This ctor is available for backward compatibility. On newer versions of Uno.UI, the BindableTypeProvidersSourceGenerator uses the single-parameter ctor
///
- public BindableProperty(Type propertyType, PropertyGetterHandler getter, PropertySetterHandler? setter)
+ public BindableProperty(
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
+ Type propertyType,
+ PropertyGetterHandler getter,
+ PropertySetterHandler? setter)
{
Getter = getter;
Setter = setter;
@@ -35,6 +40,7 @@ public BindableProperty(Type propertyType, PropertyGetterHandler getter, Propert
public PropertySetterHandler? Setter { get; }
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
public Type PropertyType { get; }
public DependencyProperty? DependencyProperty { get; }
diff --git a/src/Uno.UI/DataBinding/BindableType.cs b/src/Uno.UI/DataBinding/BindableType.cs
index e5f362d4fdc7..635d94bfd4ca 100644
--- a/src/Uno.UI/DataBinding/BindableType.cs
+++ b/src/Uno.UI/DataBinding/BindableType.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -16,6 +17,13 @@ namespace Uno.UI.DataBinding
///
public class BindableType : IBindableType
{
+ internal const DynamicallyAccessedMemberTypes TypeRequirements =
+ DynamicallyAccessedMemberTypes.NonPublicConstructors // DependencyProperty.Register()
+ | DynamicallyAccessedMemberTypes.PublicConstructors
+ | DynamicallyAccessedMemberTypes.PublicFields
+ | DynamicallyAccessedMemberTypes.PublicProperties
+ ;
+
private readonly Hashtable _properties;
private StringIndexerGetterDelegate? _stringIndexerGetter;
private StringIndexerSetterDelegate? _stringIndexerSetter;
@@ -26,12 +34,16 @@ public class BindableType : IBindableType
///
/// Provide an estimated number of properties, so the dictionary does not need to grow unnecessarily.
/// The actual .NET type that corresponds to this instance.
- public BindableType(int estimatedPropertySize, Type sourceType)
+ public BindableType(
+ int estimatedPropertySize,
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
+ Type sourceType)
{
_properties = new Hashtable(estimatedPropertySize);
Type = sourceType;
}
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
public Type Type { get; }
public ActivatorDelegate? CreateInstance()
@@ -61,7 +73,9 @@ public void AddActivator(ActivatorDelegate activator)
_activator = activator;
}
- public void AddProperty(string name, PropertyGetterHandler getter, PropertySetterHandler? setter = null)
+ public void AddProperty<
+ [DynamicallyAccessedMembers(TypeRequirements)] T
+ >(string name, PropertyGetterHandler getter, PropertySetterHandler? setter = null)
{
_properties[name] = new BindableProperty(typeof(T), getter, setter);
}
@@ -71,7 +85,12 @@ public void AddProperty(DependencyProperty property)
_properties[property.Name] = new BindableProperty(property);
}
- public void AddProperty(string name, Type propertyType, PropertyGetterHandler getter, PropertySetterHandler? setter = null)
+ public void AddProperty(
+ string name,
+ [DynamicallyAccessedMembers(TypeRequirements)]
+ Type propertyType,
+ PropertyGetterHandler getter,
+ PropertySetterHandler? setter = null)
{
_properties[name] = new BindableProperty(propertyType, getter, setter);
}
diff --git a/src/Uno.UI/DataBinding/IBindableProperty.cs b/src/Uno.UI/DataBinding/IBindableProperty.cs
index e5c730e1752e..4172052a0292 100644
--- a/src/Uno.UI/DataBinding/IBindableProperty.cs
+++ b/src/Uno.UI/DataBinding/IBindableProperty.cs
@@ -3,6 +3,7 @@
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
@@ -26,6 +27,7 @@ public interface IBindableProperty
///
/// Gets the type of the property
///
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
Type PropertyType { get; }
///
diff --git a/src/Uno.UI/DataBinding/IBindableType.cs b/src/Uno.UI/DataBinding/IBindableType.cs
index 5cb44c7b8788..0c6e07ee837e 100644
--- a/src/Uno.UI/DataBinding/IBindableType.cs
+++ b/src/Uno.UI/DataBinding/IBindableType.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -31,6 +32,7 @@ public interface IBindableType
///
/// Provides the Type of this bindable type
///
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
Type Type { get; }
///
diff --git a/src/Uno.UI/UI/Xaml/Controls/Frame/Frame.Properties.cs b/src/Uno.UI/UI/Xaml/Controls/Frame/Frame.Properties.cs
index a918ed8d6e72..9797c4d97c92 100644
--- a/src/Uno.UI/UI/Xaml/Controls/Frame/Frame.Properties.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/Frame/Frame.Properties.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using Microsoft.UI.Xaml.Navigation;
namespace Microsoft.UI.Xaml.Controls;
@@ -117,6 +118,8 @@ public Type CurrentSourcePageType
///
/// Identifies the CurrentSourcePageType dependency property.
///
+ [UnconditionalSuppressMessage("Trimming", "IL2111", Justification = "`typeof(Type)` triggers IL2111 regarding `Type.TypeInitializer`, but Uno doesn't use `Type.TypeInitializer`!")]
+ // warning IL2111: Method 'System.Type.TypeInitializer.get' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
public static DependencyProperty CurrentSourcePageTypeProperty { get; } =
DependencyProperty.Register(
nameof(CurrentSourcePageType),
@@ -174,6 +177,8 @@ public Type SourcePageType
///
/// Identifies the SourcePageType dependency property.
///
+ [UnconditionalSuppressMessage("Trimming", "IL2111", Justification = "`typeof(Type)` triggers IL2111 regarding `Type.TypeInitializer`, but Uno doesn't use `Type.TypeInitializer`!")]
+ // warning IL2111: Method 'System.Type.TypeInitializer.get' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
public static DependencyProperty SourcePageTypeProperty { get; } =
DependencyProperty.Register(
nameof(SourcePageType),
diff --git a/src/Uno.UI/UI/Xaml/DependencyProperty.cs b/src/Uno.UI/UI/Xaml/DependencyProperty.cs
index ae69c2f44178..7fef939347b1 100644
--- a/src/Uno.UI/UI/Xaml/DependencyProperty.cs
+++ b/src/Uno.UI/UI/Xaml/DependencyProperty.cs
@@ -16,6 +16,7 @@
using Uno;
using Uno.Extensions;
using Uno.UI;
+using Uno.UI.DataBinding;
using Uno.UI.Dispatching;
using Uno.UI.Helpers;
using Uno.UI.Xaml.Media;
@@ -54,13 +55,22 @@ public sealed partial class DependencyProperty
private readonly Flags _flags;
private string _name;
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
private Type _propertyType;
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
private Type _ownerType;
private readonly int _uniqueId;
private static int _globalId = -1;
- private DependencyProperty(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, bool attached)
+ private DependencyProperty(
+ string name,
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
+ Type propertyType,
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
+ Type ownerType,
+ PropertyMetadata defaultMetadata,
+ bool attached)
{
_name = name;
_propertyType = propertyType;
@@ -140,8 +150,8 @@ internal bool IsDependencyObjectCollection
/// A property with the same name has already been declared for the ownerType
public static DependencyProperty Register(
string name,
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type propertyType,
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type ownerType,
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)] Type propertyType,
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)] Type ownerType,
PropertyMetadata typeMetadata)
{
typeMetadata = FixMetadataIfNeeded(propertyType, typeMetadata);
@@ -196,8 +206,8 @@ private static PropertyMetadata FixMetadataIfNeeded(
///
internal static DependencyProperty Register(
string name,
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type propertyType,
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type ownerType,
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)] Type propertyType,
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)] Type ownerType,
FrameworkPropertyMetadata typeMetadata)
#pragma warning disable RS0030 // Do not used banned APIs
=> Register(name, propertyType, ownerType, (PropertyMetadata)typeMetadata);
@@ -214,8 +224,8 @@ internal static DependencyProperty Register(
/// A property with the same name has already been declared for the ownerType
public static DependencyProperty RegisterAttached(
string name,
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type propertyType,
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type ownerType,
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)] Type propertyType,
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)] Type ownerType,
PropertyMetadata defaultMetadata)
{
defaultMetadata = FixMetadataIfNeeded(propertyType, defaultMetadata);
@@ -297,11 +307,13 @@ public PropertyMetadata GetMetadata(Type forType)
return _ownerTypeMetadata.CloneWithOverwrittenDefaultValue(defaultValueForType);
}
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
internal Type OwnerType
{
get { return _ownerType; }
}
+ [DynamicallyAccessedMembers(BindableType.TypeRequirements)]
internal Type Type
{
get { return _propertyType; }
diff --git a/src/Uno.UI/UI/Xaml/Navigation/PageStackEntry.Properties.cs b/src/Uno.UI/UI/Xaml/Navigation/PageStackEntry.Properties.cs
index 5a300df148b7..65c61bb48cb7 100644
--- a/src/Uno.UI/UI/Xaml/Navigation/PageStackEntry.Properties.cs
+++ b/src/Uno.UI/UI/Xaml/Navigation/PageStackEntry.Properties.cs
@@ -37,7 +37,8 @@ public Type SourcePageType
///
/// Identifies the SourcePageType dependency property.
///
- [UnconditionalSuppressMessage("Trimming", "IL2111", Justification = "@jonpryor has no idea what the trimmer is talking about.")]
+ [UnconditionalSuppressMessage("Trimming", "IL2111", Justification = "`typeof(Type)` triggers IL2111 regarding `Type.TypeInitializer`, but Uno doesn't use `Type.TypeInitializer`!")]
+ // warning IL2111: Method 'System.Type.TypeInitializer.get' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
public static DependencyProperty SourcePageTypeProperty { get; } =
DependencyProperty.Register(
nameof(SourcePageType),