Bladeren bron

* MapCodeGenerator.cs, SoapCodeExporter.cs: Generate the same XmlInclude
attributes that MS.NET generates.
* SerializationCodeGenerator.cs: Avoid duplicate generation of maps in the
same reader/writer.
* XmlCodeExporter.cs: Added support for ignore flag in maps and members.
* XmlReflectionImporter.cs: Changed GetReflectionMembers to match
MS.NET member ordering. Patch by David Taylor.
* XmlSchemaImporter.cs: When generating a choice member, set the ignore
flag. The generated enum must also not be included in the schema.
* XmlTypeMapMember.cs: Added ignore flag.
* XmlTypeMapping.cs: The AttributeMembers property now returns the
attributes in the correct order.

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

Lluis Sanchez 21 jaren geleden
bovenliggende
commit
aae87fab03

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

@@ -1,3 +1,18 @@
+2004-06-10  Lluis Sanchez Gual <[email protected]>
+
+	* MapCodeGenerator.cs, SoapCodeExporter.cs: Generate the same XmlInclude
+	  attributes that MS.NET generates.
+	* SerializationCodeGenerator.cs: Avoid duplicate generation of maps in the
+	  same reader/writer.
+	* XmlCodeExporter.cs: Added support for ignore flag in maps and members.
+	* XmlReflectionImporter.cs: Changed GetReflectionMembers to match
+	  MS.NET member ordering. Patch by David Taylor.
+	* XmlSchemaImporter.cs: When generating a choice member, set the ignore
+	  flag. The generated enum must also not be included in the schema.
+	* XmlTypeMapMember.cs: Added ignore flag.
+	* XmlTypeMapping.cs: The AttributeMembers property now returns the 
+	  attributes in the correct order.
+
 2004-06-03  Gert Driesen <[email protected]>
 
 	* XmlSerializationReader.cs: added missing protected members

+ 52 - 18
mcs/class/System.XML/System.Xml.Serialization/MapCodeGenerator.cs

