Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
XmlSerializationILGen.cs
Go to the documentation of this file.
7
9
11{
12 private int _nextMethodNumber;
13
15
17
19
21
23
24 private readonly TypeScope[] _scopes;
25
26 private readonly TypeDesc _stringTypeDesc;
27
28 private readonly TypeDesc _qnameTypeDesc;
29
30 private readonly string _className;
31
33
34 private int _references;
35
37
39
41
43
44 protected CodeGenerator ilg;
45
47
48 internal int NextMethodNumber
49 {
50 get
51 {
52 return _nextMethodNumber;
53 }
54 set
55 {
57 }
58 }
59
61
63
65
66 internal string ClassName => _className;
67
68 internal TypeScope[] Scopes => _scopes;
69
71
73
75 {
76 get
77 {
78 return _moduleBuilder;
79 }
80 set
81 {
83 }
84 }
85
87
88 [RequiresUnreferencedCode("Calls GetTypeDesc")]
89 internal XmlSerializationILGen(TypeScope[] scopes, string access, string className)
90 {
91 _scopes = scopes;
92 if (scopes.Length != 0)
93 {
94 _stringTypeDesc = scopes[0].GetTypeDesc(typeof(string));
96 }
100 }
101
102 internal static Regex NewRegex(string pattern)
103 {
104 Regex value;
105 lock (s_regexs)
106 {
107 if (!s_regexs.TryGetValue(pattern, out value))
108 {
109 value = new Regex(pattern);
110 s_regexs.Add(pattern, value);
111 }
112 }
113 return value;
114 }
115
126
128 {
130 }
131
132 [RequiresUnreferencedCode("calls WriteStructMethod")]
133 internal virtual void GenerateMethod(TypeMapping mapping)
134 {
135 }
136
137 [RequiresUnreferencedCode("calls GenerateMethod")]
139 {
140 while (_references > 0)
141 {
144 }
145 }
146
157
159 {
160 if (a == null)
161 {
162 return new TypeMapping[32];
163 }
164 if (index < a.Length)
165 {
166 return a;
167 }
170 return array;
171 }
172
173 [return: NotNullIfNotNull("value")]
174 internal string GetCSharpString(string value)
175 {
177 }
178
179 [RequiresUnreferencedCode("calls LoadMember")]
197
198 [RequiresUnreferencedCode("calls LoadMember")]
200 {
201 ilg.Ldarg(0);
203 ilg.Load(null);
204 ilg.If(Cmp.EqualTo);
205 ilg.Ldarg(0);
206 ilg.Ldloc(typeof(Hashtable), "_tmp");
208 ilg.EndIf();
209 ilg.EndIf();
210 ilg.Ldarg(0);
213 ilg.EndMethod();
214 }
215
216 [RequiresUnreferencedCode("calls GenerateHashtableGetBegin")]
218 {
220 if (methods != null && methods.Length != 0 && xmlMappings != null && xmlMappings.Length == methods.Length)
221 {
222 MethodInfo method = typeof(Hashtable).GetMethod("set_Item", new Type[2]
223 {
224 typeof(object),
225 typeof(object)
226 });
227 for (int i = 0; i < methods.Length; i++)
228 {
229 if (methods[i] != null)
230 {
231 ilg.Ldloc(typeof(Hashtable), "_tmp");
234 ilg.Call(method);
235 }
236 }
237 }
239 return fieldBuilder;
240 }
241
243 {
245 ilg.BeginMethod(typeof(bool), "CanSerialize", new Type[1] { typeof(Type) }, new string[1] { "type" }, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig);
247 foreach (Type type in types)
248 {
249 if (!(type == null) && (type.IsPublic || type.IsNestedPublic) && hashSet.Add(type) && !type.IsGenericType && !type.ContainsGenericParameters)
250 {
251 ilg.Ldarg("type");
252 ilg.Ldc(type);
253 ilg.If(Cmp.EqualTo);
254 ilg.Ldc(boolVar: true);
256 ilg.EndIf();
257 }
258 }
259 ilg.Ldc(boolVar: false);
261 ilg.EndMethod();
262 }
263
264 [RequiresUnreferencedCode("Uses CreatedTypes Dictionary")]
266 {
272 ilg.BeginMethod(typeof(XmlSerializationReader), "CreateReader", Type.EmptyTypes, Array.Empty<string>(), MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig);
274 ilg.EndMethod();
276 ilg.BeginMethod(typeof(XmlSerializationWriter), "CreateWriter", Type.EmptyTypes, Array.Empty<string>(), MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig);
278 ilg.EndMethod();
281 CreatedTypes.Add(type.Name, type);
282 return baseSerializer;
283 }
284
285 [RequiresUnreferencedCode("uses CreatedTypes dictionary")]
286 internal string GenerateTypedSerializer(string readMethod, string writeMethod, XmlMapping mapping, CodeIdentifiers classes, string baseSerializer, string readerClass, string writerClass)
287 {
288 string text = CodeIdentifier.MakeValid(Accessor.UnescapeName(mapping.Accessor.Mapping.TypeDesc.Name));
289 text = classes.AddUnique(text + "Serializer", mapping);
292 ilg.BeginMethod(typeof(bool), "CanDeserialize", new Type[1] { typeof(XmlReader) }, new string[1] { "xmlReader" }, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig);
293 if (mapping.Accessor.Any)
294 {
295 ilg.Ldc(boolVar: true);
298 }
299 else
300 {
301 MethodInfo method = typeof(XmlReader).GetMethod("IsStartElement", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, new Type[2]
302 {
303 typeof(string),
304 typeof(string)
305 });
306 ilg.Ldarg(ilg.GetArg("xmlReader"));
307 ilg.Ldstr(GetCSharpString(mapping.Accessor.Name));
308 ilg.Ldstr(GetCSharpString(mapping.Accessor.Namespace));
309 ilg.Call(method);
312 }
315 ilg.EndMethod();
316 if (writeMethod != null)
317 {
319 ilg.BeginMethod(typeof(void), "Serialize", new Type[2]
320 {
321 typeof(object),
323 }, new string[2] { "objectToSerialize", "writer" }, MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig);
324 MethodInfo method2 = CreatedTypes[writerClass].GetMethod(writeMethod, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, new Type[1] { (mapping is XmlMembersMapping) ? typeof(object[]) : typeof(object) });
325 ilg.Ldarg("writer");
327 ilg.Ldarg("objectToSerialize");
329 {
330 ilg.ConvertValue(typeof(object), typeof(object[]));
331 }
333 ilg.EndMethod();
334 }
335 if (readMethod != null)
336 {
338 ilg.BeginMethod(typeof(object), "Deserialize", new Type[1] { typeof(XmlSerializationReader) }, new string[1] { "reader" }, MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig);
339 MethodInfo method3 = CreatedTypes[readerClass].GetMethod(readMethod, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.EmptyTypes);
340 ilg.Ldarg("reader");
343 ilg.EndMethod();
344 }
347 CreatedTypes.Add(type.Name, type);
348 return type.Name;
349 }
350
351 [RequiresUnreferencedCode("calls GetConstructor")]
353 {
354 string privateName = "typedSerializers";
355 FieldBuilder fieldBuilder = GenerateHashtableGetBegin(privateName, "TypedSerializers", serializerContractTypeBuilder);
356 MethodInfo method = typeof(Hashtable).GetMethod("Add", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, new Type[2]
357 {
358 typeof(object),
359 typeof(object)
360 });
361 foreach (string key in serializers.Keys)
362 {
363 ConstructorInfo constructor = CreatedTypes[serializers[key]].GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.EmptyTypes);
364 ilg.Ldloc(typeof(Hashtable), "_tmp");
365 ilg.Ldstr(GetCSharpString(key));
366 ilg.New(constructor);
367 ilg.Call(method);
368 }
369 GenerateHashtableGetEnd(fieldBuilder);
370 return fieldBuilder;
371 }
372
373 [RequiresUnreferencedCode("Uses CreatedTypes Dictionary")]
375 {
377 ilg.BeginMethod(typeof(XmlSerializer), "GetSerializer", new Type[1] { typeof(Type) }, new string[1] { "type" }, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig);
378 for (int i = 0; i < xmlMappings.Length; i++)
379 {
381 {
382 Type type = xmlMappings[i].Accessor.Mapping.TypeDesc.Type;
383 if (!(type == null) && (type.IsPublic || type.IsNestedPublic) && !type.IsGenericType && !type.ContainsGenericParameters)
384 {
385 ilg.Ldarg("type");
386 ilg.Ldc(type);
387 ilg.If(Cmp.EqualTo);
388 ConstructorInfo constructor = CreatedTypes[serializers[xmlMappings[i].Key]].GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.EmptyTypes);
389 ilg.New(constructor);
390 ilg.Stloc(ilg.ReturnLocal);
391 ilg.Br(ilg.ReturnLabel);
392 ilg.EndIf();
393 }
394 }
395 }
396 ilg.Load(null);
397 ilg.Stloc(ilg.ReturnLocal);
398 ilg.Br(ilg.ReturnLabel);
399 ilg.MarkLabel(ilg.ReturnLabel);
400 ilg.Ldloc(ilg.ReturnLocal);
401 ilg.EndMethod();
402 }
403
404 [RequiresUnreferencedCode("calls GenerateTypedSerializers")]
406 {
407 TypeBuilder typeBuilder = CodeGenerator.CreateTypeBuilder(_moduleBuilder, "XmlSerializerContract", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(XmlSerializerImplementation), Type.EmptyTypes);
408 ilg = new CodeGenerator(typeBuilder);
409 PropertyBuilder propertyBuilder = typeBuilder.DefineProperty("Reader", PropertyAttributes.None, typeof(XmlSerializationReader), null, null, null, null, null);
410 ilg.BeginMethod(typeof(XmlSerializationReader), "get_Reader", Type.EmptyTypes, Array.Empty<string>(), MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName);
411 propertyBuilder.SetGetMethod(ilg.MethodBuilder);
412 ConstructorInfo constructor = CreatedTypes[readerType].GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.EmptyTypes);
413 ilg.New(constructor);
414 ilg.EndMethod();
415 ilg = new CodeGenerator(typeBuilder);
416 propertyBuilder = typeBuilder.DefineProperty("Writer", PropertyAttributes.None, typeof(XmlSerializationWriter), null, null, null, null, null);
417 ilg.BeginMethod(typeof(XmlSerializationWriter), "get_Writer", Type.EmptyTypes, Array.Empty<string>(), MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName);
418 propertyBuilder.SetGetMethod(ilg.MethodBuilder);
419 constructor = CreatedTypes[writerType].GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Type.EmptyTypes);
420 ilg.New(constructor);
421 ilg.EndMethod();
422 FieldBuilder memberInfo = GeneratePublicMethods("readMethods", "ReadMethods", readMethods, xmlMappings, typeBuilder);
423 FieldBuilder memberInfo2 = GeneratePublicMethods("writeMethods", "WriteMethods", writerMethods, xmlMappings, typeBuilder);
424 FieldBuilder memberInfo3 = GenerateTypedSerializers(serializers, typeBuilder);
425 GenerateSupportedTypes(types, typeBuilder);
426 GenerateGetSerializer(serializers, xmlMappings, typeBuilder);
428 ilg = new CodeGenerator(typeBuilder);
429 ilg.BeginMethod(typeof(void), ".ctor", Type.EmptyTypes, Array.Empty<string>(), MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
430 ilg.Ldarg(0);
431 ilg.Load(null);
433 ilg.Ldarg(0);
434 ilg.Load(null);
436 ilg.Ldarg(0);
437 ilg.Load(null);
439 ilg.Ldarg(0);
440 ilg.Call(constructor2);
441 ilg.EndMethod();
442 Type type = typeBuilder.CreateTypeInfo().AsType();
443 CreatedTypes.Add(type.Name, type);
444 }
445
446 internal static bool IsWildcard(SpecialMapping mapping)
447 {
449 {
450 return ((SerializableMapping)mapping).IsAny;
451 }
452 return mapping.TypeDesc.CanBeElementValue;
453 }
454
455 [RequiresUnreferencedCode("calls ILGenLoad")]
456 internal void ILGenLoad(string source)
457 {
458 ILGenLoad(source, null);
459 }
460
461 [RequiresUnreferencedCode("calls LoadMember")]
462 internal void ILGenLoad(string source, Type type)
463 {
464 if (source.StartsWith("o.@", StringComparison.Ordinal))
465 {
466 MemberInfo memberInfo = memberInfos[source.Substring(3)];
467 ilg.LoadMember(ilg.GetVariable("o"), memberInfo);
468 if (type != null)
469 {
470 Type source2 = ((memberInfo is FieldInfo) ? ((FieldInfo)memberInfo).FieldType : ((PropertyInfo)memberInfo).PropertyType);
472 }
473 }
474 else
475 {
476 SourceInfo sourceInfo = new SourceInfo(source, null, null, null, ilg);
477 sourceInfo.Load(type);
478 }
479 }
480}
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
bool ICollection< KeyValuePair< TKey, TValue > >. Contains(KeyValuePair< TKey, TValue > keyValuePair)
void Add(TKey key, TValue value)
ConstructorBuilder DefineDefaultConstructor(MethodAttributes attributes)
static int DefineMethod(QCallModule module, int tkParent, string name, byte[] signature, int sigLength, MethodAttributes attributes)
static int DefineProperty(QCallModule module, int tkParent, string name, PropertyAttributes attributes, byte[] signature, int sigLength)
virtual Type AsType()
Definition TypeInfo.cs:106
static readonly Type[] EmptyTypes
Definition Type.cs:19
static string UnescapeName(string name)
Definition Accessor.cs:191
void ConvertValue(Type source, Type target)
LocalBuilder DeclareLocal(Type type, string name)
void StoreMember(MemberInfo memberInfo)
void New(ConstructorInfo constructorInfo)
void BeginMethod(Type returnType, string methodName, Type[] argTypes, string[] argNames, MethodAttributes methodAttributes)
static TypeBuilder CreateTypeBuilder(ModuleBuilder moduleBuilder, string name, TypeAttributes attributes, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type parent, Type[] interfaces)
Type LoadMember(object obj, MemberInfo memberInfo)
void Call(MethodInfo methodInfo)
void Stloc(Type type, string name)
void Ldloc(LocalBuilder localBuilder)
static string MakeValid(string identifier)
static string GetCSharpName(string name)
TypeDesc GetTypeDesc(string name, string ns)
Definition TypeScope.cs:224
void GenerateHashtableGetEnd(FieldBuilder fieldBuilder)
void GenerateSupportedTypes(Type[] types, TypeBuilder serializerContractTypeBuilder)
void GenerateSerializerContract(string className, XmlMapping[] xmlMappings, Type[] types, string readerType, string[] readMethods, string writerType, string[] writerMethods, Dictionary< string, string > serializers)
XmlSerializationILGen(TypeScope[] scopes, string access, string className)
string GenerateTypedSerializer(string readMethod, string writeMethod, XmlMapping mapping, CodeIdentifiers classes, string baseSerializer, string readerClass, string writerClass)
readonly Dictionary< string, MethodBuilderInfo > _methodBuilders
string GenerateBaseSerializer(string baseSerializer, string readerClass, string writerClass, CodeIdentifiers classes)
static readonly Dictionary< string, Regex > s_regexs
TypeMapping[] EnsureArrayIndex(TypeMapping[] a, int index)
FieldBuilder GeneratePublicMethods(string privateName, string publicName, string[] methods, XmlMapping[] xmlMappings, TypeBuilder serializerContractTypeBuilder)
MethodBuilder EnsureMethodBuilder(TypeBuilder typeBuilder, string methodName, MethodAttributes attributes, Type returnType, Type[] parameterTypes)
static bool IsWildcard(SpecialMapping mapping)
void GenerateGetSerializer(Dictionary< string, string > serializers, XmlMapping[] xmlMappings, TypeBuilder serializerContractTypeBuilder)
FieldBuilder GenerateTypedSerializers(Dictionary< string, string > serializers, TypeBuilder serializerContractTypeBuilder)
readonly Dictionary< TypeMapping, string > _methodNames
FieldBuilder GenerateHashtableGetBegin(string privateName, string publicName, TypeBuilder serializerContractTypeBuilder)
MethodBuilderInfo GetMethodBuilder(string methodName)