From e7bbc9120608b2f71bd339526b4f6208fce599cc Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Tue, 28 May 2024 15:35:41 -0500 Subject: [PATCH 1/5] Don't trim members called by TypeDescriptor's use of reflection --- .../src/System/Data/DataColumn.cs | 5 +++ .../src/System/Data/DataTable.cs | 10 ++++++ .../tests/System/Data/DataColumnTest.cs | 33 +++++++++++++++++++ .../tests/System/Data/DataTableTest.cs | 31 +++++++++++++++++ .../src/System/Data/Odbc/OdbcCommand.cs | 2 ++ .../src/System/Data/Odbc/OdbcParameter.cs | 4 +++ .../System.Data.OleDb/src/OleDbCommand.cs | 2 ++ .../System.Data.OleDb/src/OleDbParameter.cs | 7 ++++ 8 files changed, 94 insertions(+) diff --git a/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs b/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs index 3c048496bc8061..b723e27929b2f5 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs @@ -121,6 +121,11 @@ public DataColumn(string? columnName, [DynamicallyAccessedMembers(DynamicallyAcc /// column is an attribute. /// [RequiresUnreferencedCode("Members from serialized types or types used in expressions may be trimmed if not referenced directly.")] + [DynamicDependency(nameof(ShouldSerializeCaption))] + [DynamicDependency(nameof(ShouldSerializeDefaultValue))] + [DynamicDependency(nameof(ShouldSerializeNamespace))] + [DynamicDependency(nameof(ResetCaption))] + [DynamicDependency(nameof(ResetNamespace))] public DataColumn(string? columnName, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] Type dataType, string? expr, MappingType type) { GC.SuppressFinalize(this); diff --git a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs index 428393d70ea17d..79e60e84af796a 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs @@ -161,6 +161,16 @@ public class DataTable : MarshalByValueComponent, IListSource, ISupportInitializ /// /// Initializes a new instance of the class with no arguments. /// + [DynamicDependency(nameof(ShouldSerializeCaseSensitive))] + [DynamicDependency(nameof(ShouldSerializeLocale))] + [DynamicDependency(nameof(ShouldSerializeNamespace))] + [DynamicDependency(nameof(ShouldSerializePrimaryKey))] + [DynamicDependency(nameof(ResetCaseSensitive))] + [DynamicDependency(nameof(ResetColumns))] + [DynamicDependency(nameof(ResetConstraints))] + [DynamicDependency(nameof(ResetIndexes))] + [DynamicDependency(nameof(ResetNamespace))] + [DynamicDependency(nameof(ResetPrimaryKey))] public DataTable() { GC.SuppressFinalize(this); diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs index 8e318d2d138083..c9a4813456a5db 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs @@ -793,6 +793,39 @@ public void NonSqlNullableType_RequiresPublicStaticNull() Assert.Throws(() => t.Columns.Add("c3", typeof(NullableTypeWithoutNullMember))); } + [Fact] + public void MethodsCalledByReflectionAreNotTrimmed() + { + DataColumn dc = new DataColumn + { + ColumnName = "dataColumn", + DataType = typeof(DateTime) + }; + + PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(dc); + + Assert.False(properties[nameof(DataColumn.DefaultValue)].ShouldSerializeValue(dc)); + dc.DefaultValue = DateTime.MinValue; + Assert.True(properties[nameof(DataColumn.DefaultValue)].ShouldSerializeValue(dc)); + properties[nameof(DataColumn.DefaultValue)].ResetValue(dc); // Reset method is not available + Assert.Equal(DateTime.MinValue, dc.DefaultValue); + Assert.True(properties[nameof(DataColumn.DefaultValue)].ShouldSerializeValue(dc)); + + Assert.False(properties[nameof(DataColumn.Caption)].ShouldSerializeValue(dc)); + dc.Caption = "Caption"; + Assert.True(properties[nameof(DataColumn.Caption)].ShouldSerializeValue(dc)); + properties[nameof(DataColumn.Caption)].ResetValue(dc); // Reset method is available + Assert.False(properties[nameof(DataColumn.Caption)].ShouldSerializeValue(dc)); + Assert.Equal("dataColumn", dc.Caption); + + Assert.False(properties[nameof(DataColumn.Namespace)].ShouldSerializeValue(dc)); + dc.Namespace = "Namespace"; + Assert.True(properties[nameof(DataColumn.Namespace)].ShouldSerializeValue(dc)); + properties[nameof(DataColumn.Namespace)].ResetValue(dc); // Reset method is available + Assert.False(properties[nameof(DataColumn.Namespace)].ShouldSerializeValue(dc)); + Assert.Equal("", dc.Namespace); + } + private sealed class NullableTypeWithNullProperty : INullable { public bool IsNull => true; diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs index bc032b1208fc76..2ec1af86a958f9 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs @@ -1818,6 +1818,37 @@ public void TableInitializedEventTest4() dt.Initialized -= new EventHandler(OnTableInitialized); } + [Fact] + public void MethodsCalledByReflectionAreNotTrimmed() + { + DataTable dt = new DataTable(); + dt.CaseSensitive = true; + dt.Locale = new CultureInfo("en-US"); + dt.PrimaryKey = new DataColumn[] { dt.Columns.Add("id", typeof(int)) }; + dt.Namespace = "NS"; + + PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(dt); + + Assert.True(properties[nameof(DataTable.PrimaryKey)].ShouldSerializeValue(dt)); + properties[nameof(DataTable.PrimaryKey)].ResetValue(dt); // Reset method is available + Assert.False(properties[nameof(DataTable.PrimaryKey)].ShouldSerializeValue(dt)); + Assert.Equal(0, dt.PrimaryKey.Length); + + Assert.True(properties[nameof(DataTable.CaseSensitive)].ShouldSerializeValue(dt)); + properties[nameof(DataTable.CaseSensitive)].ResetValue(dt); // Reset method is available + Assert.False(properties[nameof(DataTable.CaseSensitive)].ShouldSerializeValue(dt)); + Assert.False(dt.CaseSensitive); + + Assert.True(properties[nameof(DataTable.Locale)].ShouldSerializeValue(dt)); + properties[nameof(DataTable.Locale)].ResetValue(dt); + Assert.True(properties[nameof(DataTable.Locale)].ShouldSerializeValue(dt)); // Reset method is not available + + Assert.True(properties[nameof(DataTable.Namespace)].ShouldSerializeValue(dt)); + properties[nameof(DataTable.Namespace)].ResetValue(dt); // Reset method is available + Assert.False(properties[nameof(DataTable.Namespace)].ShouldSerializeValue(dt)); + Assert.Equal("", dt.Namespace); + } + private void OnTableInitialized(object src, EventArgs args) { _tableInitialized = true; diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs index a0fd1e4ea87b9f..584dbd747cc96f 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs @@ -41,6 +41,8 @@ public sealed class OdbcCommand : DbCommand, ICloneable private ConnectionState _cmdState; + [DynamicDependency(nameof(ResetCommandTimeout))] + [DynamicDependency(nameof(ShouldSerializeCommandTimeout))] public OdbcCommand() : base() { GC.SuppressFinalize(this); diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs index e7904b01029957..91004012941c37 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs @@ -68,6 +68,10 @@ public sealed partial class OdbcParameter : DbParameter, ICloneable, IDataParame private ODBC32.SQL_C _prepared_Sql_C_Type; + [DynamicDependency(nameof(ResetDbType))] // Calls DbParameter.ResetOdbcType() + [DynamicDependency(nameof(ShouldSerializePrecision))] + [DynamicDependency(nameof(ShouldSerializeScale))] + [DynamicDependency(nameof(ShouldSerializeSize))] public OdbcParameter() : base() { // uses System.Threading! diff --git a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs index 81ed633271852d..ae4bb30c6079e8 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs @@ -46,6 +46,8 @@ public sealed class OleDbCommand : DbCommand, ICloneable, IDbCommand private int _changeID; private int _lastChangeID; + [DynamicDependency(nameof(ResetCommandTimeout))] + [DynamicDependency(nameof(ResetConnection))] public OleDbCommand() : base() { GC.SuppressFinalize(this); diff --git a/src/libraries/System.Data.OleDb/src/OleDbParameter.cs b/src/libraries/System.Data.OleDb/src/OleDbParameter.cs index 81055cf09716d9..5cc955e1d26344 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbParameter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbParameter.cs @@ -22,6 +22,13 @@ public sealed partial class OleDbParameter : DbParameter, ICloneable, IDbDataPar private NativeDBType? _coerceMetaType; + [DynamicDependency(nameof(ResetDbType))] // Calls ResetOleDbType() + [DynamicDependency(nameof(ResetParent))] + [DynamicDependency(nameof(ResetSize))] + [DynamicDependency(nameof(ShouldSerializeOleDbType))] + [DynamicDependency(nameof(ShouldSerializePrecision))] + [DynamicDependency(nameof(ShouldSerializeScale))] + [DynamicDependency(nameof(ShouldSerializeSize))] public OleDbParameter() : base() { // V1.0 nothing } From 7c06b148c48a89ec0cfcf249959fb7ba75e07387 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Mon, 10 Jun 2024 15:14:37 -0500 Subject: [PATCH 2/5] Remove OOB asm changes; not part of original issue --- .../System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs | 2 -- .../System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs | 4 ---- src/libraries/System.Data.OleDb/src/OleDbCommand.cs | 2 -- src/libraries/System.Data.OleDb/src/OleDbParameter.cs | 7 ------- 4 files changed, 15 deletions(-) diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs index 584dbd747cc96f..a0fd1e4ea87b9f 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs @@ -41,8 +41,6 @@ public sealed class OdbcCommand : DbCommand, ICloneable private ConnectionState _cmdState; - [DynamicDependency(nameof(ResetCommandTimeout))] - [DynamicDependency(nameof(ShouldSerializeCommandTimeout))] public OdbcCommand() : base() { GC.SuppressFinalize(this); diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs index 91004012941c37..e7904b01029957 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs @@ -68,10 +68,6 @@ public sealed partial class OdbcParameter : DbParameter, ICloneable, IDataParame private ODBC32.SQL_C _prepared_Sql_C_Type; - [DynamicDependency(nameof(ResetDbType))] // Calls DbParameter.ResetOdbcType() - [DynamicDependency(nameof(ShouldSerializePrecision))] - [DynamicDependency(nameof(ShouldSerializeScale))] - [DynamicDependency(nameof(ShouldSerializeSize))] public OdbcParameter() : base() { // uses System.Threading! diff --git a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs index ae4bb30c6079e8..81ed633271852d 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs @@ -46,8 +46,6 @@ public sealed class OleDbCommand : DbCommand, ICloneable, IDbCommand private int _changeID; private int _lastChangeID; - [DynamicDependency(nameof(ResetCommandTimeout))] - [DynamicDependency(nameof(ResetConnection))] public OleDbCommand() : base() { GC.SuppressFinalize(this); diff --git a/src/libraries/System.Data.OleDb/src/OleDbParameter.cs b/src/libraries/System.Data.OleDb/src/OleDbParameter.cs index 5cc955e1d26344..81055cf09716d9 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbParameter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbParameter.cs @@ -22,13 +22,6 @@ public sealed partial class OleDbParameter : DbParameter, ICloneable, IDbDataPar private NativeDBType? _coerceMetaType; - [DynamicDependency(nameof(ResetDbType))] // Calls ResetOleDbType() - [DynamicDependency(nameof(ResetParent))] - [DynamicDependency(nameof(ResetSize))] - [DynamicDependency(nameof(ShouldSerializeOleDbType))] - [DynamicDependency(nameof(ShouldSerializePrecision))] - [DynamicDependency(nameof(ShouldSerializeScale))] - [DynamicDependency(nameof(ShouldSerializeSize))] public OleDbParameter() : base() { // V1.0 nothing } From 53dbd361233adf52bab12b33d7217714822d8adb Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Mon, 10 Jun 2024 17:41:44 -0500 Subject: [PATCH 3/5] Add DataSet and DataRow support --- .../src/System/Data/DataSet.cs | 5 +++ .../tests/System/Data/DataColumnTest.cs | 19 +++++++++-- .../tests/System/Data/DataRowTest.cs | 12 ++++++- .../tests/System/Data/DataSetTest.cs | 16 ++++++++++ .../tests/System/Data/DataTableTest.cs | 32 ++++++++++++++++--- 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs index 37c1fb283d7e19..20c927551a2bd1 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs @@ -80,6 +80,11 @@ public class DataSet : MarshalByValueComponent, IListSource, IXmlSerializable, I /// /// Initializes a new instance of the class. /// + [DynamicDependency(nameof(ShouldSerializeLocale))] + [DynamicDependency(nameof(ShouldSerializeRelations))] + [DynamicDependency(nameof(ShouldSerializeTables))] + [DynamicDependency(nameof(ResetRelations))] + [DynamicDependency(nameof(ResetTables))] public DataSet() { GC.SuppressFinalize(this); diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs index c9a4813456a5db..537102ac68a4f9 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs @@ -33,7 +33,7 @@ using System.ComponentModel; using System.Data.SqlTypes; - +using System.Reflection; using Xunit; namespace System.Data.Tests @@ -794,7 +794,22 @@ public void NonSqlNullableType_RequiresPublicStaticNull() } [Fact] - public void MethodsCalledByReflectionAreNotTrimmed() + public void MethodsCalledByReflectionSerializersAreNotTrimmed() + { + Assert.True(ShouldSerializeExists(nameof(DataColumn.Caption))); + Assert.True(ShouldSerializeExists(nameof(DataColumn.DefaultValue))); + Assert.True(ShouldSerializeExists(nameof(DataColumn.Namespace))); + + Assert.True(ResetExists(nameof(DataColumn.Caption))); + Assert.False(ResetExists(nameof(DataColumn.DefaultValue))); + Assert.True(ResetExists(nameof(DataColumn.Namespace))); + + bool ShouldSerializeExists(string name) => typeof(DataColumn).GetMethod("ShouldSerialize" + name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) != null; + bool ResetExists(string name) => typeof(DataColumn).GetMethod("Reset" + name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) != null; + } + + [Fact] + public void MethodsCalledByReflectionSerializersAreNotTrimmedUsingTypeDescriptor() { DataColumn dc = new DataColumn { diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataRowTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataRowTest.cs index 5dd1ba770cc5f9..07acb864750f24 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataRowTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataRowTest.cs @@ -29,7 +29,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // - +using System.Reflection; using Xunit; namespace System.Data.Tests @@ -876,5 +876,15 @@ public void SetParent_missing_ParentRow() Assert.Equal(DBNull.Value, childRow[childColumn1]); Assert.Equal("value", childRow[childColumn2]); } + + [Fact] + public void MethodsCalledByReflectionSerializersAreNotTrimmed() + { + Assert.False(ShouldSerializeExists("LastChangedColumn")); + Assert.True(ResetExists("LastChangedColumn")); + + bool ShouldSerializeExists(string name) => typeof(DataRow).GetProperty("ShouldSerialize" + name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) != null; + bool ResetExists(string name) => typeof(DataRow).GetMethod("Reset" + name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) != null; + } } } diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataSetTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataSetTest.cs index f8edbc0491e6fc..0c9a4dc2a8fbcb 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataSetTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataSetTest.cs @@ -41,6 +41,7 @@ using Microsoft.DotNet.RemoteExecutor; using Xunit; using System.Tests; +using System.Reflection; namespace System.Data.Tests { @@ -1621,6 +1622,21 @@ static void RunTest() } } + [Fact] + public void MethodsCalledByReflectionSerializersAreNotTrimmed() + { + Assert.True(ShouldSerializeExists(nameof(DataSet.Relations))); + Assert.True(ShouldSerializeExists(nameof(DataSet.Tables))); + Assert.True(ShouldSerializeExists(nameof(DataSet.Locale))); + + Assert.True(ResetExists(nameof(DataSet.Relations))); + Assert.True(ResetExists(nameof(DataSet.Tables))); + Assert.False(ResetExists(nameof(DataSet.Locale))); + + bool ShouldSerializeExists(string name) => typeof(DataSet).GetMethod("ShouldSerialize" + name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) != null; + bool ResetExists(string name) => typeof(DataSet).GetMethod("Reset" + name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) != null; + } + #region DataSet.CreateDataReader Tests and DataSet.Load Tests private DataSet _ds; diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs index 2ec1af86a958f9..4fb880b51ea3ca 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs @@ -33,6 +33,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; +using System.Reflection; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization.Formatters.Tests; using System.Tests; @@ -1819,7 +1820,30 @@ public void TableInitializedEventTest4() } [Fact] - public void MethodsCalledByReflectionAreNotTrimmed() + public void MethodsCalledByReflectionSerializersAreNotTrimmed() + { + Assert.True(ShouldSerializeExists(nameof(DataTable.CaseSensitive))); + Assert.False(ShouldSerializeExists("Columns")); + Assert.False(ShouldSerializeExists("Constraints")); + Assert.False(ShouldSerializeExists("Indexes")); + Assert.True(ShouldSerializeExists(nameof(DataTable.Locale))); + Assert.True(ShouldSerializeExists(nameof(DataTable.Namespace))); + Assert.True(ShouldSerializeExists(nameof(DataTable.PrimaryKey))); + + Assert.True(ResetExists(nameof(DataTable.CaseSensitive))); + Assert.True(ResetExists("Columns")); + Assert.True(ResetExists("Constraints")); + Assert.True(ResetExists("Indexes")); + Assert.False(ResetExists(nameof(DataTable.Locale))); + Assert.True(ResetExists(nameof(DataTable.Namespace))); + Assert.True(ResetExists(nameof(DataTable.PrimaryKey))); + + bool ShouldSerializeExists(string name) => typeof(DataTable).GetMethod("ShouldSerialize" + name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) != null; + bool ResetExists(string name) => typeof(DataTable).GetMethod("Reset" + name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) != null; + } + + [Fact] + public void MethodsCalledByReflectionSerializersAreNotTrimmedUsingTypeDescriptor() { DataTable dt = new DataTable(); dt.CaseSensitive = true; @@ -1830,12 +1854,12 @@ public void MethodsCalledByReflectionAreNotTrimmed() PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(dt); Assert.True(properties[nameof(DataTable.PrimaryKey)].ShouldSerializeValue(dt)); - properties[nameof(DataTable.PrimaryKey)].ResetValue(dt); // Reset method is available + properties[nameof(DataTable.PrimaryKey)].ResetValue(dt); Assert.False(properties[nameof(DataTable.PrimaryKey)].ShouldSerializeValue(dt)); Assert.Equal(0, dt.PrimaryKey.Length); Assert.True(properties[nameof(DataTable.CaseSensitive)].ShouldSerializeValue(dt)); - properties[nameof(DataTable.CaseSensitive)].ResetValue(dt); // Reset method is available + properties[nameof(DataTable.CaseSensitive)].ResetValue(dt); Assert.False(properties[nameof(DataTable.CaseSensitive)].ShouldSerializeValue(dt)); Assert.False(dt.CaseSensitive); @@ -1844,7 +1868,7 @@ public void MethodsCalledByReflectionAreNotTrimmed() Assert.True(properties[nameof(DataTable.Locale)].ShouldSerializeValue(dt)); // Reset method is not available Assert.True(properties[nameof(DataTable.Namespace)].ShouldSerializeValue(dt)); - properties[nameof(DataTable.Namespace)].ResetValue(dt); // Reset method is available + properties[nameof(DataTable.Namespace)].ResetValue(dt); Assert.False(properties[nameof(DataTable.Namespace)].ShouldSerializeValue(dt)); Assert.Equal("", dt.Namespace); } From 2ef382528c1fe7774bcc48e212ad387c420db029 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Tue, 11 Jun 2024 11:49:27 -0500 Subject: [PATCH 4/5] Move dependencies from code to XML --- .../ILLink.Descriptors.LibraryBuild.xml | 34 +++++++++++++++++++ .../src/System/Data/DataColumn.cs | 5 --- .../src/System/Data/DataSet.cs | 5 --- .../src/System/Data/DataTable.cs | 10 ------ .../tests/System/Data/DataColumnTest.cs | 6 ++-- 5 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 src/libraries/System.Data.Common/src/ILLink/ILLink.Descriptors.LibraryBuild.xml diff --git a/src/libraries/System.Data.Common/src/ILLink/ILLink.Descriptors.LibraryBuild.xml b/src/libraries/System.Data.Common/src/ILLink/ILLink.Descriptors.LibraryBuild.xml new file mode 100644 index 00000000000000..5073e8c22f7c98 --- /dev/null +++ b/src/libraries/System.Data.Common/src/ILLink/ILLink.Descriptors.LibraryBuild.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs b/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs index b723e27929b2f5..3c048496bc8061 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs @@ -121,11 +121,6 @@ public DataColumn(string? columnName, [DynamicallyAccessedMembers(DynamicallyAcc /// column is an attribute. /// [RequiresUnreferencedCode("Members from serialized types or types used in expressions may be trimmed if not referenced directly.")] - [DynamicDependency(nameof(ShouldSerializeCaption))] - [DynamicDependency(nameof(ShouldSerializeDefaultValue))] - [DynamicDependency(nameof(ShouldSerializeNamespace))] - [DynamicDependency(nameof(ResetCaption))] - [DynamicDependency(nameof(ResetNamespace))] public DataColumn(string? columnName, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] Type dataType, string? expr, MappingType type) { GC.SuppressFinalize(this); diff --git a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs index 20c927551a2bd1..37c1fb283d7e19 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs @@ -80,11 +80,6 @@ public class DataSet : MarshalByValueComponent, IListSource, IXmlSerializable, I /// /// Initializes a new instance of the class. /// - [DynamicDependency(nameof(ShouldSerializeLocale))] - [DynamicDependency(nameof(ShouldSerializeRelations))] - [DynamicDependency(nameof(ShouldSerializeTables))] - [DynamicDependency(nameof(ResetRelations))] - [DynamicDependency(nameof(ResetTables))] public DataSet() { GC.SuppressFinalize(this); diff --git a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs index 79e60e84af796a..428393d70ea17d 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs @@ -161,16 +161,6 @@ public class DataTable : MarshalByValueComponent, IListSource, ISupportInitializ /// /// Initializes a new instance of the class with no arguments. /// - [DynamicDependency(nameof(ShouldSerializeCaseSensitive))] - [DynamicDependency(nameof(ShouldSerializeLocale))] - [DynamicDependency(nameof(ShouldSerializeNamespace))] - [DynamicDependency(nameof(ShouldSerializePrimaryKey))] - [DynamicDependency(nameof(ResetCaseSensitive))] - [DynamicDependency(nameof(ResetColumns))] - [DynamicDependency(nameof(ResetConstraints))] - [DynamicDependency(nameof(ResetIndexes))] - [DynamicDependency(nameof(ResetNamespace))] - [DynamicDependency(nameof(ResetPrimaryKey))] public DataTable() { GC.SuppressFinalize(this); diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs index 537102ac68a4f9..6f823a15619656 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataColumnTest.cs @@ -822,21 +822,21 @@ public void MethodsCalledByReflectionSerializersAreNotTrimmedUsingTypeDescriptor Assert.False(properties[nameof(DataColumn.DefaultValue)].ShouldSerializeValue(dc)); dc.DefaultValue = DateTime.MinValue; Assert.True(properties[nameof(DataColumn.DefaultValue)].ShouldSerializeValue(dc)); - properties[nameof(DataColumn.DefaultValue)].ResetValue(dc); // Reset method is not available + properties[nameof(DataColumn.DefaultValue)].ResetValue(dc); Assert.Equal(DateTime.MinValue, dc.DefaultValue); Assert.True(properties[nameof(DataColumn.DefaultValue)].ShouldSerializeValue(dc)); Assert.False(properties[nameof(DataColumn.Caption)].ShouldSerializeValue(dc)); dc.Caption = "Caption"; Assert.True(properties[nameof(DataColumn.Caption)].ShouldSerializeValue(dc)); - properties[nameof(DataColumn.Caption)].ResetValue(dc); // Reset method is available + properties[nameof(DataColumn.Caption)].ResetValue(dc); Assert.False(properties[nameof(DataColumn.Caption)].ShouldSerializeValue(dc)); Assert.Equal("dataColumn", dc.Caption); Assert.False(properties[nameof(DataColumn.Namespace)].ShouldSerializeValue(dc)); dc.Namespace = "Namespace"; Assert.True(properties[nameof(DataColumn.Namespace)].ShouldSerializeValue(dc)); - properties[nameof(DataColumn.Namespace)].ResetValue(dc); // Reset method is available + properties[nameof(DataColumn.Namespace)].ResetValue(dc); Assert.False(properties[nameof(DataColumn.Namespace)].ShouldSerializeValue(dc)); Assert.Equal("", dc.Namespace); } From b7a7928f2bd31fff51dee9d20fe462e186f2db64 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Wed, 12 Jun 2024 09:09:34 -0500 Subject: [PATCH 5/5] Remove PublicKeyToken --- .../src/ILLink/ILLink.Descriptors.LibraryBuild.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Data.Common/src/ILLink/ILLink.Descriptors.LibraryBuild.xml b/src/libraries/System.Data.Common/src/ILLink/ILLink.Descriptors.LibraryBuild.xml index 5073e8c22f7c98..057b8b37f83675 100644 --- a/src/libraries/System.Data.Common/src/ILLink/ILLink.Descriptors.LibraryBuild.xml +++ b/src/libraries/System.Data.Common/src/ILLink/ILLink.Descriptors.LibraryBuild.xml @@ -1,6 +1,6 @@ - +