Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build-common/NHibernate.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<VersionPatch Condition="'$(VersionPatch)' == ''">1</VersionPatch>
<!-- Clear VersionSuffix for making release and set it to dev for making development builds -->
<VersionSuffix Condition="'$(VersionSuffix)' == ''"></VersionSuffix>
<LangVersion Condition="'$(MSBuildProjectExtension)' != '.vbproj'">12.0</LangVersion>
<LangVersion Condition="'$(MSBuildProjectExtension)' != '.vbproj'">14.0</LangVersion>

<VersionPrefix Condition="'$(VersionPrefix)' == ''">$(NhVersion).$(VersionPatch)</VersionPrefix>
<VersionSuffix Condition="'$(VersionSuffix)' != '' AND '$(BuildNumber)' != ''">$(VersionSuffix).$(BuildNumber)</VersionSuffix>
Expand Down
4 changes: 2 additions & 2 deletions src/NHibernate/Linq/Functions/QueryableGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ public CollectionContainsGenerator()
{
SupportedMethods = new[]
{
ReflectHelper.FastGetMethodDefinition(Queryable.Contains, default(IQueryable<object>), default(object)),
ReflectHelper.FastGetMethodDefinition(Enumerable.Contains, default(IEnumerable<object>), default(object))
ReflectionCache.QueryableMethods.ContainsDefinition,
ReflectionCache.EnumerableMethods.ContainsDefinition,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,41 @@ protected override Expression VisitConstant(ConstantExpression expression)
}
return base.VisitConstant(expression);
}

#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (IsMemoryExtensionContains(node.Method) &&
TryUnwrapImplicitSpanConversion(node.Arguments[0], out var array) &&
array.Type.IsArray)
{
var contains =
ReflectionCache.EnumerableMethods.ContainsDefinition.MakeGenericMethod(array.Type.GetElementType());

return base.VisitMethodCall(Expression.Call(contains, array, node.Arguments[1]));
}

return base.VisitMethodCall(node);
}

private static bool TryUnwrapImplicitSpanConversion(Expression span, out Expression array)
{
if (span is MethodCallExpression { Method: { Name: "op_Implicit" } method, Arguments: [var arg] } &&
(method.DeclaringType.IsSpan() || method.DeclaringType.IsReadOnlySpan()))
{
array = arg;
return true;
}

array = null;
return false;
}

private static bool IsMemoryExtensionContains(MethodInfo method)
{
return method.Name == "Contains" && method.DeclaringType == typeof(MemoryExtensions);
}
#endif
}

internal struct QueryVariable : IEquatable<QueryVariable>
Expand Down
6 changes: 6 additions & 0 deletions src/NHibernate/Util/ReflectionCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ internal static class EnumerableMethods

internal static readonly MethodInfo CastDefinition =
ReflectHelper.FastGetMethodDefinition(Enumerable.Cast<object>, default(IEnumerable));

internal static MethodInfo ContainsDefinition =
ReflectHelper.FastGetMethodDefinition(Enumerable.Contains, default(IEnumerable<object>), default(object));

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

internal static MethodInfo ContainsDefinition =
ReflectHelper.FastGetMethodDefinition(Queryable.Contains, default(IQueryable<object>), default(object));

internal static readonly MethodInfo CountDefinition =
ReflectHelper.FastGetMethodDefinition(Queryable.Count, default(IQueryable<object>));
internal static readonly MethodInfo CountWithPredicateDefinition =
Expand Down
18 changes: 13 additions & 5 deletions src/NHibernate/Util/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,20 @@ internal static bool IsIntegralNumberType(this System.Type type)
internal static bool IsRealNumberType(this System.Type type)
{
var code = System.Type.GetTypeCode(type);
if (code == TypeCode.Decimal || code == TypeCode.Single || code == TypeCode.Double)
{
return true;
}
return code == TypeCode.Decimal || code == TypeCode.Single || code == TypeCode.Double;
}


#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
internal static bool IsSpan(this System.Type type)
{
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Span<>);
}

return false;
internal static bool IsReadOnlySpan(this System.Type type)
{
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ReadOnlySpan<>);
}
#endif
}
}
Loading