IEnumerableConverterFactoryHelpers
using System.Reflection;
namespace System.Text.Json.Serialization
{
internal static class IEnumerableConverterFactoryHelpers
{
private const string ImmutableArrayTypeName = "System.Collections.Immutable.ImmutableArray";
private const string ImmutableArrayGenericTypeName = "System.Collections.Immutable.ImmutableArray`1";
private const string ImmutableListTypeName = "System.Collections.Immutable.ImmutableList";
private const string ImmutableListGenericTypeName = "System.Collections.Immutable.ImmutableList`1";
private const string ImmutableListGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableList`1";
private const string ImmutableStackTypeName = "System.Collections.Immutable.ImmutableStack";
private const string ImmutableStackGenericTypeName = "System.Collections.Immutable.ImmutableStack`1";
private const string ImmutableStackGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableStack`1";
private const string ImmutableQueueTypeName = "System.Collections.Immutable.ImmutableQueue";
private const string ImmutableQueueGenericTypeName = "System.Collections.Immutable.ImmutableQueue`1";
private const string ImmutableQueueGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableQueue`1";
private const string ImmutableSortedSetTypeName = "System.Collections.Immutable.ImmutableSortedSet";
private const string ImmutableSortedSetGenericTypeName = "System.Collections.Immutable.ImmutableSortedSet`1";
private const string ImmutableHashSetTypeName = "System.Collections.Immutable.ImmutableHashSet";
private const string ImmutableHashSetGenericTypeName = "System.Collections.Immutable.ImmutableHashSet`1";
private const string ImmutableSetGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableSet`1";
private const string ImmutableDictionaryTypeName = "System.Collections.Immutable.ImmutableDictionary";
private const string ImmutableDictionaryGenericTypeName = "System.Collections.Immutable.ImmutableDictionary`2";
private const string ImmutableDictionaryGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableDictionary`2";
private const string ImmutableSortedDictionaryTypeName = "System.Collections.Immutable.ImmutableSortedDictionary";
private const string ImmutableSortedDictionaryGenericTypeName = "System.Collections.Immutable.ImmutableSortedDictionary`2";
internal static Type GetCompatibleGenericBaseClass(this Type type, Type baseType)
{
Type type2 = type;
while (type2 != (Type)null && type2 != typeof(object)) {
if (type2.IsGenericType) {
Type genericTypeDefinition = type2.GetGenericTypeDefinition();
if (genericTypeDefinition == baseType)
return type2;
}
type2 = type2.BaseType;
}
return null;
}
internal static Type GetCompatibleGenericInterface(this Type type, Type interfaceType)
{
Type type2 = type;
if (type2.IsGenericType)
type2 = type2.GetGenericTypeDefinition();
if (type2 == interfaceType)
return type;
Type[] interfaces = type.GetInterfaces();
foreach (Type type3 in interfaces) {
if (type3.IsGenericType) {
Type genericTypeDefinition = type3.GetGenericTypeDefinition();
if (genericTypeDefinition == interfaceType)
return type3;
}
}
return null;
}
public static bool IsImmutableDictionaryType(this Type type)
{
if (type.IsGenericType && type.Assembly.FullName.StartsWith("System.Collections.Immutable,", StringComparison.Ordinal)) {
switch (type.GetGenericTypeDefinition().FullName) {
case "System.Collections.Immutable.ImmutableDictionary`2":
case "System.Collections.Immutable.IImmutableDictionary`2":
case "System.Collections.Immutable.ImmutableSortedDictionary`2":
return true;
default:
return false;
}
}
return false;
}
public static bool IsImmutableEnumerableType(this Type type)
{
if (!type.IsGenericType || !type.Assembly.FullName.StartsWith("System.Collections.Immutable,", StringComparison.Ordinal))
return false;
string fullName = type.GetGenericTypeDefinition().FullName;
if (fullName != null) {
switch (fullName) {
case "System.Collections.Immutable.ImmutableArray`1":
case "System.Collections.Immutable.ImmutableList`1":
case "System.Collections.Immutable.IImmutableList`1":
case "System.Collections.Immutable.ImmutableStack`1":
case "System.Collections.Immutable.IImmutableStack`1":
case "System.Collections.Immutable.ImmutableQueue`1":
case "System.Collections.Immutable.IImmutableQueue`1":
case "System.Collections.Immutable.ImmutableSortedSet`1":
case "System.Collections.Immutable.ImmutableHashSet`1":
case "System.Collections.Immutable.IImmutableSet`1":
return true;
}
}
return false;
}
public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, Type elementType)
{
Type immutableEnumerableConstructingType = GetImmutableEnumerableConstructingType(type);
MethodInfo[] methods = immutableEnumerableConstructingType.GetMethods();
MethodInfo[] array = methods;
foreach (MethodInfo methodInfo in array) {
if (methodInfo.Name == "CreateRange" && methodInfo.GetParameters().Length == 1 && methodInfo.IsGenericMethod && methodInfo.GetGenericArguments().Length == 1)
return methodInfo.MakeGenericMethod(elementType);
}
ThrowHelper.ThrowNotSupportedException_SerializationNotSupported(type, null, null);
return null;
}
public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, Type elementType)
{
Type immutableDictionaryConstructingType = GetImmutableDictionaryConstructingType(type);
MethodInfo[] methods = immutableDictionaryConstructingType.GetMethods();
MethodInfo[] array = methods;
foreach (MethodInfo methodInfo in array) {
if (methodInfo.Name == "CreateRange" && methodInfo.GetParameters().Length == 1 && methodInfo.IsGenericMethod && methodInfo.GetGenericArguments().Length == 2)
return methodInfo.MakeGenericMethod(typeof(string), elementType);
}
ThrowHelper.ThrowNotSupportedException_SerializationNotSupported(type, null, null);
return null;
}
private static Type GetImmutableEnumerableConstructingType(Type type)
{
Type genericTypeDefinition = type.GetGenericTypeDefinition();
string fullName = genericTypeDefinition.FullName;
if (fullName != null) {
string name;
switch (fullName) {
case "System.Collections.Immutable.ImmutableArray`1":
name = "System.Collections.Immutable.ImmutableArray";
goto IL_017d;
case "System.Collections.Immutable.ImmutableList`1":
case "System.Collections.Immutable.IImmutableList`1":
name = "System.Collections.Immutable.ImmutableList";
goto IL_017d;
case "System.Collections.Immutable.ImmutableStack`1":
case "System.Collections.Immutable.IImmutableStack`1":
name = "System.Collections.Immutable.ImmutableStack";
goto IL_017d;
case "System.Collections.Immutable.ImmutableQueue`1":
case "System.Collections.Immutable.IImmutableQueue`1":
name = "System.Collections.Immutable.ImmutableQueue";
goto IL_017d;
case "System.Collections.Immutable.ImmutableSortedSet`1":
name = "System.Collections.Immutable.ImmutableSortedSet";
goto IL_017d;
case "System.Collections.Immutable.ImmutableHashSet`1":
case "System.Collections.Immutable.IImmutableSet`1":
{
name = "System.Collections.Immutable.ImmutableHashSet";
goto IL_017d;
}
IL_017d:
return genericTypeDefinition.Assembly.GetType(name);
}
}
return null;
}
private static Type GetImmutableDictionaryConstructingType(Type type)
{
Type genericTypeDefinition = type.GetGenericTypeDefinition();
string name;
switch (genericTypeDefinition.FullName) {
case "System.Collections.Immutable.ImmutableDictionary`2":
case "System.Collections.Immutable.IImmutableDictionary`2":
name = "System.Collections.Immutable.ImmutableDictionary";
break;
case "System.Collections.Immutable.ImmutableSortedDictionary`2":
name = "System.Collections.Immutable.ImmutableSortedDictionary";
break;
default:
return null;
}
return genericTypeDefinition.Assembly.GetType(name);
}
public static bool IsNonGenericStackOrQueue(this Type type)
{
Type type2 = Type.GetType("System.Collections.Stack, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
Type type3 = Type.GetType("System.Collections.Queue, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
if (!type2.IsAssignableFrom(type))
return type3.IsAssignableFrom(type);
return true;
}
}
}