Explorar o código

2007-04-20 Atsushi Enomoto <[email protected]>

	* 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
Atsushi Eno %!s(int64=18) %!d(string=hai) anos
pai
achega
ef23f4f0cc

+ 6 - 0
mcs/class/System.XML/System.Xml.Serialization/ChangeLog

@@ -1,3 +1,9 @@
+2007-04-20  Atsushi Enomoto  <[email protected]>
+
+	* XmlTypeMapping.cs, ReflectionHelper.cs,
+	  XmlSerializationReaderInterpreter.cs, SerializationCodeGenerator.cs:
+	  support instantiation by private constructor.
+
 2007-04-19  Konstantin Triger <[email protected]>
 
 	* XmlSchemaExporter.cs: do not export twice simple types.

+ 7 - 1
mcs/class/System.XML/System.Xml.Serialization/ReflectionHelper.cs

@@ -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)

+ 6 - 6
mcs/class/System.XML/System.Xml.Serialization/SerializationCodeGenerator.cs

@@ -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 ("}");

+ 6 - 6
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs

@@ -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

+ 1 - 1
mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs

@@ -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) 
 			{

+ 5 - 0
mcs/class/System.XML/Test/System.Xml.Serialization/ChangeLog

@@ -1,3 +1,8 @@
+2007-04-20  Atsushi Enomoto  <[email protected]>
+
+	* XmlSerializerTests.cs :
+	  Added test for serializing private-constructor-only class.
+
 2007-02-20  Atsushi Enomoto  <[email protected]>
 
 	* XmlSerializationReaderTests.cs : test non-empty element as well.

+ 19 - 0
mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs

@@ -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;