Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
JsonTypeInfo.cs
Go to the documentation of this file.
9
11
13public abstract class JsonTypeInfo<T> : JsonTypeInfo
14{
16
18 {
19 get
20 {
21 return _serialize;
22 }
23 private protected set
24 {
26 base.HasSerialize = value != null;
27 }
28 }
29
34}
35[DebuggerDisplay("ConverterStrategy.{ConverterStrategy}, {Type.Name}")]
36public class JsonTypeInfo
37{
38 internal delegate object ConstructorDelegate();
39
41
42 private sealed class ParameterLookupKey
43 {
44 public string Name { get; }
45
46 public Type Type { get; }
47
48 public ParameterLookupKey(string name, Type type)
49 {
50 Name = name;
51 Type = type;
52 }
53
54 public override int GetHashCode()
55 {
56 return StringComparer.OrdinalIgnoreCase.GetHashCode(Name);
57 }
58
59 public override bool Equals([NotNullWhen(true)] object obj)
60 {
62 if (Type == parameterLookupKey.Type)
63 {
64 return string.Equals(Name, parameterLookupKey.Name, StringComparison.OrdinalIgnoreCase);
65 }
66 return false;
67 }
68 }
69
70 private sealed class ParameterLookupValue
71 {
72 public string DuplicateName { get; set; }
73
75
80 }
81
82 internal static readonly Type ObjectType = typeof(object);
83
84 private const int PropertyNameKeyLength = 7;
85
86 private const int ParameterNameCountCacheThreshold = 32;
87
88 private const int PropertyNameCountCacheThreshold = 64;
89
91
93
95
96 private volatile PropertyRef[] _propertyRefsSorted;
97
99
101
102 internal const string JsonObjectTypeName = "System.Text.Json.Nodes.JsonObject";
103
105
107
109
110 internal int ParameterCount { get; private set; }
111
112 internal ConstructorDelegate? CreateObject { get; set; }
113
114 internal object? CreateObjectWithArgs { get; set; }
115
116 internal object? AddMethodDelegate { get; set; }
117
118 internal JsonPropertyInfo? DataExtensionProperty { get; private set; }
119
120 internal bool HasSerialize { get; set; }
121
123 {
124 get
125 {
126 if (_elementTypeInfo == null && ElementType != null)
127 {
129 }
130 return _elementTypeInfo;
131 }
132 set
133 {
135 }
136 }
137
138 internal Type? ElementType { get; set; }
139
141 {
142 get
143 {
144 if (_keyTypeInfo == null && KeyType != null)
145 {
147 }
148 return _keyTypeInfo;
149 }
150 set
151 {
153 }
154 }
155
156 internal Type? KeyType { get; set; }
157
158 internal JsonSerializerOptions Options { get; set; }
159
160 internal Type Type { get; private set; }
161
163
165
167 {
168 get
169 {
170 if (_genericMethods == null)
171 {
173 }
174 return _genericMethods;
175 }
176 }
177
178 internal JsonNumberHandling? NumberHandling { get; set; }
179
191
198
203
204 [MethodImpl(MethodImplOptions.AggressiveInlining)]
206 {
207 ulong key = GetKey(propertyName);
209 if (propertyRefsSorted != null)
210 {
211 int propertyIndex = frame.PropertyIndex;
212 int num = propertyRefsSorted.Length;
213 int num2 = Math.Min(propertyIndex, num);
214 int num3 = num2 - 1;
215 while (true)
216 {
217 if (num2 < num)
218 {
221 {
222 utf8PropertyName = propertyRef.NameFromJson;
223 return propertyRef.Info;
224 }
225 num2++;
226 if (num3 >= 0)
227 {
230 {
231 utf8PropertyName = propertyRef.NameFromJson;
232 return propertyRef.Info;
233 }
234 num3--;
235 }
236 }
237 else
238 {
239 if (num3 < 0)
240 {
241 break;
242 }
245 {
246 utf8PropertyName = propertyRef.NameFromJson;
247 return propertyRef.Info;
248 }
249 num3--;
250 }
251 }
252 }
254 {
256 {
257 if (propertyName.SequenceEqual(value.NameAsUtf8Bytes))
258 {
259 utf8PropertyName = value.NameAsUtf8Bytes;
260 }
261 else
262 {
263 utf8PropertyName = propertyName.ToArray();
264 }
265 }
266 else
267 {
268 utf8PropertyName = value.NameAsUtf8Bytes;
269 }
270 }
271 else
272 {
274 utf8PropertyName = propertyName.ToArray();
275 }
276 int num4 = 0;
277 if (propertyRefsSorted != null)
278 {
279 num4 = propertyRefsSorted.Length;
280 }
281 if (num4 < 64)
282 {
283 if (frame.PropertyRefCache != null)
284 {
285 num4 += frame.PropertyRefCache.Count;
286 }
287 if (num4 < 64)
288 {
289 if (frame.PropertyRefCache == null)
290 {
292 }
294 frame.PropertyRefCache.Add(propertyRef);
295 }
296 }
297 return value;
298 }
299
300 [MethodImpl(MethodImplOptions.AggressiveInlining)]
302 {
303 ulong key = GetKey(propertyName);
305 if (parameterRefsSorted != null)
306 {
307 int parameterIndex = frame.CtorArgumentState.ParameterIndex;
308 int num = parameterRefsSorted.Length;
309 int num2 = Math.Min(parameterIndex, num);
310 int num3 = num2 - 1;
311 while (true)
312 {
313 if (num2 < num)
314 {
317 {
318 utf8PropertyName = parameterRef.NameFromJson;
319 return parameterRef.Info;
320 }
321 num2++;
322 if (num3 >= 0)
323 {
326 {
327 utf8PropertyName = parameterRef.NameFromJson;
328 return parameterRef.Info;
329 }
330 num3--;
331 }
332 }
333 else
334 {
335 if (num3 < 0)
336 {
337 break;
338 }
341 {
342 utf8PropertyName = parameterRef.NameFromJson;
343 return parameterRef.Info;
344 }
345 num3--;
346 }
347 }
348 }
350 {
352 {
353 if (propertyName.SequenceEqual(value.NameAsUtf8Bytes))
354 {
355 utf8PropertyName = value.NameAsUtf8Bytes;
356 }
357 else
358 {
359 utf8PropertyName = propertyName.ToArray();
360 }
361 }
362 else
363 {
364 utf8PropertyName = value.NameAsUtf8Bytes;
365 }
366 }
367 else
368 {
369 utf8PropertyName = propertyName.ToArray();
370 }
371 int num4 = 0;
372 if (parameterRefsSorted != null)
373 {
374 num4 = parameterRefsSorted.Length;
375 }
376 if (num4 < 32)
377 {
378 if (frame.CtorArgumentState.ParameterRefCache != null)
379 {
380 num4 += frame.CtorArgumentState.ParameterRefCache.Count;
381 }
382 if (num4 < 32)
383 {
384 if (frame.CtorArgumentState.ParameterRefCache == null)
385 {
387 }
389 frame.CtorArgumentState.ParameterRefCache.Add(parameterRef);
390 }
391 }
392 return value;
393 }
394
395 [MethodImpl(MethodImplOptions.AggressiveInlining)]
397 {
398 if (key == propertyRef.Key && (propertyName.Length <= 7 || propertyName.SequenceEqual(propertyRef.NameFromJson)))
399 {
400 return true;
401 }
402 return false;
403 }
404
405 [MethodImpl(MethodImplOptions.AggressiveInlining)]
407 {
408 if (key == parameterRef.Key && (parameterName.Length <= 7 || parameterName.SequenceEqual(parameterRef.NameFromJson)))
409 {
410 return true;
411 }
412 return false;
413 }
414
415 [MethodImpl(MethodImplOptions.AggressiveInlining)]
416 internal static ulong GetKey(ReadOnlySpan<byte> name)
417 {
418 ref byte reference = ref MemoryMarshal.GetReference(name);
419 int length = name.Length;
420 ulong num;
421 if (length > 7)
422 {
423 num = Unsafe.ReadUnaligned<ulong>(ref reference) & 0xFFFFFFFFFFFFFFuL;
424 num |= (ulong)((long)Math.Min(length, 255) << 56);
425 }
426 else
427 {
428 num = ((length > 5) ? (Unsafe.ReadUnaligned<uint>(ref reference) | ((ulong)Unsafe.ReadUnaligned<ushort>(ref Unsafe.Add(ref reference, 4)) << 32)) : ((length > 3) ? ((ulong)Unsafe.ReadUnaligned<uint>(ref reference)) : ((ulong)((length > 1) ? Unsafe.ReadUnaligned<ushort>(ref reference) : 0))));
429 num |= (ulong)((long)length << 56);
430 if (((uint)length & (true ? 1u : 0u)) != 0)
431 {
432 int num2 = length - 1;
433 num |= (ulong)Unsafe.Add(ref reference, num2) << num2 * 8;
434 }
435 }
436 return num;
437 }
438
440 {
441 List<PropertyRef> propertyRefCache = frame.PropertyRefCache;
442 if (_propertyRefsSorted != null)
443 {
445 while (list.Count + propertyRefCache.Count > 64)
446 {
448 }
450 _propertyRefsSorted = list.ToArray();
451 }
452 else
453 {
455 }
457 }
458
460 {
461 List<ParameterRef> parameterRefCache = frame.CtorArgumentState.ParameterRefCache;
462 if (_parameterRefsSorted != null)
463 {
465 while (list.Count + parameterRefCache.Count > 32)
466 {
468 }
470 _parameterRefsSorted = list.ToArray();
471 }
472 else
473 {
475 }
477 }
478
514
528
529 internal JsonTypeInfo()
530 {
531 }
532
534 {
535 Type = type;
536 Options = options ?? throw new ArgumentNullException("options");
538 }
539
540 [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
545
546 [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
548 {
549 Type = type;
553 ElementType = converter.ElementType;
555 {
556 case ConverterStrategy.Object:
557 {
558 CreateObject = Options.MemberAccessorStrategy.CreateConstructor(type);
560 PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
561 bool propertyOrderSpecified = false;
563 Type type2 = type;
564 while (true)
565 {
566 PropertyInfo[] array = properties;
567 foreach (PropertyInfo propertyInfo in array)
568 {
569 bool flag = propertyInfo.IsVirtual();
570 string name = propertyInfo.Name;
571 if (propertyInfo.GetIndexParameters().Length != 0 || PropertyIsOverridenAndIgnored(name, propertyInfo.PropertyType, flag, ignoredMembers))
572 {
573 continue;
574 }
575 MethodInfo? getMethod = propertyInfo.GetMethod;
576 if ((object)getMethod == null || !getMethod.IsPublic)
577 {
578 MethodInfo? setMethod = propertyInfo.SetMethod;
579 if ((object)setMethod == null || !setMethod.IsPublic)
580 {
581 if (JsonPropertyInfo.GetAttribute<JsonIncludeAttribute>(propertyInfo) != null)
582 {
584 }
585 continue;
586 }
587 }
589 }
590 FieldInfo[] fields = type2.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
591 foreach (FieldInfo fieldInfo in fields)
592 {
593 string name2 = fieldInfo.Name;
595 {
596 continue;
597 }
598 bool flag2 = JsonPropertyInfo.GetAttribute<JsonIncludeAttribute>(fieldInfo) != null;
599 if (fieldInfo.IsPublic)
600 {
602 {
604 }
605 }
606 else if (flag2)
607 {
609 }
610 }
611 type2 = type2.BaseType;
612 if (type2 == null)
613 {
614 break;
615 }
616 properties = type2.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
617 }
619 {
620 PropertyCache.List.Sort((KeyValuePair<string, JsonPropertyInfo> p1, KeyValuePair<string, JsonPropertyInfo> p2) => p1.Value.Order.CompareTo(p2.Value.Order));
621 }
622 if (converter.ConstructorIsParameterized)
623 {
625 ParameterInfo[] parameters = converter.ConstructorInfo.GetParameters();
626 int num = parameters.Length;
629 }
630 break;
631 }
632 case ConverterStrategy.Enumerable:
634 if (converter.RequiresDynamicMemberAccessors)
635 {
636 converter.Initialize(Options, this);
637 }
638 break;
639 case ConverterStrategy.Dictionary:
640 KeyType = converter.KeyType;
642 if (converter.RequiresDynamicMemberAccessors)
643 {
644 converter.Initialize(Options, this);
645 }
646 break;
647 case ConverterStrategy.Value:
648 CreateObject = Options.MemberAccessorStrategy.CreateConstructor(type);
649 break;
650 case ConverterStrategy.None:
652 break;
653 default:
654 throw new InvalidOperationException();
655 }
656 }
657
674
699
701 {
705 {
707 string clrName = value.ClrName;
708 ParameterLookupKey key = new ParameterLookupKey(clrName, value.DeclaredPropertyType);
710 if (!dictionary.TryAdd(in key, in value2))
711 {
714 }
715 }
717 {
719 if (dictionary.TryGetValue(parameterLookupKey, out var value3))
720 {
721 if (value3.DuplicateName != null)
722 {
724 }
725 JsonPropertyInfo jsonPropertyInfo = value3.JsonPropertyInfo;
728 }
730 {
732 }
733 }
736 }
737
739 {
740 int num = parameters.Length;
742 for (int i = 0; i < num; i++)
743 {
744 ParameterInfo parameterInfo = parameters[i];
746 {
747 Name = parameterInfo.Name,
748 ParameterType = parameterInfo.ParameterType,
749 Position = parameterInfo.Position,
750 HasDefaultValue = parameterInfo.HasDefaultValue,
751 DefaultValue = parameterInfo.GetDefaultValue()
752 };
754 }
755 return array;
756 }
757
759 {
761 {
762 return false;
763 }
764 if (currentMemberType == value.DeclaredPropertyType && currentMemberIsVirtual)
765 {
766 return value.IsVirtual;
767 }
768 return false;
769 }
770
779
781 {
782 Type declaredPropertyType = jsonPropertyInfo.DeclaredPropertyType;
783 if (typeof(IDictionary<string, object>).IsAssignableFrom(declaredPropertyType) || typeof(IDictionary<string, JsonElement>).IsAssignableFrom(declaredPropertyType) || (declaredPropertyType.FullName == "System.Text.Json.Nodes.JsonObject" && (object)declaredPropertyType.Assembly == GetType().Assembly))
784 {
786 }
787 return false;
788 }
789
801
803 {
806 Type runtimeType2 = jsonConverter.RuntimeType;
807 if (type == runtimeType2)
808 {
810 }
811 else if (type.IsInterface)
812 {
814 }
815 else if (runtimeType2.IsInterface)
816 {
818 }
819 else if (type.IsAssignableFrom(runtimeType2))
820 {
822 }
823 else if (runtimeType2.IsAssignableFrom(type) || jsonConverter.TypeToConvert.IsAssignableFrom(type))
824 {
826 }
827 else
828 {
829 runtimeType = null;
831 }
832 return jsonConverter;
833 }
834
842
844 {
845 if (!type.IsPointer && !IsByRefLike(type))
846 {
847 return type.ContainsGenericParameters;
848 }
849 return true;
850 }
851
852 private static bool IsByRefLike(Type type)
853 {
854 return type.IsByRefLike;
855 }
856
861}
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
void AddRange(IEnumerable< KeyValuePair< TKey, TValue > > collection)
bool TryAdd(TKey key, TValue value)
void Add(TKey key, TValue value)
static byte Min(byte val1, byte val2)
Definition Math.cs:912
virtual ? MethodInfo GetMethod
virtual ? MethodInfo SetMethod
ParameterInfo[] GetIndexParameters()
static StringComparer OrdinalIgnoreCase
static string Utf8GetString(ReadOnlySpan< byte > bytes)
static Attribute GetAttributeThatCanHaveMultiple(Type classType, Type attributeType, MemberInfo memberInfo)
JsonConverter GetConverterInternal(Type typeToConvert)
static JsonParameterInfo CreateIgnoredParameterPlaceholder(JsonParameterInfoValues parameterInfo, JsonPropertyInfo matchingProperty, bool sourceGenMode)
static JsonPropertyInfo CreateIgnoredPropertyPlaceholder(MemberInfo memberInfo, Type memberType, bool isVirtual, JsonSerializerOptions options)
void InitializeConstructorParameters(JsonParameterInfoValues[] jsonParameters, bool sourceGenMode=false)
JsonTypeInfo(Type type, JsonConverter converter, Type runtimeType, JsonSerializerOptions options)
static void ValidateType(Type type, Type parentClassType, MemberInfo memberInfo, JsonSerializerOptions options)
void UpdateSortedPropertyCache(ref ReadStackFrame frame)
JsonTypeInfo(Type type, JsonSerializerOptions options)
JsonTypeInfo(Type type, JsonSerializerOptions options, bool dummy)
static JsonParameterInfo CreateConstructorParameter(JsonParameterInfoValues parameterInfo, JsonPropertyInfo jsonPropertyInfo, bool sourceGenMode, JsonSerializerOptions options)
Func< JsonSerializerContext, JsonPropertyInfo[]> PropInitFunc
static bool IsPropertyRefEqual(in PropertyRef propertyRef, ReadOnlySpan< byte > propertyName, ulong key)
void CacheMember(JsonPropertyInfo jsonPropertyInfo, JsonPropertyDictionary< JsonPropertyInfo > propertyCache, ref Dictionary< string, JsonPropertyInfo > ignoredMembers)
static ulong GetKey(ReadOnlySpan< byte > name)
JsonParameterInfo GetParameter(ReadOnlySpan< byte > propertyName, ref ReadStackFrame frame, out byte[] utf8PropertyName)
JsonPropertyDictionary< JsonParameterInfo > ParameterCache
void UpdateSortedParameterCache(ref ReadStackFrame frame)
static bool PropertyIsOverridenAndIgnored(string currentMemberName, Type currentMemberType, bool currentMemberIsVirtual, Dictionary< string, JsonPropertyInfo > ignoredMembers)
static JsonPropertyInfo AddProperty(MemberInfo memberInfo, Type memberType, Type parentClassType, bool isVirtual, JsonNumberHandling? parentTypeNumberHandling, JsonSerializerOptions options)
static JsonConverter GetConverter(Type type, Type parentClassType, MemberInfo memberInfo, out Type runtimeType, JsonSerializerOptions options)
JsonPropertyInfo GetProperty(ReadOnlySpan< byte > propertyName, ref ReadStackFrame frame, out byte[] utf8PropertyName)
static JsonPropertyInfo CreateProperty(Type declaredPropertyType, Type runtimePropertyType, MemberInfo memberInfo, Type parentClassType, bool isVirtual, JsonConverter converter, JsonSerializerOptions options, JsonNumberHandling? parentTypeNumberHandling=null, JsonIgnoreCondition? ignoreCondition=null)
void CacheMember(Type declaringType, Type memberType, MemberInfo memberInfo, bool isVirtual, JsonNumberHandling? typeNumberHandling, ref bool propertyOrderSpecified, ref Dictionary< string, JsonPropertyInfo > ignoredMembers)
void ValidateAndAssignDataExtensionProperty(JsonPropertyInfo jsonPropertyInfo)
Func< JsonParameterInfoValues[]> CtorParamInitFunc
bool IsValidDataExtensionProperty(JsonPropertyInfo jsonPropertyInfo)
static JsonParameterInfoValues[] GetParameterInfoArray(ParameterInfo[] parameters)
delegate T ParameterizedConstructorDelegate< T, TArg0, TArg1, TArg2, TArg3 >(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3)
JsonPropertyDictionary< JsonPropertyInfo > PropertyCache
static ? JsonNumberHandling GetNumberHandlingForType(Type type)
static JsonPropertyInfo CreatePropertyInfoForTypeInfo(Type declaredPropertyType, Type runtimePropertyType, JsonConverter converter, JsonNumberHandling? numberHandling, JsonSerializerOptions options)
static bool IsParameterRefEqual(in ParameterRef parameterRef, ReadOnlySpan< byte > parameterName, ulong key)
static void ThrowInvalidOperationException_JsonIncludeOnNonPublicInvalid(string memberName, Type declaringType)
static void ThrowInvalidOperationException_SerializationDuplicateTypeAttribute(Type classType, Type attribute)
static void ThrowInvalidOperationException_CannotSerializeInvalidType(Type type, Type parentClassType, MemberInfo memberInfo)
static void ThrowInvalidOperationException_SerializationDataExtensionPropertyInvalid(Type type, JsonPropertyInfo jsonPropertyInfo)
static void ThrowInvalidOperationException_NoMetadataForTypeProperties(JsonSerializerContext context, Type type)
static void ThrowInvalidOperationException_MultiplePropertiesBindToConstructorParameters(Type parentType, string parameterName, string firstMatchName, string secondMatchName)
static void ThrowInvalidOperationException_SerializerPropertyNameConflict(Type type, JsonPropertyInfo jsonPropertyInfo)
static void ThrowInvalidOperationException_NoMetadataForTypeCtorParams(JsonSerializerContext context, Type type)
static void ThrowNotSupportedException_SerializationNotSupported(Type propertyType)
static void ThrowInvalidOperationException_ExtensionDataCannotBindToCtorParam(JsonPropertyInfo jsonPropertyInfo)