@@ -18,13 +18,13 @@ namespace System.Xml.Serialization {
 		CodeCompileUnit codeCompileUnit;
 		CodeAttributeDeclarationCollection includeMetadata;
 		XmlTypeMapping exportedAnyType = null;
-		bool encodedFormat;
+		protected bool includeArrayTypes;
 
 		Hashtable exportedMaps = new Hashtable ();
+		Hashtable includeMaps = new Hashtable ();
 
 		public MapCodeGenerator (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit)
 		{
-			includeMetadata = new CodeAttributeDeclarationCollection ();
 			this.codeCompileUnit = codeCompileUnit;
 			this.codeNamespace = codeNamespace;
 		}
@@ -33,15 +33,23 @@ namespace System.Xml.Serialization {
 		{
 			get 
 			{ 
+				if (includeMetadata != null) return includeMetadata;
+				includeMetadata = new CodeAttributeDeclarationCollection ();
+				
 				if (exportedAnyType != null)
 				{
 					foreach (XmlTypeMapping map in exportedAnyType.DerivedTypes) 
 					{
-						if (IsMapExported (map)) continue;
+						if (IsMapExported (map) || !map.IncludeInSchema) continue;
 						ExportTypeMapping (map);
 						GenerateClassInclude (includeMetadata, map);
 					}
 				}
+				else {
+					foreach (XmlTypeMapping map in includeMaps.Values)
+						GenerateClassInclude (includeMetadata, map);
+				}
+				
 				return includeMetadata; 
 			}
 		}
@@ -57,6 +65,7 @@ namespace System.Xml.Serialization {
 		public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping)
 		{
 			ExportMapCode (xmlTypeMapping);
+			RemoveInclude (xmlTypeMapping);
 		}
 
 		void ExportMapCode (XmlTypeMapping map)
@@ -119,7 +128,10 @@ namespace System.Xml.Serialization {
 			{
 				CodeTypeReference ctr = new CodeTypeReference (map.BaseMap.TypeData.FullTypeName);
 				codeClass.BaseTypes.Add (ctr);
-				ExportMapCode (map.BaseMap);
+				if (map.BaseMap.IncludeInSchema) {
+					ExportMapCode (map.BaseMap);
+					AddInclude (map.BaseMap);
+				}
 			}
 
 			ExportDerivedTypes (map, codeClass, false);
@@ -133,7 +145,7 @@ namespace System.Xml.Serialization {
 					codeClass.CustomAttributes = new CodeAttributeDeclarationCollection ();
 
 				GenerateClassInclude (codeClass.CustomAttributes, tm);
-				if (!onlyIncludes) ExportMapCode (tm);
+				if (!onlyIncludes && tm.IncludeInSchema) ExportMapCode (tm);
 				ExportDerivedTypes (tm, codeClass, onlyIncludes);
 			}
 		}
@@ -194,21 +206,21 @@ namespace System.Xml.Serialization {
 			}
 		}
 
-		CodeMemberField CreateFieldMember (TypeData type, string name, object defaultValue, string comments)
+		CodeMemberField CreateFieldMember (XmlTypeMapMember member)
 		{
-			CodeMemberField codeField = new CodeMemberField (GetDomType (type), name);
+			CodeMemberField codeField = new CodeMemberField (GetDomType (member.TypeData), member.Name);
 			codeField.Attributes = MemberAttributes.Public;
-			AddComments (codeField, comments);
+			AddComments (codeField, member.Documentation);
 
-			if (defaultValue != System.DBNull.Value)
-				GenerateDefaultAttribute (codeField, type, defaultValue);
+			if (member.DefaultValue != System.DBNull.Value)
+				GenerateDefaultAttribute (codeField, member.TypeData, member.DefaultValue);
 
 			return codeField;
 		}
 
 		void AddAttributeFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberAttribute attinfo, string defaultNamespace)
 		{
-			CodeMemberField codeField = CreateFieldMember (attinfo.TypeData, attinfo.Name, attinfo.DefaultValue, attinfo.Documentation);
+			CodeMemberField codeField = CreateFieldMember (attinfo);
 			codeClass.Members.Add (codeField);
 
 			CodeAttributeDeclarationCollection attributes = codeField.CustomAttributes;
@@ -217,8 +229,10 @@ namespace System.Xml.Serialization {
 			GenerateAttributeMember (attributes, attinfo, defaultNamespace, false);
 			if (attributes.Count > 0) codeField.CustomAttributes = attributes;
 
-			if (attinfo.MappedType != null)
+			if (attinfo.MappedType != null) {
 				ExportMapCode (attinfo.MappedType);
+				RemoveInclude (attinfo.MappedType);
+			}
 
 			if (attinfo.TypeData.IsValueType && attinfo.IsOptionalValueType)
 			{
@@ -236,7 +250,7 @@ namespace System.Xml.Serialization {
 
 		void AddElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)
 		{
-			CodeMemberField codeField = CreateFieldMember (member.TypeData, member.Name, member.DefaultValue, member.Documentation);
+			CodeMemberField codeField = CreateFieldMember (member);
 			codeClass.Members.Add (codeField);
 			
 			CodeAttributeDeclarationCollection attributes = codeField.CustomAttributes;
@@ -271,7 +285,10 @@ namespace System.Xml.Serialization {
 					continue;
 
 				GenerateElementInfoMember (attributes, member, einfo, defaultType, defaultNamespace, addAlwaysAttr, forceUseMemberName);
-				if (einfo.MappedType != null) ExportMapCode (einfo.MappedType);
+				if (einfo.MappedType != null) {
+					ExportMapCode (einfo.MappedType);
+					RemoveInclude (einfo.MappedType);
+				}
 			}
 
 			GenerateElementMember (attributes, member);
@@ -279,7 +296,7 @@ namespace System.Xml.Serialization {
 
 		void AddAnyElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)
 		{
-			CodeMemberField codeField = CreateFieldMember (member.TypeData, member.Name, member.DefaultValue, member.Documentation);
+			CodeMemberField codeField = CreateFieldMember (member);
 			codeClass.Members.Add (codeField);
 
 			CodeAttributeDeclarationCollection attributes = new CodeAttributeDeclarationCollection ();
@@ -329,7 +346,11 @@ namespace System.Xml.Serialization {
 				else defaultName = ainfo.TypeData.XmlType;
 
 				GenerateArrayItemAttributes (attributes, listMap, type, ainfo, defaultName, defaultNamespace, nestingLevel);
-				if (ainfo.MappedType != null) ExportMapCode (ainfo.MappedType);
+				if (ainfo.MappedType != null) {
+					if (!IsMapExported (ainfo.MappedType) && includeArrayTypes)
+						AddInclude (ainfo.MappedType);
+					ExportMapCode (ainfo.MappedType);
+				}
 			}
 
 			if (listMap.IsMultiArray)
@@ -344,8 +365,11 @@ namespace System.Xml.Serialization {
 			ListMap listMap = (ListMap) map.ObjectMap;
 			foreach (XmlTypeMapElementInfo ainfo in listMap.ItemInfo)
 			{
-				if (ainfo.MappedType != null)
+				if (ainfo.MappedType != null) {
+					if (!IsMapExported (ainfo.MappedType) && includeArrayTypes)
+						AddInclude (ainfo.MappedType);
 					ExportMapCode (ainfo.MappedType);
+				}
 			}
 		}
 
@@ -394,6 +418,17 @@ namespace System.Xml.Serialization {
 				codeEnum.Members.Add (codeField);
 			}
 		}
+		
+		void AddInclude (XmlTypeMapping map)
+		{
+			if (!includeMaps.ContainsKey (map.TypeData.FullTypeName))
+				includeMaps [map.TypeData.FullTypeName] = map;
+		}
+
+		void RemoveInclude (XmlTypeMapping map)
+		{
+			includeMaps.Remove (map.TypeData.FullTypeName);
+		}
 
 		#endregion
 		
@@ -402,7 +437,6 @@ namespace System.Xml.Serialization {
 		bool IsMapExported (XmlTypeMapping map)
 		{
 			if (exportedMaps.Contains (map.TypeData.FullTypeName)) return true;
-			if (!map.IncludeInSchema && map.TypeData.Type != typeof(object)) return true;
 			return false;
 		}
 

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

@@ -163,15 +163,24 @@ namespace System.Xml.Serialization
 			}
 			
 			Hashtable mapsByNamespace = new Hashtable ();
+			Hashtable generatedMaps = new Hashtable ();
 			
 			for (int n=0; n<_xmlMaps.Length; n++)
 			{
 				_typeMap = _xmlMaps [n];
 				if (_typeMap == null) continue;
 				
+				_result = generatedMaps [_typeMap] as GenerationResult;
+				if (_result != null) {
+					_results[n] = _result;
+					continue;
+				}
+				
 				_result = new GenerationResult ();
 				_results[n] = _result;
 				
+				generatedMaps [_typeMap] = _result;
+				
 				string typeName;
 				if (_typeMap is XmlTypeMapping) typeName = ((XmlTypeMapping)_typeMap).TypeName;
 				else typeName = ((XmlMembersMapping)_typeMap).ElementName;

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

@@ -85,6 +85,7 @@ namespace System.Xml.Serialization {
 		public SoapMapCodeGenerator (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit)
 		: base (codeNamespace, codeCompileUnit)
 		{
+			includeArrayTypes = true;
 		}
 
 		protected override void GenerateClass (XmlTypeMapping map, CodeTypeDeclaration codeClass)

+ 7 - 0
mcs/class/System.XML/System.Xml.Serialization/XmlCodeExporter.cs

@@ -129,6 +129,7 @@ namespace System.Xml.Serialization {
 			CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlType");
 			if (map.XmlType != map.TypeData.TypeName) att.Arguments.Add (GetArg (map.XmlType));
 			if (map.XmlTypeNamespace != "") att.Arguments.Add (GetArg ("Namespace", map.XmlTypeNamespace));
+			if (!map.IncludeInSchema) att.Arguments.Add (GetArg ("IncludeInSchema", false));
 			AddCustomAttribute (codeClass, att, false);
 
 			CodeAttributeDeclaration ratt = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlRoot");
@@ -157,6 +158,9 @@ namespace System.Xml.Serialization {
 			if (attinfo.Form != XmlSchemaForm.None) att.Arguments.Add (GetEnumArg ("Form","System.Xml.Schema.XmlSchemaForm",attinfo.Form.ToString()));
 			if (!TypeTranslator.IsDefaultPrimitiveTpeData(attinfo.TypeData)) att.Arguments.Add (GetArg ("DataType",attinfo.TypeData.XmlType));
 			attributes.Add (att);
+			
+			if (attinfo.Ignore)
+				attributes.Add (new CodeAttributeDeclaration ("System.Xml.Serialization.XmlIgnoreAttribute"));
 		}
 		
 		protected override void GenerateElementInfoMember (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberElement member, XmlTypeMapElementInfo einfo, TypeData defaultType, string defaultNamespace, bool addAlwaysAttr, bool forceUseMemberName)
@@ -178,6 +182,9 @@ namespace System.Xml.Serialization {
 				att.Arguments.Add (GetArg(member.ChoiceMember));
 				attributes.Add (att);
 			}
+
+			if (member.Ignore)
+				attributes.Add (new CodeAttributeDeclaration ("System.Xml.Serialization.XmlIgnoreAttribute"));
 		}
 		
 		protected override void GenerateArrayElement (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberElement member, string defaultNamespace, bool forceUseMemberName)

+ 78 - 32
mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs

@@ -525,46 +525,92 @@ namespace System.Xml.Serialization {
 
 		ICollection GetReflectionMembers (Type type)
 		{
-			ArrayList members = new ArrayList();
-			MemberInfo[] tmembers = type.GetMembers (BindingFlags.Instance | BindingFlags.Public);
-			int currentTypePos = 0;
-			Type currentType = null;
-			
-			foreach (MemberInfo tmember in tmembers)
+			// First we want to find the inheritance hierarchy in reverse order.
+			Type currentType = type;
+			ArrayList typeList = new ArrayList();
+			typeList.Add(currentType);
+			while (currentType != typeof(object))
+			{
+				currentType = currentType.BaseType; // Read the base type.
+				typeList.Insert(0, currentType); // Insert at 0 to reverse the order.
+			}
+
+			// Read all Fields via reflection.
+			ArrayList fieldList = new ArrayList();
+			FieldInfo[] tfields = type.GetFields (BindingFlags.Instance | BindingFlags.Public);
+			currentType = null;
+			int currentIndex = 0;
+			foreach (FieldInfo field in tfields)
 			{
-				if (currentType != tmember.DeclaringType)
+				// This statement ensures fields are ordered starting from the base type.
+				if (currentType != field.DeclaringType)
 				{
-					currentType = tmember.DeclaringType;
-					currentTypePos = 0;
+					currentType = field.DeclaringType;
+					currentIndex=0;
 				}
-				
-				if (tmember is FieldInfo)
+				fieldList.Insert(currentIndex++, field);
+			}
+
+			// Read all Properties via reflection.
+			ArrayList propList = new ArrayList();
+			PropertyInfo[] tprops = type.GetProperties (BindingFlags.Instance | BindingFlags.Public);
+			currentType = null;
+			currentIndex = 0;
+			foreach (PropertyInfo prop in tprops)
+			{
+				// This statement ensures properties are ordered starting from the base type.
+				if (currentType != prop.DeclaringType)
+				{
+					currentType = prop.DeclaringType;
+					currentIndex = 0;
+				}
+				if (!prop.CanRead) continue;
+				if (!prop.CanWrite && TypeTranslator.GetTypeData (prop.PropertyType).SchemaType != SchemaTypes.Array) continue;
+				if (prop.GetIndexParameters().Length > 0) continue;
+				propList.Insert(currentIndex++, prop);
+			}
+
+			ArrayList members = new ArrayList();
+			int fieldIndex=0;
+			int propIndex=0;
+			// We now step through the type hierarchy from the base (object) through
+			// to the supplied class, as each step outputting all Fields, and then
+			// all Properties.  This is the exact same ordering as .NET 1.0/1.1.
+			foreach (Type t in typeList)
+			{
+				// Add any fields matching the current DeclaringType.
+				while (fieldIndex < fieldList.Count)
 				{
-					FieldInfo field = tmember as FieldInfo;
-					XmlAttributes atts = attributeOverrides[type, field.Name];
-					if (atts == null) atts = new XmlAttributes (field);
-					if (atts.XmlIgnore) continue;
-					XmlReflectionMember member = new XmlReflectionMember(field.Name, field.FieldType, atts);
-					members.Insert (currentTypePos, member);
-					currentTypePos++;
+					FieldInfo field = (FieldInfo)fieldList[fieldIndex];
+					if (field.DeclaringType==t)
+					{
+						fieldIndex++;
+						XmlAttributes atts = attributeOverrides[type, field.Name];
+						if (atts == null) atts = new XmlAttributes (field);
+						if (atts.XmlIgnore) continue;
+						XmlReflectionMember member = new XmlReflectionMember(field.Name, field.FieldType, atts);
+						members.Add(member);
+					}
+					else break;
 				}
-				else if (tmember is PropertyInfo)
+
+				// Add any properties matching the current DeclaringType.
+				while (propIndex < propList.Count)
 				{
-					PropertyInfo prop  = tmember as PropertyInfo;
-					if (!prop.CanRead) continue;
-					if (!prop.CanWrite && TypeTranslator.GetTypeData (prop.PropertyType).SchemaType != SchemaTypes.Array)
-						continue;
-					if (prop.GetIndexParameters().Length > 0) continue;
-						
-					XmlAttributes atts = attributeOverrides[type, prop.Name];
-					if (atts == null) atts = new XmlAttributes (prop);
-					if (atts.XmlIgnore) continue;
-					XmlReflectionMember member = new XmlReflectionMember(prop.Name, prop.PropertyType, atts);
-					members.Insert (currentTypePos, member);
-					currentTypePos++;
+					PropertyInfo prop = (PropertyInfo)propList[propIndex];
+					if (prop.DeclaringType==t)
+					{
+						propIndex++;
+						XmlAttributes atts = attributeOverrides[type, prop.Name];
+						if (atts == null) atts = new XmlAttributes (prop);
+						if (atts.XmlIgnore) continue;
+						XmlReflectionMember member = new XmlReflectionMember(prop.Name, prop.PropertyType, atts);
+						members.Add(member);
+					}
+					else break;
 				}
 			}
-			return members;
+			return members;		
 		}
 		
 		private XmlTypeMapMember CreateMapMember (XmlReflectionMember rmember, string defaultNamespace)

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

@@ -851,18 +851,21 @@ namespace System.Xml.Serialization {
 			{
 				// Create the choice member
 				XmlTypeMapMemberElement choiceMember = new XmlTypeMapMemberElement ();
+				choiceMember.Ignore = true;
 				choiceMember.Name = classIds.AddUnique (member.Name + "ElementName", choiceMember);
 				member.ChoiceMember = choiceMember.Name;
 
 				// Create the choice enum
 				XmlTypeMapping enumMap = CreateTypeMapping (new XmlQualifiedName (member.Name + "ChoiceType", typeQName.Namespace), SchemaTypes.Enum, null);
+				enumMap.IncludeInSchema = false;
 
 				CodeIdentifiers codeIdents = new CodeIdentifiers ();
 				EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [choices.Count];
 				for (int n=0; n<choices.Count; n++)
 				{
 					XmlTypeMapElementInfo it =(XmlTypeMapElementInfo) choices[n];
-					string xmlName = (it.Namespace != null && it.Namespace != "") ? it.Namespace + ":" + it.ElementName : it.ElementName;
+					bool extraNs = (it.Namespace != null && it.Namespace != "" && it.Namespace != typeQName.Namespace);
+					string xmlName = extraNs ? it.Namespace + ":" + it.ElementName : it.ElementName;
 					string enumName = codeIdents.AddUnique (CodeIdentifier.MakeValid (it.ElementName), it);
 					members [n] = new EnumMap.EnumMapMember (xmlName, enumName);
 				}

+ 16 - 7
mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapMember.cs

@@ -25,8 +25,11 @@ namespace System.Xml.Serialization
 		MemberInfo _specifiedMember;
 		object _defaultValue = System.DBNull.Value;
 		string documentation;
-		bool _isOptional;
-		bool _isReturnValue;
+		int _flags;
+		
+		const int OPTIONAL = 1;
+		const int RETURN_VALUE = 2;
+		const int IGNORE = 4;
 
 		public XmlTypeMapMember()
 		{
@@ -100,20 +103,26 @@ namespace System.Xml.Serialization
 		
 		public bool IsOptionalValueType
 		{
-			get { return _isOptional; }
-			set { _isOptional = value; }
+			get { return (_flags & OPTIONAL) != 0; }
+			set { _flags = value ? (_flags | OPTIONAL) : (_flags & ~OPTIONAL); }
 		}
 		
 		public bool IsReturnValue
 		{
-			get { return _isReturnValue; }
-			set { _isReturnValue = value; }
+			get { return (_flags & RETURN_VALUE) != 0; }
+			set { _flags = value ? (_flags | RETURN_VALUE) : (_flags & ~RETURN_VALUE); }
+		}
+		
+		public bool Ignore
+		{
+			get { return (_flags & IGNORE) != 0; }
+			set { _flags = value ? (_flags | IGNORE) : (_flags & ~IGNORE); }
 		}
 		
 		public void CheckOptionalValueType (Type type)
 		{
 			if (_member == null) InitMember (type);
-			_isOptional = (_specifiedMember != null);
+			IsOptionalValueType = (_specifiedMember != null);
 		}
 		
 		public bool GetValueSpecified (object ob)

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

@@ -155,6 +155,7 @@ namespace System.Xml.Serialization
 		Hashtable _elements = new Hashtable ();
 		ArrayList _elementMembers;
 		Hashtable _attributeMembers;
+		XmlTypeMapMemberAttribute[] _attributeMembersArray;
 		XmlTypeMapElementInfo[] _elementsByIndex;
 		ArrayList _flatLists;
 		ArrayList _allMembers = new ArrayList ();
@@ -186,6 +187,7 @@ namespace System.Xml.Serialization
 				string key = BuildKey (atm.AttributeName, atm.Namespace);
 				if (_attributeMembers.ContainsKey (key))
 					throw new InvalidOperationException ("The XML attribute named '" + atm.AttributeName + "' from namespace '" + atm.Namespace + "' already present in the current scope. Use XML attributes to specify another XML name or namespace for the attribute.");
+				member.Index = _attributeMembers.Count;
 				_attributeMembers.Add (key, member);
 				return;
 			}
@@ -314,7 +316,16 @@ namespace System.Xml.Serialization
 
 		public ICollection AttributeMembers
 		{
-			get { return (_attributeMembers != null) ? _attributeMembers.Values : null; }
+			get 
+			{
+				if (_attributeMembers == null) return null;
+				if (_attributeMembersArray != null) return _attributeMembersArray;
+				
+				_attributeMembersArray = new XmlTypeMapMemberAttribute[_attributeMembers.Count];
+				foreach (XmlTypeMapMemberAttribute mem in _attributeMembers.Values)
+					_attributeMembersArray [mem.Index] = mem;
+				return _attributeMembersArray;
+			}
 		}
 
 		public ICollection ElementMembers