From 06bfc4f2f927798e628eddd3b12561eacc1ed2f3 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Wed, 16 Jun 2021 17:19:49 +0200 Subject: [PATCH 1/5] Add ILLink annotations to S.D.Common related to DbConnectionStringBuilder --- .../MetadataPropertyDescriptorWrapper.cs | 9 +- .../System.ComponentModel.TypeConverter.cs | 7 +- .../Linq/ComponentModel/XComponentModel.cs | 3 + .../ComponentModel/CustomTypeDescriptor.cs | 1 + .../ComponentModel/ICustomTypeDescriptor.cs | 1 + .../ComponentModel/PropertyDescriptor.cs | 8 +- .../ReflectPropertyDescriptor.cs | 11 ++- .../System/ComponentModel/TypeDescriptor.cs | 6 +- .../ref/System.Data.Common.cs | 5 + .../src/ILLink/ILLink.Suppressions.xml | 54 ----------- .../System/Data/Common/DataRecordInternal.cs | 1 + .../Data/Common/DbConnectionStringBuilder.cs | 12 ++- .../src/System/Data/Common/DbDataRecord.cs | 1 + .../src/System/Data/DataRowView.cs | 1 + .../DataViewManagerListItemTypeDescriptor.cs | 1 + .../DbConnectionStringBuilder.cs | 96 +++++++++++++++++++ .../System.Data.Common.TrimmingTests.proj | 5 + 17 files changed, 162 insertions(+), 60 deletions(-) create mode 100644 src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs index f771e0e340d853..0397663e86f405 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs @@ -3,6 +3,7 @@ using System; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Linq; namespace System.ComponentModel.DataAnnotations @@ -20,6 +21,7 @@ public MetadataPropertyDescriptorWrapper(PropertyDescriptor descriptor, Attribut _isReadOnly = (readOnlyAttribute != null ? readOnlyAttribute.IsReadOnly : false); } + [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public override void AddValueChanged(object component, EventHandler handler) { _descriptor.AddValueChanged(component, handler); } public override bool CanResetValue(object component) { return _descriptor.CanResetValue(component); } @@ -41,6 +43,7 @@ public override bool IsReadOnly public override Type PropertyType { get { return _descriptor.PropertyType; } } + [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public override void RemoveValueChanged(object component, EventHandler handler) { _descriptor.RemoveValueChanged(component, handler); } public override void ResetValue(object component) { _descriptor.ResetValue(component); } @@ -49,6 +52,10 @@ public override bool IsReadOnly public override bool ShouldSerializeValue(object component) { return _descriptor.ShouldSerializeValue(component); } - public override bool SupportsChangeEvents { get { return _descriptor.SupportsChangeEvents; } } + public override bool SupportsChangeEvents + { + [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] + get { return _descriptor.SupportsChangeEvents; } + } } } diff --git a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs index d8ca41c78fb690..cda74ed7f43920 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs @@ -296,6 +296,7 @@ protected CustomTypeDescriptor(System.ComponentModel.ICustomTypeDescriptor paren public virtual System.ComponentModel.PropertyDescriptor GetDefaultProperty() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] public virtual object GetEditor(System.Type editorBaseType) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public virtual System.ComponentModel.EventDescriptorCollection GetEvents() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] public virtual System.ComponentModel.EventDescriptorCollection GetEvents(System.Attribute[] attributes) { throw null; } @@ -579,6 +580,7 @@ public partial interface ICustomTypeDescriptor System.ComponentModel.PropertyDescriptor GetDefaultProperty(); [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object GetEditor(System.Type editorBaseType); + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] System.ComponentModel.EventDescriptorCollection GetEvents(); [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] System.ComponentModel.EventDescriptorCollection GetEvents(System.Attribute[] attributes); @@ -1055,7 +1057,8 @@ protected PropertyDescriptor(string name, System.Attribute[] attrs) : base (defa public abstract bool IsReadOnly { get; } public abstract System.Type PropertyType { get; } public System.ComponentModel.DesignerSerializationVisibility SerializationVisibility { get { throw null; } } - public virtual bool SupportsChangeEvents { get { throw null; } } + public virtual bool SupportsChangeEvents { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] get { throw null; } } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public virtual void AddValueChanged(object component, System.EventHandler handler) { } public abstract bool CanResetValue(object component); protected object CreateInstance([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type type) { throw null; } @@ -1079,6 +1082,7 @@ protected override void FillAttributes(System.Collections.IList attributeList) { public abstract object GetValue(object component); protected internal System.EventHandler GetValueChangedHandler(object component) { throw null; } protected virtual void OnValueChanged(object component, System.EventArgs e) { } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public virtual void RemoveValueChanged(object component, System.EventHandler handler) { } public abstract void ResetValue(object component); public abstract void SetValue(object component, object value); @@ -1470,6 +1474,7 @@ public static void CreateAssociation(object primary, object secondary) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The Type of component cannot be statically discovered.")] public static System.ComponentModel.EventDescriptorCollection GetEvents(object component, bool noCustomTypeDesc) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public static System.ComponentModel.EventDescriptorCollection GetEvents([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type componentType) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] public static System.ComponentModel.EventDescriptorCollection GetEvents([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type componentType, System.Attribute[] attributes) { throw null; } diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/MS/Internal/Xml/Linq/ComponentModel/XComponentModel.cs b/src/libraries/System.ComponentModel.TypeConverter/src/MS/Internal/Xml/Linq/ComponentModel/XComponentModel.cs index 67df1e5bbacef0..d2c10bb338b34b 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/MS/Internal/Xml/Linq/ComponentModel/XComponentModel.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/MS/Internal/Xml/Linq/ComponentModel/XComponentModel.cs @@ -86,9 +86,11 @@ public override Type PropertyType public override bool SupportsChangeEvents { + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] get { return true; } } + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public override void AddValueChanged(object component, EventHandler handler) { bool hasValueChangedHandler = GetValueChangedHandler(component) != null; @@ -108,6 +110,7 @@ public override bool CanResetValue(object component) return false; } + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public override void RemoveValueChanged(object component, EventHandler handler) { base.RemoveValueChanged(component, handler); diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CustomTypeDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CustomTypeDescriptor.cs index 03de81f6433766..d97340165c092c 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CustomTypeDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CustomTypeDescriptor.cs @@ -108,6 +108,7 @@ public virtual TypeConverter GetConverter() /// returned. If no parent is provided,this will return an empty /// event collection. /// + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public virtual EventDescriptorCollection GetEvents() { if (_parent != null) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ICustomTypeDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ICustomTypeDescriptor.cs index 699ebc3d22748d..f9568046323cec 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ICustomTypeDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ICustomTypeDescriptor.cs @@ -53,6 +53,7 @@ public interface ICustomTypeDescriptor /// /// Gets the events for this instance of a component. /// + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] EventDescriptorCollection GetEvents(); /// diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/PropertyDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/PropertyDescriptor.cs index 92da2abeffabcc..5b3d179b221226 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/PropertyDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/PropertyDescriptor.cs @@ -121,6 +121,7 @@ public DesignerSerializationVisibility SerializationVisibility /// /// Allows interested objects to be notified when this property changes. /// + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public virtual void AddValueChanged(object component, EventHandler handler) { if (component == null) @@ -399,6 +400,7 @@ protected virtual void OnValueChanged(object component, EventArgs e) /// /// Allows interested objects to be notified when this property changes. /// + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public virtual void RemoveValueChanged(object component, EventHandler handler) { if (component == null) @@ -465,6 +467,10 @@ protected internal EventHandler GetValueChangedHandler(object component) /// from direct calls made to PropertyDescriptor.SetValue (value=false). For example, the component may /// implement the INotifyPropertyChanged interface, or may have an explicit '{name}Changed' event for this property. /// - public virtual bool SupportsChangeEvents => false; + public virtual bool SupportsChangeEvents + { + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] + get => false; + } } } diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectPropertyDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectPropertyDescriptor.cs index 8178284444baf4..1f412fed4f85cf 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectPropertyDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectPropertyDescriptor.cs @@ -246,6 +246,7 @@ private object AmbientValue /// private EventDescriptor ChangedEventValue { + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] get { if (!_state[s_bitChangedQueried]) @@ -263,6 +264,7 @@ private EventDescriptor ChangedEventValue /// private EventDescriptor IPropChangedEventValue { + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] get { if (!_state[s_bitIPropChangedQueried]) @@ -481,6 +483,7 @@ private MethodInfo ShouldSerializeMethodValue /// /// Allows interested objects to be notified when this property changes. /// + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public override void AddValueChanged(object component, EventHandler handler) { if (component == null) @@ -963,6 +966,7 @@ protected override void OnValueChanged(object component, EventArgs e) /// /// Allows interested objects to be notified when this property changes. /// + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public override void RemoveValueChanged(object component, EventHandler handler) { if (component == null) @@ -1197,6 +1201,11 @@ public override bool ShouldSerializeValue(object component) /// from direct calls made to PropertyDescriptor.SetValue (value=false). For example, the component may /// implement the INotifyPropertyChanged interface, or may have an explicit '{name}Changed' event for this property. /// - public override bool SupportsChangeEvents => IPropChangedEventValue != null || ChangedEventValue != null; + public override bool SupportsChangeEvents + { + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] + + get => IPropChangedEventValue != null || ChangedEventValue != null; + } } } diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs index d70821726637d7..56f5b53535fc45 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs @@ -1018,6 +1018,7 @@ public static object GetEditor( /// /// Gets a collection of events for a specified type of component. /// + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public static EventDescriptorCollection GetEvents( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type componentType) { @@ -2746,6 +2747,7 @@ object ICustomTypeDescriptor.GetEditor(Type editorBaseType) return _handler.GetEditor(_instance, editorBaseType); } + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return _handler.GetEvents(_instance); @@ -3067,6 +3069,7 @@ object ICustomTypeDescriptor.GetEditor(Type editorBaseType) /// /// ICustomTypeDescriptor implementation. /// + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { EventDescriptorCollection events = _primary.GetEvents() ?? _secondary.GetEvents(); @@ -3468,7 +3471,7 @@ object ICustomTypeDescriptor.GetEditor(Type editorBaseType) /// /// ICustomTypeDescriptor implementation. /// - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "The ctor of this Type has RequiresUnreferencedCode.")] + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { // Check to see if the provider we get is a ReflectTypeDescriptionProvider. @@ -3801,6 +3804,7 @@ object ICustomTypeDescriptor.GetEditor(Type editorBaseType) /// /// ICustomTypeDescriptor implementation. /// + [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { // Check to see if the provider we get is a ReflectTypeDescriptionProvider. diff --git a/src/libraries/System.Data.Common/ref/System.Data.Common.cs b/src/libraries/System.Data.Common/ref/System.Data.Common.cs index a4bc1f651f202b..dd1d6f8ea28cdd 100644 --- a/src/libraries/System.Data.Common/ref/System.Data.Common.cs +++ b/src/libraries/System.Data.Common/ref/System.Data.Common.cs @@ -477,6 +477,7 @@ public void EndEdit() { } System.ComponentModel.PropertyDescriptor System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object System.ComponentModel.ICustomTypeDescriptor.GetEditor(System.Type editorBaseType) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents(System.Attribute[] attributes) { throw null; } @@ -2095,6 +2096,7 @@ protected virtual void OnStateChange(System.Data.StateChangeEventArgs stateChang System.Data.IDbTransaction System.Data.IDbConnection.BeginTransaction(System.Data.IsolationLevel isolationLevel) { throw null; } System.Data.IDbCommand System.Data.IDbConnection.CreateCommand() { throw null; } } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public partial class DbConnectionStringBuilder : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable, System.ComponentModel.ICustomTypeDescriptor { public DbConnectionStringBuilder() { } @@ -2130,6 +2132,7 @@ public virtual void Clear() { } protected internal void ClearPropertyDescriptors() { } public virtual bool ContainsKey(string keyword) { throw null; } public virtual bool EquivalentTo(System.Data.Common.DbConnectionStringBuilder connectionStringBuilder) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("PropertyDescriptor's PropertyType cannot be statically discovered. The Type of component cannot be statically discovered.")] protected virtual void GetProperties(System.Collections.Hashtable propertyDescriptors) { } public virtual bool Remove(string keyword) { throw null; } public virtual bool ShouldSerialize(string keyword) { throw null; } @@ -2150,6 +2153,7 @@ void System.Collections.IDictionary.Remove(object keyword) { } System.ComponentModel.PropertyDescriptor System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object System.ComponentModel.ICustomTypeDescriptor.GetEditor(System.Type editorBaseType) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents(System.Attribute[] attributes) { throw null; } @@ -2332,6 +2336,7 @@ protected DbDataRecord() { } System.ComponentModel.PropertyDescriptor System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object System.ComponentModel.ICustomTypeDescriptor.GetEditor(System.Type editorBaseType) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents(System.Attribute[] attributes) { throw null; } diff --git a/src/libraries/System.Data.Common/src/ILLink/ILLink.Suppressions.xml b/src/libraries/System.Data.Common/src/ILLink/ILLink.Suppressions.xml index ffcb7d78381c4e..3e47be79791de4 100644 --- a/src/libraries/System.Data.Common/src/ILLink/ILLink.Suppressions.xml +++ b/src/libraries/System.Data.Common/src/ILLink/ILLink.Suppressions.xml @@ -103,59 +103,5 @@ member M:System.Data.ProviderBase.SchemaMapping.SetupSchemaWithoutKeyInfo(System.Data.MissingMappingAction,System.Data.MissingSchemaAction,System.Boolean,System.Data.DataColumn,System.Object) - - ILLink - IL2026 - member - M:System.Data.Common.DbConnectionStringBuilder.GetProperties(System.Collections.Hashtable) - - - ILLink - IL2026 - member - M:System.Data.Common.DbConnectionStringBuilder.System#ComponentModel#ICustomTypeDescriptor#GetAttributes - - - ILLink - IL2026 - member - M:System.Data.Common.DbConnectionStringBuilder.System#ComponentModel#ICustomTypeDescriptor#GetClassName - - - ILLink - IL2026 - member - M:System.Data.Common.DbConnectionStringBuilder.System#ComponentModel#ICustomTypeDescriptor#GetComponentName - - - ILLink - IL2026 - member - M:System.Data.Common.DbConnectionStringBuilder.System#ComponentModel#ICustomTypeDescriptor#GetConverter - - - ILLink - IL2026 - member - M:System.Data.Common.DbConnectionStringBuilder.System#ComponentModel#ICustomTypeDescriptor#GetDefaultEvent - - - ILLink - IL2026 - member - M:System.Data.Common.DbConnectionStringBuilder.System#ComponentModel#ICustomTypeDescriptor#GetDefaultProperty - - - ILLink - IL2026 - member - M:System.Data.Common.DbConnectionStringBuilder.System#ComponentModel#ICustomTypeDescriptor#GetEditor(System.Type) - - - ILLink - IL2026 - member - M:System.Data.Common.DbConnectionStringBuilder.System#ComponentModel#ICustomTypeDescriptor#GetEvents - diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs index e9f240e9d74d90..8586193d8bf450 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs @@ -343,6 +343,7 @@ object ICustomTypeDescriptor.GetEditor(Type editorBaseType) } #nullable enable + [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return new EventDescriptorCollection(null); diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs index 3c3ac63548ef8a..bdc9f9ed2238d1 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs @@ -12,6 +12,7 @@ namespace System.Data.Common { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public class DbConnectionStringBuilder : IDictionary, ICustomTypeDescriptor { // keyword->value currently listed in the connection string @@ -387,6 +388,7 @@ internal Attribute[] GetAttributesFromCollection(AttributeCollection collection) return attributes; } + [RequiresUnreferencedCode("PropertyDescriptor's PropertyType cannot be statically discovered. The Type of component cannot be statically discovered.")] private PropertyDescriptorCollection GetProperties() { PropertyDescriptorCollection? propertyDescriptors = _propertyDescriptors; @@ -412,6 +414,7 @@ private PropertyDescriptorCollection GetProperties() return propertyDescriptors; } + [RequiresUnreferencedCode("PropertyDescriptor's PropertyType cannot be statically discovered. The Type of component cannot be statically discovered.")] protected virtual void GetProperties(Hashtable propertyDescriptors) { long logScopeId = DataCommonEventSource.Log.EnterScope(" {0}", ObjectID); @@ -562,16 +565,22 @@ private PropertyDescriptorCollection GetProperties(Attribute[]? attributes) return new PropertyDescriptorCollection(filteredPropertiesArray); } -// TODO: Enable after System.ComponentModel.TypeConverter is annotated + // TODO-NULLABLE: Enable after System.ComponentModel.TypeConverter is annotated #nullable disable + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "The type of component is statically known. This class is marked with [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]")] string ICustomTypeDescriptor.GetClassName() { return TypeDescriptor.GetClassName(this, true); } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "The type of component is statically known. This class is marked with [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]")] string ICustomTypeDescriptor.GetComponentName() { return TypeDescriptor.GetComponentName(this, true); } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "The type of component is statically known. This class is marked with [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]")] AttributeCollection ICustomTypeDescriptor.GetAttributes() { return TypeDescriptor.GetAttributes(this, true); @@ -606,6 +615,7 @@ EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); } + [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return TypeDescriptor.GetEvents(this, true); diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbDataRecord.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbDataRecord.cs index b2ee9ec585767b..930378dfe9f5b4 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbDataRecord.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbDataRecord.cs @@ -89,6 +89,7 @@ protected virtual DbDataReader GetDbDataReader(int i) [RequiresUnreferencedCode("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object ICustomTypeDescriptor.GetEditor(Type editorBaseType) => null; + [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() => new EventDescriptorCollection(null); [RequiresUnreferencedCode("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] diff --git a/src/libraries/System.Data.Common/src/System/Data/DataRowView.cs b/src/libraries/System.Data.Common/src/System/Data/DataRowView.cs index 4b86f5f59fa8b0..5c98190ca3e976 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataRowView.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataRowView.cs @@ -249,6 +249,7 @@ public void EndEdit() [RequiresUnreferencedCode("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object ICustomTypeDescriptor.GetEditor(Type editorBaseType) => null; + [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() => new EventDescriptorCollection(null); [RequiresUnreferencedCode("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] diff --git a/src/libraries/System.Data.Common/src/System/Data/DataViewManagerListItemTypeDescriptor.cs b/src/libraries/System.Data.Common/src/System/Data/DataViewManagerListItemTypeDescriptor.cs index 20b61fc1a36511..3201701ada37f7 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataViewManagerListItemTypeDescriptor.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataViewManagerListItemTypeDescriptor.cs @@ -78,6 +78,7 @@ internal DataView GetDataView(DataTable table) /// provides. If the component is sited, the site may add or remove /// additional events. /// + [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() => new EventDescriptorCollection(null); /// diff --git a/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs b/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs new file mode 100644 index 00000000000000..238ebf27c51a43 --- /dev/null +++ b/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Data.Common; +using System.ComponentModel; +using System.Collections; + +class Program +{ + static int Main(string[] args) + { + DbConnectionStringBuilder2 dcsb2 = new(); + ICustomTypeDescriptor td = dcsb2; + if (td.GetClassName() != "DbConnectionStringBuilder2") + { + throw new Exception("Class name got trimmed"); + } + + if (td.GetComponentName() != "Test Component Name") + { + throw new Exception("Component name got trimmed"); + } + + bool foundAttr = false; + string attrName = "Test" + ((args != null) ? "Attribute" : ""); + foreach (Attribute attr in td.GetAttributes()) + { + if (attr.GetType().Name == attrName) + { + if (attr.ToString() != "Test Attribute Value") + { + throw new Exception("Test attribute value differs"); + } + + if (foundAttr) + { + throw new Exception("More than one attribute found"); + } + + foundAttr = true; + } + } + + if (!foundAttr) + { + throw new Exception("Attribute not found"); + } + + return 100; + } +} + +[Test("Test Attribute Value")] +class DbConnectionStringBuilder2 : DbConnectionStringBuilder, IComponent +{ + public Hashtable GetProperties2() + { + Hashtable propertyDescriptors = new Hashtable(); + GetProperties(propertyDescriptors); + return propertyDescriptors; + } + +#pragma warning disable CS0067 // The event is never used + public event EventHandler Disposed; +#pragma warning restore CS0067 + + public string TestProperty { get; set; } + public ISite Site { get => new TestSite(); set => throw new NotImplementedException(); } + public void Dispose() { } +} + +class TestSite : INestedSite +{ + public string FullName => null; + public IComponent Component => throw new NotImplementedException(); + public IContainer Container => throw new NotImplementedException(); + public bool DesignMode => throw new NotImplementedException(); + public string Name { get => "Test Component Name"; set => throw new NotImplementedException(); } + public object GetService(Type serviceType) => null; +} + +class TestAttribute : Attribute +{ + public string Test { get; private set; } + + public TestAttribute(string test) + { + Test = test; + } + + public override string ToString() + { + return Test; + } +} diff --git a/src/libraries/System.Data.Common/tests/TrimmingTests/System.Data.Common.TrimmingTests.proj b/src/libraries/System.Data.Common/tests/TrimmingTests/System.Data.Common.TrimmingTests.proj index da4a46f2ae141a..7254c33fc9c7ba 100644 --- a/src/libraries/System.Data.Common/tests/TrimmingTests/System.Data.Common.TrimmingTests.proj +++ b/src/libraries/System.Data.Common/tests/TrimmingTests/System.Data.Common.TrimmingTests.proj @@ -1,5 +1,10 @@ + + + + + From 6c73e52f9942f8da7aac0868e1e3cb425e2062ba Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Thu, 17 Jun 2021 13:19:31 +0200 Subject: [PATCH 2/5] address some feedback --- .../Data/Common/DbConnectionStringBuilder.cs | 6 + .../DbConnectionStringBuilder.cs | 119 +++++++++--------- 2 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs index bdc9f9ed2238d1..9dc724ace93914 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs @@ -571,12 +571,18 @@ private PropertyDescriptorCollection GetProperties(Attribute[]? attributes) Justification = "The type of component is statically known. This class is marked with [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]")] string ICustomTypeDescriptor.GetClassName() { + // Below call is necessary to tell the trimmer that it should mark derived types appropriately. + // We cannot use GetClassName overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. + Type thisType = GetType(); return TypeDescriptor.GetClassName(this, true); } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "The type of component is statically known. This class is marked with [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]")] string ICustomTypeDescriptor.GetComponentName() { + // Below call is necessary to tell the trimmer that it should mark derived types appropriately. + // We cannot use GetClassName overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. + Type thisType = GetType(); return TypeDescriptor.GetComponentName(this, true); } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", diff --git a/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs b/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs index 238ebf27c51a43..2f5cbe25c05382 100644 --- a/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs @@ -6,91 +6,86 @@ using System.ComponentModel; using System.Collections; -class Program +namespace DbConnectionStringBuilderTrimmingTests { - static int Main(string[] args) + class Program { - DbConnectionStringBuilder2 dcsb2 = new(); - ICustomTypeDescriptor td = dcsb2; - if (td.GetClassName() != "DbConnectionStringBuilder2") + static int Main(string[] args) { - throw new Exception("Class name got trimmed"); - } + DbConnectionStringBuilder2 dcsb2 = new(); + ICustomTypeDescriptor td = dcsb2; + if (td.GetClassName() != "DbConnectionStringBuilderTrimmingTests.DbConnectionStringBuilder2") + { + throw new Exception("Class name got trimmed"); + } - if (td.GetComponentName() != "Test Component Name") - { - throw new Exception("Component name got trimmed"); - } + if (td.GetComponentName() != "Test Component Name") + { + throw new Exception("Component name got trimmed"); + } - bool foundAttr = false; - string attrName = "Test" + ((args != null) ? "Attribute" : ""); - foreach (Attribute attr in td.GetAttributes()) - { - if (attr.GetType().Name == attrName) + bool foundAttr = false; + + foreach (Attribute attr in td.GetAttributes()) { - if (attr.ToString() != "Test Attribute Value") + if (attr.GetType().Name == "TestAttribute") { - throw new Exception("Test attribute value differs"); - } + if (attr.ToString() != "Test Attribute Value") + { + throw new Exception("Test attribute value differs"); + } - if (foundAttr) - { - throw new Exception("More than one attribute found"); + if (foundAttr) + { + throw new Exception("More than one attribute found"); + } + + foundAttr = true; } + } - foundAttr = true; + if (!foundAttr) + { + throw new Exception("Attribute not found"); } - } - if (!foundAttr) - { - throw new Exception("Attribute not found"); + return 100; } - - return 100; } -} -[Test("Test Attribute Value")] -class DbConnectionStringBuilder2 : DbConnectionStringBuilder, IComponent -{ - public Hashtable GetProperties2() + [Test("Test Attribute Value")] + class DbConnectionStringBuilder2 : DbConnectionStringBuilder, IComponent { - Hashtable propertyDescriptors = new Hashtable(); - GetProperties(propertyDescriptors); - return propertyDescriptors; - } - #pragma warning disable CS0067 // The event is never used - public event EventHandler Disposed; + public event EventHandler Disposed; #pragma warning restore CS0067 - public string TestProperty { get; set; } - public ISite Site { get => new TestSite(); set => throw new NotImplementedException(); } - public void Dispose() { } -} - -class TestSite : INestedSite -{ - public string FullName => null; - public IComponent Component => throw new NotImplementedException(); - public IContainer Container => throw new NotImplementedException(); - public bool DesignMode => throw new NotImplementedException(); - public string Name { get => "Test Component Name"; set => throw new NotImplementedException(); } - public object GetService(Type serviceType) => null; -} - -class TestAttribute : Attribute -{ - public string Test { get; private set; } + public ISite Site { get => new TestSite(); set => throw new NotImplementedException(); } + public void Dispose() { } + } - public TestAttribute(string test) + class TestSite : INestedSite { - Test = test; + public string FullName => null; + public IComponent Component => throw new NotImplementedException(); + public IContainer Container => throw new NotImplementedException(); + public bool DesignMode => throw new NotImplementedException(); + public string Name { get => "Test Component Name"; set => throw new NotImplementedException(); } + public object GetService(Type serviceType) => null; } - public override string ToString() + class TestAttribute : Attribute { - return Test; + public string Test { get; private set; } + + public TestAttribute(string test) + { + Test = test; + } + + public override string ToString() + { + return Test; + } } } From cba8b0e5addaf69ba140d68b9353d4ef015fb2cb Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Fri, 18 Jun 2021 11:49:07 +0200 Subject: [PATCH 3/5] Make GetEvents() safe --- .../MetadataPropertyDescriptorWrapper.cs | 8 +--- .../System.ComponentModel.TypeConverter.cs | 7 +--- .../Linq/ComponentModel/XComponentModel.cs | 3 -- .../ComponentModel/CustomTypeDescriptor.cs | 1 - .../ComponentModel/ICustomTypeDescriptor.cs | 1 - .../ComponentModel/PropertyDescriptor.cs | 8 +--- .../ReflectPropertyDescriptor.cs | 11 +---- .../System/ComponentModel/TypeDescriptor.cs | 6 +-- .../ref/System.Data.Common.cs | 3 -- .../System/Data/Common/DataRecordInternal.cs | 1 - .../Data/Common/DbConnectionStringBuilder.cs | 6 ++- .../src/System/Data/Common/DbDataRecord.cs | 1 - .../src/System/Data/DataRowView.cs | 1 - .../DataViewManagerListItemTypeDescriptor.cs | 1 - .../DbConnectionStringBuilder.cs | 40 +++++++++++++++++++ 15 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs index 0397663e86f405..9450f2a5df6fc0 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs @@ -21,7 +21,6 @@ public MetadataPropertyDescriptorWrapper(PropertyDescriptor descriptor, Attribut _isReadOnly = (readOnlyAttribute != null ? readOnlyAttribute.IsReadOnly : false); } - [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public override void AddValueChanged(object component, EventHandler handler) { _descriptor.AddValueChanged(component, handler); } public override bool CanResetValue(object component) { return _descriptor.CanResetValue(component); } @@ -43,7 +42,6 @@ public override bool IsReadOnly public override Type PropertyType { get { return _descriptor.PropertyType; } } - [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public override void RemoveValueChanged(object component, EventHandler handler) { _descriptor.RemoveValueChanged(component, handler); } public override void ResetValue(object component) { _descriptor.ResetValue(component); } @@ -52,10 +50,6 @@ public override bool IsReadOnly public override bool ShouldSerializeValue(object component) { return _descriptor.ShouldSerializeValue(component); } - public override bool SupportsChangeEvents - { - [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] - get { return _descriptor.SupportsChangeEvents; } - } + public override bool SupportsChangeEvents { get { return _descriptor.SupportsChangeEvents; } } } } diff --git a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs index cda74ed7f43920..d8ca41c78fb690 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs @@ -296,7 +296,6 @@ protected CustomTypeDescriptor(System.ComponentModel.ICustomTypeDescriptor paren public virtual System.ComponentModel.PropertyDescriptor GetDefaultProperty() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] public virtual object GetEditor(System.Type editorBaseType) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public virtual System.ComponentModel.EventDescriptorCollection GetEvents() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] public virtual System.ComponentModel.EventDescriptorCollection GetEvents(System.Attribute[] attributes) { throw null; } @@ -580,7 +579,6 @@ public partial interface ICustomTypeDescriptor System.ComponentModel.PropertyDescriptor GetDefaultProperty(); [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object GetEditor(System.Type editorBaseType); - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] System.ComponentModel.EventDescriptorCollection GetEvents(); [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] System.ComponentModel.EventDescriptorCollection GetEvents(System.Attribute[] attributes); @@ -1057,8 +1055,7 @@ protected PropertyDescriptor(string name, System.Attribute[] attrs) : base (defa public abstract bool IsReadOnly { get; } public abstract System.Type PropertyType { get; } public System.ComponentModel.DesignerSerializationVisibility SerializationVisibility { get { throw null; } } - public virtual bool SupportsChangeEvents { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] get { throw null; } } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] + public virtual bool SupportsChangeEvents { get { throw null; } } public virtual void AddValueChanged(object component, System.EventHandler handler) { } public abstract bool CanResetValue(object component); protected object CreateInstance([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type type) { throw null; } @@ -1082,7 +1079,6 @@ protected override void FillAttributes(System.Collections.IList attributeList) { public abstract object GetValue(object component); protected internal System.EventHandler GetValueChangedHandler(object component) { throw null; } protected virtual void OnValueChanged(object component, System.EventArgs e) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public virtual void RemoveValueChanged(object component, System.EventHandler handler) { } public abstract void ResetValue(object component); public abstract void SetValue(object component, object value); @@ -1474,7 +1470,6 @@ public static void CreateAssociation(object primary, object secondary) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The Type of component cannot be statically discovered.")] public static System.ComponentModel.EventDescriptorCollection GetEvents(object component, bool noCustomTypeDesc) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] public static System.ComponentModel.EventDescriptorCollection GetEvents([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type componentType) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] public static System.ComponentModel.EventDescriptorCollection GetEvents([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type componentType, System.Attribute[] attributes) { throw null; } diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/MS/Internal/Xml/Linq/ComponentModel/XComponentModel.cs b/src/libraries/System.ComponentModel.TypeConverter/src/MS/Internal/Xml/Linq/ComponentModel/XComponentModel.cs index d2c10bb338b34b..67df1e5bbacef0 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/MS/Internal/Xml/Linq/ComponentModel/XComponentModel.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/MS/Internal/Xml/Linq/ComponentModel/XComponentModel.cs @@ -86,11 +86,9 @@ public override Type PropertyType public override bool SupportsChangeEvents { - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] get { return true; } } - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public override void AddValueChanged(object component, EventHandler handler) { bool hasValueChangedHandler = GetValueChangedHandler(component) != null; @@ -110,7 +108,6 @@ public override bool CanResetValue(object component) return false; } - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public override void RemoveValueChanged(object component, EventHandler handler) { base.RemoveValueChanged(component, handler); diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CustomTypeDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CustomTypeDescriptor.cs index d97340165c092c..03de81f6433766 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CustomTypeDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CustomTypeDescriptor.cs @@ -108,7 +108,6 @@ public virtual TypeConverter GetConverter() /// returned. If no parent is provided,this will return an empty /// event collection. /// - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public virtual EventDescriptorCollection GetEvents() { if (_parent != null) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ICustomTypeDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ICustomTypeDescriptor.cs index f9568046323cec..699ebc3d22748d 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ICustomTypeDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ICustomTypeDescriptor.cs @@ -53,7 +53,6 @@ public interface ICustomTypeDescriptor /// /// Gets the events for this instance of a component. /// - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] EventDescriptorCollection GetEvents(); /// diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/PropertyDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/PropertyDescriptor.cs index 5b3d179b221226..92da2abeffabcc 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/PropertyDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/PropertyDescriptor.cs @@ -121,7 +121,6 @@ public DesignerSerializationVisibility SerializationVisibility /// /// Allows interested objects to be notified when this property changes. /// - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public virtual void AddValueChanged(object component, EventHandler handler) { if (component == null) @@ -400,7 +399,6 @@ protected virtual void OnValueChanged(object component, EventArgs e) /// /// Allows interested objects to be notified when this property changes. /// - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public virtual void RemoveValueChanged(object component, EventHandler handler) { if (component == null) @@ -467,10 +465,6 @@ protected internal EventHandler GetValueChangedHandler(object component) /// from direct calls made to PropertyDescriptor.SetValue (value=false). For example, the component may /// implement the INotifyPropertyChanged interface, or may have an explicit '{name}Changed' event for this property. /// - public virtual bool SupportsChangeEvents - { - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] - get => false; - } + public virtual bool SupportsChangeEvents => false; } } diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectPropertyDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectPropertyDescriptor.cs index 1f412fed4f85cf..8178284444baf4 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectPropertyDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectPropertyDescriptor.cs @@ -246,7 +246,6 @@ private object AmbientValue /// private EventDescriptor ChangedEventValue { - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] get { if (!_state[s_bitChangedQueried]) @@ -264,7 +263,6 @@ private EventDescriptor ChangedEventValue /// private EventDescriptor IPropChangedEventValue { - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] get { if (!_state[s_bitIPropChangedQueried]) @@ -483,7 +481,6 @@ private MethodInfo ShouldSerializeMethodValue /// /// Allows interested objects to be notified when this property changes. /// - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public override void AddValueChanged(object component, EventHandler handler) { if (component == null) @@ -966,7 +963,6 @@ protected override void OnValueChanged(object component, EventArgs e) /// /// Allows interested objects to be notified when this property changes. /// - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public override void RemoveValueChanged(object component, EventHandler handler) { if (component == null) @@ -1201,11 +1197,6 @@ public override bool ShouldSerializeValue(object component) /// from direct calls made to PropertyDescriptor.SetValue (value=false). For example, the component may /// implement the INotifyPropertyChanged interface, or may have an explicit '{name}Changed' event for this property. /// - public override bool SupportsChangeEvents - { - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] - - get => IPropChangedEventValue != null || ChangedEventValue != null; - } + public override bool SupportsChangeEvents => IPropChangedEventValue != null || ChangedEventValue != null; } } diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs index 56f5b53535fc45..d70821726637d7 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs @@ -1018,7 +1018,6 @@ public static object GetEditor( /// /// Gets a collection of events for a specified type of component. /// - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] public static EventDescriptorCollection GetEvents( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type componentType) { @@ -2747,7 +2746,6 @@ object ICustomTypeDescriptor.GetEditor(Type editorBaseType) return _handler.GetEditor(_instance, editorBaseType); } - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return _handler.GetEvents(_instance); @@ -3069,7 +3067,6 @@ object ICustomTypeDescriptor.GetEditor(Type editorBaseType) /// /// ICustomTypeDescriptor implementation. /// - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { EventDescriptorCollection events = _primary.GetEvents() ?? _secondary.GetEvents(); @@ -3471,7 +3468,7 @@ object ICustomTypeDescriptor.GetEditor(Type editorBaseType) /// /// ICustomTypeDescriptor implementation. /// - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "The ctor of this Type has RequiresUnreferencedCode.")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { // Check to see if the provider we get is a ReflectTypeDescriptionProvider. @@ -3804,7 +3801,6 @@ object ICustomTypeDescriptor.GetEditor(Type editorBaseType) /// /// ICustomTypeDescriptor implementation. /// - [RequiresUnreferencedCode(EventDescriptor.RequiresUnreferencedCodeMessage)] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { // Check to see if the provider we get is a ReflectTypeDescriptionProvider. diff --git a/src/libraries/System.Data.Common/ref/System.Data.Common.cs b/src/libraries/System.Data.Common/ref/System.Data.Common.cs index dd1d6f8ea28cdd..6e5aa2d07595e7 100644 --- a/src/libraries/System.Data.Common/ref/System.Data.Common.cs +++ b/src/libraries/System.Data.Common/ref/System.Data.Common.cs @@ -477,7 +477,6 @@ public void EndEdit() { } System.ComponentModel.PropertyDescriptor System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object System.ComponentModel.ICustomTypeDescriptor.GetEditor(System.Type editorBaseType) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents(System.Attribute[] attributes) { throw null; } @@ -2153,7 +2152,6 @@ void System.Collections.IDictionary.Remove(object keyword) { } System.ComponentModel.PropertyDescriptor System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object System.ComponentModel.ICustomTypeDescriptor.GetEditor(System.Type editorBaseType) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents(System.Attribute[] attributes) { throw null; } @@ -2336,7 +2334,6 @@ protected DbDataRecord() { } System.ComponentModel.PropertyDescriptor System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object System.ComponentModel.ICustomTypeDescriptor.GetEditor(System.Type editorBaseType) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] System.ComponentModel.EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents(System.Attribute[] attributes) { throw null; } diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs index 8586193d8bf450..e9f240e9d74d90 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs @@ -343,7 +343,6 @@ object ICustomTypeDescriptor.GetEditor(Type editorBaseType) } #nullable enable - [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return new EventDescriptorCollection(null); diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs index 9dc724ace93914..10965ecf824eec 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs @@ -621,9 +621,13 @@ EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); } - [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "The type of component is statically known. This class is marked with [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { + // Below call is necessary to tell the trimmer that it should mark derived types appropriately. + // We cannot use GetClassName overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. + Type thisType = GetType(); return TypeDescriptor.GetEvents(this, true); } [RequiresUnreferencedCode("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbDataRecord.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbDataRecord.cs index 930378dfe9f5b4..b2ee9ec585767b 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbDataRecord.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbDataRecord.cs @@ -89,7 +89,6 @@ protected virtual DbDataReader GetDbDataReader(int i) [RequiresUnreferencedCode("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object ICustomTypeDescriptor.GetEditor(Type editorBaseType) => null; - [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() => new EventDescriptorCollection(null); [RequiresUnreferencedCode("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] diff --git a/src/libraries/System.Data.Common/src/System/Data/DataRowView.cs b/src/libraries/System.Data.Common/src/System/Data/DataRowView.cs index 5c98190ca3e976..4b86f5f59fa8b0 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataRowView.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataRowView.cs @@ -249,7 +249,6 @@ public void EndEdit() [RequiresUnreferencedCode("Editors registered in TypeDescriptor.AddEditorTable may be trimmed.")] object ICustomTypeDescriptor.GetEditor(Type editorBaseType) => null; - [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() => new EventDescriptorCollection(null); [RequiresUnreferencedCode("The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")] diff --git a/src/libraries/System.Data.Common/src/System/Data/DataViewManagerListItemTypeDescriptor.cs b/src/libraries/System.Data.Common/src/System/Data/DataViewManagerListItemTypeDescriptor.cs index 3201701ada37f7..20b61fc1a36511 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataViewManagerListItemTypeDescriptor.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataViewManagerListItemTypeDescriptor.cs @@ -78,7 +78,6 @@ internal DataView GetDataView(DataTable table) /// provides. If the component is sited, the site may add or remove /// additional events. /// - [RequiresUnreferencedCode("The built-in EventDescriptor implementation uses Reflection which requires unreferenced code.")] EventDescriptorCollection ICustomTypeDescriptor.GetEvents() => new EventDescriptorCollection(null); /// diff --git a/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs b/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs index 2f5cbe25c05382..86fcc05acabb89 100644 --- a/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs @@ -14,6 +14,7 @@ static int Main(string[] args) { DbConnectionStringBuilder2 dcsb2 = new(); ICustomTypeDescriptor td = dcsb2; + if (td.GetClassName() != "DbConnectionStringBuilderTrimmingTests.DbConnectionStringBuilder2") { throw new Exception("Class name got trimmed"); @@ -49,6 +50,42 @@ static int Main(string[] args) throw new Exception("Attribute not found"); } + bool foundEvent = false; + bool foundEventWithDisplayName = false; + + foreach (EventDescriptor ev in td.GetEvents()) + { + if (ev.DisplayName == "TestEvent") + { + if (foundEvent) + { + throw new Exception("More than one event TestEvent found."); + } + + foundEvent = true; + } + + if (ev.DisplayName == "Event With DisplayName") + { + if (foundEventWithDisplayName) + { + throw new Exception("More than one event with display name found."); + } + + foundEventWithDisplayName = true; + } + } + + if (!foundEvent) + { + throw new Exception("Event not found"); + } + + if (!foundEventWithDisplayName) + { + throw new Exception("Event with DisplayName not found"); + } + return 100; } } @@ -58,6 +95,9 @@ class DbConnectionStringBuilder2 : DbConnectionStringBuilder, IComponent { #pragma warning disable CS0067 // The event is never used public event EventHandler Disposed; + public event Action TestEvent; + [DisplayName("Event With DisplayName")] + public event Action TestEvent2; #pragma warning restore CS0067 public ISite Site { get => new TestSite(); set => throw new NotImplementedException(); } From ac6f4c525254d5870793079e01f27041fdb3ab49 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Fri, 18 Jun 2021 12:31:48 +0200 Subject: [PATCH 4/5] make GetProperties safe --- .../MetadataPropertyDescriptorWrapper.cs | 1 - .../ref/System.Data.Common.cs | 1 - .../Data/Common/DbConnectionStringBuilder.cs | 20 +++++++++---- .../DbConnectionStringBuilder.cs | 28 +++++++++++++++++++ 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs index 9450f2a5df6fc0..f771e0e340d853 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/MetadataPropertyDescriptorWrapper.cs @@ -3,7 +3,6 @@ using System; using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; using System.Linq; namespace System.ComponentModel.DataAnnotations diff --git a/src/libraries/System.Data.Common/ref/System.Data.Common.cs b/src/libraries/System.Data.Common/ref/System.Data.Common.cs index 6e5aa2d07595e7..99c16272c7d084 100644 --- a/src/libraries/System.Data.Common/ref/System.Data.Common.cs +++ b/src/libraries/System.Data.Common/ref/System.Data.Common.cs @@ -2131,7 +2131,6 @@ public virtual void Clear() { } protected internal void ClearPropertyDescriptors() { } public virtual bool ContainsKey(string keyword) { throw null; } public virtual bool EquivalentTo(System.Data.Common.DbConnectionStringBuilder connectionStringBuilder) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("PropertyDescriptor's PropertyType cannot be statically discovered. The Type of component cannot be statically discovered.")] protected virtual void GetProperties(System.Collections.Hashtable propertyDescriptors) { } public virtual bool Remove(string keyword) { throw null; } public virtual bool ShouldSerialize(string keyword) { throw null; } diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs index 10965ecf824eec..dc754e467e89f1 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs @@ -388,7 +388,6 @@ internal Attribute[] GetAttributesFromCollection(AttributeCollection collection) return attributes; } - [RequiresUnreferencedCode("PropertyDescriptor's PropertyType cannot be statically discovered. The Type of component cannot be statically discovered.")] private PropertyDescriptorCollection GetProperties() { PropertyDescriptorCollection? propertyDescriptors = _propertyDescriptors; @@ -414,7 +413,16 @@ private PropertyDescriptorCollection GetProperties() return propertyDescriptors; } - [RequiresUnreferencedCode("PropertyDescriptor's PropertyType cannot be statically discovered. The Type of component cannot be statically discovered.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "The type of component is statically known. This class is marked with [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]")] + private PropertyDescriptorCollection GetPropertiesOfThis() + { + // Below call is necessary to tell the trimmer that it should mark derived types appropriately. + // We cannot use overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. + Type thisType = GetType(); + return TypeDescriptor.GetProperties(this, true); + } + protected virtual void GetProperties(Hashtable propertyDescriptors) { long logScopeId = DataCommonEventSource.Log.EnterScope(" {0}", ObjectID); @@ -423,7 +431,7 @@ protected virtual void GetProperties(Hashtable propertyDescriptors) // show all strongly typed properties (not already added) // except ConnectionString iff BrowsableConnectionString Attribute[]? attributes; - foreach (PropertyDescriptor reflected in TypeDescriptor.GetProperties(this, true)) + foreach (PropertyDescriptor reflected in GetPropertiesOfThis()) { Debug.Assert(reflected != null); if (ADP.ConnectionString != reflected.Name) @@ -572,7 +580,7 @@ private PropertyDescriptorCollection GetProperties(Attribute[]? attributes) string ICustomTypeDescriptor.GetClassName() { // Below call is necessary to tell the trimmer that it should mark derived types appropriately. - // We cannot use GetClassName overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. + // We cannot use overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. Type thisType = GetType(); return TypeDescriptor.GetClassName(this, true); } @@ -581,7 +589,7 @@ string ICustomTypeDescriptor.GetClassName() string ICustomTypeDescriptor.GetComponentName() { // Below call is necessary to tell the trimmer that it should mark derived types appropriately. - // We cannot use GetClassName overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. + // We cannot use overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. Type thisType = GetType(); return TypeDescriptor.GetComponentName(this, true); } @@ -626,7 +634,7 @@ EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { // Below call is necessary to tell the trimmer that it should mark derived types appropriately. - // We cannot use GetClassName overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. + // We cannot use overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. Type thisType = GetType(); return TypeDescriptor.GetEvents(this, true); } diff --git a/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs b/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs index 86fcc05acabb89..78ac56e9f751a2 100644 --- a/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.Common/tests/TrimmingTests/DbConnectionStringBuilder.cs @@ -86,6 +86,26 @@ static int Main(string[] args) throw new Exception("Event with DisplayName not found"); } + bool propertyFound = false; + foreach (DictionaryEntry kv in dcsb2.GetProperties2()) + { + PropertyDescriptor val = (PropertyDescriptor)kv.Value; + if (val.Name == "TestProperty") + { + if (propertyFound) + { + throw new Exception("More than one property TestProperty found."); + } + + propertyFound = true; + } + } + + if (!propertyFound) + { + throw new Exception("Property not found"); + } + return 100; } } @@ -100,8 +120,16 @@ class DbConnectionStringBuilder2 : DbConnectionStringBuilder, IComponent public event Action TestEvent2; #pragma warning restore CS0067 + public string TestProperty { get; set; } public ISite Site { get => new TestSite(); set => throw new NotImplementedException(); } public void Dispose() { } + + public Hashtable GetProperties2() + { + Hashtable propertyDescriptors = new Hashtable(); + GetProperties(propertyDescriptors); + return propertyDescriptors; + } } class TestSite : INestedSite From 57e8405e50e57c2f54d2dc52a909c50f9164d916 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Mon, 21 Jun 2021 19:40:05 +0200 Subject: [PATCH 5/5] Mark GetProperties with RUC --- .../ref/System.Data.Common.cs | 1 + .../Data/Common/DbConnectionStringBuilder.cs | 18 +++++++----------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Data.Common/ref/System.Data.Common.cs b/src/libraries/System.Data.Common/ref/System.Data.Common.cs index 99c16272c7d084..ce7de38a7aefd2 100644 --- a/src/libraries/System.Data.Common/ref/System.Data.Common.cs +++ b/src/libraries/System.Data.Common/ref/System.Data.Common.cs @@ -2131,6 +2131,7 @@ public virtual void Clear() { } protected internal void ClearPropertyDescriptors() { } public virtual bool ContainsKey(string keyword) { throw null; } public virtual bool EquivalentTo(System.Data.Common.DbConnectionStringBuilder connectionStringBuilder) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("PropertyDescriptor's PropertyType cannot be statically discovered.")] protected virtual void GetProperties(System.Collections.Hashtable propertyDescriptors) { } public virtual bool Remove(string keyword) { throw null; } public virtual bool ShouldSerialize(string keyword) { throw null; } diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs index dc754e467e89f1..027fe42f0b08ef 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionStringBuilder.cs @@ -388,6 +388,7 @@ internal Attribute[] GetAttributesFromCollection(AttributeCollection collection) return attributes; } + [RequiresUnreferencedCode("PropertyDescriptor's PropertyType cannot be statically discovered.")] private PropertyDescriptorCollection GetProperties() { PropertyDescriptorCollection? propertyDescriptors = _propertyDescriptors; @@ -413,25 +414,20 @@ private PropertyDescriptorCollection GetProperties() return propertyDescriptors; } - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", - Justification = "The type of component is statically known. This class is marked with [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]")] - private PropertyDescriptorCollection GetPropertiesOfThis() - { - // Below call is necessary to tell the trimmer that it should mark derived types appropriately. - // We cannot use overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. - Type thisType = GetType(); - return TypeDescriptor.GetProperties(this, true); - } - + [RequiresUnreferencedCode("PropertyDescriptor's PropertyType cannot be statically discovered.")] protected virtual void GetProperties(Hashtable propertyDescriptors) { long logScopeId = DataCommonEventSource.Log.EnterScope(" {0}", ObjectID); try { + // Below call is necessary to tell the trimmer that it should mark derived types appropriately. + // We cannot use overload which takes type because the result might differ if derived class implements ICustomTypeDescriptor. + Type thisType = GetType(); + // show all strongly typed properties (not already added) // except ConnectionString iff BrowsableConnectionString Attribute[]? attributes; - foreach (PropertyDescriptor reflected in GetPropertiesOfThis()) + foreach (PropertyDescriptor reflected in TypeDescriptor.GetProperties(this, true)) { Debug.Assert(reflected != null); if (ADP.ConnectionString != reflected.Name)