Skip to content

Commit 677ba3c

Browse files
committed
Support for C# 14
1 parent d350885 commit 677ba3c

File tree

4 files changed

+56
-7
lines changed

4 files changed

+56
-7
lines changed

src/NHibernate/Linq/Functions/QueryableGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ public CollectionContainsGenerator()
148148
{
149149
SupportedMethods = new[]
150150
{
151-
ReflectHelper.FastGetMethodDefinition(Queryable.Contains, default(IQueryable<object>), default(object)),
152-
ReflectHelper.FastGetMethodDefinition(Enumerable.Contains, default(IEnumerable<object>), default(object))
151+
ReflectionCache.QueryableMethods.ContainsDefinition,
152+
ReflectionCache.EnumerableMethods.ContainsDefinition,
153153
};
154154
}
155155

src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,41 @@ protected override Expression VisitConstant(ConstantExpression expression)
187187
}
188188
return base.VisitConstant(expression);
189189
}
190+
191+
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
192+
protected override Expression VisitMethodCall(MethodCallExpression node)
193+
{
194+
if (IsMemoryExtensionContains(node.Method) &&
195+
TryUnwrapImplicitSpanConversion(node.Arguments[0], out var array) &&
196+
array.Type.IsArray)
197+
{
198+
var contains =
199+
ReflectionCache.EnumerableMethods.ContainsDefinition.MakeGenericMethod(array.Type.GetElementType());
200+
201+
return base.VisitMethodCall(Expression.Call(contains, array, node.Arguments[1]));
202+
}
203+
204+
return base.VisitMethodCall(node);
205+
}
206+
207+
private static bool TryUnwrapImplicitSpanConversion(Expression span, out Expression array)
208+
{
209+
if (span is MethodCallExpression { Method: { Name: "op_Implicit" } method, Arguments: [var arg] } &&
210+
(method.DeclaringType.IsSpan() || method.DeclaringType.IsReadOnlySpan()))
211+
{
212+
array = arg;
213+
return true;
214+
}
215+
216+
array = null;
217+
return false;
218+
}
219+
220+
private static bool IsMemoryExtensionContains(MethodInfo method)
221+
{
222+
return method.Name == "Contains" && method.DeclaringType == typeof(MemoryExtensions);
223+
}
224+
#endif
190225
}
191226

192227
internal struct QueryVariable : IEquatable<QueryVariable>

src/NHibernate/Util/ReflectionCache.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ internal static class EnumerableMethods
3333

3434
internal static readonly MethodInfo CastDefinition =
3535
ReflectHelper.FastGetMethodDefinition(Enumerable.Cast<object>, default(IEnumerable));
36+
37+
internal static MethodInfo ContainsDefinition =
38+
ReflectHelper.FastGetMethodDefinition(Enumerable.Contains, default(IEnumerable<object>), default(object));
3639

3740
internal static readonly MethodInfo GroupByWithElementSelectorDefinition =
3841
ReflectHelper.FastGetMethodDefinition(Enumerable.GroupBy, default(IEnumerable<object>), default(Func<object, object>), default(Func<object, object>));
@@ -89,6 +92,9 @@ internal static class QueryableMethods
8992
default(Expression<Func<object, int>>),
9093
default(Expression<Func<object, IEnumerable<object>, object>>));
9194

95+
internal static MethodInfo ContainsDefinition =
96+
ReflectHelper.FastGetMethodDefinition(Queryable.Contains, default(IQueryable<object>), default(object));
97+
9298
internal static readonly MethodInfo CountDefinition =
9399
ReflectHelper.FastGetMethodDefinition(Queryable.Count, default(IQueryable<object>));
94100
internal static readonly MethodInfo CountWithPredicateDefinition =

src/NHibernate/Util/TypeExtensions.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,20 @@ internal static bool IsIntegralNumberType(this System.Type type)
6868
internal static bool IsRealNumberType(this System.Type type)
6969
{
7070
var code = System.Type.GetTypeCode(type);
71-
if (code == TypeCode.Decimal || code == TypeCode.Single || code == TypeCode.Double)
72-
{
73-
return true;
74-
}
71+
return code == TypeCode.Decimal || code == TypeCode.Single || code == TypeCode.Double;
72+
}
73+
74+
75+
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
76+
internal static bool IsSpan(this System.Type type)
77+
{
78+
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Span<>);
79+
}
7580

76-
return false;
81+
internal static bool IsReadOnlySpan(this System.Type type)
82+
{
83+
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ReadOnlySpan<>);
7784
}
85+
#endif
7886
}
7987
}

0 commit comments

Comments
 (0)