2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.XML / System.Xml.Serialization / MapCodeGenerator.cs
blobafd732cebbef958e7bfc52c4a331c51d17d34218
1 //
2 // System.Xml.Serialization.MapCodeGenerator
3 //
4 // Author:
5 // Lluis Sanchez Gual (lluis@ximian.com)
6 //
7 // Copyright (C) Ximian, Inc., 2003
8 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.CodeDom;
32 using System.CodeDom.Compiler;
33 using System.Collections;
34 #if NET_2_0
35 using System.ComponentModel;
36 using System.Diagnostics;
37 #endif
38 using System.Globalization;
39 using System.Xml.Schema;
41 using Microsoft.CSharp;
43 namespace System.Xml.Serialization {
44 internal class MapCodeGenerator {
46 CodeNamespace codeNamespace;
47 CodeCompileUnit codeCompileUnit;
48 CodeAttributeDeclarationCollection includeMetadata;
49 XmlTypeMapping exportedAnyType = null;
50 protected bool includeArrayTypes;
51 #if NET_2_0
52 CodeDomProvider codeProvider;
53 #endif
54 CodeGenerationOptions options;
55 CodeIdentifiers identifiers;
57 Hashtable exportedMaps = new Hashtable ();
58 Hashtable includeMaps = new Hashtable ();
60 public MapCodeGenerator (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeGenerationOptions options)
62 this.codeCompileUnit = codeCompileUnit;
63 this.codeNamespace = codeNamespace;
64 this.options = options;
65 this.identifiers = new CodeIdentifiers ();
68 public MapCodeGenerator (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeDomProvider codeProvider, CodeGenerationOptions options, Hashtable mappings)
70 this.codeCompileUnit = codeCompileUnit;
71 this.codeNamespace = codeNamespace;
72 this.options = options;
73 #if NET_2_0
74 this.codeProvider = codeProvider;
75 this.identifiers = new CodeIdentifiers ((codeProvider.LanguageOptions & LanguageOptions.CaseInsensitive) == 0);
76 #else
77 this.identifiers = new CodeIdentifiers ();
78 #endif
79 // this.mappings = mappings;
82 public CodeAttributeDeclarationCollection IncludeMetadata
84 get
86 if (includeMetadata != null) return includeMetadata;
87 includeMetadata = new CodeAttributeDeclarationCollection ();
89 foreach (XmlTypeMapping map in includeMaps.Values)
90 GenerateClassInclude (includeMetadata, map);
92 return includeMetadata;
96 #region Code generation methods
98 public void ExportMembersMapping (XmlMembersMapping xmlMembersMapping)
100 CodeTypeDeclaration dummyClass = new CodeTypeDeclaration ();
101 ExportMembersMapCode (dummyClass, (ClassMap)xmlMembersMapping.ObjectMap, xmlMembersMapping.Namespace, null);
104 public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping, bool isTopLevel)
106 ExportMapCode (xmlTypeMapping, isTopLevel);
107 RemoveInclude (xmlTypeMapping);
110 void ExportMapCode (XmlTypeMapping map, bool isTopLevel)
112 switch (map.TypeData.SchemaType)
114 case SchemaTypes.Enum:
115 ExportEnumCode (map, isTopLevel);
116 break;
118 case SchemaTypes.Array:
119 ExportArrayCode (map);
120 break;
122 case SchemaTypes.Class:
123 ExportClassCode (map, isTopLevel);
124 break;
126 case SchemaTypes.XmlSerializable:
127 case SchemaTypes.XmlNode:
128 case SchemaTypes.Primitive:
129 // Ignore
130 break;
134 void ExportClassCode (XmlTypeMapping map, bool isTopLevel)
136 CodeTypeDeclaration codeClass;
137 if (IsMapExported (map)) {
138 codeClass = GetMapDeclaration (map);
139 if (codeClass != null) {
140 // Regenerate attributes, since things may have changed
141 codeClass.CustomAttributes.Clear ();
142 #if NET_2_0
143 AddClassAttributes (codeClass);
144 #endif
145 GenerateClass (map, codeClass, isTopLevel);
146 ExportDerivedTypeAttributes (map, codeClass);
148 return;
151 if (map.TypeData.Type == typeof(object))
153 exportedAnyType = map;
154 SetMapExported (map, null);
155 foreach (XmlTypeMapping dmap in exportedAnyType.DerivedTypes) {
156 if (IsMapExported (dmap) || !dmap.IncludeInSchema) continue;
157 ExportTypeMapping (dmap, false);
158 AddInclude (dmap);
160 return;
163 codeClass = new CodeTypeDeclaration (map.TypeData.TypeName);
164 SetMapExported (map, codeClass);
166 AddCodeType (codeClass, map.Documentation);
167 codeClass.Attributes = MemberAttributes.Public;
169 #if NET_2_0
170 codeClass.IsPartial = CodeProvider.Supports(GeneratorSupport.PartialTypes);
171 AddClassAttributes (codeClass);
172 #endif
174 GenerateClass (map, codeClass, isTopLevel);
175 ExportDerivedTypeAttributes (map, codeClass);
177 ExportMembersMapCode (codeClass, (ClassMap)map.ObjectMap, map.XmlTypeNamespace, map.BaseMap);
179 if (map.BaseMap != null && map.BaseMap.TypeData.SchemaType != SchemaTypes.XmlNode)
181 CodeTypeReference ctr = GetDomType (map.BaseMap.TypeData, false);
182 codeClass.BaseTypes.Add (ctr);
183 if (map.BaseMap.IncludeInSchema) {
184 ExportMapCode (map.BaseMap, false);
185 AddInclude (map.BaseMap);
188 ExportDerivedTypes (map, codeClass);
191 void ExportDerivedTypeAttributes (XmlTypeMapping map, CodeTypeDeclaration codeClass)
193 foreach (XmlTypeMapping tm in map.DerivedTypes)
195 GenerateClassInclude (codeClass.CustomAttributes, tm);
196 ExportDerivedTypeAttributes (tm, codeClass);
200 void ExportDerivedTypes (XmlTypeMapping map, CodeTypeDeclaration codeClass)
202 foreach (XmlTypeMapping tm in map.DerivedTypes)
204 if (codeClass.CustomAttributes == null)
205 codeClass.CustomAttributes = new CodeAttributeDeclarationCollection ();
207 ExportMapCode (tm, false);
208 ExportDerivedTypes (tm, codeClass);
212 void ExportMembersMapCode (CodeTypeDeclaration codeClass, ClassMap map, string defaultNamespace, XmlTypeMapping baseMap)
214 ICollection attributes = map.AttributeMembers;
215 ICollection members = map.ElementMembers;
217 // collect names
218 if (attributes != null)
219 foreach (XmlTypeMapMemberAttribute attr in attributes)
220 identifiers.AddUnique (attr.Name, attr);
221 if (members != null)
222 foreach (XmlTypeMapMemberElement member in members)
223 identifiers.AddUnique (member.Name, member);
225 // Write attributes
227 if (attributes != null) {
228 foreach (XmlTypeMapMemberAttribute attr in attributes) {
229 if (baseMap != null && DefinedInBaseMap (baseMap, attr)) continue;
230 AddAttributeFieldMember (codeClass, attr, defaultNamespace);
234 members = map.ElementMembers;
236 if (members != null)
238 foreach (XmlTypeMapMemberElement member in members)
240 if (baseMap != null && DefinedInBaseMap (baseMap, member)) continue;
242 Type memType = member.GetType();
243 if (memType == typeof(XmlTypeMapMemberList))
245 AddArrayElementFieldMember (codeClass, (XmlTypeMapMemberList) member, defaultNamespace);
247 else if (memType == typeof(XmlTypeMapMemberFlatList))
249 AddElementFieldMember (codeClass, member, defaultNamespace);
251 else if (memType == typeof(XmlTypeMapMemberAnyElement))
253 AddAnyElementFieldMember (codeClass, member, defaultNamespace);
255 else if (memType == typeof(XmlTypeMapMemberElement))
257 AddElementFieldMember (codeClass, member, defaultNamespace);
259 else
261 throw new InvalidOperationException ("Member type " + memType + " not supported");
266 XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
267 if (anyAttrMember != null)
269 CodeTypeMember codeField = CreateFieldMember (codeClass, anyAttrMember.TypeData, anyAttrMember.Name);
270 AddComments (codeField, anyAttrMember.Documentation);
271 codeField.Attributes = MemberAttributes.Public;
272 GenerateAnyAttribute (codeField);
276 CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, Type type, string name)
278 return CreateFieldMember (codeClass, new CodeTypeReference(type), name, System.DBNull.Value, null, null);
281 CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, TypeData type, string name)
283 return CreateFieldMember (codeClass, GetDomType (type, false), name, System.DBNull.Value, null, null);
286 CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMember member)
288 return CreateFieldMember (codeClass, GetDomType (member.TypeData, member.RequiresNullable), member.Name, member.DefaultValue, member.TypeData, member.Documentation);
291 CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, CodeTypeReference type, string name, object defaultValue, TypeData defaultType, string documentation)
293 CodeMemberField codeField = null;
294 CodeTypeMember codeProp = null;
296 if ((options & CodeGenerationOptions.GenerateProperties) > 0) {
297 string field = identifiers.AddUnique (CodeIdentifier.MakeCamel (name + "Field"), name);
298 codeField = new CodeMemberField (type, field);
299 codeField.Attributes = MemberAttributes.Private;
300 codeClass.Members.Add (codeField);
302 CodeMemberProperty prop = new CodeMemberProperty ();
303 prop.Name = name;
304 prop.Type = type;
305 prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
306 codeProp = prop;
307 prop.HasGet = prop.HasSet = true;
309 CodeExpression ce = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), field);
310 prop.SetStatements.Add (new CodeAssignStatement (ce, new CodePropertySetValueReferenceExpression()));
311 prop.GetStatements.Add (new CodeMethodReturnStatement (ce));
313 else {
314 codeField = new CodeMemberField (type, name);
315 codeField.Attributes = MemberAttributes.Public;
316 codeProp = codeField;
319 if (defaultValue != System.DBNull.Value)
320 GenerateDefaultAttribute (codeField, codeProp, defaultType, defaultValue);
322 AddComments (codeProp, documentation);
323 codeClass.Members.Add (codeProp);
324 return codeProp;
327 void AddAttributeFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberAttribute attinfo, string defaultNamespace)
329 CodeTypeMember codeField = CreateFieldMember (codeClass, attinfo);
331 CodeAttributeDeclarationCollection attributes = codeField.CustomAttributes;
332 if (attributes == null) attributes = new CodeAttributeDeclarationCollection ();
334 GenerateAttributeMember (attributes, attinfo, defaultNamespace, false);
335 if (attributes.Count > 0) codeField.CustomAttributes = attributes;
337 if (attinfo.MappedType != null) {
338 ExportMapCode (attinfo.MappedType, false);
339 RemoveInclude (attinfo.MappedType);
342 if (attinfo.TypeData.IsValueType && attinfo.IsOptionalValueType)
344 codeField = CreateFieldMember (codeClass, typeof(bool), identifiers.MakeUnique (attinfo.Name + "Specified"));
345 codeField.Attributes = MemberAttributes.Public;
346 GenerateSpecifierMember (codeField);
350 public void AddAttributeMemberAttributes (XmlTypeMapMemberAttribute attinfo, string defaultNamespace, CodeAttributeDeclarationCollection attributes, bool forceUseMemberName)
352 GenerateAttributeMember (attributes, attinfo, defaultNamespace, forceUseMemberName);
355 void AddElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)
357 CodeTypeMember codeField = CreateFieldMember (codeClass, member);
359 CodeAttributeDeclarationCollection attributes = codeField.CustomAttributes;
360 if (attributes == null) attributes = new CodeAttributeDeclarationCollection ();
362 AddElementMemberAttributes (member, defaultNamespace, attributes, false);
363 if (attributes.Count > 0) codeField.CustomAttributes = attributes;
365 if (member.TypeData.IsValueType && member.IsOptionalValueType)
367 codeField = CreateFieldMember (codeClass, typeof(bool), identifiers.MakeUnique (member.Name + "Specified"));
368 codeField.Attributes = MemberAttributes.Public;
369 GenerateSpecifierMember (codeField);
373 public void AddElementMemberAttributes (XmlTypeMapMemberElement member, string defaultNamespace, CodeAttributeDeclarationCollection attributes, bool forceUseMemberName)
375 TypeData defaultType = member.TypeData;
376 bool addAlwaysAttr = false;
378 if (member is XmlTypeMapMemberFlatList)
380 defaultType = defaultType.ListItemTypeData;
381 addAlwaysAttr = true;
384 foreach (XmlTypeMapElementInfo einfo in member.ElementInfo)
386 if (einfo.MappedType != null) {
387 ExportMapCode (einfo.MappedType, false);
388 RemoveInclude (einfo.MappedType);
391 if (ExportExtraElementAttributes (attributes, einfo, defaultNamespace, defaultType))
392 continue;
394 GenerateElementInfoMember (attributes, member, einfo, defaultType, defaultNamespace, addAlwaysAttr, forceUseMemberName | addAlwaysAttr);
397 GenerateElementMember (attributes, member);
400 void AddAnyElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)
402 CodeTypeMember codeField = CreateFieldMember (codeClass, member);
404 CodeAttributeDeclarationCollection attributes = new CodeAttributeDeclarationCollection ();
405 foreach (XmlTypeMapElementInfo einfo in member.ElementInfo)
406 ExportExtraElementAttributes (attributes, einfo, defaultNamespace, einfo.TypeData);
408 if (attributes.Count > 0) codeField.CustomAttributes = attributes;
411 bool DefinedInBaseMap (XmlTypeMapping map, XmlTypeMapMember member)
413 if (((ClassMap)map.ObjectMap).FindMember (member.Name) != null)
414 return true;
415 else if (map.BaseMap != null)
416 return DefinedInBaseMap (map.BaseMap, member);
417 else
418 return false;
421 void AddArrayElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberList member, string defaultNamespace)
423 CodeTypeMember codeField = CreateFieldMember (codeClass, member.TypeData, member.Name);
425 CodeAttributeDeclarationCollection attributes = new CodeAttributeDeclarationCollection ();
426 AddArrayAttributes (attributes, member, defaultNamespace, false);
428 ListMap listMap = (ListMap) member.ListTypeMapping.ObjectMap;
429 AddArrayItemAttributes (attributes, listMap, member.TypeData.ListItemTypeData, defaultNamespace, 0);
431 if (attributes.Count > 0) codeField.CustomAttributes = attributes;
434 public void AddArrayAttributes (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberElement member, string defaultNamespace, bool forceUseMemberName)
436 GenerateArrayElement (attributes, member, defaultNamespace, forceUseMemberName);
439 public void AddArrayItemAttributes (CodeAttributeDeclarationCollection attributes, ListMap listMap, TypeData type, string defaultNamespace, int nestingLevel)
441 foreach (XmlTypeMapElementInfo ainfo in listMap.ItemInfo)
443 string defaultName;
444 if (ainfo.MappedType != null) defaultName = ainfo.MappedType.ElementName;
445 else defaultName = ainfo.TypeData.XmlType;
447 GenerateArrayItemAttributes (attributes, listMap, type, ainfo, defaultName, defaultNamespace, nestingLevel);
448 if (ainfo.MappedType != null) {
449 if (!IsMapExported (ainfo.MappedType) && includeArrayTypes)
450 AddInclude (ainfo.MappedType);
451 ExportMapCode (ainfo.MappedType, false);
455 if (listMap.IsMultiArray)
457 XmlTypeMapping nmap = listMap.NestedArrayMapping;
458 AddArrayItemAttributes (attributes, (ListMap) nmap.ObjectMap, nmap.TypeData.ListItemTypeData, defaultNamespace, nestingLevel + 1);
462 void ExportArrayCode (XmlTypeMapping map)
464 ListMap listMap = (ListMap) map.ObjectMap;
465 foreach (XmlTypeMapElementInfo ainfo in listMap.ItemInfo)
467 if (ainfo.MappedType != null) {
468 if (!IsMapExported (ainfo.MappedType) && includeArrayTypes)
469 AddInclude (ainfo.MappedType);
470 ExportMapCode (ainfo.MappedType, false);
475 bool ExportExtraElementAttributes (CodeAttributeDeclarationCollection attributes, XmlTypeMapElementInfo einfo, string defaultNamespace, TypeData defaultType)
477 if (einfo.IsTextElement) {
478 GenerateTextElementAttribute (attributes, einfo, defaultType);
479 return true;
481 else if (einfo.IsUnnamedAnyElement) {
482 GenerateUnnamedAnyElementAttribute (attributes, einfo, defaultNamespace);
483 return true;
485 return false;
488 void ExportEnumCode (XmlTypeMapping map, bool isTopLevel)
490 if (IsMapExported (map)) return;
492 CodeTypeDeclaration codeEnum = new CodeTypeDeclaration (map.TypeData.TypeName);
493 SetMapExported (map, codeEnum);
495 codeEnum.Attributes = MemberAttributes.Public;
496 codeEnum.IsEnum = true;
497 AddCodeType (codeEnum, map.Documentation);
499 EnumMap emap = (EnumMap) map.ObjectMap;
500 if (emap.IsFlags)
501 codeEnum.CustomAttributes.Add (new CodeAttributeDeclaration ("System.FlagsAttribute"));
503 #if NET_2_0
504 CodeAttributeDeclaration generatedCodeAttribute = new CodeAttributeDeclaration (
505 new CodeTypeReference (typeof(GeneratedCodeAttribute)));
506 generatedCodeAttribute.Arguments.Add (new CodeAttributeArgument (
507 new CodePrimitiveExpression ("System.Xml")));
508 generatedCodeAttribute.Arguments.Add (new CodeAttributeArgument (
509 new CodePrimitiveExpression (Consts.FxFileVersion)));
510 codeEnum.CustomAttributes.Add (generatedCodeAttribute);
512 codeEnum.CustomAttributes.Add (new CodeAttributeDeclaration (
513 new CodeTypeReference (typeof (SerializableAttribute))));
514 #endif
516 GenerateEnum (map, codeEnum, isTopLevel);
518 int flag = 1;
519 foreach (EnumMap.EnumMapMember emem in emap.Members)
521 CodeMemberField codeField = new CodeMemberField ("", emem.EnumName);
522 if (emap.IsFlags) {
523 codeField.InitExpression = new CodePrimitiveExpression (flag);
524 flag *= 2;
527 AddComments (codeField, emem.Documentation);
529 GenerateEnumItem (codeField, emem);
530 codeEnum.Members.Add (codeField);
534 void AddInclude (XmlTypeMapping map)
536 if (!includeMaps.ContainsKey (map.TypeData.FullTypeName))
537 includeMaps [map.TypeData.FullTypeName] = map;
540 void RemoveInclude (XmlTypeMapping map)
542 includeMaps.Remove (map.TypeData.FullTypeName);
545 #endregion
547 #region Helper methods
549 bool IsMapExported (XmlTypeMapping map)
551 if (exportedMaps.Contains (map.TypeData.FullTypeName)) return true;
552 return false;
555 void SetMapExported (XmlTypeMapping map, CodeTypeDeclaration declaration)
557 exportedMaps.Add (map.TypeData.FullTypeName, declaration);
560 CodeTypeDeclaration GetMapDeclaration (XmlTypeMapping map)
562 return exportedMaps [map.TypeData.FullTypeName] as CodeTypeDeclaration;
565 public static void AddCustomAttribute (CodeTypeMember ctm, CodeAttributeDeclaration att, bool addIfNoParams)
567 if (att.Arguments.Count == 0 && !addIfNoParams) return;
569 if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
570 ctm.CustomAttributes.Add (att);
573 public static void AddCustomAttribute (CodeTypeMember ctm, string name, params CodeAttributeArgument[] args)
575 if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
576 ctm.CustomAttributes.Add (new CodeAttributeDeclaration (name, args));
579 public static CodeAttributeArgument GetArg (string name, object value)
581 return new CodeAttributeArgument (name, new CodePrimitiveExpression(value));
584 public static CodeAttributeArgument GetArg (object value)
586 return new CodeAttributeArgument (new CodePrimitiveExpression(value));
589 public static CodeAttributeArgument GetTypeArg (string name, string typeName)
591 return new CodeAttributeArgument (name, new CodeTypeOfExpression(typeName));
594 public static CodeAttributeArgument GetEnumArg (string name, string enumType, string enumValue)
596 return new CodeAttributeArgument (name, new CodeFieldReferenceExpression (new CodeTypeReferenceExpression(enumType), enumValue));
599 public static void AddComments (CodeTypeMember member, string comments)
601 if (comments == null || comments == "") member.Comments.Add (new CodeCommentStatement ("<remarks/>", true));
602 else member.Comments.Add (new CodeCommentStatement ("<remarks>\n" + comments + "\n</remarks>", true));
605 void AddCodeType (CodeTypeDeclaration type, string comments)
607 AddComments (type, comments);
608 codeNamespace.Types.Add (type);
611 #if NET_2_0
612 void AddClassAttributes (CodeTypeDeclaration codeClass)
614 CodeAttributeDeclaration generatedCodeAttribute = new CodeAttributeDeclaration (
615 new CodeTypeReference (typeof (GeneratedCodeAttribute)));
616 generatedCodeAttribute.Arguments.Add (new CodeAttributeArgument (
617 new CodePrimitiveExpression ("System.Xml")));
618 generatedCodeAttribute.Arguments.Add (new CodeAttributeArgument (
619 new CodePrimitiveExpression (Consts.FxFileVersion)));
620 codeClass.CustomAttributes.Add (generatedCodeAttribute);
622 codeClass.CustomAttributes.Add (new CodeAttributeDeclaration (
623 new CodeTypeReference (typeof (SerializableAttribute))));
624 codeClass.CustomAttributes.Add (new CodeAttributeDeclaration (
625 new CodeTypeReference (typeof (DebuggerStepThroughAttribute))));
627 CodeAttributeDeclaration designerCategoryAttribute = new CodeAttributeDeclaration (
628 new CodeTypeReference (typeof (DesignerCategoryAttribute)));
629 designerCategoryAttribute.Arguments.Add (new CodeAttributeArgument (
630 new CodePrimitiveExpression ("code")));
631 codeClass.CustomAttributes.Add (designerCategoryAttribute);
633 #endif
635 CodeTypeReference GetDomType (TypeData data, bool requiresNullable)
637 #if NET_2_0
638 if (data.IsValueType && (data.IsNullable || requiresNullable))
639 return new CodeTypeReference ("System.Nullable", new CodeTypeReference (data.FullTypeName));
640 #endif
641 if (data.SchemaType == SchemaTypes.Array)
642 return new CodeTypeReference (GetDomType (data.ListItemTypeData, false),1);
643 else
644 return new CodeTypeReference (data.FullTypeName);
647 #endregion
649 #region Private Properties
651 #if NET_2_0
652 private CodeDomProvider CodeProvider {
653 get {
654 if (codeProvider == null) {
655 codeProvider = new CSharpCodeProvider ();
657 return codeProvider;
660 #endif
662 #endregion
664 #region Overridable methods
666 protected virtual void GenerateClass (XmlTypeMapping map, CodeTypeDeclaration codeClass, bool isTopLevel)
670 protected virtual void GenerateClassInclude (CodeAttributeDeclarationCollection attributes, XmlTypeMapping map)
674 protected virtual void GenerateAnyAttribute (CodeTypeMember codeField)
678 protected virtual void GenerateDefaultAttribute (CodeMemberField internalField, CodeTypeMember externalField, TypeData typeData, object defaultValue)
680 if (typeData.Type == null)
682 // It must be an enumeration defined in the schema.
683 if (typeData.SchemaType != SchemaTypes.Enum)
684 throw new InvalidOperationException ("Type " + typeData.TypeName + " not supported");
686 IFormattable defaultValueFormattable = defaultValue as IFormattable;
687 CodeFieldReferenceExpression fref = new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (GetDomType (typeData, false)), defaultValueFormattable != null ? defaultValueFormattable.ToString(null, CultureInfo.InvariantCulture) : defaultValue.ToString ());
688 CodeAttributeArgument arg = new CodeAttributeArgument (fref);
689 AddCustomAttribute (externalField, "System.ComponentModel.DefaultValue", arg);
690 //internalField.InitExpression = fref;
692 else
694 AddCustomAttribute (externalField, "System.ComponentModel.DefaultValue", GetArg (defaultValue));
695 //internalField.InitExpression = new CodePrimitiveExpression (defaultValue);
699 protected virtual void GenerateAttributeMember (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberAttribute attinfo, string defaultNamespace, bool forceUseMemberName)
703 protected virtual void GenerateElementInfoMember (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberElement member, XmlTypeMapElementInfo einfo, TypeData defaultType, string defaultNamespace, bool addAlwaysAttr, bool forceUseMemberName)
707 protected virtual void GenerateElementMember (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberElement member)
711 protected virtual void GenerateArrayElement (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberElement member, string defaultNamespace, bool forceUseMemberName)
715 protected virtual void GenerateArrayItemAttributes (CodeAttributeDeclarationCollection attributes, ListMap listMap, TypeData type, XmlTypeMapElementInfo ainfo, string defaultName, string defaultNamespace, int nestingLevel)
719 protected virtual void GenerateTextElementAttribute (CodeAttributeDeclarationCollection attributes, XmlTypeMapElementInfo einfo, TypeData defaultType)
723 protected virtual void GenerateUnnamedAnyElementAttribute (CodeAttributeDeclarationCollection attributes, XmlTypeMapElementInfo einfo, string defaultNamespace)
727 protected virtual void GenerateEnum (XmlTypeMapping map, CodeTypeDeclaration codeEnum, bool isTopLevel)
731 protected virtual void GenerateEnumItem (CodeMemberField codeField, EnumMap.EnumMapMember emem)
735 protected virtual void GenerateSpecifierMember (CodeTypeMember codeField)
739 #endregion