Use Type.GetTypeCode() instead of private extension (#57540)
authorSteve Molloy <smolloy@microsoft.com>
Tue, 17 Aug 2021 18:11:38 +0000 (11:11 -0700)
committerGitHub <noreply@github.com>
Tue, 17 Aug 2021 18:11:38 +0000 (11:11 -0700)
* Use official Type.GetTypeCode() instead of the extension that was added to fill the gap in the earlier days of .Net Core.
* Bring reflection-based serializer in line with RefEmit behavior for 'object' serialization.

src/libraries/System.Private.Xml/src/System.Private.Xml.csproj
src/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs
src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationWriter.cs
src/libraries/System.Private.Xml/src/System/Xml/Serialization/TypeCode.cs [deleted file]
src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs
src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs
src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs
src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs

index 205d11e..2afc279 100644 (file)
     <Compile Include="System\Xml\Serialization\Configuration\DateTimeSerializationSection.cs" />
     <Compile Include="System\Xml\Extensions\ExtensionMethods.cs" />
     <Compile Include="System\Xml\Serialization\Globals.cs" />
-    <Compile Include="System\Xml\Serialization\TypeCode.cs" />
   </ItemGroup>
   <!-- Embedded DTD files -->
   <ItemGroup>
index 8ce0a5c..d642fa0 100644 (file)
@@ -719,7 +719,7 @@ namespace System.Xml.Serialization
 
         internal void Ldobj(Type type)
         {
-            OpCode opCode = GetLdindOpCode(type.GetTypeCode());
+            OpCode opCode = GetLdindOpCode(Type.GetTypeCode(type));
             if (!opCode.Equals(OpCodes.Nop))
             {
                 _ilGen!.Emit(opCode);
@@ -781,7 +781,7 @@ namespace System.Xml.Serialization
             }
             else
             {
-                switch (valueType.GetTypeCode())
+                switch (Type.GetTypeCode(valueType))
                 {
                     case TypeCode.Boolean:
                         Ldc((bool)o);
@@ -1037,7 +1037,7 @@ namespace System.Xml.Serialization
             }
             else
             {
-                OpCode opCode = GetLdelemOpCode(arrayElementType.GetTypeCode());
+                OpCode opCode = GetLdelemOpCode(Type.GetTypeCode(arrayElementType));
                 Debug.Assert(!opCode.Equals(OpCodes.Nop));
                 if (opCode.Equals(OpCodes.Nop))
                     throw new InvalidOperationException(SR.Format(SR.ArrayTypeIsNotSupported, arrayElementType.AssemblyQualifiedName));
@@ -1083,7 +1083,7 @@ namespace System.Xml.Serialization
                 Stelem(Enum.GetUnderlyingType(arrayElementType));
             else
             {
-                OpCode opCode = GetStelemOpCode(arrayElementType.GetTypeCode());
+                OpCode opCode = GetStelemOpCode(Type.GetTypeCode(arrayElementType));
                 if (opCode.Equals(OpCodes.Nop))
                     throw new InvalidOperationException(SR.Format(SR.ArrayTypeIsNotSupported, arrayElementType.AssemblyQualifiedName));
                 _ilGen!.Emit(opCode);
@@ -1197,7 +1197,7 @@ namespace System.Xml.Serialization
             {
                 if (source.IsValueType)
                 {
-                    OpCode opCode = GetConvOpCode(target.GetTypeCode());
+                    OpCode opCode = GetConvOpCode(Type.GetTypeCode(target));
                     if (opCode.Equals(OpCodes.Nop))
                     {
                         throw new CodeGeneratorConversionException(source, target, isAddress, "NoConversionPossibleTo");
index 7969b74..78595d0 100644 (file)
@@ -668,52 +668,27 @@ namespace System.Xml.Serialization
         [RequiresUnreferencedCode("calls WriteMember")]
         private bool WriteEnumAndArrayTypes(StructMapping structMapping, object o, string n, string? ns)
         {
-            if (o is Enum)
-            {
-                Writer.WriteStartElement(n, ns);
+            Type objType = o.GetType();
 
-                EnumMapping? enumMapping = null;
-                Type enumType = o.GetType();
-                foreach (var m in _mapping.Scope!.TypeMappings)
+            foreach (var m in _mapping.Scope!.TypeMappings)
+            {
+                if (m is EnumMapping em && em.TypeDesc!.Type == objType)
                 {
-                    if (m is EnumMapping em && em.TypeDesc!.Type == enumType)
-                    {
-                        enumMapping = em;
-                        break;
-                    }
+                    Writer.WriteStartElement(n, ns);
+                    WriteXsiType(em.TypeName!, ns);
+                    Writer.WriteString(WriteEnumMethod(em, o));
+                    Writer.WriteEndElement();
+                    return true;
                 }
 
-                if (enumMapping == null)
-                    throw new InvalidOperationException(SR.XmlInternalError);
-
-                WriteXsiType(enumMapping.TypeName!, ns);
-                Writer.WriteString(WriteEnumMethod(enumMapping, o));
-                Writer.WriteEndElement();
-                return true;
-            }
-
-            if (o is Array)
-            {
-                Writer.WriteStartElement(n, ns);
-                ArrayMapping? arrayMapping = null;
-                Type arrayType = o.GetType();
-                foreach (var m in _mapping.Scope!.TypeMappings)
+                if (m is ArrayMapping am && am.TypeDesc!.Type == objType)
                 {
-                    if (m is ArrayMapping am && am.TypeDesc!.Type == arrayType)
-                    {
-                        arrayMapping = am;
-                        break;
-                    }
+                    Writer.WriteStartElement(n, ns);
+                    WriteXsiType(am.TypeName!, ns);
+                    WriteMember(o, null, am.ElementsSortedByDerivation!, null, null, am.TypeDesc!, true);
+                    Writer.WriteEndElement();
+                    return true;
                 }
-
-                if (arrayMapping == null)
-                    throw new InvalidOperationException(SR.XmlInternalError);
-
-                WriteXsiType(arrayMapping.TypeName!, ns);
-                WriteMember(o, null, arrayMapping.ElementsSortedByDerivation!, null, null, arrayMapping.TypeDesc!, true);
-                Writer.WriteEndElement();
-
-                return true;
             }
 
             return false;
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/TypeCode.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/TypeCode.cs
deleted file mode 100644 (file)
index ccdd174..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Xml.Serialization
-{
-    using System;
-
-    internal enum TypeCode
-    {
-        Empty = 0,          // Null reference
-        Object = 1,         // Instance that isn't a value
-        DBNull = 2,         // Database null value
-        Boolean = 3,        // Boolean
-        Char = 4,           // Unicode character
-        SByte = 5,          // Signed 8-bit integer
-        Byte = 6,           // Unsigned 8-bit integer
-        Int16 = 7,          // Signed 16-bit integer
-        UInt16 = 8,         // Unsigned 16-bit integer
-        Int32 = 9,          // Signed 32-bit integer
-        UInt32 = 10,        // Unsigned 32-bit integer
-        Int64 = 11,         // Signed 64-bit integer
-        UInt64 = 12,        // Unsigned 64-bit integer
-        Single = 13,        // IEEE 32-bit float
-        Double = 14,        // IEEE 64-bit double
-        Decimal = 15,       // Decimal
-        DateTime = 16,      // DateTime
-        String = 18,        // Unicode character string
-    }
-
-    internal static class TypeExtensionMethods
-    {
-        public static TypeCode GetTypeCode(this Type type)
-        {
-            if (type == null)
-            {
-                return TypeCode.Empty;
-            }
-            else if (type == typeof(bool))
-            {
-                return TypeCode.Boolean;
-            }
-            else if (type == typeof(char))
-            {
-                return TypeCode.Char;
-            }
-            else if (type == typeof(sbyte))
-            {
-                return TypeCode.SByte;
-            }
-            else if (type == typeof(byte))
-            {
-                return TypeCode.Byte;
-            }
-            else if (type == typeof(short))
-            {
-                return TypeCode.Int16;
-            }
-            else if (type == typeof(ushort))
-            {
-                return TypeCode.UInt16;
-            }
-            else if (type == typeof(int))
-            {
-                return TypeCode.Int32;
-            }
-            else if (type == typeof(uint))
-            {
-                return TypeCode.UInt32;
-            }
-            else if (type == typeof(long))
-            {
-                return TypeCode.Int64;
-            }
-            else if (type == typeof(ulong))
-            {
-                return TypeCode.UInt64;
-            }
-            else if (type == typeof(float))
-            {
-                return TypeCode.Single;
-            }
-            else if (type == typeof(double))
-            {
-                return TypeCode.Double;
-            }
-            else if (type == typeof(decimal))
-            {
-                return TypeCode.Decimal;
-            }
-            else if (type == typeof(DateTime))
-            {
-                return TypeCode.DateTime;
-            }
-            else if (type == typeof(string))
-            {
-                return TypeCode.String;
-            }
-            else
-            {
-                return TypeCode.Object;
-            }
-        }
-    }
-}
index 9709c95..4597c97 100644 (file)
@@ -571,7 +571,7 @@ namespace System.Xml.Serialization
             if (type.IsEnum)
                 return false;
 
-            switch (type.GetTypeCode())
+            switch (Type.GetTypeCode(type))
             {
                 case TypeCode.String: return true;
                 case TypeCode.Int32: return true;
index 9a8cdf6..46877f9 100644 (file)
@@ -194,7 +194,7 @@ namespace System.Xml.Serialization
             string typeName;
             string typeNs = XmlSchema.Namespace;
 
-            switch (type.GetTypeCode())
+            switch (Type.GetTypeCode(type))
             {
                 case TypeCode.String: typeName = "string"; break;
                 case TypeCode.Int32: typeName = "int"; break;
@@ -254,7 +254,7 @@ namespace System.Xml.Serialization
             Type t = o.GetType();
             bool wroteStartElement = false;
 
-            switch (t.GetTypeCode())
+            switch (Type.GetTypeCode(t))
             {
                 case TypeCode.String:
                     value = (string)o;
@@ -1312,7 +1312,7 @@ namespace System.Xml.Serialization
                 return;
             }
             Type t = o.GetType();
-            if (t.GetTypeCode() == TypeCode.Object && !(o is Guid) && (t != typeof(XmlQualifiedName)) && !(o is XmlNode[]) && (t != typeof(byte[])))
+            if (Type.GetTypeCode(t) == TypeCode.Object && !(o is Guid) && (t != typeof(XmlQualifiedName)) && !(o is XmlNode[]) && (t != typeof(byte[])))
             {
                 if ((suppressReference || _soap12) && !IsIdDefined(o))
                 {
index 3c36a83..15d78f2 100644 (file)
@@ -835,7 +835,7 @@ namespace System.Xml.Serialization
         {
             XmlSerializationPrimitiveWriter writer = new XmlSerializationPrimitiveWriter();
             writer.Init(xmlWriter, namespaces, null, null, null);
-            switch (_primitiveType!.GetTypeCode())
+            switch (Type.GetTypeCode(_primitiveType))
             {
                 case TypeCode.String:
                     writer.Write_string(o);
@@ -917,7 +917,7 @@ namespace System.Xml.Serialization
             XmlSerializationPrimitiveReader reader = new XmlSerializationPrimitiveReader();
             reader.Init(xmlReader, events, null, null);
             object? o;
-            switch (_primitiveType!.GetTypeCode())
+            switch (Type.GetTypeCode(_primitiveType))
             {
                 case TypeCode.String:
                     o = reader.Read_string();
index 0001146..c918520 100644 (file)
@@ -237,6 +237,20 @@ string.Format(@"<?xml version=""1.0"" encoding=""utf-8""?>
         Assert.StrictEqual(x.P1, y.P1);
     }
 
+#if !XMLSERIALIZERGENERATORTESTS
+    [Fact]
+    public static void Xml_EnumAsObject()
+    {
+        object o = MyEnum.Three;
+        object o2 = SerializeAndDeserialize<object>(o,
+@"<?xml version=""1.0"" encoding=""utf-8""?>
+<anyType xmlns:q1=""http://www.w3.org/2001/XMLSchema"" p2:type=""q1:int"" xmlns:p2=""http://www.w3.org/2001/XMLSchema-instance"">2</anyType>");
+        Assert.NotNull(o2);
+        Assert.StrictEqual((int)o, o2);
+        Assert.Equal(MyEnum.Three, (MyEnum)o2);
+    }
+#endif
+
     [Fact]
     public static void Xml_DCClassWithEnumAndStruct()
     {