diff --git a/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml b/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml index 95df6776ce7ab..3256637c95633 100644 --- a/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml +++ b/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml @@ -25,6 +25,12 @@ member M:System.Xml.Serialization.XmlAttributes.get_IgnoreAttribute + + ILLink + IL2057 + member + M:System.Xml.Serialization.XmlSerializationWriterCodeGen.WriteCheckDefault(System.Xml.Serialization.TypeMapping,System.String,System.Object,System.Boolean) + ILLink IL2057 @@ -41,13 +47,25 @@ ILLink IL2067 member - M:System.Xml.Serialization.CodeGenerator.CreateTypeBuilder(System.Reflection.Emit.ModuleBuilder,System.String,System.Reflection.TypeAttributes,System.Type,System.Type[]) + M:System.Xml.Serialization.ReflectionXmlSerializationReader.ReflectionCreateObject(System.Type) ILLink - IL2067 + IL2070 member - M:System.Xml.Serialization.ReflectionXmlSerializationReader.ReflectionCreateObject(System.Type) + M:System.Xml.Serialization.Compiler.AddImport(System.Type,System.Collections.Hashtable) + + + ILLink + IL2070 + member + M:System.Xml.Serialization.ReflectionAwareCodeGen.WriteMappingInfo(System.Xml.Serialization.TypeMapping,System.String,System.Type) + + + ILLink + IL2070 + member + M:System.Xml.Serialization.ReflectionAwareCodeGen.WriteMemberInfo(System.Type,System.String,System.String,System.String) ILLink @@ -193,6 +211,12 @@ member M:System.Xml.Serialization.TempAssembly.LoadGeneratedAssembly(System.Type,System.String,System.Xml.Serialization.XmlSerializerImplementation@) + + ILLink + IL2072 + member + M:System.Xml.Serialization.XmlSerializationILGen.GenerateTypedSerializer(System.String,System.String,System.Xml.Serialization.XmlMapping,System.Xml.Serialization.CodeIdentifiers,System.String,System.String,System.String) + ILLink IL2072 diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs index f7ded1c2176cd..41f3f51feb212 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs @@ -23,13 +23,13 @@ namespace System.Xml.Serialization { internal class CodeGenerator { - internal static BindingFlags InstancePublicBindingFlags = BindingFlags.Instance | BindingFlags.Public; - internal static BindingFlags InstanceBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - internal static BindingFlags StaticBindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; - internal static MethodAttributes PublicMethodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig; - internal static MethodAttributes PublicOverrideMethodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig; - internal static MethodAttributes ProtectedOverrideMethodAttributes = MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig; - internal static MethodAttributes PrivateMethodAttributes = MethodAttributes.Private | MethodAttributes.HideBySig; + internal const BindingFlags InstancePublicBindingFlags = BindingFlags.Instance | BindingFlags.Public; + internal const BindingFlags InstanceBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + internal const BindingFlags StaticBindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; + internal const MethodAttributes PublicMethodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig; + internal const MethodAttributes PublicOverrideMethodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig; + internal const MethodAttributes ProtectedOverrideMethodAttributes = MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig; + internal const MethodAttributes PrivateMethodAttributes = MethodAttributes.Private | MethodAttributes.HideBySig; private readonly TypeBuilder _typeBuilder; private MethodBuilder? _methodBuilder; @@ -1242,7 +1242,13 @@ internal static ModuleBuilder CreateModuleBuilder(AssemblyBuilder assemblyBuilde { return assemblyBuilder.DefineDynamicModule(name); } - internal static TypeBuilder CreateTypeBuilder(ModuleBuilder moduleBuilder, string name, TypeAttributes attributes, Type parent, Type[] interfaces) + + internal static TypeBuilder CreateTypeBuilder( + ModuleBuilder moduleBuilder, + string name, + TypeAttributes attributes, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type parent, + Type[] interfaces) { // parent is nullable if no base class return moduleBuilder.DefineType(TempAssembly.GeneratedAssemblyNamespace + "." + name, diff --git a/src/libraries/System.Private.Xml/tests/TrimmingTests/System.Xml.TrimmingTests.proj b/src/libraries/System.Private.Xml/tests/TrimmingTests/System.Xml.TrimmingTests.proj new file mode 100644 index 0000000000000..a30ad093ba40e --- /dev/null +++ b/src/libraries/System.Private.Xml/tests/TrimmingTests/System.Xml.TrimmingTests.proj @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlSerializer.Deserialize.cs b/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlSerializer.Deserialize.cs new file mode 100644 index 0000000000000..608e16b62dbea --- /dev/null +++ b/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlSerializer.Deserialize.cs @@ -0,0 +1,86 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Xml.Schema; + +namespace System.Xml.Serialization.TrimmingTests +{ + internal class Program + { + // Preserve these types until XmlSerializer is fully trim-safe. + // see https://github.com/dotnet/runtime/issues/44768 + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(Response))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DataUpdates))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DataUpdatesDataUpdateInfo))] + public static int Main() + { + using StringReader stringReader = new StringReader(@" + + + + + + + "); + + Response obj = (Response)new XmlSerializer(typeof(Response)).Deserialize(stringReader); + if (obj.DataUpdates.DataUpdateInfo.Count == 3 && + obj.DataUpdates.DataUpdateInfo.All(i => i.DataDate.Year == 2009 && i.LastUpdatedDate.Year == 2010)) + { + return 100; + } + + return -1; + } + } + + [Serializable] + [XmlType(AnonymousType = true)] + [XmlRoot(Namespace = "", IsNullable = false)] + public class Response + { + public Response() + { + this.DataUpdates = new DataUpdates(); + } + + [XmlElement(Order = 0)] + public DataUpdates DataUpdates { get; set; } + } + + [Serializable] + [XmlType(AnonymousType = true)] + [XmlRoot(Namespace = "", IsNullable = false)] + public class DataUpdates + { + public DataUpdates() + { + this.DataUpdateInfo = new List(); + } + + [XmlElement("DataUpdateInfo", Form = XmlSchemaForm.Unqualified, Order = 0)] + public List DataUpdateInfo { get; set; } + } + + [Serializable] + [XmlType(AnonymousType = true)] + public class DataUpdatesDataUpdateInfo + { + public DataUpdatesDataUpdateInfo() + { + } + + [XmlAttribute] + public DateTime DataDate { get; set; } + + [XmlAttribute] + public string DataType { get; set; } + + [XmlAttribute] + public DateTime LastUpdatedDate { get; set; } + } +} diff --git a/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlSerializer.Serialize.cs b/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlSerializer.Serialize.cs new file mode 100644 index 0000000000000..1e127dd7893c9 --- /dev/null +++ b/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlSerializer.Serialize.cs @@ -0,0 +1,95 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Xml.Schema; + +namespace System.Xml.Serialization.TrimmingTests +{ + internal class Program + { + // Preserve these types until XmlSerializer is fully trim-safe. + // see https://github.com/dotnet/runtime/issues/44768 + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(Response))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DataUpdates))] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DataUpdatesDataUpdateInfo))] + public static int Main() + { + Response obj = new Response(); + obj.DataUpdates.DataUpdateInfo.Add(new DataUpdatesDataUpdateInfo() + { + DataDate = new DateTime(2009, 4, 13), + DataType = "Data", + LastUpdatedDate = new DateTime(2010, 12, 12) + }); + obj.DataUpdates.DataUpdateInfo.Add(new DataUpdatesDataUpdateInfo() + { + DataDate = new DateTime(2009, 4, 14), + DataType = "Data", + LastUpdatedDate = new DateTime(2010, 12, 12) + }); + + using StringWriter writer = new StringWriter(); + new XmlSerializer(typeof(Response)).Serialize(writer, obj); + string serialized = writer.ToString(); + + if (serialized.Contains("") && + serialized.Contains(@"") && + serialized.Contains(@"")) + { + return 100; + } + + return -1; + } + } + + [Serializable] + [XmlType(AnonymousType = true)] + [XmlRoot(Namespace = "", IsNullable = false)] + public class Response + { + public Response() + { + this.DataUpdates = new DataUpdates(); + } + + [XmlElement(Order = 0)] + public DataUpdates DataUpdates { get; set; } + } + + [Serializable] + [XmlType(AnonymousType = true)] + [XmlRoot(Namespace = "", IsNullable = false)] + public class DataUpdates + { + public DataUpdates() + { + this.DataUpdateInfo = new List(); + } + + [XmlElement("DataUpdateInfo", Form = XmlSchemaForm.Unqualified, Order = 0)] + public List DataUpdateInfo { get; set; } + } + + [Serializable] + [XmlType(AnonymousType = true)] + public class DataUpdatesDataUpdateInfo + { + public DataUpdatesDataUpdateInfo() + { + } + + [XmlAttribute] + public DateTime DataDate { get; set; } + + [XmlAttribute] + public string DataType { get; set; } + + [XmlAttribute] + public DateTime LastUpdatedDate { get; set; } + } +}