Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
JsonFormatWriterGenerator.cs
Go to the documentation of this file.
6using System.Xml;
7
9
10internal sealed class JsonFormatWriterGenerator
11{
12 private sealed class CriticalHelper
13 {
15
17
19
21
23
25
26 private int _typeIndex = 1;
27
28 private int _childElementIndex;
29
30 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
31 internal JsonFormatClassWriterDelegate GenerateClassWriter(ClassDataContract classContract)
32 {
33 _ilg = new CodeGenerator();
34 bool flag = classContract.RequiresMemberAccessForWrite(null);
35 try
36 {
37 BeginMethod(_ilg, "Write" + DataContract.SanitizeTypeName(classContract.StableName.Name) + "ToJson", typeof(JsonFormatClassWriterDelegate), flag);
38 }
40 {
41 if (!flag)
42 {
43 throw;
44 }
45 classContract.RequiresMemberAccessForWrite(securityException);
46 }
47 InitArgs(classContract.UnderlyingType);
50 return (JsonFormatClassWriterDelegate)_ilg.EndMethod();
51 }
52
53 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
54 internal JsonFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
55 {
56 _ilg = new CodeGenerator();
57 bool flag = collectionContract.RequiresMemberAccessForWrite(null);
58 try
59 {
60 BeginMethod(_ilg, "Write" + DataContract.SanitizeTypeName(collectionContract.StableName.Name) + "ToJson", typeof(JsonFormatCollectionWriterDelegate), flag);
61 }
63 {
64 if (!flag)
65 {
66 throw;
67 }
68 collectionContract.RequiresMemberAccessForWrite(securityException);
69 }
70 InitArgs(collectionContract.UnderlyingType);
71 if (collectionContract.IsReadOnlyContract)
72 {
74 }
76 return (JsonFormatCollectionWriterDelegate)_ilg.EndMethod();
77 }
78
80 {
82 ParameterInfo[] parameters = invokeMethod.GetParameters();
83 Type[] array = new Type[parameters.Length];
84 for (int i = 0; i < parameters.Length; i++)
85 {
86 array[i] = parameters[i].ParameterType;
87 }
90 }
91
92 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
93 private void InitArgs(Type objType)
94 {
98 _objectLocal = _ilg.DeclareLocal(objType, "objSerialized");
100 _ilg.Load(arg);
102 {
105 }
107 {
110 }
111 else if (objType.IsGenericType && objType.GetGenericTypeDefinition() == Globals.TypeOfKeyValuePairAdapter)
112 {
114 _ilg.ConvertValue(arg.ArgType, Globals.TypeOfKeyValuePair.MakeGenericType(classDataContract.KeyValuePairGenericArguments));
115 _ilg.New(classDataContract.KeyValuePairAdapterConstructorInfo);
116 }
117 else
118 {
119 _ilg.ConvertValue(arg.ArgType, objType);
120 }
122 }
123
128
140
142 {
143 if (classContract.BaseContract != null)
144 {
146 }
147 if (classContract.OnSerializing != null)
148 {
152 _ilg.Call(classContract.OnSerializing);
153 }
154 }
155
157 {
158 if (classContract.BaseContract != null)
159 {
160 InvokeOnSerialized(classContract.BaseContract);
161 }
162 if (classContract.OnSerialized != null)
163 {
167 _ilg.Call(classContract.OnSerialized);
168 }
169 }
170
171 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
195
196 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
198 {
200 int count = classContract.Members.Count;
202 int num2 = 0;
203 while (num2 < count)
204 {
210 if (!dataMember.EmitDefaultValue)
211 {
214 }
216 if (flag || !TryWritePrimitive(memberType, localBuilder, dataMember.MemberInfo, null, null, num2 + _childElementIndex))
217 {
218 if (flag)
219 {
221 }
222 else
223 {
225 }
226 if (localBuilder == null)
227 {
229 }
232 }
233 if (classContract.HasExtensionData)
234 {
236 }
237 if (!dataMember.EmitDefaultValue)
238 {
239 if (dataMember.IsRequired)
240 {
241 _ilg.Else();
243 }
244 _ilg.EndIf();
245 }
246 num2++;
247 num++;
248 }
249 _typeIndex++;
251 return num;
252 }
253
262
263 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
265 {
270 if (collectionContract.Kind == CollectionKind.Array)
271 {
276 {
280 {
287 }
288 _ilg.EndFor();
289 }
290 return;
291 }
292 MethodInfo methodInfo = null;
293 switch (collectionContract.Kind)
294 {
295 case CollectionKind.Dictionary:
296 case CollectionKind.List:
297 case CollectionKind.Collection:
299 break;
300 case CollectionKind.GenericList:
301 case CollectionKind.GenericCollection:
303 break;
304 case CollectionKind.GenericDictionary:
306 break;
307 }
308 if (methodInfo != null)
309 {
311 }
312 bool flag = false;
313 bool flag2 = false;
314 Type type = null;
315 Type[] array = null;
316 if (collectionContract.Kind == CollectionKind.GenericDictionary)
317 {
318 flag2 = true;
321 }
322 else if (collectionContract.Kind == CollectionKind.Dictionary)
323 {
324 flag = true;
325 array = new Type[2]
326 {
329 };
331 }
332 else
333 {
334 type = collectionContract.GetEnumeratorMethod.ReturnType;
335 }
336 MethodInfo methodInfo2 = type.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.Public, Type.EmptyTypes);
337 MethodInfo methodInfo3 = type.GetMethod("get_Current", BindingFlags.Instance | BindingFlags.Public, Type.EmptyTypes);
338 if (methodInfo2 == null || methodInfo3 == null)
339 {
340 if (type.IsInterface)
341 {
342 if (methodInfo2 == null)
343 {
345 }
346 if (methodInfo3 == null)
347 {
349 }
350 }
351 else
352 {
355 if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
356 {
357 Type[] interfaces = type.GetInterfaces();
358 Type[] array2 = interfaces;
359 foreach (Type type2 in array2)
360 {
361 if (type2.IsGenericType && type2.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric && type2.GetGenericArguments()[0] == collectionContract.ItemType)
362 {
364 break;
365 }
366 }
367 }
368 if (methodInfo2 == null)
369 {
371 }
372 if (methodInfo3 == null)
373 {
375 }
376 }
377 }
378 Type returnType = methodInfo3.ReturnType;
381 _ilg.Call(_objectLocal, collectionContract.GetEnumeratorMethod);
382 if (flag)
383 {
384 ConstructorInfo constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, new Type[1] { Globals.TypeOfIDictionaryEnumerator });
387 }
388 else if (flag2)
389 {
390 Type type3 = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(array));
391 ConstructorInfo constructor2 = type.GetConstructor(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, new Type[1] { type3 });
392 _ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, type3);
394 }
396 bool flag3 = flag || flag2;
397 if (flag3)
398 {
399 Type type4 = Globals.TypeOfKeyValue.MakeGenericType(array);
400 PropertyInfo property = type4.GetProperty("Key");
401 PropertyInfo property2 = type4.GetProperty("Value");
404 _ilg.If();
411 _ilg.ToString(array[0]);
420 _ilg.Else();
421 }
424 if (methodInfo == null)
425 {
427 }
429 {
431 if (flag2 || flag)
432 {
440 _ilg.Load(localBuilder4.LocalType);
443 }
444 else
445 {
447 }
449 }
451 if (flag3)
452 {
453 _ilg.EndIf();
454 }
455 [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2060:MakeGenericMethod", Justification = "The call to MakeGenericMethod is safe due to the fact that IncrementCollectionCountGeneric is not annotated.")]
457 {
459 }
460 }
461
462 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
464 {
466 if (primitiveDataContract == null || primitiveDataContract.UnderlyingType == Globals.TypeOfObject)
467 {
468 return false;
469 }
470 if (type.IsValueType)
471 {
473 }
474 else
475 {
478 }
479 if (value != null)
480 {
481 _ilg.Load(value);
482 }
483 else if (memberInfo != null)
484 {
487 }
488 else
489 {
491 }
492 if (name != null)
493 {
494 _ilg.Load(name);
495 }
496 else
497 {
499 }
500 _ilg.Load(null);
501 _ilg.Call(primitiveDataContract.XmlFormatWriterMethod);
502 return true;
503 }
504
505 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
507 {
509 if (primitiveDataContract == null)
510 {
511 return false;
512 }
513 string text = null;
514 switch (Type.GetTypeCode(itemType))
515 {
516 case TypeCode.Boolean:
517 text = "WriteJsonBooleanArray";
518 break;
519 case TypeCode.DateTime:
520 text = "WriteJsonDateTimeArray";
521 break;
522 case TypeCode.Decimal:
523 text = "WriteJsonDecimalArray";
524 break;
525 case TypeCode.Int32:
526 text = "WriteJsonInt32Array";
527 break;
528 case TypeCode.Int64:
529 text = "WriteJsonInt64Array";
530 break;
531 case TypeCode.Single:
532 text = "WriteJsonSingleArray";
533 break;
534 case TypeCode.Double:
535 text = "WriteJsonDoubleArray";
536 break;
537 }
538 if (text != null)
539 {
541 MethodInfo method = typeof(JsonWriterDelegator).GetMethod(text, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, new Type[3]
542 {
543 type,
544 typeof(XmlDictionaryString),
545 typeof(XmlDictionaryString)
546 });
548 return true;
549 }
550 return false;
551 }
552
553 private void WriteArrayAttribute()
554 {
555 _ilg.Call(_xmlWriterArg, JsonFormatGeneratorStatics.WriteAttributeStringMethod, null, "type", string.Empty, "array");
556 }
557
558 private void WriteObjectAttribute()
559 {
561 }
562
563 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
565 {
566 Type type = memberValue.LocalType;
567 if (type.IsPointer)
568 {
570 _ilg.Load(type);
573 memberValue = _ilg.DeclareLocal(type, "memberValueRefPointer");
575 }
576 bool flag = type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfNullable;
577 if (type.IsValueType && !flag)
578 {
580 if (primitiveDataContract != null)
581 {
582 _ilg.Call(_xmlWriterArg, primitiveDataContract.XmlFormatContentWriterMethod, memberValue);
583 }
584 else
585 {
587 }
588 return;
589 }
590 if (flag)
591 {
593 type = memberValue.LocalType;
594 }
595 else
596 {
598 _ilg.Load(null);
599 _ilg.Ceq();
600 }
601 _ilg.If();
603 _ilg.Else();
605 if (primitiveDataContract2 != null && primitiveDataContract2.UnderlyingType != Globals.TypeOfObject)
606 {
607 if (flag)
608 {
609 _ilg.Call(_xmlWriterArg, primitiveDataContract2.XmlFormatContentWriterMethod, memberValue);
610 }
611 else
612 {
613 _ilg.Call(_contextArg, primitiveDataContract2.XmlFormatContentWriterMethod, _xmlWriterArg, memberValue);
614 }
615 }
616 else
617 {
618 if (type == Globals.TypeOfObject || type == Globals.TypeOfValueType || ((IList)Globals.TypeOfNullable.GetInterfaces()).Contains((object?)type))
619 {
622 memberValue = _ilg.DeclareLocal(Globals.TypeOfObject, "unwrappedMemberValue");
625 _ilg.If(memberValue, Cmp.EqualTo, null);
627 _ilg.Else();
628 }
631 {
632 _ilg.EndIf();
633 }
634 }
635 _ilg.EndIf();
636 }
637
656
658 {
659 Type type = memberValue.LocalType;
663 while (type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfNullable)
664 {
666 _ilg.Dup();
667 _ilg.Call(typeof(Nullable<>).MakeGenericType(type2).GetMethod("get_HasValue"));
669 _ilg.Call(typeof(Nullable<>).MakeGenericType(type2).GetMethod("get_Value"));
670 type = type2;
671 }
672 memberValue = _ilg.DeclareLocal(type, "nullableUnwrappedMemberValue");
674 _ilg.Load(false);
675 _ilg.Br(label2);
677 _ilg.Pop();
680 _ilg.Load(true);
682 return memberValue;
683 }
684
686 {
688 if (nameLocal == null)
689 {
691 }
692 else
693 {
695 }
696 _ilg.Load(null);
697 if (nameLocal != null && nameLocal.LocalType == typeof(string))
698 {
700 }
701 else
702 {
704 }
705 }
706
711 }
712
713 private readonly CriticalHelper _helper;
714
716 {
717 _helper = new CriticalHelper();
718 }
719
720 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
721 internal JsonFormatClassWriterDelegate GenerateClassWriter(ClassDataContract classContract)
722 {
724 }
725
726 [RequiresUnreferencedCode("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")]
731
732 [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern", Justification = "The trimmer will never remove the Invoke method from delegates.")]
734 {
735 return delegateType.GetMethod("Invoke");
736 }
737}
void LoadArrayElement(object obj, object arrayIndex)
void EndForEach(MethodInfo moveNextMethod)
void Call(object thisObj, MethodInfo methodInfo)
void BeginMethod(DynamicMethod dynamicMethod, Type delegateType, string methodName, Type[] argTypes, bool allowPrivateMemberAccess)
Type LoadMember(MemberInfo memberInfo)
object For(LocalBuilder local, object start, object end)
LocalBuilder DeclareLocal(Type type, string name, object initialValue)
void ForEach(LocalBuilder local, Type elementType, Type enumeratorType, LocalBuilder enumerator, MethodInfo getCurrentMethod)
void ConvertValue(Type source, Type target)
void New(ConstructorInfo constructorInfo)
static MethodInfo GetTargetMethodWithName(string name, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type interfaceType)
static int GetId(RuntimeTypeHandle typeHandle)
static string SanitizeTypeName(string typeName)
static DataContract GetDataContract(Type type)
void BeginMethod(CodeGenerator ilg, string methodName, Type delegateType, bool allowPrivateMemberAccess)
bool TryWritePrimitive(Type type, LocalBuilder value, MemberInfo memberInfo, LocalBuilder arrayItemIndex, LocalBuilder name, int nameIndex)
void ThrowIfCannotSerializeReadOnlyTypes(PropertyInfo serializationExceptionMessageProperty)
void InternalSerialize(MethodInfo methodInfo, LocalBuilder memberValue, Type memberType, bool writeXsiType)
JsonFormatClassWriterDelegate GenerateClassWriter(ClassDataContract classContract)
int WriteMembers(ClassDataContract classContract, LocalBuilder extensionDataLocal, ClassDataContract derivedMostClassContract)
JsonFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
bool TryWritePrimitiveArray(Type type, Type itemType, LocalBuilder value, LocalBuilder itemName)
JsonFormatClassWriterDelegate GenerateClassWriter(ClassDataContract classContract)
JsonFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
static PrimitiveDataContract GetPrimitiveDataContract(Type type)
virtual Type[] GetGenericArguments()
Definition Type.cs:500
override MemberTypes MemberType
Definition Type.cs:41
static TypeCode GetTypeCode(Type? type)
Definition Type.cs:919
Type[] GetInterfaces()
static readonly Type[] EmptyTypes
Definition Type.cs:19
TypeCode
Definition TypeCode.cs:4