Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Xml / System / Xml / Serialization / SoapCodeExporter.cs
blob0f69038917033f8f7e1813b2ce5c64ac6c8d74f6
1 //------------------------------------------------------------------------------
2 // <copyright file="SoapCodeExporter.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
8 namespace System.Xml.Serialization {
10 using System;
11 using System.Collections;
12 using System.IO;
13 using System.ComponentModel;
14 using System.Xml.Schema;
15 using System.CodeDom;
16 using System.CodeDom.Compiler;
17 using System.Reflection;
18 using System.Diagnostics;
19 using System.Xml;
20 using System.Security.Permissions;
22 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter"]/*' />
23 /// <internalonly/>
24 /// <devdoc>
25 /// <para>[To be supplied.]</para>
26 /// </devdoc>
27 public class SoapCodeExporter : CodeExporter {
29 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.SoapCodeExporter"]/*' />
30 /// <devdoc>
31 /// <para>[To be supplied.]</para>
32 /// </devdoc>
33 public SoapCodeExporter(CodeNamespace codeNamespace) : base(codeNamespace, null, null, CodeGenerationOptions.GenerateProperties, null) {}
34 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.SoapCodeExporter1"]/*' />
35 /// <devdoc>
36 /// <para>[To be supplied.]</para>
37 /// </devdoc>
38 public SoapCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit) : base(codeNamespace, codeCompileUnit, null, CodeGenerationOptions.GenerateProperties, null) {}
40 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.SoapCodeExporter2"]/*' />
41 /// <devdoc>
42 /// <para>[To be supplied.]</para>
43 /// </devdoc>
44 public SoapCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeGenerationOptions options) : base(codeNamespace, codeCompileUnit, null, CodeGenerationOptions.GenerateProperties, null) {}
46 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.SoapCodeExporter3"]/*' />
47 /// <devdoc>
48 /// <para>[To be supplied.]</para>
49 /// </devdoc>
50 public SoapCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeGenerationOptions options, Hashtable mappings)
51 : base(codeNamespace, codeCompileUnit, null, options, mappings) {}
53 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.SoapCodeExporter4"]/*' />
54 /// <devdoc>
55 /// <para>[To be supplied.]</para>
56 /// </devdoc>
57 public SoapCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeDomProvider codeProvider, CodeGenerationOptions options, Hashtable mappings)
58 : base(codeNamespace, codeCompileUnit, codeProvider, options, mappings) {}
60 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.ExportTypeMapping"]/*' />
61 /// <devdoc>
62 /// <para>[To be supplied.]</para>
63 /// </devdoc>
64 public void ExportTypeMapping(XmlTypeMapping xmlTypeMapping) {
65 xmlTypeMapping.CheckShallow();
66 CheckScope(xmlTypeMapping.Scope);
67 ExportElement(xmlTypeMapping.Accessor);
70 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.ExportMembersMapping"]/*' />
71 /// <devdoc>
72 /// <para>[To be supplied.]</para>
73 /// </devdoc>
74 public void ExportMembersMapping(XmlMembersMapping xmlMembersMapping) {
75 xmlMembersMapping.CheckShallow();
76 CheckScope(xmlMembersMapping.Scope);
77 for (int i = 0; i < xmlMembersMapping.Count; i++) {
78 ExportElement((ElementAccessor)xmlMembersMapping[i].Accessor);
82 void ExportElement(ElementAccessor element) {
83 ExportType(element.Mapping);
86 void ExportType(TypeMapping mapping) {
87 if (mapping.IsReference)
88 return;
89 if (ExportedMappings[mapping] == null) {
90 CodeTypeDeclaration codeClass = null;
91 ExportedMappings.Add(mapping, mapping);
92 if (mapping is EnumMapping) {
93 codeClass = ExportEnum((EnumMapping)mapping, typeof(SoapEnumAttribute));
95 else if (mapping is StructMapping) {
96 codeClass = ExportStruct((StructMapping)mapping);
98 else if (mapping is ArrayMapping) {
99 EnsureTypesExported(((ArrayMapping)mapping).Elements, null);
101 if (codeClass != null) {
102 // Add [GeneratedCodeAttribute(Tool=.., Version=..)]
103 codeClass.CustomAttributes.Add(GeneratedCodeAttribute);
105 // Add [SerializableAttribute]
106 codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(SerializableAttribute).FullName));
108 if (!codeClass.IsEnum) {
109 // Add [DebuggerStepThrough]
110 codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DebuggerStepThroughAttribute).FullName));
111 // Add [DesignerCategory("code")]
112 codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DesignerCategoryAttribute).FullName, new CodeAttributeArgument[] {new CodeAttributeArgument(new CodePrimitiveExpression("code"))}));
114 AddTypeMetadata(codeClass.CustomAttributes, typeof(SoapTypeAttribute), mapping.TypeDesc.Name, Accessor.UnescapeName(mapping.TypeName), mapping.Namespace, mapping.IncludeInSchema);
115 ExportedClasses.Add(mapping, codeClass);
120 CodeTypeDeclaration ExportStruct(StructMapping mapping) {
121 if (mapping.TypeDesc.IsRoot) {
122 ExportRoot(mapping, typeof(SoapIncludeAttribute));
123 return null;
125 if (!mapping.IncludeInSchema)
126 return null;
128 string className = mapping.TypeDesc.Name;
129 string baseName = mapping.TypeDesc.BaseTypeDesc == null ? string.Empty : mapping.TypeDesc.BaseTypeDesc.Name;
131 CodeTypeDeclaration codeClass = new CodeTypeDeclaration(className);
132 codeClass.IsPartial = CodeProvider.Supports(GeneratorSupport.PartialTypes);
133 codeClass.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
135 CodeNamespace.Types.Add(codeClass);
137 if (baseName != null && baseName.Length > 0) {
138 codeClass.BaseTypes.Add(baseName);
140 else
141 AddPropertyChangedNotifier(codeClass);
143 codeClass.TypeAttributes |= TypeAttributes.Public;
144 if (mapping.TypeDesc.IsAbstract)
145 codeClass.TypeAttributes |= TypeAttributes.Abstract;
147 CodeExporter.AddIncludeMetadata(codeClass.CustomAttributes, mapping, typeof(SoapIncludeAttribute));
149 if (GenerateProperties) {
150 for (int i = 0; i < mapping.Members.Length; i++) {
151 ExportProperty(codeClass, mapping.Members[i], mapping.Scope);
154 else {
155 for (int i = 0; i < mapping.Members.Length; i++) {
156 ExportMember(codeClass, mapping.Members[i]);
159 for (int i = 0; i < mapping.Members.Length; i++) {
160 EnsureTypesExported(mapping.Members[i].Elements, null);
163 if (mapping.BaseMapping != null)
164 ExportType(mapping.BaseMapping);
166 ExportDerivedStructs(mapping);
167 CodeGenerator.ValidateIdentifiers(codeClass);
168 return codeClass;
171 [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")]
172 internal override void ExportDerivedStructs(StructMapping mapping) {
173 for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping)
174 ExportType(derived);
177 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.AddMappingMetadata"]/*' />
178 /// <devdoc>
179 /// <para>[To be supplied.]</para>
180 /// </devdoc>
181 public void AddMappingMetadata(CodeAttributeDeclarationCollection metadata, XmlMemberMapping member, bool forceUseMemberName) {
182 AddMemberMetadata(metadata, member.Mapping, forceUseMemberName);
185 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.AddMappingMetadata1"]/*' />
186 /// <devdoc>
187 /// <para>[To be supplied.]</para>
188 /// </devdoc>
189 public void AddMappingMetadata(CodeAttributeDeclarationCollection metadata, XmlMemberMapping member) {
190 AddMemberMetadata(metadata, member.Mapping, false);
193 void AddElementMetadata(CodeAttributeDeclarationCollection metadata, string elementName, TypeDesc typeDesc, bool isNullable) {
194 CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(SoapElementAttribute).FullName);
195 if (elementName != null) {
196 attribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(elementName)));
198 if (typeDesc != null && typeDesc.IsAmbiguousDataType) {
199 attribute.Arguments.Add(new CodeAttributeArgument("DataType", new CodePrimitiveExpression(typeDesc.DataType.Name)));
201 if (isNullable) {
202 attribute.Arguments.Add(new CodeAttributeArgument("IsNullable", new CodePrimitiveExpression(true)));
204 metadata.Add(attribute);
207 void AddMemberMetadata(CodeAttributeDeclarationCollection metadata, MemberMapping member, bool forceUseMemberName) {
208 if (member.Elements.Length == 0) return;
209 ElementAccessor element = member.Elements[0];
210 TypeMapping mapping = (TypeMapping)element.Mapping;
211 string elemName = Accessor.UnescapeName(element.Name);
212 bool sameName = ((elemName == member.Name) && !forceUseMemberName);
214 if (!sameName || mapping.TypeDesc.IsAmbiguousDataType || element.IsNullable) {
215 AddElementMetadata(metadata, sameName ? null : elemName, mapping.TypeDesc.IsAmbiguousDataType ? mapping.TypeDesc : null, element.IsNullable);
219 void ExportMember(CodeTypeDeclaration codeClass, MemberMapping member) {
220 string fieldType = member.GetTypeName(CodeProvider);
221 CodeMemberField field = new CodeMemberField(fieldType, member.Name);
222 field.Attributes = (field.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
223 field.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
224 codeClass.Members.Add(field);
225 AddMemberMetadata(field.CustomAttributes, member, false);
227 if (member.CheckSpecified != SpecifiedAccessor.None) {
228 field = new CodeMemberField(typeof(bool).FullName, member.Name + "Specified");
229 field.Attributes = (field.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
230 field.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
231 CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(SoapIgnoreAttribute).FullName);
232 field.CustomAttributes.Add(attribute);
233 codeClass.Members.Add(field);
237 void ExportProperty(CodeTypeDeclaration codeClass, MemberMapping member, CodeIdentifiers memberScope) {
238 string fieldName = memberScope.AddUnique(CodeExporter.MakeFieldName(member.Name), member);
239 string fieldType = member.GetTypeName(CodeProvider);
240 // need to create a private field
241 CodeMemberField field = new CodeMemberField(fieldType, fieldName);
242 field.Attributes = MemberAttributes.Private;
243 codeClass.Members.Add(field);
245 CodeMemberProperty prop = CreatePropertyDeclaration(field, member.Name, fieldType);
246 prop.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
247 AddMemberMetadata(prop.CustomAttributes, member, false);
248 codeClass.Members.Add(prop);
250 if (member.CheckSpecified != SpecifiedAccessor.None) {
251 field = new CodeMemberField(typeof(bool).FullName, fieldName + "Specified");
252 field.Attributes = MemberAttributes.Private;
253 codeClass.Members.Add(field);
255 prop = CreatePropertyDeclaration(field, member.Name + "Specified", typeof(bool).FullName);
256 prop.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
257 CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(SoapIgnoreAttribute).FullName);
258 prop.CustomAttributes.Add(attribute);
259 codeClass.Members.Add(prop);
263 internal override void EnsureTypesExported(Accessor[] accessors, string ns) {
264 if (accessors == null) return;
265 for (int i = 0; i < accessors.Length; i++)
266 ExportType(accessors[i].Mapping);