Skip to content

Commit 2f91cdb

Browse files
committed
TypeHelper: structural changes
- organize caches and item factories for them into region - rename ValueTuple1, ValueTuple8 static tokens with names which reflect fields meaning - add summaries for public members
1 parent 73d0fda commit 2f91cdb

File tree

1 file changed

+65
-14
lines changed

1 file changed

+65
-14
lines changed

Orm/Xtensive.Orm/Reflection/TypeHelper.cs

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ public int GetHashCode((Type, Type[]) obj)
4747

4848
private static readonly object EmitLock = new object();
4949
private static readonly int NullableTypeMetadataToken = WellKnownTypes.NullableOfT.MetadataToken;
50-
private static readonly int ValueTuple1 = typeof(ValueTuple<>).MetadataToken;
51-
private static readonly int ValueTuple8 = typeof(ValueTuple<,,,,,,,>).MetadataToken;
50+
private static readonly int ValueTuple1MetadataToken = typeof(ValueTuple<>).MetadataToken;
51+
private static readonly int ValueTuple8MetadataToken = typeof(ValueTuple<,,,,,,,>).MetadataToken;
5252
private static readonly Module SystemCoreLibModule = WellKnownTypes.NullableOfT.Module;
5353
private static readonly Type CompilerGeneratedAttributeType = typeof(CompilerGeneratedAttribute);
5454
private static readonly string TypeHelperNamespace = typeof(TypeHelper).Namespace;
5555

56+
#region Caches and cache items factories
5657
#if NET8_0_OR_GREATER
5758
private static readonly ConcurrentDictionary<(Type, Type[]), ConstructorInvoker> ConstructorInvokerByTypes =
5859
new(new TypesEqualityComparer());
@@ -71,16 +72,11 @@ public int GetHashCode((Type, Type[]) obj)
7172
private static readonly ConcurrentDictionary<(MethodInfo, Type), MethodInfo> GenericMethodInstances1 = new();
7273

7374
private static readonly ConcurrentDictionary<(MethodInfo, Type, Type), MethodInfo> GenericMethodInstances2 = new();
74-
7575
#if NET8_0_OR_GREATER
76-
private static readonly ConcurrentDictionary<(MethodInfo, Type), MethodInvoker> GenericMethodInvokers1 = new();
77-
private static readonly ConcurrentDictionary<(MethodInfo, Type, Type), MethodInvoker> GenericMethodInvokers2 = new();
7876

79-
private static readonly Func<(MethodInfo genericDefinition, Type typeArgument), MethodInvoker> GenericMethodInvokerFactory1 =
80-
key => MethodInvoker.Create(key.genericDefinition.MakeGenericMethod(key.typeArgument));
77+
private static readonly ConcurrentDictionary<(MethodInfo, Type), MethodInvoker> GenericMethodInvokers1 = new();
8178

82-
private static readonly Func<(MethodInfo genericDefinition, Type typeArgument1, Type typeArgument2), MethodInvoker> GenericMethodInvokerFactory2 =
83-
key => MethodInvoker.Create(key.genericDefinition.MakeGenericMethod(key.typeArgument1, key.typeArgument2));
79+
private static readonly ConcurrentDictionary<(MethodInfo, Type, Type), MethodInvoker> GenericMethodInvokers2 = new();
8480
#endif
8581

8682
private static readonly ConcurrentDictionary<(Type, Type), Type> GenericTypeInstances1 = new();
@@ -93,11 +89,21 @@ public int GetHashCode((Type, Type[]) obj)
9389
private static readonly Func<(MethodInfo genericDefinition, Type typeArgument1, Type typeArgument2), MethodInfo> GenericMethodFactory2 =
9490
key => key.genericDefinition.MakeGenericMethod(key.typeArgument1, key.typeArgument2);
9591

96-
private static readonly Func<(Type genericDefinition, Type typeArgument), Type> GenericTypeFactory1 = key =>
97-
key.genericDefinition.MakeGenericType(key.typeArgument);
92+
private static readonly Func<(Type genericDefinition, Type typeArgument), Type> GenericTypeFactory1 =
93+
key => key.genericDefinition.MakeGenericType(key.typeArgument);
94+
95+
private static readonly Func<(Type genericDefinition, Type typeArgument1, Type typeArgument2), Type> GenericTypeFactory2 =
96+
key => key.genericDefinition.MakeGenericType(key.typeArgument1, key.typeArgument2);
97+
#if NET8_0_OR_GREATER
9898

99-
private static readonly Func<(Type genericDefinition, Type typeArgument1, Type typeArgument2), Type> GenericTypeFactory2 = key =>
100-
key.genericDefinition.MakeGenericType(key.typeArgument1, key.typeArgument2);
99+
private static readonly Func<(MethodInfo genericDefinition, Type typeArgument), MethodInvoker> GenericMethodInvokerFactory1 =
100+
key => MethodInvoker.Create(key.genericDefinition.MakeGenericMethod(key.typeArgument));
101+
102+
private static readonly Func<(MethodInfo genericDefinition, Type typeArgument1, Type typeArgument2), MethodInvoker> GenericMethodInvokerFactory2 =
103+
key => MethodInvoker.Create(key.genericDefinition.MakeGenericMethod(key.typeArgument1, key.typeArgument2));
104+
#endif
105+
106+
#endregion
101107

