The Labs \ Source Viewer \ SSCLI \ System.Xml.Serialization \ XmlCodeExporter

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlCodeExporter.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. // <owner current="true" primary="true">ElenaK</owner>
  15. //------------------------------------------------------------------------------
  16. namespace System.Xml.Serialization
  17. {
  18.    
  19.     using System;
  20.     using System.Collections;
  21.     using System.IO;
  22.     using System.ComponentModel;
  23.     using System.Xml.Schema;
  24.     using System.CodeDom;
  25.     using System.CodeDom.Compiler;
  26.     using System.Reflection;
  27.     using System.Globalization;
  28.     using System.Diagnostics;
  29.     using System.Security.Permissions;
  30.     using System.Xml.Serialization.Advanced;
  31.    
  32.     /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter"]/*' />
  33.     ///<internalonly/>
  34.     /// <devdoc>
  35.     /// <para>[To be supplied.]</para>
  36.     /// </devdoc>
  37.     public class XmlCodeExporter : CodeExporter
  38.     {
  39.         /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.XmlCodeExporter"]/*' />
  40.         /// <devdoc>
  41.         /// <para>[To be supplied.]</para>
  42.         /// </devdoc>
  43.         public XmlCodeExporter(CodeNamespace codeNamespace) : base(codeNamespace, null, null, CodeGenerationOptions.GenerateProperties, null)
  44.         {
  45.         }
  46.        
  47.         /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.XmlCodeExporter1"]/*' />
  48.         /// <devdoc>
  49.         /// <para>[To be supplied.]</para>
  50.         /// </devdoc>
  51.         public XmlCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit) : base(codeNamespace, codeCompileUnit, null, CodeGenerationOptions.GenerateProperties, null)
  52.         {
  53.         }
  54.        
  55.         /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.XmlCodeExporter2"]/*' />
  56.         /// <devdoc>
  57.         /// <para>[To be supplied.]</para>
  58.         /// </devdoc>
  59.         public XmlCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeGenerationOptions options) : base(codeNamespace, codeCompileUnit, null, options, null)
  60.         {
  61.         }
  62.        
  63.         /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.XmlCodeExporter3"]/*' />
  64.         /// <devdoc>
  65.         /// <para>[To be supplied.]</para>
  66.         /// </devdoc>
  67.         public XmlCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeGenerationOptions options, Hashtable mappings) : base(codeNamespace, codeCompileUnit, null, options, mappings)
  68.         {
  69.         }
  70.        
  71.         /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.XmlCodeExporter4"]/*' />
  72.         /// <devdoc>
  73.         /// <para>[To be supplied.]</para>
  74.         /// </devdoc>
  75.         public XmlCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeDomProvider codeProvider, CodeGenerationOptions options, Hashtable mappings) : base(codeNamespace, codeCompileUnit, codeProvider, options, mappings)
  76.         {
  77.         }
  78.        
  79.         /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.ExportTypeMapping"]/*' />
  80.         /// <devdoc>
  81.         /// <para>[To be supplied.]</para>
  82.         /// </devdoc>
  83.         public void ExportTypeMapping(XmlTypeMapping xmlTypeMapping)
  84.         {
  85.             xmlTypeMapping.CheckShallow();
  86.             CheckScope(xmlTypeMapping.Scope);
  87.             if (xmlTypeMapping.Accessor.Any)
  88.                 throw new InvalidOperationException(Res.GetString(Res.XmlIllegalWildcard));
  89.            
  90.             ExportElement(xmlTypeMapping.Accessor);
  91.         }
  92.        
  93.         /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.ExportMembersMapping"]/*' />
  94.         /// <devdoc>
  95.         /// <para>[To be supplied.]</para>
  96.         /// </devdoc>
  97.         public void ExportMembersMapping(XmlMembersMapping xmlMembersMapping)
  98.         {
  99.             xmlMembersMapping.CheckShallow();
  100.             CheckScope(xmlMembersMapping.Scope);
  101.            
  102.             for (int i = 0; i < xmlMembersMapping.Count; i++) {
  103.                 AccessorMapping mapping = xmlMembersMapping[i].Mapping;
  104.                 if (mapping.Xmlns == null) {
  105.                     if (mapping.Attribute != null) {
  106.                         ExportType(mapping.Attribute.Mapping, Accessor.UnescapeName(mapping.Attribute.Name), mapping.Attribute.Namespace, null, false);
  107.                     }
  108.                     if (mapping.Elements != null) {
  109.                         for (int j = 0; j < mapping.Elements.Length; j++) {
  110.                             ElementAccessor element = mapping.Elements[j];
  111.                             ExportType(element.Mapping, Accessor.UnescapeName(element.Name), element.Namespace, null, false);
  112.                         }
  113.                     }
  114.                     if (mapping.Text != null) {
  115.                         ExportType(mapping.Text.Mapping, Accessor.UnescapeName(mapping.Text.Name), mapping.Text.Namespace, null, false);
  116.                     }
  117.                 }
  118.             }
  119.         }
  120.        
  121.         void ExportElement(ElementAccessor element)
  122.         {
  123.             ExportType(element.Mapping, Accessor.UnescapeName(element.Name), element.Namespace, element, true);
  124.         }
  125.        
  126.         void ExportType(TypeMapping mapping, string ns)
  127.         {
  128.             ExportType(mapping, null, ns, null, true);
  129.         }
  130.        
  131.         void ExportType(TypeMapping mapping, string name, string ns, ElementAccessor rootElement, bool checkReference)
  132.         {
  133.             if (mapping.IsReference && mapping.Namespace != Soap.Encoding)
  134.                 return;
  135.            
  136.             if (mapping is StructMapping && checkReference && ((StructMapping)mapping).ReferencedByTopLevelElement && rootElement == null)
  137.                 return;
  138.            
  139.             if (mapping is ArrayMapping && rootElement != null && rootElement.IsTopLevelInSchema && ((ArrayMapping)mapping).TopLevelMapping != null) {
  140.                 mapping = ((ArrayMapping)mapping).TopLevelMapping;
  141.             }
  142.            
  143.             CodeTypeDeclaration codeClass = null;
  144.            
  145.             if (ExportedMappings[mapping] == null) {
  146.                 ExportedMappings.Add(mapping, mapping);
  147.                 if (mapping.TypeDesc.IsMappedType) {
  148.                     codeClass = mapping.TypeDesc.ExtendedType.ExportTypeDefinition(CodeNamespace, CodeCompileUnit);
  149.                 }
  150.                 else if (mapping is EnumMapping) {
  151.                     codeClass = ExportEnum((EnumMapping)mapping, typeof(XmlEnumAttribute));
  152.                 }
  153.                 else if (mapping is StructMapping) {
  154.                     codeClass = ExportStruct((StructMapping)mapping);
  155.                 }
  156.                 else if (mapping is ArrayMapping) {
  157.                     EnsureTypesExported(((ArrayMapping)mapping).Elements, ns);
  158.                 }
  159.                 if (codeClass != null) {
  160.                     if (!mapping.TypeDesc.IsMappedType) {
  161.                         // Add [GeneratedCodeAttribute(Tool=.., Version=..)]
  162.                         codeClass.CustomAttributes.Add(GeneratedCodeAttribute);
  163.                        
  164.                         // Add [SerializableAttribute]
  165.                         codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(SerializableAttribute).FullName));
  166.                        
  167.                         if (!codeClass.IsEnum) {
  168.                             // Add [DebuggerStepThrough]
  169.                             codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DebuggerStepThroughAttribute).FullName));
  170.                             // Add [DesignerCategory("code")]
  171.                             codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DesignerCategoryAttribute).FullName, new CodeAttributeArgument[] {new CodeAttributeArgument(new CodePrimitiveExpression("code"))}));
  172.                         }
  173.                         AddTypeMetadata(codeClass.CustomAttributes, typeof(XmlTypeAttribute), mapping.TypeDesc.Name, Accessor.UnescapeName(mapping.TypeName), mapping.Namespace, mapping.IncludeInSchema);
  174.                     }
  175.                     else if (FindAttributeDeclaration(typeof(GeneratedCodeAttribute), codeClass.CustomAttributes) == null) {
  176.                         // Add [GeneratedCodeAttribute(Tool=.., Version=..)]
  177.                         codeClass.CustomAttributes.Add(GeneratedCodeAttribute);
  178.                     }
  179.                     ExportedClasses.Add(mapping, codeClass);
  180.                 }
  181.             }
  182.             else
  183.                 codeClass = (CodeTypeDeclaration)ExportedClasses[mapping];
  184.            
  185.             if (codeClass != null && rootElement != null)
  186.                 AddRootMetadata(codeClass.CustomAttributes, mapping, name, ns, rootElement);
  187.         }
  188.        
  189.         void AddRootMetadata(CodeAttributeDeclarationCollection metadata, TypeMapping typeMapping, string name, string ns, ElementAccessor rootElement)
  190.         {
  191.             string rootAttrName = typeof(XmlRootAttribute).FullName;
  192.            
  193.             // check that we haven't already added a root attribute since we can only add one
  194.             foreach (CodeAttributeDeclaration attr in metadata) {
  195.                 if (attr.Name == rootAttrName)
  196.                     return;
  197.             }
  198.            
  199.             CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(rootAttrName);
  200.             if (typeMapping.TypeDesc.Name != name) {
  201.                 attribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(name)));
  202.             }
  203.             if (ns != null) {
  204.                 attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(ns)));
  205.             }
  206.             if (typeMapping.TypeDesc != null && typeMapping.TypeDesc.IsAmbiguousDataType) {
  207.                 attribute.Arguments.Add(new CodeAttributeArgument("DataType", new CodePrimitiveExpression(typeMapping.TypeDesc.DataType.Name)));
  208.             }
  209.             if ((object)(rootElement.IsNullable) != null) {
  210.                 attribute.Arguments.Add(new CodeAttributeArgument("IsNullable", new CodePrimitiveExpression((bool)rootElement.IsNullable)));
  211.             }
  212.             metadata.Add(attribute);
  213.         }
  214.        
  215.         CodeAttributeArgument[] GetDefaultValueArguments(PrimitiveMapping mapping, object value, out CodeExpression initExpression)
  216.         {
  217.             initExpression = null;
  218.             if (value == null)
  219.                 return null;
  220.            
  221.             CodeExpression valueExpression = null;
  222.             CodeExpression typeofValue = null;
  223.             Type type = value.GetType();
  224.             CodeAttributeArgument[] arguments = null;
  225.            
  226.             if (mapping is EnumMapping) {
  227.                 #if DEBUG
  228.                 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  229.                 if (value.GetType() != typeof(string))
  230.                     throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "Invalid enumeration type " + value.GetType().Name));
  231.                 #endif
  232.                
  233.                 if (((EnumMapping)mapping).IsFlags) {
  234.                     string[] values = ((string)value).Split(null);
  235.                     for (int i = 0; i < values.Length; i++) {
  236.                         if (values[i].Length == 0)
  237.                             continue;
  238.                         CodeExpression enumRef = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(mapping.TypeDesc.FullName), values[i]);
  239.                         if (valueExpression != null)
  240.                             valueExpression = new CodeBinaryOperatorExpression(valueExpression, CodeBinaryOperatorType.BitwiseOr, enumRef);
  241.                         else
  242.                             valueExpression = enumRef;
  243.                     }
  244.                 }
  245.                 else {
  246.                     valueExpression = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(mapping.TypeDesc.FullName), (string)value);
  247.                 }
  248.                 initExpression = valueExpression;
  249.                 arguments = new CodeAttributeArgument[] {new CodeAttributeArgument(valueExpression)};
  250.             }
  251.             else if (type == typeof(bool) || type == typeof(Int32) || type == typeof(string) || type == typeof(double)) {
  252.                
  253.                 initExpression = valueExpression = new CodePrimitiveExpression(value);
  254.                 arguments = new CodeAttributeArgument[] {new CodeAttributeArgument(valueExpression)};
  255.             }
  256.             else if (type == typeof(Int16) || type == typeof(Int64) || type == typeof(float) || type == typeof(byte) || type == typeof(decimal)) {
  257.                 valueExpression = new CodePrimitiveExpression(Convert.ToString(value, NumberFormatInfo.InvariantInfo));
  258.                 typeofValue = new CodeTypeOfExpression(type.FullName);
  259.                 arguments = new CodeAttributeArgument[] {new CodeAttributeArgument(typeofValue), new CodeAttributeArgument(valueExpression)};
  260.                 initExpression = new CodeCastExpression(type.FullName, new CodePrimitiveExpression(value));
  261.             }
  262.             else if (type == typeof(sbyte) || type == typeof(UInt16) || type == typeof(UInt32) || type == typeof(UInt64)) {
  263.                 // need to promote the non-CLS complient types
  264.                
  265.                 value = PromoteType(type, value);
  266.                
  267.                 valueExpression = new CodePrimitiveExpression(Convert.ToString(value, NumberFormatInfo.InvariantInfo));
  268.                 typeofValue = new CodeTypeOfExpression(type.FullName);
  269.                 arguments = new CodeAttributeArgument[] {new CodeAttributeArgument(typeofValue), new CodeAttributeArgument(valueExpression)};
  270.                 initExpression = new CodeCastExpression(type.FullName, new CodePrimitiveExpression(value));
  271.             }
  272.             else if (type == typeof(DateTime)) {
  273.                 DateTime dt = (DateTime)value;
  274.                 string dtString;
  275.                 long ticks;
  276.                 if (mapping.TypeDesc.FormatterName == "Date") {
  277.                     dtString = XmlCustomFormatter.FromDate(dt);
  278.                     ticks = (new DateTime(dt.Year, dt.Month, dt.Day)).Ticks;
  279.                 }
  280.                 else if (mapping.TypeDesc.FormatterName == "Time") {
  281.                     dtString = XmlCustomFormatter.FromDateTime(dt);
  282.                     ticks = dt.Ticks;
  283.                 }
  284.                 else {
  285.                     dtString = XmlCustomFormatter.FromDateTime(dt);
  286.                     ticks = dt.Ticks;
  287.                 }
  288.                 valueExpression = new CodePrimitiveExpression(dtString);
  289.                 typeofValue = new CodeTypeOfExpression(type.FullName);
  290.                 arguments = new CodeAttributeArgument[] {new CodeAttributeArgument(typeofValue), new CodeAttributeArgument(valueExpression)};
  291.                 initExpression = new CodeObjectCreateExpression(new CodeTypeReference(typeof(DateTime)), new CodeExpression[] {new CodePrimitiveExpression(ticks)});
  292.             }
  293.             else if (type == typeof(Guid)) {
  294.                 valueExpression = new CodePrimitiveExpression(Convert.ToString(value, NumberFormatInfo.InvariantInfo));
  295.                 typeofValue = new CodeTypeOfExpression(type.FullName);
  296.                 arguments = new CodeAttributeArgument[] {new CodeAttributeArgument(typeofValue), new CodeAttributeArgument(valueExpression)};
  297.                 initExpression = new CodeObjectCreateExpression(new CodeTypeReference(typeof(Guid)), new CodeExpression[] {valueExpression});
  298.                
  299.             }
  300.             if (mapping.TypeDesc.FullName != type.ToString() && !(mapping is EnumMapping)) {
  301.                 // generate cast
  302.                 initExpression = new CodeCastExpression(mapping.TypeDesc.FullName, initExpression);
  303.             }
  304.             return arguments;
  305.         }
  306.        
  307.         object ImportDefault(TypeMapping mapping, string defaultValue)
  308.         {
  309.             if (defaultValue == null)
  310.                 return null;
  311.            
  312.             if (mapping.IsList) {
  313.                 string[] vals = defaultValue.Trim().Split(null);
  314.                
  315.                 // count all non-zero length values;
  316.                 int count = 0;
  317.                 for (int i = 0; i < vals.Length; i++) {
  318.                     if (vals[i] != null && vals[i].Length > 0)
  319.                         count++;
  320.                 }
  321.                
  322.                 object[] values = new object[count];
  323.                 count = 0;
  324.                 for (int i = 0; i < vals.Length; i++) {
  325.                     if (vals[i] != null && vals[i].Length > 0) {
  326.                         values[count++] = ImportDefaultValue(mapping, vals[i]);
  327.                     }
  328.                 }
  329.                 return values;
  330.             }
  331.             return ImportDefaultValue(mapping, defaultValue);
  332.         }
  333.        
  334.         object ImportDefaultValue(TypeMapping mapping, string defaultValue)
  335.         {
  336.             if (defaultValue == null)
  337.                 return null;
  338.             if (!(mapping is PrimitiveMapping))
  339.                 return DBNull.Value;
  340.            
  341.             if (mapping is EnumMapping) {
  342.                 EnumMapping em = (EnumMapping)mapping;
  343.                 ConstantMapping[] c = em.Constants;
  344.                
  345.                 if (em.IsFlags) {
  346.                     Hashtable values = new Hashtable();
  347.                     string[] names = new string[c.Length];
  348.                     long[] ids = new long[c.Length];
  349.                    
  350.                     for (int i = 0; i < c.Length; i++) {
  351.                         ids[i] = em.IsFlags ? 1l << i : (long)i;
  352.                         names[i] = c[i].Name;
  353.                         values.Add(c[i].XmlName, ids[i]);
  354.                     }
  355.                     // this validates the values
  356.                     long val = XmlCustomFormatter.ToEnum(defaultValue, values, em.TypeName, true);
  357.                     return XmlCustomFormatter.FromEnum(val, names, ids, em.TypeDesc.FullName);
  358.                 }
  359.                 else {
  360.                     for (int i = 0; i < c.Length; i++) {
  361.                         if (c[i].XmlName == defaultValue)
  362.                             return c[i].Name;
  363.                     }
  364.                 }
  365.                 throw new InvalidOperationException(Res.GetString(Res.XmlInvalidDefaultValue, defaultValue, em.TypeDesc.FullName));
  366.             }
  367.            
  368.             // Primitive mapping
  369.             PrimitiveMapping pm = (PrimitiveMapping)mapping;
  370.            
  371.             if (!pm.TypeDesc.HasCustomFormatter) {
  372.                 if (pm.TypeDesc.FormatterName == "String")
  373.                     return defaultValue;
  374.                 if (pm.TypeDesc.FormatterName == "DateTime")
  375.                     return XmlCustomFormatter.ToDateTime(defaultValue);
  376.                
  377.                 Type formatter = typeof(XmlConvert);
  378.                
  379.                 MethodInfo format = formatter.GetMethod("To" + pm.TypeDesc.FormatterName, new Type[] {typeof(string)});
  380.                 if (format != null) {
  381.                     return format.Invoke(formatter, new object[] {defaultValue});
  382.                 }
  383.                 #if DEBUG
  384.                 Debug.WriteLineIf(DiagnosticsSwitches.XmlSerialization.TraceVerbose, "XmlSerialization::Failed to GetMethod " + formatter.Name + ".To" + pm.TypeDesc.FormatterName);
  385.                 #endif
  386.             }
  387.             else {
  388.                 if (pm.TypeDesc.HasDefaultSupport) {
  389.                     return XmlCustomFormatter.ToDefaultValue(defaultValue, pm.TypeDesc.FormatterName);
  390.                 }
  391.             }
  392.             return DBNull.Value;
  393.         }
  394.        
  395.         void AddDefaultValueAttribute(CodeMemberField field, CodeAttributeDeclarationCollection metadata, object defaultValue, TypeMapping mapping, CodeCommentStatementCollection comments, TypeDesc memberTypeDesc, Accessor accessor, CodeConstructor ctor)
  396.         {
  397.             string attributeName = accessor.IsFixed ? "fixed" : "default";
  398.             if (!memberTypeDesc.HasDefaultSupport) {
  399.                 if (comments != null && defaultValue is string) {
  400.                     DropDefaultAttribute(accessor, comments, memberTypeDesc.FullName);
  401.                     // do not generate intializers for the user prefered types if they do not have default capability
  402.                     AddWarningComment(comments, Res.GetString(Res.XmlDropAttributeValue, attributeName, mapping.TypeName, defaultValue.ToString()));
  403.                 }
  404.                 return;
  405.             }
  406.             if (memberTypeDesc.IsArrayLike && accessor is ElementAccessor) {
  407.                 if (comments != null && defaultValue is string) {
  408.                     DropDefaultAttribute(accessor, comments, memberTypeDesc.FullName);
  409.                     // do not generate intializers for array-like types
  410.                     AddWarningComment(comments, Res.GetString(Res.XmlDropArrayAttributeValue, attributeName, defaultValue.ToString(), ((ElementAccessor)accessor).Name));
  411.                 }
  412.                 return;
  413.             }
  414.             if (mapping.TypeDesc.IsMappedType && field != null && defaultValue is string) {
  415.                 SchemaImporterExtension extension = mapping.TypeDesc.ExtendedType.Extension;
  416.                 CodeExpression init = extension.ImportDefaultValue((string)defaultValue, mapping.TypeDesc.FullName);
  417.                
  418.                 if (init != null) {
  419.                     if (ctor != null) {
  420.                         AddInitializationStatement(ctor, field, init);
  421.                     }
  422.                     else {
  423.                         field.InitExpression = extension.ImportDefaultValue((string)defaultValue, mapping.TypeDesc.FullName);
  424.                     }
  425.                 }
  426.                 if (comments != null) {
  427.                     DropDefaultAttribute(accessor, comments, mapping.TypeDesc.FullName);
  428.                     if (init == null) {
  429.                         AddWarningComment(comments, Res.GetString(Res.XmlNotKnownDefaultValue, extension.GetType().FullName, attributeName, (string)defaultValue, mapping.TypeName, mapping.Namespace));
  430.                     }
  431.                 }
  432.                 return;
  433.             }
  434.             object value = null;
  435.             if (defaultValue is string || defaultValue == null) {
  436.                 value = ImportDefault(mapping, (string)defaultValue);
  437.             }
  438.             if (value == null)
  439.                 return;
  440.             if (!(mapping is PrimitiveMapping)) {
  441.                 DropDefaultAttribute(accessor, comments, memberTypeDesc.FullName);
  442.                 AddWarningComment(comments, Res.GetString(Res.XmlDropNonPrimitiveAttributeValue, attributeName, defaultValue.ToString()));
  443.                 return;
  444.             }
  445.             PrimitiveMapping pm = (PrimitiveMapping)mapping;
  446.            
  447.             if (comments != null && !pm.TypeDesc.HasDefaultSupport && pm.TypeDesc.IsMappedType) {
  448.                 // do not generate intializers for the user prefered types if they do not have default capability
  449.                 DropDefaultAttribute(accessor, comments, pm.TypeDesc.FullName);
  450.                 return;
  451.             }
  452.             if (value == DBNull.Value) {
  453.                 if (comments != null) {
  454.                     AddWarningComment(comments, Res.GetString(Res.XmlDropAttributeValue, attributeName, pm.TypeName, defaultValue.ToString()));
  455.                 }
  456.                 return;
  457.             }
  458.             CodeAttributeArgument[] arguments = null;
  459.             CodeExpression initExpression = null;
  460.            
  461.             if (pm.IsList) {
  462.                 #if DEBUG
  463.                 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  464.                 if (value.GetType() != typeof(object[]))
  465.                     throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "Default value for list should be object[], not " + value.GetType().Name));
  466.                 #endif
  467.                
  468.                 object[] vals = (object[])value;
  469.                 CodeExpression[] initializers = new CodeExpression[vals.Length];
  470.                 for (int i = 0; i < vals.Length; i++) {
  471.                     GetDefaultValueArguments(pm, vals[i], out initializers[i]);
  472.                 }
  473.                 initExpression = new CodeArrayCreateExpression(field.Type, initializers);
  474.                
  475.             }
  476.             else {
  477.                 arguments = GetDefaultValueArguments(pm, value, out initExpression);
  478.             }
  479.            
  480.             if (field != null) {
  481.                 if (ctor != null) {
  482.                     AddInitializationStatement(ctor, field, initExpression);
  483.                 }
  484.                 else {
  485.                     field.InitExpression = initExpression;
  486.                 }
  487.             }
  488.             if (arguments != null && pm.TypeDesc.HasDefaultSupport && accessor.IsOptional && !accessor.IsFixed) {
  489.                 // Add [DefaultValueAttribute]
  490.                 CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(DefaultValueAttribute).FullName, arguments);
  491.                 metadata.Add(attribute);
  492.             }
  493.             else if (comments != null) {
  494.                 DropDefaultAttribute(accessor, comments, memberTypeDesc.FullName);
  495.             }
  496.         }
  497.        
  498.         static void AddInitializationStatement(CodeConstructor ctor, CodeMemberField field, CodeExpression init)
  499.         {
  500.             CodeAssignStatement assign = new CodeAssignStatement();
  501.             assign.Left = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), field.Name);
  502.             assign.Right = init;
  503.             ctor.Statements.Add(assign);
  504.         }
  505.        
  506.         static void DropDefaultAttribute(Accessor accessor, CodeCommentStatementCollection comments, string type)
  507.         {
  508.             if (!accessor.IsFixed && accessor.IsOptional) {
  509.                 AddWarningComment(comments, Res.GetString(Res.XmlDropDefaultAttribute, type));
  510.             }
  511.         }
  512.        
  513.         CodeTypeDeclaration ExportStruct(StructMapping mapping)
  514.         {
  515.             if (mapping.TypeDesc.IsRoot) {
  516.                 ExportRoot(mapping, typeof(XmlIncludeAttribute));
  517.                 return null;
  518.             }
  519.            
  520.             string className = mapping.TypeDesc.Name;
  521.             string baseName = mapping.TypeDesc.BaseTypeDesc == null || mapping.TypeDesc.BaseTypeDesc.IsRoot ? string.Empty : mapping.TypeDesc.BaseTypeDesc.FullName;
  522.            
  523.             CodeTypeDeclaration codeClass = new CodeTypeDeclaration(className);
  524.             codeClass.IsPartial = CodeProvider.Supports(GeneratorSupport.PartialTypes);
  525.             codeClass.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
  526.            
  527.             CodeNamespace.Types.Add(codeClass);
  528.            
  529.             CodeConstructor ctor = new CodeConstructor();
  530.             ctor.Attributes = (ctor.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
  531.             codeClass.Members.Add(ctor);
  532.             if (mapping.TypeDesc.IsAbstract) {
  533.                 ctor.Attributes |= MemberAttributes.Abstract;
  534.             }
  535.            
  536.             if (baseName != null && baseName.Length > 0) {
  537.                 codeClass.BaseTypes.Add(baseName);
  538.             }
  539.             else
  540.                 AddPropertyChangedNotifier(codeClass);
  541.            
  542.             codeClass.TypeAttributes |= TypeAttributes.Public;
  543.             if (mapping.TypeDesc.IsAbstract) {
  544.                 codeClass.TypeAttributes |= TypeAttributes.Abstract;
  545.             }
  546.            
  547.             AddIncludeMetadata(codeClass.CustomAttributes, mapping, typeof(XmlIncludeAttribute));
  548.            
  549.             if (GenerateProperties) {
  550.                 for (int i = 0; i < mapping.Members.Length; i++) {
  551.                     ExportProperty(codeClass, mapping.Members[i], mapping.Namespace, mapping.Scope, ctor);
  552.                 }
  553.             }
  554.             else {
  555.                 for (int i = 0; i < mapping.Members.Length; i++) {
  556.                     ExportMember(codeClass, mapping.Members[i], mapping.Namespace, ctor);
  557.                 }
  558.             }
  559.            
  560.             for (int i = 0; i < mapping.Members.Length; i++) {
  561.                 EnsureTypesExported(mapping.Members[i].Elements, mapping.Namespace);
  562.                 EnsureTypesExported(mapping.Members[i].Attribute, mapping.Namespace);
  563.                 EnsureTypesExported(mapping.Members[i].Text, mapping.Namespace);
  564.             }
  565.            
  566.             if (mapping.BaseMapping != null)
  567.                 ExportType(mapping.BaseMapping, mapping.Namespace);
  568.            
  569.             ExportDerivedStructs(mapping);
  570.             CodeGenerator.ValidateIdentifiers(codeClass);
  571.             if (ctor.Statements.Count == 0)
  572.                 codeClass.Members.Remove(ctor);
  573.             return codeClass;
  574.         }
  575.        
  576.         [PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
  577.         internal override void ExportDerivedStructs(StructMapping mapping)
  578.         {
  579.             for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping)
  580.                 ExportType(derived, mapping.Namespace);
  581.         }
  582.        
  583.         /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.AddMappingMetadata"]/*' />
  584.         /// <devdoc>
  585.         /// <para>[To be supplied.]</para>
  586.         /// </devdoc>
  587.         public void AddMappingMetadata(CodeAttributeDeclarationCollection metadata, XmlTypeMapping mapping, string ns)
  588.         {
  589.             mapping.CheckShallow();
  590.             CheckScope(mapping.Scope);
  591.             // For struct or enum mappings, we generate the XmlRoot on the struct/class/enum. For primitives
  592.             // or arrays, there is nowhere to generate the XmlRoot, so we generate it elsewhere (on the
  593.             // method for web services get/post).
  594.             if (mapping.Mapping is StructMapping || mapping.Mapping is EnumMapping)
  595.                 return;
  596.             AddRootMetadata(metadata, mapping.Mapping, Accessor.UnescapeName(mapping.Accessor.Name), mapping.Accessor.Namespace, mapping.Accessor);
  597.         }
  598.        
  599.         /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.AddMappingMetadata1"]/*' />
  600.         /// <devdoc>
  601.         /// <para>[To be supplied.]</para>
  602.         /// </devdoc>
  603.         public void AddMappingMetadata(CodeAttributeDeclarationCollection metadata, XmlMemberMapping member, string ns, bool forceUseMemberName)
  604.         {
  605.             AddMemberMetadata(null, metadata, member.Mapping, ns, forceUseMemberName, null, null);
  606.         }
  607.        
  608.         /// <include file='doc\XmlCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.AddMappingMetadata2"]/*' />
  609.         /// <devdoc>
  610.         /// <para>[To be supplied.]</para>
  611.         /// </devdoc>
  612.         public void AddMappingMetadata(CodeAttributeDeclarationCollection metadata, XmlMemberMapping member, string ns)
  613.         {
  614.             AddMemberMetadata(null, metadata, member.Mapping, ns, false, null, null);
  615.         }
  616.        
  617.         void ExportArrayElements(CodeAttributeDeclarationCollection metadata, ArrayMapping array, string ns, TypeDesc elementTypeDesc, int nestingLevel)
  618.         {
  619.             for (int i = 0; i < array.Elements.Length; i++) {
  620.                 ElementAccessor arrayElement = array.Elements[i];
  621.                 TypeMapping elementMapping = arrayElement.Mapping;
  622.                 string elementName = Accessor.UnescapeName(arrayElement.Name);
  623.                 bool sameName = arrayElement.Mapping.TypeDesc.IsArray ? false : elementName == arrayElement.Mapping.TypeName;
  624.                 bool sameElementType = elementMapping.TypeDesc == elementTypeDesc;
  625.                 bool sameElementNs = arrayElement.Form == XmlSchemaForm.Unqualified || arrayElement.Namespace == ns;
  626.                 bool sameNullable = arrayElement.IsNullable == elementMapping.TypeDesc.IsNullable;
  627.                 bool defaultForm = arrayElement.Form != XmlSchemaForm.Unqualified;
  628.                 if (!sameName || !sameElementType || !sameElementNs || !sameNullable || !defaultForm || nestingLevel > 0)
  629.                     ExportArrayItem(metadata, sameName ? null : elementName, sameElementNs ? null : arrayElement.Namespace, sameElementType ? null : elementMapping.TypeDesc, elementMapping.TypeDesc, arrayElement.IsNullable, defaultForm ? XmlSchemaForm.None : arrayElement.Form, nestingLevel);
  630.                 if (elementMapping is ArrayMapping)
  631.                     ExportArrayElements(metadata, (ArrayMapping)elementMapping, ns, elementTypeDesc.ArrayElementTypeDesc, nestingLevel + 1);
  632.             }
  633.         }
  634.        
  635.         void AddMemberMetadata(CodeMemberField field, CodeAttributeDeclarationCollection metadata, MemberMapping member, string ns, bool forceUseMemberName, CodeCommentStatementCollection comments, CodeConstructor ctor)
  636.         {
  637.             if (member.Xmlns != null) {
  638.                 CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlNamespaceDeclarationsAttribute).FullName);
  639.                 metadata.Add(attribute);
  640.             }
  641.             else if (member.Attribute != null) {
  642.                 AttributeAccessor attribute = member.Attribute;
  643.                 if (attribute.Any)
  644.                     ExportAnyAttribute(metadata);
  645.                 else {
  646.                     TypeMapping mapping = (TypeMapping)attribute.Mapping;
  647.                     string attrName = Accessor.UnescapeName(attribute.Name);
  648.                     bool sameType = mapping.TypeDesc == member.TypeDesc || (member.TypeDesc.IsArrayLike && mapping.TypeDesc == member.TypeDesc.ArrayElementTypeDesc);
  649.                     bool sameName = attrName == member.Name && !forceUseMemberName;
  650.                     bool sameNs = attribute.Namespace == ns;
  651.                     bool defaultForm = attribute.Form != XmlSchemaForm.Qualified;
  652.                     ExportAttribute(metadata, sameName ? null : attrName, sameNs ? null : attribute.Namespace, sameType ? null : mapping.TypeDesc, mapping.TypeDesc, defaultForm ? XmlSchemaForm.None : attribute.Form);
  653.                    
  654.                     AddDefaultValueAttribute(field, metadata, attribute.Default, mapping, comments, member.TypeDesc, attribute, ctor);
  655.                 }
  656.             }
  657.             else {
  658.                 if (member.Text != null) {
  659.                     TypeMapping mapping = (TypeMapping)member.Text.Mapping;
  660.                     bool sameType = mapping.TypeDesc == member.TypeDesc || (member.TypeDesc.IsArrayLike && mapping.TypeDesc == member.TypeDesc.ArrayElementTypeDesc);
  661.                     ExportText(metadata, sameType ? null : mapping.TypeDesc, mapping.TypeDesc.IsAmbiguousDataType ? mapping.TypeDesc.DataType.Name : null);
  662.                 }
  663.                 if (member.Elements.Length == 1) {
  664.                     ElementAccessor element = member.Elements[0];
  665.                     TypeMapping mapping = (TypeMapping)element.Mapping;
  666.                     string elemName = Accessor.UnescapeName(element.Name);
  667.                     bool sameName = ((elemName == member.Name) && !forceUseMemberName);
  668.                     bool isArray = mapping is ArrayMapping;
  669.                     bool sameNs = element.Namespace == ns;
  670.                     bool defaultForm = element.Form != XmlSchemaForm.Unqualified;
  671.                    
  672.                     if (element.Any)
  673.                         ExportAnyElement(metadata, elemName, element.Namespace, member.SequenceId);
  674.                     else if (isArray) {
  675.                         bool sameType = mapping.TypeDesc == member.TypeDesc;
  676.                         ArrayMapping array = (ArrayMapping)mapping;
  677.                         if (!sameName || !sameNs || element.IsNullable || !defaultForm || member.SequenceId != -1)
  678.                             ExportArray(metadata, sameName ? null : elemName, sameNs ? null : element.Namespace, element.IsNullable, defaultForm ? XmlSchemaForm.None : element.Form, member.SequenceId);
  679.                         else if (mapping.TypeDesc.ArrayElementTypeDesc == new TypeScope().GetTypeDesc(typeof(byte))) {
  680.                             // special case for byte[]. It can be a primitive (base64Binary or hexBinary), or it can
  681.                             // be an array of bytes. Our default is primitive; specify [XmlArray] to get array behavior.
  682.                             ExportArray(metadata, null, null, false, XmlSchemaForm.None, member.SequenceId);
  683.                         }
  684.                         ExportArrayElements(metadata, array, element.Namespace, member.TypeDesc.ArrayElementTypeDesc, 0);
  685.                     }
  686.                     else {
  687.                         bool sameType = mapping.TypeDesc == member.TypeDesc || (member.TypeDesc.IsArrayLike && mapping.TypeDesc == member.TypeDesc.ArrayElementTypeDesc);
  688.                         if (member.TypeDesc.IsArrayLike)
  689.                             sameName = false;
  690.                         ExportElement(metadata, sameName ? null : elemName, sameNs ? null : element.Namespace, sameType ? null : mapping.TypeDesc, mapping.TypeDesc, element.IsNullable, defaultForm ? XmlSchemaForm.None : element.Form, member.SequenceId);
  691.                     }
  692.                     AddDefaultValueAttribute(field, metadata, element.Default, mapping, comments, member.TypeDesc, element, ctor);
  693.                 }
  694.                 else {
  695.                     for (int i = 0; i < member.Elements.Length; i++) {
  696.                         ElementAccessor element = member.Elements[i];
  697.                         string elemName = Accessor.UnescapeName(element.Name);
  698.                         bool sameNs = element.Namespace == ns;
  699.                         if (element.Any)
  700.                             ExportAnyElement(metadata, elemName, element.Namespace, member.SequenceId);
  701.                         else {
  702.                             bool defaultForm = element.Form != XmlSchemaForm.Unqualified;
  703.                             ExportElement(metadata, elemName, sameNs ? null : element.Namespace, ((TypeMapping)element.Mapping).TypeDesc, ((TypeMapping)element.Mapping).TypeDesc, element.IsNullable, defaultForm ? XmlSchemaForm.None : element.Form, member.SequenceId);
  704.                         }
  705.                     }
  706.                 }
  707.                 if (member.ChoiceIdentifier != null) {
  708.                     CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlChoiceIdentifierAttribute).FullName);
  709.                     attribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(member.ChoiceIdentifier.MemberName)));
  710.                     metadata.Add(attribute);
  711.                 }
  712.                 if (member.Ignore) {
  713.                     CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlIgnoreAttribute).FullName);
  714.                     metadata.Add(attribute);
  715.                 }
  716.             }
  717.         }
  718.        
  719.         void ExportMember(CodeTypeDeclaration codeClass, MemberMapping member, string ns, CodeConstructor ctor)
  720.         {
  721.             string fieldType = member.GetTypeName(CodeProvider);
  722.             CodeMemberField field = new CodeMemberField(fieldType, member.Name);
  723.             field.Attributes = (field.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
  724.             field.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
  725.             codeClass.Members.Add(field);
  726.             AddMemberMetadata(field, field.CustomAttributes, member, ns, false, field.Comments, ctor);
  727.            
  728.             if (member.CheckSpecified) {
  729.                 field = new CodeMemberField(typeof(bool).FullName, member.Name + "Specified");
  730.                 field.Attributes = (field.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
  731.                 field.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
  732.                 CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlIgnoreAttribute).FullName);
  733.                 field.CustomAttributes.Add(attribute);
  734.                 codeClass.Members.Add(field);
  735.             }
  736.         }
  737.        
  738.         void ExportProperty(CodeTypeDeclaration codeClass, MemberMapping member, string ns, CodeIdentifiers memberScope, CodeConstructor ctor)
  739.         {
  740.             string fieldName = memberScope.AddUnique(MakeFieldName(member.Name), member);
  741.             string fieldType = member.GetTypeName(CodeProvider);
  742.             // need to create a private field
  743.             CodeMemberField field = new CodeMemberField(fieldType, fieldName);
  744.             field.Attributes = MemberAttributes.Private;
  745.             codeClass.Members.Add(field);
  746.            
  747.             CodeMemberProperty prop = CreatePropertyDeclaration(field, member.Name, fieldType);
  748.             prop.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
  749.             AddMemberMetadata(field, prop.CustomAttributes, member, ns, false, prop.Comments, ctor);
  750.             codeClass.Members.Add(prop);
  751.            
  752.             if (member.CheckSpecified) {
  753.                 field = new CodeMemberField(typeof(bool).FullName, fieldName + "Specified");
  754.                 field.Attributes = MemberAttributes.Private;
  755.                 codeClass.Members.Add(field);
  756.                
  757.                 prop = CreatePropertyDeclaration(field, member.Name + "Specified", typeof(bool).FullName);
  758.                 prop.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
  759.                 CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlIgnoreAttribute).FullName);
  760.                 prop.CustomAttributes.Add(attribute);
  761.                 codeClass.Members.Add(prop);
  762.             }
  763.         }
  764.        
  765.         void ExportText(CodeAttributeDeclarationCollection metadata, TypeDesc typeDesc, string dataType)
  766.         {
  767.             CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlTextAttribute).FullName);
  768.             if (typeDesc != null) {
  769.                 attribute.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression(typeDesc.FullName)));
  770.             }
  771.             if (dataType != null) {
  772.                 attribute.Arguments.Add(new CodeAttributeArgument("DataType", new CodePrimitiveExpression(dataType)));
  773.             }
  774.             metadata.Add(attribute);
  775.         }
  776.        
  777.         void ExportAttribute(CodeAttributeDeclarationCollection metadata, string name, string ns, TypeDesc typeDesc, TypeDesc dataTypeDesc, XmlSchemaForm form)
  778.         {
  779.             ExportMetadata(metadata, typeof(XmlAttributeAttribute), name, ns, typeDesc, dataTypeDesc, null, form, 0, -1
  780.             );
  781.         }
  782.        
  783.         void ExportArrayItem(CodeAttributeDeclarationCollection metadata, string name, string ns, TypeDesc typeDesc, TypeDesc dataTypeDesc, bool isNullable, XmlSchemaForm form, int nestingLevel)
  784.         {
  785.             ExportMetadata(metadata, typeof(XmlArrayItemAttribute), name, ns, typeDesc, dataTypeDesc, isNullable ? null : (object)false, form, nestingLevel, -1
  786.             );
  787.         }
  788.        
  789.         void ExportElement(CodeAttributeDeclarationCollection metadata, string name, string ns, TypeDesc typeDesc, TypeDesc dataTypeDesc, bool isNullable, XmlSchemaForm form, int sequenceId)
  790.         {
  791.             ExportMetadata(metadata, typeof(XmlElementAttribute), name, ns, typeDesc, dataTypeDesc, isNullable ? (object)true : null, form, 0, sequenceId
  792.             );
  793.         }
  794.        
  795.         void ExportArray(CodeAttributeDeclarationCollection metadata, string name, string ns, bool isNullable, XmlSchemaForm form, int sequenceId)
  796.         {
  797.             ExportMetadata(metadata, typeof(XmlArrayAttribute), name, ns, null, null, isNullable ? (object)true : null, form, 0, sequenceId
  798.             );
  799.         }
  800.        
  801.         void ExportMetadata(CodeAttributeDeclarationCollection metadata, Type attributeType, string name, string ns, TypeDesc typeDesc, TypeDesc dataTypeDesc, object isNullable, XmlSchemaForm form, int nestingLevel, int sequenceId
  802.         )
  803.         {
  804.             CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(attributeType.FullName);
  805.             if (name != null) {
  806.                 attribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(name)));
  807.             }
  808.             if (typeDesc != null) {
  809.                 if (isNullable != null && (bool)isNullable && typeDesc.IsValueType && !typeDesc.IsMappedType && CodeProvider.Supports(GeneratorSupport.GenericTypeReference)) {
  810.                     attribute.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression("System.Nullable`1[" + typeDesc.FullName + "]")));
  811.                     isNullable = null;
  812.                 }
  813.                 else {
  814.                     attribute.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression(typeDesc.FullName)));
  815.                 }
  816.             }
  817.             if (form != XmlSchemaForm.None) {
  818.                 attribute.Arguments.Add(new CodeAttributeArgument("Form", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(XmlSchemaForm).FullName), Enum.Format(typeof(XmlSchemaForm), form, "G"))));
  819.                
  820.                 if (form == XmlSchemaForm.Unqualified && ns != null && ns.Length == 0) {
  821.                     ns = null;
  822.                 }
  823.             }
  824.             if (ns != null) {
  825.                 attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(ns)));
  826.             }
  827.             if (dataTypeDesc != null && dataTypeDesc.IsAmbiguousDataType && !dataTypeDesc.IsMappedType) {
  828.                 attribute.Arguments.Add(new CodeAttributeArgument("DataType", new CodePrimitiveExpression(dataTypeDesc.DataType.Name)));
  829.             }
  830.             if (isNullable != null) {
  831.                 attribute.Arguments.Add(new CodeAttributeArgument("IsNullable", new CodePrimitiveExpression((bool)isNullable)));
  832.             }
  833.             if (nestingLevel > 0) {
  834.                 attribute.Arguments.Add(new CodeAttributeArgument("NestingLevel", new CodePrimitiveExpression(nestingLevel)));
  835.             }
  836.             if (sequenceId >= 0) {
  837.                 attribute.Arguments.Add(new CodeAttributeArgument("Order", new CodePrimitiveExpression(sequenceId)));
  838.             }
  839.             if (attribute.Arguments.Count == 0 && attributeType == typeof(XmlElementAttribute))
  840.                 return;
  841.             metadata.Add(attribute);
  842.         }
  843.        
  844.         void ExportAnyElement(CodeAttributeDeclarationCollection metadata, string name, string ns, int sequenceId)
  845.         {
  846.             CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlAnyElementAttribute).FullName);
  847.             if (name != null && name.Length > 0) {
  848.                 attribute.Arguments.Add(new CodeAttributeArgument("Name", new CodePrimitiveExpression(name)));
  849.             }
  850.             if (ns != null && ns.Length > 0) {
  851.                 attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(ns)));
  852.             }
  853.             if (sequenceId >= 0) {
  854.                 attribute.Arguments.Add(new CodeAttributeArgument("Order", new CodePrimitiveExpression(sequenceId)));
  855.             }
  856.             metadata.Add(attribute);
  857.         }
  858.        
  859.         void ExportAnyAttribute(CodeAttributeDeclarationCollection metadata)
  860.         {
  861.             metadata.Add(new CodeAttributeDeclaration(typeof(XmlAnyAttributeAttribute).FullName));
  862.         }
  863.        
  864.         internal override void EnsureTypesExported(Accessor[] accessors, string ns)
  865.         {
  866.             if (accessors == null)
  867.                 return;
  868.             for (int i = 0; i < accessors.Length; i++)
  869.                 EnsureTypesExported(accessors[i], ns);
  870.         }
  871.        
  872.         void EnsureTypesExported(Accessor accessor, string ns)
  873.         {
  874.             if (accessor == null)
  875.                 return;
  876.             ExportType(accessor.Mapping, ns);
  877.         }
  878.     }
  879. }

Developer Fusion