//
using System.CodeDom;
+using System.CodeDom.Compiler;
using System.Collections;
+using System.ComponentModel;
+using System.Diagnostics;
using System.Globalization;
using System.Xml.Schema;
+using Microsoft.CSharp;
+
namespace System.Xml.Serialization {
internal class MapCodeGenerator {
CodeNamespace codeNamespace;
- CodeCompileUnit codeCompileUnit;
+// CodeCompileUnit codeCompileUnit;
CodeAttributeDeclarationCollection includeMetadata;
- XmlTypeMapping exportedAnyType = null;
+ XmlTypeMapping exportedAnyType;
protected bool includeArrayTypes;
+ CodeDomProvider codeProvider;
+ CodeGenerationOptions options;
+ CodeIdentifiers identifiers;
Hashtable exportedMaps = new Hashtable ();
Hashtable includeMaps = new Hashtable ();
- public MapCodeGenerator (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit)
+ public MapCodeGenerator (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeGenerationOptions options)
{
- this.codeCompileUnit = codeCompileUnit;
+// this.codeCompileUnit = codeCompileUnit;
this.codeNamespace = codeNamespace;
+ this.options = options;
+ this.identifiers = new CodeIdentifiers ();
+ }
+
+ public MapCodeGenerator (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeDomProvider codeProvider, CodeGenerationOptions options, Hashtable mappings)
+ {
+// this.codeCompileUnit = codeCompileUnit;
+ this.codeNamespace = codeNamespace;
+ this.options = options;
+ this.codeProvider = codeProvider;
+ this.identifiers = new CodeIdentifiers ((codeProvider.LanguageOptions & LanguageOptions.CaseInsensitive) == 0);
+// this.mappings = mappings;
}
public CodeAttributeDeclarationCollection IncludeMetadata
if (includeMetadata != null) return includeMetadata;
includeMetadata = new CodeAttributeDeclarationCollection ();
- if (exportedAnyType != null)
- {
- foreach (XmlTypeMapping map in exportedAnyType.DerivedTypes)
- {
- if (IsMapExported (map) || !map.IncludeInSchema) continue;
- ExportTypeMapping (map);
- GenerateClassInclude (includeMetadata, map);
- }
- }
- else {
- foreach (XmlTypeMapping map in includeMaps.Values)
- GenerateClassInclude (includeMetadata, map);
- }
+ foreach (XmlTypeMapping map in includeMaps.Values)
+ GenerateClassInclude (includeMetadata, map);
return includeMetadata;
}
ExportMembersMapCode (dummyClass, (ClassMap)xmlMembersMapping.ObjectMap, xmlMembersMapping.Namespace, null);
}
- public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping)
+ public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping, bool isTopLevel)
{
- ExportMapCode (xmlTypeMapping);
+ ExportMapCode (xmlTypeMapping, isTopLevel);
RemoveInclude (xmlTypeMapping);
}
- void ExportMapCode (XmlTypeMapping map)
+ void ExportMapCode (XmlTypeMapping map, bool isTopLevel)
{
switch (map.TypeData.SchemaType)
{
case SchemaTypes.Enum:
- ExportEnumCode (map);
+ ExportEnumCode (map, isTopLevel);
break;
case SchemaTypes.Array:
break;
case SchemaTypes.Class:
- ExportClassCode (map);
+ ExportClassCode (map, isTopLevel);
break;
case SchemaTypes.XmlSerializable:
}
}
- void ExportClassCode (XmlTypeMapping map)
+ void ExportClassCode (XmlTypeMapping map, bool isTopLevel)
{
CodeTypeDeclaration codeClass;
-
if (IsMapExported (map)) {
- // Regenerate attributes, since things may have changed
codeClass = GetMapDeclaration (map);
if (codeClass != null) {
- codeClass.CustomAttributes = null;
- GenerateClass (map, codeClass);
- ExportDerivedTypes (map, codeClass, true);
+ // Regenerate attributes, since things may have changed
+ codeClass.CustomAttributes.Clear ();
+ AddClassAttributes (codeClass);
+ GenerateClass (map, codeClass, isTopLevel);
+ ExportDerivedTypeAttributes (map, codeClass);
}
return;
}
{
exportedAnyType = map;
SetMapExported (map, null);
+ foreach (XmlTypeMapping dmap in exportedAnyType.DerivedTypes) {
+ if (IsMapExported (dmap) || !dmap.IncludeInSchema) continue;
+ ExportTypeMapping (dmap, false);
+ AddInclude (dmap);
+ }
return;
}
codeClass = new CodeTypeDeclaration (map.TypeData.TypeName);
SetMapExported (map, codeClass);
-
+
AddCodeType (codeClass, map.Documentation);
codeClass.Attributes = MemberAttributes.Public;
- GenerateClass (map, codeClass);
+ codeClass.IsPartial = CodeProvider.Supports(GeneratorSupport.PartialTypes);
+ AddClassAttributes (codeClass);
+ GenerateClass (map, codeClass, isTopLevel);
+ ExportDerivedTypeAttributes (map, codeClass);
+
ExportMembersMapCode (codeClass, (ClassMap)map.ObjectMap, map.XmlTypeNamespace, map.BaseMap);
if (map.BaseMap != null && map.BaseMap.TypeData.SchemaType != SchemaTypes.XmlNode)
{
- CodeTypeReference ctr = new CodeTypeReference (map.BaseMap.TypeData.FullTypeName);
+ CodeTypeReference ctr = GetDomType (map.BaseMap.TypeData, false);
codeClass.BaseTypes.Add (ctr);
if (map.BaseMap.IncludeInSchema) {
- ExportMapCode (map.BaseMap);
+ ExportMapCode (map.BaseMap, false);
AddInclude (map.BaseMap);
}
}
-
- ExportDerivedTypes (map, codeClass, false);
+ ExportDerivedTypes (map, codeClass);
}
- void ExportDerivedTypes (XmlTypeMapping map, CodeTypeDeclaration codeClass, bool onlyIncludes)
+ void ExportDerivedTypeAttributes (XmlTypeMapping map, CodeTypeDeclaration codeClass)
+ {
+ foreach (XmlTypeMapping tm in map.DerivedTypes)
+ {
+ GenerateClassInclude (codeClass.CustomAttributes, tm);
+ ExportDerivedTypeAttributes (tm, codeClass);
+ }
+ }
+
+ void ExportDerivedTypes (XmlTypeMapping map, CodeTypeDeclaration codeClass)
{
foreach (XmlTypeMapping tm in map.DerivedTypes)
{
if (codeClass.CustomAttributes == null)
codeClass.CustomAttributes = new CodeAttributeDeclarationCollection ();
- GenerateClassInclude (codeClass.CustomAttributes, tm);
- if (!onlyIncludes && tm.IncludeInSchema) ExportMapCode (tm);
- ExportDerivedTypes (tm, codeClass, onlyIncludes);
+ ExportMapCode (tm, false);
+ ExportDerivedTypes (tm, codeClass);
}
}
void ExportMembersMapCode (CodeTypeDeclaration codeClass, ClassMap map, string defaultNamespace, XmlTypeMapping baseMap)
{
+ ICollection attributes = map.AttributeMembers;
ICollection members = map.ElementMembers;
+
+ // collect names
+ if (attributes != null)
+ foreach (XmlTypeMapMemberAttribute attr in attributes)
+ identifiers.AddUnique (attr.Name, attr);
+ if (members != null)
+ foreach (XmlTypeMapMemberElement member in members)
+ identifiers.AddUnique (member.Name, member);
+
+ // Write attributes
+
+ if (attributes != null) {
+ foreach (XmlTypeMapMemberAttribute attr in attributes) {
+ if (baseMap != null && DefinedInBaseMap (baseMap, attr)) continue;
+ AddAttributeFieldMember (codeClass, attr, defaultNamespace);
+ }
+ }
+
+ members = map.ElementMembers;
if (members != null)
{
}
}
- // Write attributes
-
- ICollection attributes = map.AttributeMembers;
- if (attributes != null)
- {
- foreach (XmlTypeMapMemberAttribute attr in attributes) {
- if (baseMap != null && DefinedInBaseMap (baseMap, attr)) continue;
- AddAttributeFieldMember (codeClass, attr, defaultNamespace);
- }
- }
-
XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
if (anyAttrMember != null)
{
- CodeMemberField codeField = new CodeMemberField (GetDomType (anyAttrMember.TypeData), anyAttrMember.Name);
+ CodeTypeMember codeField = CreateFieldMember (codeClass, anyAttrMember.TypeData, anyAttrMember.Name);
AddComments (codeField, anyAttrMember.Documentation);
codeField.Attributes = MemberAttributes.Public;
GenerateAnyAttribute (codeField);
- codeClass.Members.Add (codeField);
}
}
+
+ CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, Type type, string name)
+ {
+ return CreateFieldMember (codeClass, new CodeTypeReference(type), name, System.DBNull.Value, null, null);
+ }
- CodeMemberField CreateFieldMember (XmlTypeMapMember member)
+ CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, TypeData type, string name)
{
- CodeMemberField codeField = new CodeMemberField (GetDomType (member.TypeData), member.Name);
- codeField.Attributes = MemberAttributes.Public;
- AddComments (codeField, member.Documentation);
+ return CreateFieldMember (codeClass, GetDomType (type, false), name, System.DBNull.Value, null, null);
+ }
- if (member.DefaultValue != System.DBNull.Value)
- GenerateDefaultAttribute (codeField, member.TypeData, member.DefaultValue);
+ CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMember member)
+ {
+ return CreateFieldMember (codeClass, GetDomType (member.TypeData, member.RequiresNullable), member.Name, member.DefaultValue, member.TypeData, member.Documentation);
+ }
+
+ CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, CodeTypeReference type, string name, object defaultValue, TypeData defaultType, string documentation)
+ {
+ CodeMemberField codeField = null;
+ CodeTypeMember codeProp = null;
- return codeField;
+ if ((options & CodeGenerationOptions.GenerateProperties) > 0) {
+ string field = identifiers.AddUnique (CodeIdentifier.MakeCamel (name + "Field"), name);
+ codeField = new CodeMemberField (type, field);
+ codeField.Attributes = MemberAttributes.Private;
+ codeClass.Members.Add (codeField);
+
+ CodeMemberProperty prop = new CodeMemberProperty ();
+ prop.Name = name;
+ prop.Type = type;
+ prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+ codeProp = prop;
+ prop.HasGet = prop.HasSet = true;
+
+ CodeExpression ce = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), field);
+ prop.SetStatements.Add (new CodeAssignStatement (ce, new CodePropertySetValueReferenceExpression()));
+ prop.GetStatements.Add (new CodeMethodReturnStatement (ce));
+ }
+ else {
+ codeField = new CodeMemberField (type, name);
+ codeField.Attributes = MemberAttributes.Public;
+ codeProp = codeField;
+ }
+
+ if (defaultValue != System.DBNull.Value)
+ GenerateDefaultAttribute (codeField, codeProp, defaultType, defaultValue);
+
+ AddComments (codeProp, documentation);
+ codeClass.Members.Add (codeProp);
+ return codeProp;
}
void AddAttributeFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberAttribute attinfo, string defaultNamespace)
{
- CodeMemberField codeField = CreateFieldMember (attinfo);
- codeClass.Members.Add (codeField);
+ CodeTypeMember codeField = CreateFieldMember (codeClass, attinfo);
CodeAttributeDeclarationCollection attributes = codeField.CustomAttributes;
if (attributes == null) attributes = new CodeAttributeDeclarationCollection ();
if (attributes.Count > 0) codeField.CustomAttributes = attributes;
if (attinfo.MappedType != null) {
- ExportMapCode (attinfo.MappedType);
+ ExportMapCode (attinfo.MappedType, false);
RemoveInclude (attinfo.MappedType);
}
if (attinfo.TypeData.IsValueType && attinfo.IsOptionalValueType)
{
- codeField = new CodeMemberField (typeof(bool), attinfo.Name + "Specified");
+ codeField = CreateFieldMember (codeClass, typeof(bool), identifiers.MakeUnique (attinfo.Name + "Specified"));
codeField.Attributes = MemberAttributes.Public;
- codeClass.Members.Add (codeField);
GenerateSpecifierMember (codeField);
}
}
void AddElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)
{
- CodeMemberField codeField = CreateFieldMember (member);
- codeClass.Members.Add (codeField);
+ CodeTypeMember codeField = CreateFieldMember (codeClass, member);
CodeAttributeDeclarationCollection attributes = codeField.CustomAttributes;
if (attributes == null) attributes = new CodeAttributeDeclarationCollection ();
if (member.TypeData.IsValueType && member.IsOptionalValueType)
{
- codeField = new CodeMemberField (typeof(bool), member.Name + "Specified");
+ codeField = CreateFieldMember (codeClass, typeof(bool), identifiers.MakeUnique (member.Name + "Specified"));
codeField.Attributes = MemberAttributes.Public;
- codeClass.Members.Add (codeField);
GenerateSpecifierMember (codeField);
}
}
foreach (XmlTypeMapElementInfo einfo in member.ElementInfo)
{
- if (ExportExtraElementAttributes (attributes, einfo, defaultNamespace, defaultType))
- continue;
-
- GenerateElementInfoMember (attributes, member, einfo, defaultType, defaultNamespace, addAlwaysAttr, forceUseMemberName);
if (einfo.MappedType != null) {
- ExportMapCode (einfo.MappedType);
+ ExportMapCode (einfo.MappedType, false);
RemoveInclude (einfo.MappedType);
}
+
+ if (ExportExtraElementAttributes (attributes, einfo, defaultNamespace, defaultType))
+ continue;
+
+ GenerateElementInfoMember (attributes, member, einfo, defaultType, defaultNamespace, addAlwaysAttr, forceUseMemberName | addAlwaysAttr);
}
GenerateElementMember (attributes, member);
void AddAnyElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)
{
- CodeMemberField codeField = CreateFieldMember (member);
- codeClass.Members.Add (codeField);
+ CodeTypeMember codeField = CreateFieldMember (codeClass, member);
CodeAttributeDeclarationCollection attributes = new CodeAttributeDeclarationCollection ();
foreach (XmlTypeMapElementInfo einfo in member.ElementInfo)
void AddArrayElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberList member, string defaultNamespace)
{
- CodeMemberField codeField = new CodeMemberField (GetDomType (member.TypeData), member.Name);
- AddComments (codeField, member.Documentation);
- codeField.Attributes = MemberAttributes.Public;
- codeClass.Members.Add (codeField);
-
+ CodeTypeMember codeField = CreateFieldMember (codeClass, member.TypeData, member.Name);
+
CodeAttributeDeclarationCollection attributes = new CodeAttributeDeclarationCollection ();
AddArrayAttributes (attributes, member, defaultNamespace, false);
if (ainfo.MappedType != null) {
if (!IsMapExported (ainfo.MappedType) && includeArrayTypes)
AddInclude (ainfo.MappedType);
- ExportMapCode (ainfo.MappedType);
+ ExportMapCode (ainfo.MappedType, false);
}
}
if (ainfo.MappedType != null) {
if (!IsMapExported (ainfo.MappedType) && includeArrayTypes)
AddInclude (ainfo.MappedType);
- ExportMapCode (ainfo.MappedType);
+ ExportMapCode (ainfo.MappedType, false);
}
}
}
return false;
}
- void ExportEnumCode (XmlTypeMapping map)
+ void ExportEnumCode (XmlTypeMapping map, bool isTopLevel)
{
if (IsMapExported (map)) return;
codeEnum.IsEnum = true;
AddCodeType (codeEnum, map.Documentation);
- GenerateEnum (map, codeEnum);
EnumMap emap = (EnumMap) map.ObjectMap;
-
if (emap.IsFlags)
- codeEnum.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Flags"));
+ codeEnum.CustomAttributes.Add (new CodeAttributeDeclaration ("System.FlagsAttribute"));
+
+ CodeAttributeDeclaration generatedCodeAttribute = new CodeAttributeDeclaration (
+ new CodeTypeReference (typeof(GeneratedCodeAttribute)));
+ generatedCodeAttribute.Arguments.Add (new CodeAttributeArgument (
+ new CodePrimitiveExpression ("System.Xml")));
+ generatedCodeAttribute.Arguments.Add (new CodeAttributeArgument (
+ new CodePrimitiveExpression (Consts.FxFileVersion)));
+ codeEnum.CustomAttributes.Add (generatedCodeAttribute);
+ codeEnum.CustomAttributes.Add (new CodeAttributeDeclaration (
+ new CodeTypeReference (typeof (SerializableAttribute))));
+
+ GenerateEnum (map, codeEnum, isTopLevel);
+
int flag = 1;
foreach (EnumMap.EnumMapMember emem in emap.Members)
{
AddComments (type, comments);
codeNamespace.Types.Add (type);
}
+
+ void AddClassAttributes (CodeTypeDeclaration codeClass)
+ {
+ CodeAttributeDeclaration generatedCodeAttribute = new CodeAttributeDeclaration (
+ new CodeTypeReference (typeof (GeneratedCodeAttribute)));
+ generatedCodeAttribute.Arguments.Add (new CodeAttributeArgument (
+ new CodePrimitiveExpression ("System.Xml")));
+ generatedCodeAttribute.Arguments.Add (new CodeAttributeArgument (
+ new CodePrimitiveExpression (Consts.FxFileVersion)));
+ codeClass.CustomAttributes.Add (generatedCodeAttribute);
+
+ codeClass.CustomAttributes.Add (new CodeAttributeDeclaration (
+ new CodeTypeReference (typeof (SerializableAttribute))));
+ codeClass.CustomAttributes.Add (new CodeAttributeDeclaration (
+ new CodeTypeReference (typeof (DebuggerStepThroughAttribute))));
+
+ CodeAttributeDeclaration designerCategoryAttribute = new CodeAttributeDeclaration (
+ new CodeTypeReference (typeof (DesignerCategoryAttribute)));
+ designerCategoryAttribute.Arguments.Add (new CodeAttributeArgument (
+ new CodePrimitiveExpression ("code")));
+ codeClass.CustomAttributes.Add (designerCategoryAttribute);
+ }
- CodeTypeReference GetDomType (TypeData data)
+ CodeTypeReference GetDomType (TypeData data, bool requiresNullable)
{
+ if (data.IsValueType && (data.IsNullable || requiresNullable))
+ return new CodeTypeReference ("System.Nullable", new CodeTypeReference (data.FullTypeName));
if (data.SchemaType == SchemaTypes.Array)
- return new CodeTypeReference (GetDomType (data.ListItemTypeData),1);
+ return new CodeTypeReference (GetDomType (data.ListItemTypeData, false),1);
else
return new CodeTypeReference (data.FullTypeName);
}
#endregion
-
+
+ #region Private Properties
+
+ private CodeDomProvider CodeProvider {
+ get {
+ if (codeProvider == null) {
+ codeProvider = new CSharpCodeProvider ();
+ }
+ return codeProvider;
+ }
+ }
+
+ #endregion
+
#region Overridable methods
-
- protected virtual void GenerateClass (XmlTypeMapping map, CodeTypeDeclaration codeClass)
+
+ protected virtual void GenerateClass (XmlTypeMapping map, CodeTypeDeclaration codeClass, bool isTopLevel)
{
}
{
}
- protected virtual void GenerateAnyAttribute (CodeMemberField codeField)
+ protected virtual void GenerateAnyAttribute (CodeTypeMember codeField)
{
}
- protected virtual void GenerateDefaultAttribute (CodeMemberField codeField, TypeData typeData, object defaultValue)
+ protected virtual void GenerateDefaultAttribute (CodeMemberField internalField, CodeTypeMember externalField, TypeData typeData, object defaultValue)
{
if (typeData.Type == null)
{
throw new InvalidOperationException ("Type " + typeData.TypeName + " not supported");
IFormattable defaultValueFormattable = defaultValue as IFormattable;
- CodeFieldReferenceExpression fref = new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (typeData.FullTypeName), defaultValueFormattable != null ? defaultValueFormattable.ToString(null, CultureInfo.InvariantCulture) : defaultValue.ToString ());
+ CodeFieldReferenceExpression fref = new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (GetDomType (typeData, false)), defaultValueFormattable != null ? defaultValueFormattable.ToString(null, CultureInfo.InvariantCulture) : defaultValue.ToString ());
CodeAttributeArgument arg = new CodeAttributeArgument (fref);
- AddCustomAttribute (codeField, "System.ComponentModel.DefaultValue", arg);
- codeField.InitExpression = fref;
+ AddCustomAttribute (externalField, "System.ComponentModel.DefaultValue", arg);
+ //internalField.InitExpression = fref;
}
else
{
- AddCustomAttribute (codeField, "System.ComponentModel.DefaultValue", GetArg (defaultValue));
- codeField.InitExpression = new CodePrimitiveExpression (defaultValue);
+ defaultValue = defaultValue is decimal ? (object) ('"' + ((decimal) defaultValue).ToString (CultureInfo.InvariantCulture) + '"') : defaultValue;
+ AddCustomAttribute (externalField, "System.ComponentModel.DefaultValue", GetArg (defaultValue));
+ //internalField.InitExpression = new CodePrimitiveExpression (defaultValue);
}
}
protected virtual void GenerateUnnamedAnyElementAttribute (CodeAttributeDeclarationCollection attributes, XmlTypeMapElementInfo einfo, string defaultNamespace)
{
}
-
- protected virtual void GenerateEnum (XmlTypeMapping map, CodeTypeDeclaration codeEnum)
+
+ protected virtual void GenerateEnum (XmlTypeMapping map, CodeTypeDeclaration codeEnum, bool isTopLevel)
{
- }
+ }
protected virtual void GenerateEnumItem (CodeMemberField codeField, EnumMap.EnumMapMember emem)
{
}
- protected virtual void GenerateSpecifierMember (CodeMemberField codeField)
+ protected virtual void GenerateSpecifierMember (CodeTypeMember codeField)
{
}