102108
private static int createDummyTypeNumber = 0;
103109
private static AssemblyBuilder assemblyBuilder;
@@ -968,23 +974,68 @@ public static bool IsGenericMethodSpecificationOf(this MethodInfo method, Method
968974
|| method.Module == genericMethodDefinition.Module)
969975
&& method.IsGenericMethod && genericMethodDefinition.IsGenericMethodDefinition;
970976

977+
/// <summary>
978+
/// Makes generic <see cref="MethodInfo"/> for given definition and type argument
979+
/// or returns already existing instance from cache.
980+
/// </summary>
981+
/// <param name="genericDefinition">Generic definition of method.</param>
982+
/// <param name="typeArgument">Type argument for final generic method.</param>
983+
/// <returns>Newly created instance or already existing one.</returns>
971984
public static MethodInfo CachedMakeGenericMethod(this MethodInfo genericDefinition, Type typeArgument) =>
972985
GenericMethodInstances1.GetOrAdd((genericDefinition, typeArgument), GenericMethodFactory1);
973986

987+
/// <summary>
988+
/// Makes generic <see cref="MethodInfo"/> for given definition and type arguments
989+
/// or returns already existing instance from cache.
990+
/// </summary>
991+
/// <param name="genericDefinition">Generic definition of method.</param>
992+
/// <param name="typeArgument1">First type argument for final generic method.</param>
993+
/// <param name="typeArgument2">Second type argument for final generic method.</param>
994+
/// <returns>Newly created instance or already existing one.</returns>
974995
public static MethodInfo CachedMakeGenericMethod(this MethodInfo genericDefinition, Type typeArgument1, Type typeArgument2) =>
975996
GenericMethodInstances2.GetOrAdd((genericDefinition, typeArgument1, typeArgument2), GenericMethodFactory2);
976997

977998
#if NET8_0_OR_GREATER
999+
/// <summary>
1000+
/// Makes <see cref="MethodInvoker"/> for generic <see cref="MethodInfo"/> for given definition and type argument
1001+
/// or returns already existing instance from cache.
1002+
/// </summary>
1003+
/// <param name="genericDefinition">Generic definition of method.</param>
1004+
/// <param name="typeArgument">Type argument for final generic method.</param>
1005+
/// <returns>Newly created instance or already existing one.</returns>
9781006
public static MethodInvoker CachedMakeGenericMethodInvoker(this MethodInfo genericDefinition, Type typeArgument) =>
9791007
GenericMethodInvokers1.GetOrAdd((genericDefinition, typeArgument), GenericMethodInvokerFactory1);
9801008

1009+
/// <summary>
1010+
/// Makes <see cref="MethodInvoker"/> for generic <see cref="MethodInfo"/> for given definition and type arguments
1011+
/// or returns already existing instance from cache.
1012+
/// </summary>
1013+
/// <param name="genericDefinition">Generic definition of method.</param>
1014+
/// <param name="typeArgument1">First type argument for final generic method.</param>
1015+
/// <param name="typeArgument2">Second type argument for final generic method.</param>
1016+
/// <returns>Newly created instance or already existing one.</returns>
9811017
public static MethodInvoker CachedMakeGenericMethodInvoker(this MethodInfo genericDefinition, Type typeArgument1, Type typeArgument2) =>
9821018
GenericMethodInvokers2.GetOrAdd((genericDefinition, typeArgument1, typeArgument2), GenericMethodInvokerFactory2);
9831019
#endif
9841020

1021+
/// <summary>
1022+
/// Makes generic type of given type definition and type argument
1023+
/// or returns already existing instance from cache.
1024+
/// </summary>
1025+
/// <param name="genericDefinition">Generic type definition.</param>
1026+
/// <param name="typeArgument">Type argument for final generic type.</param>
1027+
/// <returns>Newly created instance or already existing one.</returns>
9851028
public static Type CachedMakeGenericType(this Type genericDefinition, Type typeArgument) =>
9861029
GenericTypeInstances1.GetOrAdd((genericDefinition, typeArgument), GenericTypeFactory1);
9871030

1031+
/// <summary>
1032+
/// Makes generic type of given type definition and type argument
1033+
/// or returns already existing instance from cache.
1034+
/// </summary>
1035+
/// <param name="genericDefinition">Generic type definition.</param>
1036+
/// <param name="typeArgument1">First type argument for final generic type.</param>
1037+
/// <param name="typeArgument2">Second type argument for final generic type.</param>
1038+
/// <returns>Newly created instance or already existing one.</returns>
9881039
public static Type CachedMakeGenericType(this Type genericDefinition, Type typeArgument1, Type typeArgument2) =>
9891040
GenericTypeInstances2.GetOrAdd((genericDefinition, typeArgument1, typeArgument2), GenericTypeFactory2);
9901041

@@ -1204,7 +1255,7 @@ internal static bool IsValueTuple(this Type type)
12041255
// this stands on the theory that tokens for all generic versions of ValueTuple
12051256
// go one after another.
12061257
var currentToken = type.MetadataToken;
1207-
return ((currentToken >= ValueTuple1) && currentToken <= ValueTuple8)
1258+
return ((currentToken >= ValueTuple1MetadataToken) && currentToken <= ValueTuple8MetadataToken)
12081259
&& ReferenceEquals(type.Module, SystemCoreLibModule);
12091260
}
12101261

0 commit comments

Comments
 (0)