Initial commit
[mono.git] / mcs / class / referencesource / System.Xml / System / Xml / Serialization / XmlSerializationILGen.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="XmlSerializationILGen.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">[....]</owner>                                                                
6 //------------------------------------------------------------------------------
7
8 namespace System.Xml.Serialization {
9     using System;
10     using System.Collections;
11     using System.Collections.Generic;
12     using System.Reflection;
13     using System.Reflection.Emit;
14     using System.Text.RegularExpressions;
15
16     internal class XmlSerializationILGen {
17         int nextMethodNumber = 0;
18         Hashtable methodNames = new Hashtable();
19         // Lookup name->created Method
20         Dictionary<string, MethodBuilderInfo> methodBuilders = new Dictionary<string, MethodBuilderInfo>();
21         // Lookup name->created Type
22         internal Dictionary<string, Type> CreatedTypes = new Dictionary<string, Type>();
23         // Lookup name->class Member
24         internal Dictionary<string, MemberInfo> memberInfos = new Dictionary<string, MemberInfo>();
25         ReflectionAwareILGen raCodeGen;
26         TypeScope[] scopes;
27         TypeDesc stringTypeDesc = null;
28         TypeDesc qnameTypeDesc = null;
29         string className;
30         TypeMapping[] referencedMethods;
31         int references = 0;
32         Hashtable generatedMethods = new Hashtable();
33         ModuleBuilder moduleBuilder;
34         TypeAttributes typeAttributes;
35         protected TypeBuilder typeBuilder;
36         protected CodeGenerator ilg;
37
38         internal XmlSerializationILGen(TypeScope[] scopes, string access, string className) {
39             this.scopes = scopes;
40             if (scopes.Length > 0) {
41                 stringTypeDesc = scopes[0].GetTypeDesc(typeof(string));
42                 qnameTypeDesc = scopes[0].GetTypeDesc(typeof(XmlQualifiedName));
43             }
44             this.raCodeGen = new ReflectionAwareILGen();
45             this.className = className;
46             System.Diagnostics.Debug.Assert(access == "public");
47             this.typeAttributes = TypeAttributes.Public;
48         }
49
50         internal int NextMethodNumber { get { return nextMethodNumber; } set { nextMethodNumber = value; } }
51         internal ReflectionAwareILGen RaCodeGen { get { return raCodeGen; } }
52         internal TypeDesc StringTypeDesc { get { return stringTypeDesc; } }
53         internal TypeDesc QnameTypeDesc { get { return qnameTypeDesc; } }
54         internal string ClassName { get { return className; } }
55         internal TypeScope[] Scopes { get { return scopes; } }
56         internal Hashtable MethodNames { get { return methodNames; } }
57         internal Hashtable GeneratedMethods { get { return generatedMethods; } }
58
59         internal ModuleBuilder ModuleBuilder {
60             get { System.Diagnostics.Debug.Assert(moduleBuilder != null); return moduleBuilder; }
61             set { System.Diagnostics.Debug.Assert(moduleBuilder == null && value != null); moduleBuilder = value; }
62         }
63         internal TypeAttributes TypeAttributes { get { return typeAttributes; } }
64
65         static Dictionary<string, Regex> regexs = new Dictionary<string, Regex>();
66         static internal Regex NewRegex(string pattern) {
67             Regex regex;
68             lock (regexs) {
69                 if (!regexs.TryGetValue(pattern, out regex)) {
70                     regex = new Regex(pattern);
71                     regexs.Add(pattern, regex);
72                 }
73             }
74             return regex;
75         }
76
77         internal MethodBuilder EnsureMethodBuilder(TypeBuilder typeBuilder, string methodName,
78             MethodAttributes attributes, Type returnType, Type[] parameterTypes) {
79             MethodBuilderInfo methodBuilderInfo;
80             if (!methodBuilders.TryGetValue(methodName, out methodBuilderInfo)) {
81                 MethodBuilder methodBuilder = typeBuilder.DefineMethod(
82                     methodName,
83                     attributes,
84                     returnType,
85                     parameterTypes);
86                 methodBuilderInfo = new MethodBuilderInfo(methodBuilder, parameterTypes);
87                 methodBuilders.Add(methodName, methodBuilderInfo);
88             }
89 #if DEBUG
90             else {
91                 methodBuilderInfo.Validate(returnType, parameterTypes, attributes);
92
93             }
94 #endif
95             return methodBuilderInfo.MethodBuilder;
96         }
97
98         internal MethodBuilderInfo GetMethodBuilder(string methodName) {
99             System.Diagnostics.Debug.Assert(methodBuilders.ContainsKey(methodName));
100             return methodBuilders[methodName];
101         }
102         internal virtual void GenerateMethod(TypeMapping mapping) { }
103
104         internal void GenerateReferencedMethods() {
105             while (references > 0) {
106                 TypeMapping mapping = referencedMethods[--references];
107                 GenerateMethod(mapping);
108             }
109         }
110
111         internal string ReferenceMapping(TypeMapping mapping) {
112             if (generatedMethods[mapping] == null) {
113                 referencedMethods = EnsureArrayIndex(referencedMethods, references);
114                 referencedMethods[references++] = mapping;
115             }
116             return (string)methodNames[mapping];
117         }
118
119         TypeMapping[] EnsureArrayIndex(TypeMapping[] a, int index) {
120             if (a == null) return new TypeMapping[32];
121             if (index < a.Length) return a;
122             TypeMapping[] b = new TypeMapping[a.Length + 32];
123             Array.Copy(a, b, index);
124             return b;
125         }
126
127         internal FieldBuilder GenerateHashtableGetBegin(string privateName, string publicName, TypeBuilder serializerContractTypeBuilder) {
128             FieldBuilder fieldBuilder = serializerContractTypeBuilder.DefineField(
129                 privateName,
130                 typeof(Hashtable),
131                 FieldAttributes.Private
132                 );
133             ilg = new CodeGenerator(serializerContractTypeBuilder);
134             PropertyBuilder propertyBuilder = serializerContractTypeBuilder.DefineProperty(
135                 publicName,
136                 PropertyAttributes.None,
137                 CallingConventions.HasThis,
138                 typeof(Hashtable),
139                 null, null, null, null, null);
140
141             ilg.BeginMethod(
142                 typeof(Hashtable),
143                 "get_" + publicName,
144                 CodeGenerator.EmptyTypeArray,
145                 CodeGenerator.EmptyStringArray,
146                 CodeGenerator.PublicOverrideMethodAttributes | MethodAttributes.SpecialName);
147             propertyBuilder.SetGetMethod(ilg.MethodBuilder);
148
149             ilg.Ldarg(0);
150             ilg.LoadMember(fieldBuilder);
151             ilg.Load(null);
152             // this 'if' ends in GenerateHashtableGetEnd
153             ilg.If(Cmp.EqualTo);
154
155             ConstructorInfo Hashtable_ctor = typeof(Hashtable).GetConstructor(
156                 CodeGenerator.InstanceBindingFlags,
157                 null,
158                 CodeGenerator.EmptyTypeArray,
159                 null
160                 );
161             LocalBuilder _tmpLoc = ilg.DeclareLocal(typeof(Hashtable), "_tmp");
162             ilg.New(Hashtable_ctor);
163             ilg.Stloc(_tmpLoc);
164
165             return fieldBuilder;
166         }
167
168         internal void GenerateHashtableGetEnd(FieldBuilder fieldBuilder) {
169             ilg.Ldarg(0);
170             ilg.LoadMember(fieldBuilder);
171             ilg.Load(null);
172             ilg.If(Cmp.EqualTo);
173             {
174                 ilg.Ldarg(0);
175                 ilg.Ldloc(typeof(Hashtable), "_tmp");
176                 ilg.StoreMember(fieldBuilder);
177             }
178             ilg.EndIf();
179             // 'endif' from GenerateHashtableGetBegin
180             ilg.EndIf();
181
182             ilg.Ldarg(0);
183             ilg.LoadMember(fieldBuilder);
184             ilg.GotoMethodEnd();
185
186             ilg.EndMethod();
187         }
188         internal FieldBuilder GeneratePublicMethods(string privateName, string publicName, string[] methods, XmlMapping[] xmlMappings, TypeBuilder serializerContractTypeBuilder) {
189             FieldBuilder fieldBuilder = GenerateHashtableGetBegin(privateName, publicName, serializerContractTypeBuilder);
190             if (methods != null && methods.Length != 0 && xmlMappings != null && xmlMappings.Length == methods.Length) {
191                 MethodInfo Hashtable_set_Item = typeof(Hashtable).GetMethod(
192                     "set_Item",
193                     CodeGenerator.InstanceBindingFlags,
194                     null,
195                     new Type[] { typeof(Object), typeof(Object) },
196                     null
197                     );
198                 for (int i = 0; i < methods.Length; i++) {
199                     if (methods[i] == null)
200                         continue;
201                     ilg.Ldloc(typeof(Hashtable), "_tmp");
202                     ilg.Ldstr(xmlMappings[i].Key);
203                     ilg.Ldstr(methods[i]);
204                     ilg.Call(Hashtable_set_Item);
205                 }
206             }
207             GenerateHashtableGetEnd(fieldBuilder);
208             return fieldBuilder;
209         }
210
211         internal void GenerateSupportedTypes(Type[] types, TypeBuilder serializerContractTypeBuilder) {
212             ilg = new CodeGenerator(serializerContractTypeBuilder);
213             ilg.BeginMethod(
214                 typeof(bool),
215                 "CanSerialize",
216                 new Type[] { typeof(Type) },
217                 new string[] { "type" },
218                 CodeGenerator.PublicOverrideMethodAttributes);
219             Hashtable uniqueTypes = new Hashtable();
220             for (int i = 0; i < types.Length; i++) {
221                 Type type = types[i];
222
223                 if (type == null)
224                     continue;
225                 if (!type.IsPublic && !type.IsNestedPublic)
226                     continue;
227                 if (uniqueTypes[type] != null)
228                     continue;
229                 // DDB172141: Wrong generated CS for serializer of List<string> type
230                 if (type.IsGenericType || type.ContainsGenericParameters)
231                     continue;
232                 uniqueTypes[type] = type;
233                 ilg.Ldarg("type");
234                 ilg.Ldc(type);
235                 ilg.If(Cmp.EqualTo);
236                 {
237                     ilg.Ldc(true);
238                     ilg.GotoMethodEnd();
239                 }
240                 ilg.EndIf();
241             }
242             ilg.Ldc(false);
243             ilg.GotoMethodEnd();
244             ilg.EndMethod();
245         }
246
247         internal string GenerateBaseSerializer(string baseSerializer, string readerClass, string writerClass, CodeIdentifiers classes) {
248             baseSerializer = CodeIdentifier.MakeValid(baseSerializer);
249             baseSerializer = classes.AddUnique(baseSerializer, baseSerializer);
250
251             TypeBuilder baseSerializerTypeBuilder = CodeGenerator.CreateTypeBuilder(
252                 this.moduleBuilder,
253                 CodeIdentifier.GetCSharpName(baseSerializer),
254                 TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit,
255                 typeof(XmlSerializer),
256                 CodeGenerator.EmptyTypeArray);
257
258             ConstructorInfo readerCtor = CreatedTypes[readerClass].GetConstructor(
259                CodeGenerator.InstanceBindingFlags,
260                null,
261                CodeGenerator.EmptyTypeArray,
262                null
263                );
264             ilg = new CodeGenerator(baseSerializerTypeBuilder);
265             ilg.BeginMethod(typeof(XmlSerializationReader),
266                 "CreateReader",
267                 CodeGenerator.EmptyTypeArray,
268                 CodeGenerator.EmptyStringArray,
269                 CodeGenerator.ProtectedOverrideMethodAttributes);
270             ilg.New(readerCtor);
271             ilg.EndMethod();
272
273             ConstructorInfo writerCtor = CreatedTypes[writerClass].GetConstructor(
274                CodeGenerator.InstanceBindingFlags,
275                null,
276                CodeGenerator.EmptyTypeArray,
277                null
278                );
279             ilg.BeginMethod(typeof(XmlSerializationWriter),
280                 "CreateWriter",
281                 CodeGenerator.EmptyTypeArray,
282                 CodeGenerator.EmptyStringArray,
283                 CodeGenerator.ProtectedOverrideMethodAttributes);
284             ilg.New(writerCtor);
285             ilg.EndMethod();
286
287             baseSerializerTypeBuilder.DefineDefaultConstructor(
288                 MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
289             Type baseSerializerType = baseSerializerTypeBuilder.CreateType();
290             CreatedTypes.Add(baseSerializerType.Name, baseSerializerType);
291
292             return baseSerializer;
293         }
294
295         internal string GenerateTypedSerializer(string readMethod, string writeMethod, XmlMapping mapping, CodeIdentifiers classes, string baseSerializer, string readerClass, string writerClass) {
296             string serializerName = CodeIdentifier.MakeValid(Accessor.UnescapeName(mapping.Accessor.Mapping.TypeDesc.Name));
297             serializerName = classes.AddUnique(serializerName + "Serializer", mapping);
298
299             TypeBuilder typedSerializerTypeBuilder = CodeGenerator.CreateTypeBuilder(
300                 this.moduleBuilder,
301                 CodeIdentifier.GetCSharpName(serializerName),
302                 TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit,
303                 CreatedTypes[baseSerializer],
304                 CodeGenerator.EmptyTypeArray
305                 );
306
307             ilg = new CodeGenerator(typedSerializerTypeBuilder);
308             ilg.BeginMethod(
309                 typeof(Boolean),
310                 "CanDeserialize",
311                 new Type[] { typeof(XmlReader) },
312                 new string[] { "xmlReader" },
313                 CodeGenerator.PublicOverrideMethodAttributes
314             );
315
316             if (mapping.Accessor.Any) {
317                 ilg.Ldc(true);
318                 ilg.Stloc(ilg.ReturnLocal);
319                 ilg.Br(ilg.ReturnLabel);
320             }
321             else {
322                 MethodInfo XmlReader_IsStartElement = typeof(XmlReader).GetMethod(
323                      "IsStartElement",
324                      CodeGenerator.InstanceBindingFlags,
325                      null,
326                      new Type[] { typeof(String), typeof(String) },
327                      null
328                      );
329                 ilg.Ldarg(ilg.GetArg("xmlReader"));
330                 ilg.Ldstr(mapping.Accessor.Name);
331                 ilg.Ldstr(mapping.Accessor.Namespace);
332                 ilg.Call(XmlReader_IsStartElement);
333                 ilg.Stloc(ilg.ReturnLocal);
334                 ilg.Br(ilg.ReturnLabel);
335             }
336             ilg.MarkLabel(ilg.ReturnLabel);
337             ilg.Ldloc(ilg.ReturnLocal);
338             ilg.EndMethod();
339
340             if (writeMethod != null) {
341                 ilg = new CodeGenerator(typedSerializerTypeBuilder);
342                 ilg.BeginMethod(
343                     typeof(void),
344                     "Serialize",
345                     new Type[] { typeof(object), typeof(XmlSerializationWriter) },
346                     new string[] { "objectToSerialize", "writer" },
347                     CodeGenerator.ProtectedOverrideMethodAttributes);
348                 MethodInfo writerType_writeMethod = CreatedTypes[writerClass].GetMethod(
349                     writeMethod,
350                     CodeGenerator.InstanceBindingFlags,
351                     null,
352                     new Type[] { (mapping is XmlMembersMapping) ? typeof(object[]) : typeof(object) },
353                     null
354                     );
355                 ilg.Ldarg("writer");
356                 ilg.Castclass(CreatedTypes[writerClass]);
357                 ilg.Ldarg("objectToSerialize");
358                 if (mapping is XmlMembersMapping) {
359                     ilg.ConvertValue(typeof(object), typeof(object[]));
360                 }
361                 ilg.Call(writerType_writeMethod);
362                 ilg.EndMethod();
363             }
364             if (readMethod != null) {
365                 ilg = new CodeGenerator(typedSerializerTypeBuilder);
366                 ilg.BeginMethod(
367                     typeof(object),
368                     "Deserialize",
369                     new Type[] { typeof(XmlSerializationReader) },
370                     new string[] { "reader" },
371                     CodeGenerator.ProtectedOverrideMethodAttributes);
372                 MethodInfo readerType_readMethod = CreatedTypes[readerClass].GetMethod(
373                     readMethod,
374                     CodeGenerator.InstanceBindingFlags,
375                     null,
376                     CodeGenerator.EmptyTypeArray,
377                     null
378                     );
379                 ilg.Ldarg("reader");
380                 ilg.Castclass(CreatedTypes[readerClass]);
381                 ilg.Call(readerType_readMethod);
382                 ilg.EndMethod();
383             }
384             typedSerializerTypeBuilder.DefineDefaultConstructor(CodeGenerator.PublicMethodAttributes);
385             Type typedSerializerType = typedSerializerTypeBuilder.CreateType();
386             CreatedTypes.Add(typedSerializerType.Name, typedSerializerType);
387
388             return typedSerializerType.Name;
389         }
390
391         FieldBuilder GenerateTypedSerializers(Hashtable serializers, TypeBuilder serializerContractTypeBuilder) {
392             string privateName = "typedSerializers";
393             FieldBuilder fieldBuilder = GenerateHashtableGetBegin(privateName, "TypedSerializers", serializerContractTypeBuilder);
394             MethodInfo Hashtable_Add = typeof(Hashtable).GetMethod(
395                 "Add",
396                 CodeGenerator.InstanceBindingFlags,
397                 null,
398                 new Type[] { typeof(Object), typeof(Object) },
399                 null
400                 );
401
402             foreach (string key in serializers.Keys) {
403                 ConstructorInfo ctor = CreatedTypes[(string)serializers[key]].GetConstructor(
404                     CodeGenerator.InstanceBindingFlags,
405                     null,
406                     CodeGenerator.EmptyTypeArray,
407                     null
408                     );
409                 ilg.Ldloc(typeof(Hashtable), "_tmp");
410                 ilg.Ldstr(key);
411                 ilg.New(ctor);
412                 ilg.Call(Hashtable_Add);
413             }
414             GenerateHashtableGetEnd(fieldBuilder);
415             return fieldBuilder;
416         }
417
418         //GenerateGetSerializer(serializers, xmlMappings);
419         void GenerateGetSerializer(Hashtable serializers, XmlMapping[] xmlMappings, TypeBuilder serializerContractTypeBuilder) {
420             ilg = new CodeGenerator(serializerContractTypeBuilder);
421             ilg.BeginMethod(
422                 typeof(XmlSerializer),
423                 "GetSerializer",
424                 new Type[] { typeof(Type) },
425                 new string[] { "type" },
426                 CodeGenerator.PublicOverrideMethodAttributes);
427
428             for (int i = 0; i < xmlMappings.Length; i++) {
429                 if (xmlMappings[i] is XmlTypeMapping) {
430                     Type type = xmlMappings[i].Accessor.Mapping.TypeDesc.Type;
431                     if (type == null)
432                         continue;
433                     if (!type.IsPublic && !type.IsNestedPublic)
434                         continue;
435                     // DDB172141: Wrong generated CS for serializer of List<string> type
436                     if (type.IsGenericType || type.ContainsGenericParameters)
437                         continue;
438                     ilg.Ldarg("type");
439                     ilg.Ldc(type);
440                     ilg.If(Cmp.EqualTo);
441                     {
442                         ConstructorInfo ctor = CreatedTypes[(string)serializers[xmlMappings[i].Key]].GetConstructor(
443                             CodeGenerator.InstanceBindingFlags,
444                             null,
445                             CodeGenerator.EmptyTypeArray,
446                             null
447                             );
448                         ilg.New(ctor);
449                         ilg.Stloc(ilg.ReturnLocal);
450                         ilg.Br(ilg.ReturnLabel);
451                     }
452                     ilg.EndIf();
453                 }
454             }
455             ilg.Load(null);
456             ilg.Stloc(ilg.ReturnLocal);
457             ilg.Br(ilg.ReturnLabel);
458             ilg.MarkLabel(ilg.ReturnLabel);
459             ilg.Ldloc(ilg.ReturnLocal);
460             ilg.EndMethod();
461         }
462
463         internal void GenerateSerializerContract(string className, XmlMapping[] xmlMappings, Type[] types, string readerType, string[] readMethods, string writerType, string[] writerMethods, Hashtable serializers) {
464             TypeBuilder serializerContractTypeBuilder = CodeGenerator.CreateTypeBuilder(
465                 this.moduleBuilder,
466                 "XmlSerializerContract",
467                 TypeAttributes.Public | TypeAttributes.BeforeFieldInit,
468                 typeof(XmlSerializerImplementation),
469                 CodeGenerator.EmptyTypeArray
470                 );
471
472             ilg = new CodeGenerator(serializerContractTypeBuilder);
473             PropertyBuilder propertyBuilder = serializerContractTypeBuilder.DefineProperty(
474                 "Reader",
475                 PropertyAttributes.None,
476                 CallingConventions.HasThis,
477                 typeof(XmlSerializationReader),
478                 null, null, null, null, null);
479             ilg.BeginMethod(
480                 typeof(XmlSerializationReader),
481                 "get_Reader",
482                 CodeGenerator.EmptyTypeArray,
483                 CodeGenerator.EmptyStringArray,
484                 CodeGenerator.PublicOverrideMethodAttributes | MethodAttributes.SpecialName);
485             propertyBuilder.SetGetMethod(ilg.MethodBuilder);
486             ConstructorInfo ctor = CreatedTypes[readerType].GetConstructor(
487                 CodeGenerator.InstanceBindingFlags,
488                 null,
489                 CodeGenerator.EmptyTypeArray,
490                 null
491                 );
492             ilg.New(ctor);
493             ilg.EndMethod();
494
495             ilg = new CodeGenerator(serializerContractTypeBuilder);
496             propertyBuilder = serializerContractTypeBuilder.DefineProperty(
497                 "Writer",
498                 PropertyAttributes.None,
499                 CallingConventions.HasThis,
500                 typeof(XmlSerializationWriter),
501                 null, null, null, null, null);
502             ilg.BeginMethod(
503                 typeof(XmlSerializationWriter),
504                 "get_Writer",
505                 CodeGenerator.EmptyTypeArray,
506                 CodeGenerator.EmptyStringArray,
507                 CodeGenerator.PublicOverrideMethodAttributes | MethodAttributes.SpecialName);
508             propertyBuilder.SetGetMethod(ilg.MethodBuilder);
509             ctor = CreatedTypes[writerType].GetConstructor(
510                 CodeGenerator.InstanceBindingFlags,
511                 null,
512                 CodeGenerator.EmptyTypeArray,
513                 null
514                 );
515             ilg.New(ctor);
516             ilg.EndMethod();
517
518             FieldBuilder readMethodsField = GeneratePublicMethods("readMethods", "ReadMethods", readMethods, xmlMappings, serializerContractTypeBuilder);
519             FieldBuilder writeMethodsField = GeneratePublicMethods("writeMethods", "WriteMethods", writerMethods, xmlMappings, serializerContractTypeBuilder);
520             FieldBuilder typedSerializersField = GenerateTypedSerializers(serializers, serializerContractTypeBuilder);
521             GenerateSupportedTypes(types, serializerContractTypeBuilder);
522             GenerateGetSerializer(serializers, xmlMappings, serializerContractTypeBuilder);
523
524             // Default ctor
525             ConstructorInfo baseCtor = typeof(XmlSerializerImplementation).GetConstructor(
526                 CodeGenerator.InstanceBindingFlags,
527                 null,
528                 CodeGenerator.EmptyTypeArray,
529                 null
530                 );
531             ilg = new CodeGenerator(serializerContractTypeBuilder);
532             ilg.BeginMethod(
533                 typeof(void),
534                 ".ctor",
535                 CodeGenerator.EmptyTypeArray,
536                 CodeGenerator.EmptyStringArray,
537                 CodeGenerator.PublicMethodAttributes | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName
538                 );
539             ilg.Ldarg(0);
540             ilg.Load(null);
541             ilg.StoreMember(readMethodsField);
542             ilg.Ldarg(0);
543             ilg.Load(null);
544             ilg.StoreMember(writeMethodsField);
545             ilg.Ldarg(0);
546             ilg.Load(null);
547             ilg.StoreMember(typedSerializersField);
548             ilg.Ldarg(0);
549             ilg.Call(baseCtor);
550             ilg.EndMethod();
551             // Instantiate type
552             Type serializerContractType = serializerContractTypeBuilder.CreateType();
553             CreatedTypes.Add(serializerContractType.Name, serializerContractType);
554
555         }
556
557         internal static bool IsWildcard(SpecialMapping mapping) {
558             if (mapping is SerializableMapping)
559                 return ((SerializableMapping)mapping).IsAny;
560             return mapping.TypeDesc.CanBeElementValue;
561         }
562         internal void ILGenLoad(string source) {
563             ILGenLoad(source, null);
564         }
565         internal void ILGenLoad(string source, Type type) {
566             if (source.StartsWith("o.@", StringComparison.Ordinal)) {
567                 System.Diagnostics.Debug.Assert(memberInfos.ContainsKey(source.Substring(3)));
568                 MemberInfo memInfo = memberInfos[source.Substring(3)];
569                 ilg.LoadMember(ilg.GetVariable("o"), memInfo);
570                 if (type != null) {
571                     Type memType = (memInfo.MemberType == MemberTypes.Field) ? ((FieldInfo)memInfo).FieldType : ((PropertyInfo)memInfo).PropertyType;
572                     ilg.ConvertValue(memType, type);
573                 }
574             }
575             else {
576                 SourceInfo info = new SourceInfo(source, null, null, null, ilg);
577                 info.Load(type);
578             }
579         }
580     }
581 }