2007-04-20 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Fri, 20 Apr 2007 11:13:46 +0000 (11:13 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Fri, 20 Apr 2007 11:13:46 +0000 (11:13 -0000)
* XmlTypeMapping.cs, ReflectionHelper.cs,
  XmlSerializationReaderInterpreter.cs, SerializationCodeGenerator.cs:
  support instantiation by private constructor.

* XmlSerializerTests.cs :
  Added test for serializing private-constructor-only class.

svn path=/trunk/mcs/; revision=76003

mcs/class/System.XML/System.Xml.Serialization/ChangeLog
mcs/class/System.XML/System.Xml.Serialization/ReflectionHelper.cs
mcs/class/System.XML/System.Xml.Serialization/SerializationCodeGenerator.cs
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs
mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs
mcs/class/System.XML/Test/System.Xml.Serialization/ChangeLog
mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs

index 04e65d0b850a1572a6b5214e213bf341ec6f2a12..5f28bb8220153e72deb768adec235c5703b610ca 100644 (file)
@@ -1,3 +1,9 @@
+2007-04-20  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XmlTypeMapping.cs, ReflectionHelper.cs,
+         XmlSerializationReaderInterpreter.cs, SerializationCodeGenerator.cs:
+         support instantiation by private constructor.
+
 2007-04-19  Konstantin Triger <kostat@mainsoft.com>
 
        * XmlSchemaExporter.cs: do not export twice simple types.
index 0461aa75d9c71dd5e2ea87a864be2108d9d93d19..1b5ece9a8e8dc6b7a18dea6ba570c2d8db515bb1 100644 (file)
@@ -70,12 +70,18 @@ namespace System.Xml.Serialization
                {
                        return new InvalidOperationException ("There was an error reflecting '" + map.TypeFullName + "': " + message);
                }
-               
+
+               static readonly ParameterModifier [] empty_modifiers = new ParameterModifier [0];
+
                public static void CheckSerializableType (Type type, bool allowPrivateConstructors)
                {
                        if (type.IsArray) return;
                        
+#if NET_2_0
+                       if (!allowPrivateConstructors && type.GetConstructor (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, empty_modifiers) == null && !type.IsAbstract && !type.IsValueType)
+#else
                        if (!allowPrivateConstructors && type.GetConstructor (Type.EmptyTypes) == null && !type.IsAbstract && !type.IsValueType)
+#endif
                                throw new InvalidOperationException (type.FullName + " cannot be serialized because it does not have a default public constructor");
                                
                        if (type.IsInterface && !TypeTranslator.GetTypeData (type).IsListType)
index 64a09cf94a6857cf701b45aad7de2b51fff0200d..a1db7ac6f79956a68a82d298bec557807776f137 100644 (file)
@@ -1440,7 +1440,7 @@ namespace System.Xml.Serialization
                                                XmlTypeMapMember mem = (XmlTypeMapMember) members [n];
                                                if (!mem.IsReturnValue && mem.TypeData.IsValueType)
                                                        GenerateSetMemberValueFromAttr (mem, "parameters",
-                                                               "new " + mem.TypeData.FullTypeName + "()", true);
+                                                               String.Format ("({0}) Activator.CreateInstance(typeof({0}), true)", mem.TypeData.FullTypeName), true);
                                        }
 
                                        WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement && Reader.ReadState == ReadState.Interactive)");
@@ -1540,7 +1540,7 @@ namespace System.Xml.Serialization
                        }
                        else
                        {
-                               WriteLine (typeMap.TypeData.CSharpFullName + " ob = new " + typeMap.TypeData.CSharpFullName + " ();");
+                               WriteLine (typeMap.TypeData.CSharpFullName + String.Format (" ob = ({0}) Activator.CreateInstance(typeof({0}), true);", typeMap.TypeData.CSharpFullName));
                        
                                if (GenerateReadHook (HookType.type, typeMap.TypeData.Type)) {
                                        WriteLine ("return ob;");
@@ -1580,7 +1580,7 @@ namespace System.Xml.Serialization
                                }
        
                                WriteLine ("");
-                               WriteLine ("ob = new " + typeMap.TypeData.CSharpFullName + " ();");
+                               WriteLine (String.Format ("ob = ({0}) Activator.CreateInstance(typeof({0}), true);", typeMap.TypeData.CSharpFullName));
                        }
                        
                        WriteLine ("");
@@ -2130,7 +2130,7 @@ namespace System.Xml.Serialization
                                        return GetReadObjectCall (elem.MappedType, GetLiteral(elem.IsNullable), "true");
 
                                case SchemaTypes.XmlSerializable:
-                                       return GetCast (elem.TypeData, "ReadSerializable (new " + elem.TypeData.CSharpFullName + " ())");
+                                       return GetCast (elem.TypeData, String.Format ("ReadSerializable (({0}) Activator.CreateInstance(typeof({0}), true))", elem.TypeData.CSharpFullName));
 
                                default:
                                        throw new NotSupportedException ("Invalid value type");
@@ -2299,7 +2299,7 @@ namespace System.Xml.Serialization
                        {
                                WriteLine ("if (((object)" + list + ") == null)");
                                if (canCreateInstance) 
-                                       WriteLine ("\t" + list + " = new " + listType.CSharpFullName + "();");
+                                       WriteLine ("\t" + list + String.Format (" = ({0}) Activator.CreateInstance(typeof({0}), true);", listType.CSharpFullName));
                                else 
                                        WriteLine ("\tthrow CreateReadOnlyCollectionException (" + GetLiteral (listType.CSharpFullName) + ");");
                                
@@ -2420,7 +2420,7 @@ namespace System.Xml.Serialization
                        WriteLine ("if (Reader.NodeType == XmlNodeType.Element)");
                        WriteLineInd ("{");
                        WriteLine ("if (Reader.LocalName == " + GetLiteral (typeMap.ElementName) + " && Reader.NamespaceURI == " + GetLiteral (typeMap.Namespace) + ")");
-                       WriteLine ("\treturn ReadSerializable (new " + typeMap.TypeData.CSharpFullName + "());");
+                       WriteLine (String.Format ("\treturn ReadSerializable (({0}) Activator.CreateInstance(typeof({0}), true));", typeMap.TypeData.CSharpFullName));
                        WriteLine ("else");
                        WriteLine ("\tthrow CreateUnknownNodeException ();");
                        WriteLineUni ("}");
index 367f1e79581a8cc7fd4beb2c0602ded142e26554..f2b8e212d1d1d3afa608fd91cf20d86e2b31d61f 100644 (file)
@@ -223,7 +223,7 @@ namespace System.Xml.Serialization
                                        return ReadTypedPrimitive (AnyType);
             }
 
-                       object ob = Activator.CreateInstance (typeMap.TypeData.Type);
+                       object ob = Activator.CreateInstance (typeMap.TypeData.Type, true);
 
                        Reader.MoveToElement();
                        bool isEmpty = Reader.IsEmptyElement;
@@ -623,7 +623,7 @@ namespace System.Xml.Serialization
                                        return ReadObject (elem.MappedType, elem.IsNullable, true);
 
                                case SchemaTypes.XmlSerializable:
-                                       object ob = Activator.CreateInstance (elem.TypeData.Type);
+                                       object ob = Activator.CreateInstance (elem.TypeData.Type, true);
                                        return ReadSerializable ((IXmlSerializable)ob);
 
                                default:
@@ -734,7 +734,7 @@ namespace System.Xml.Serialization
                        else    // Must be IEnumerable
                        {
                                if (list == null) {
-                                       if (canCreateInstance) list = Activator.CreateInstance (type);
+                                       if (canCreateInstance) list = Activator.CreateInstance (type, true);
                                        else throw CreateReadOnlyCollectionException (type.FullName);
                                }
 
@@ -753,7 +753,7 @@ namespace System.Xml.Serialization
                        if (listType.IsArray)
                                return EnsureArrayIndex (null, 0, listType.GetElementType());
                        else
-                               return Activator.CreateInstance (listType);
+                               return Activator.CreateInstance (listType, true);
                }
                
                object InitializeList (TypeData listType)
@@ -761,7 +761,7 @@ namespace System.Xml.Serialization
                        if (listType.Type.IsArray)
                                return null;
                        else
-                               return Activator.CreateInstance (listType.Type);
+                               return Activator.CreateInstance (listType.Type, true);
                }
 
                void FillList (object list, object items)
@@ -825,7 +825,7 @@ namespace System.Xml.Serialization
                        {
                                if (Reader.LocalName == typeMap.ElementName && Reader.NamespaceURI == typeMap.Namespace)
                                {
-                                       object ob = Activator.CreateInstance (typeMap.TypeData.Type);
+                                       object ob = Activator.CreateInstance (typeMap.TypeData.Type, true);
                                        return ReadSerializable ((IXmlSerializable)ob);
                                }
                                else
index d0e35adfc4875172fcc6e693d0b93ca41a546230..8554787fe852d46aab8823b571b0d8e1fb44105d 100644 (file)
@@ -193,7 +193,7 @@ namespace System.Xml.Serialization
                internal XmlSerializableMapping(string elementName, string ns, TypeData typeData, string xmlType, string xmlTypeNamespace)
                        : base(elementName, ns, typeData, xmlType, xmlTypeNamespace)
                {
-                       IXmlSerializable serializable = (IXmlSerializable)Activator.CreateInstance(typeData.Type);
+                       IXmlSerializable serializable = (IXmlSerializable)Activator.CreateInstance (typeData.Type, true);
                        _schema = serializable.GetSchema();
                        if (_schema != null) 
                        {
index b5dab02b0eac07586e57df6085224b2f47defb45..6da11a455b611bcff8288c15ed4d91c24b50497c 100644 (file)
@@ -1,3 +1,8 @@
+2007-04-20  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XmlSerializerTests.cs :
+         Added test for serializing private-constructor-only class.
+
 2007-02-20  Atsushi Enomoto  <atsushi@ximian.com>
 
        * XmlSerializationReaderTests.cs : test non-empty element as well.
index b5836e699061027199c3e4637ef1a5638093e0d7..4be34bc3ac2f9703d7947a58e4834eb61b6465f1 100644 (file)
@@ -2585,6 +2585,16 @@ namespace MonoTests.System.XmlSerialization
                        stream.Position = 0;
                        foo = (Bug80759) serializer.Deserialize (stream);
                }
+
+               [Test]
+               public void SupportPrivateCtorOnly ()
+               {
+                       XmlSerializer xs =
+                               new XmlSerializer (typeof (PrivateCtorOnly));
+                       StringWriter sw = new StringWriter ();
+                       xs.Serialize (sw, PrivateCtorOnly.Instance);
+                       xs.Deserialize (new StringReader (sw.ToString ()));
+               }
 #endif
 
                #endregion //GenericsSeralizationTests
@@ -2646,6 +2656,15 @@ namespace MonoTests.System.XmlSerialization
                        public byte[] Data = new byte[] { 1, 2, 3 };
                }
 
+               [XmlRoot ("PrivateCtorOnly")]
+               public class PrivateCtorOnly
+               {
+                       public static PrivateCtorOnly Instance = new PrivateCtorOnly ();
+                       private PrivateCtorOnly ()
+                       {
+                       }
+               }
+
                public class CDataTextNodesType
                {
                        public CDataTextNodesInternal foo;