diff --git a/.github/workflows/GenerateAsyncCode.yml b/.github/workflows/GenerateAsyncCode.yml index 3cc770f2bbb..869ec1fa153 100644 --- a/.github/workflows/GenerateAsyncCode.yml +++ b/.github/workflows/GenerateAsyncCode.yml @@ -21,7 +21,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v5 with: - dotnet-version: 8.0.x + dotnet-version: 10.0.x - name: Generate Async code run: | diff --git a/.github/workflows/NetCoreTests.yml b/.github/workflows/NetCoreTests.yml index 5440cd919d0..6cdd67f97ff 100644 --- a/.github/workflows/NetCoreTests.yml +++ b/.github/workflows/NetCoreTests.yml @@ -66,7 +66,7 @@ jobs: - name: Set up .NET uses: actions/setup-dotnet@v5 with: - dotnet-version: 8.0.x + dotnet-version: 10.0.x - name: Checkout uses: actions/checkout@v5 diff --git a/ShowBuildMenu.sh b/ShowBuildMenu.sh index 67d44f121dd..878e4dbe6a0 100755 --- a/ShowBuildMenu.sh +++ b/ShowBuildMenu.sh @@ -172,8 +172,8 @@ testSetupMenu() { } testRun(){ - dotnet test ./src/NHibernate.Test/NHibernate.Test.csproj -f net8.0 - dotnet test ./src/NHibernate.Test.VisualBasic/NHibernate.Test.VisualBasic.vbproj -f net8.0 + dotnet test ./src/NHibernate.Test/NHibernate.Test.csproj -f net10.0 + dotnet test ./src/NHibernate.Test.VisualBasic/NHibernate.Test.VisualBasic.vbproj -f net10.0 mainMenu } diff --git a/Tools/BuildTool/BuildTool.csproj b/Tools/BuildTool/BuildTool.csproj index b3587f9d5a3..8af316fd826 100644 --- a/Tools/BuildTool/BuildTool.csproj +++ b/Tools/BuildTool/BuildTool.csproj @@ -1,6 +1,6 @@  Exe - net8.0 + net10.0 \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 6e9b2aa3be3..c26ca5d888f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,10 @@ environment: init: # Required for having windows endlines in sources zip - git config --global core.autocrlf true + - ps: | + Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -UseBasicParsing -OutFile "$env:temp\dotnet-install.ps1" + & $env:temp\dotnet-install.ps1 -Channel 10.0 -Quality preview -InstallDir "$env:ProgramFiles\dotnet" + build: off before_test: - ps: |- diff --git a/build-common/NHibernate.props b/build-common/NHibernate.props index 8385e5451f3..332e6ab41f7 100644 --- a/build-common/NHibernate.props +++ b/build-common/NHibernate.props @@ -6,7 +6,7 @@ 0 - 12.0 + 14.0 $(NhVersion).$(VersionPatch) $(VersionSuffix).$(BuildNumber) @@ -14,8 +14,8 @@ $(VersionPrefix).$(BuildNumber) $(VersionPrefix).0 - net48;net8.0 - net461;net48;netcoreapp2.0;netstandard2.0;netstandard2.1;net6.0;net8.0 + net48;net10.0 + net461;net48;netcoreapp2.0;netstandard2.0;netstandard2.1;net6.0;net8.0;net10.0 2.0.3 false true @@ -25,6 +25,7 @@ $(NoWarn);NU1903 $(NoWarn);SYSLIB0011 $(NoWarn);SYSLIB0011;SYSLIB0050;SYSLIB0051 + $(NoWarn);SYSLIB0011;SYSLIB0050;SYSLIB0051 NHibernate NHibernate.info diff --git a/global.json b/global.json index 391ba3c2a30..512142d2bea 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100", + "version": "10.0.100", "rollForward": "latestFeature" } } diff --git a/psake.ps1 b/psake.ps1 index 0eb342b2875..9b42210e404 100644 --- a/psake.ps1 +++ b/psake.ps1 @@ -132,7 +132,7 @@ Task Test -depends Build { 'NHibernate.Test', 'NHibernate.Test.VisualBasic' ) | ForEach-Object { - $assembly = [IO.Path]::Combine("src", $_, "bin", "Release", "net8.0", "$_.dll") + $assembly = [IO.Path]::Combine("src", $_, "bin", "Release", "net10.0", "$_.dll") Exec { dotnet $assembly --labels=before --nocolor "--result=$_-TestResult.xml" } diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 9c5f0a43404..9e8a423a26c 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -187,7 +187,7 @@ scanForMissingAsyncMembers: - all: true - filePath: NHibernate.Test/NHibernate.Test.csproj - targetFramework: net8.0 + targetFramework: net10.0 concurrentRun: true applyChanges: true suppressDiagnosticFailures: diff --git a/src/NHibernate.Test.VisualBasic/NHibernate.Test.VisualBasic.vbproj b/src/NHibernate.Test.VisualBasic/NHibernate.Test.VisualBasic.vbproj index ff258df5705..d05f1a030a8 100644 --- a/src/NHibernate.Test.VisualBasic/NHibernate.Test.VisualBasic.vbproj +++ b/src/NHibernate.Test.VisualBasic/NHibernate.Test.VisualBasic.vbproj @@ -8,14 +8,14 @@ On On - + Exe false - + @@ -25,11 +25,11 @@ - + - + diff --git a/src/NHibernate.Test/NHSpecificTest/NH1304/Funny.cs b/src/NHibernate.Test/NHSpecificTest/NH1304/Funny.cs index 177d3df86d5..990fd9d6aa8 100644 --- a/src/NHibernate.Test/NHSpecificTest/NH1304/Funny.cs +++ b/src/NHibernate.Test/NHSpecificTest/NH1304/Funny.cs @@ -29,8 +29,8 @@ public virtual int Id public virtual string Field { - get { return field; } - set { field = value; } + get { return this.field; } + set { this.field = value; } } public virtual string FieldCamelcase diff --git a/src/NHibernate.Test/NHSpecificTest/NH1487/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/NH1487/Fixture.cs index 4458ee19c90..16f083f5c49 100644 --- a/src/NHibernate.Test/NHSpecificTest/NH1487/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/NH1487/Fixture.cs @@ -10,10 +10,10 @@ namespace NHibernate.Test.NHSpecificTest.NH1487 public class Entity { int field; - public int Id { get { return field; } set { field = value; } } - public int A { get { return field; } set { field = value; } } - public int B { get { return field; } set { field = value; } } - public int C { get { return field; } set { field = value; } } + public int Id { get { return this.field; } set { this.field = value; } } + public int A { get { return this.field; } set { this.field = value; } } + public int B { get { return this.field; } set { this.field = value; } } + public int C { get { return this.field; } set { this.field = value; } } } /// diff --git a/src/NHibernate.Test/NHibernate.Test.csproj b/src/NHibernate.Test/NHibernate.Test.csproj index ff728f12045..c4e977dfbc5 100644 --- a/src/NHibernate.Test/NHibernate.Test.csproj +++ b/src/NHibernate.Test/NHibernate.Test.csproj @@ -7,12 +7,10 @@ $(NoWarn);3001;3002;3003;3005;8981;SYSLIB0003;SYSLIB0012 true true - - true ..\NHibernate.snk - + Exe false @@ -43,7 +41,7 @@ PreserveNewest - + @@ -65,7 +63,7 @@ - + @@ -86,16 +84,16 @@ - - + + + compile + - - diff --git a/src/NHibernate.TestDatabaseSetup/NHibernate.TestDatabaseSetup.csproj b/src/NHibernate.TestDatabaseSetup/NHibernate.TestDatabaseSetup.csproj index f9a3cb308a7..d2ca537210e 100644 --- a/src/NHibernate.TestDatabaseSetup/NHibernate.TestDatabaseSetup.csproj +++ b/src/NHibernate.TestDatabaseSetup/NHibernate.TestDatabaseSetup.csproj @@ -7,7 +7,7 @@ true $(NoWarn);3001;3002;3003;3005 - + Exe false @@ -18,7 +18,7 @@ - + diff --git a/src/NHibernate/Dialect/MsSql2000Dialect.cs b/src/NHibernate/Dialect/MsSql2000Dialect.cs index d6fb0e16781..9da139dd8d9 100644 --- a/src/NHibernate/Dialect/MsSql2000Dialect.cs +++ b/src/NHibernate/Dialect/MsSql2000Dialect.cs @@ -809,7 +809,7 @@ public LockHintAppender(MsSql2000Dialect dialect, IDictionary // Match < alias >, < alias,>, or < alias$>, the intent is to capture alias names // in various kinds of "FROM table1 alias1, table2 alias2". _matchRegex = new Regex(" (" + aliasesPattern + ")([, ]|$)"); - _unionSubclassRegex = new Regex(@"from\s+\(((?:.|\r|\n)*)\)(?:\s+as)?\s+(?" + aliasesPattern + ")", RegexOptions.IgnoreCase | RegexOptions.Multiline); + _unionSubclassRegex = new Regex(@"from\s+\(([\s\S]+)\)(?:\s+as)?\s+(?" + aliasesPattern + ")", RegexOptions.IgnoreCase | RegexOptions.Multiline); } public SqlString AppendLockHint(SqlString sql) diff --git a/src/NHibernate/Linq/Functions/QueryableGenerator.cs b/src/NHibernate/Linq/Functions/QueryableGenerator.cs index eaf44c64f4a..f29b247afc8 100644 --- a/src/NHibernate/Linq/Functions/QueryableGenerator.cs +++ b/src/NHibernate/Linq/Functions/QueryableGenerator.cs @@ -148,8 +148,8 @@ public CollectionContainsGenerator() { SupportedMethods = new[] { - ReflectHelper.FastGetMethodDefinition(Queryable.Contains, default(IQueryable), default(object)), - ReflectHelper.FastGetMethodDefinition(Enumerable.Contains, default(IEnumerable), default(object)) + ReflectionCache.QueryableMethods.ContainsDefinition, + ReflectionCache.EnumerableMethods.ContainsDefinition, }; } diff --git a/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs b/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs index b0a996379cb..834d7a30a5e 100644 --- a/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs +++ b/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs @@ -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 diff --git a/src/NHibernate/NHibernate.csproj b/src/NHibernate/NHibernate.csproj index e1d9b685f93..222349e9fbb 100644 --- a/src/NHibernate/NHibernate.csproj +++ b/src/NHibernate/NHibernate.csproj @@ -57,6 +57,10 @@ + + + + diff --git a/src/NHibernate/Properties/FieldAccessor.cs b/src/NHibernate/Properties/FieldAccessor.cs index 5a4b4df3854..7db93919893 100644 --- a/src/NHibernate/Properties/FieldAccessor.cs +++ b/src/NHibernate/Properties/FieldAccessor.cs @@ -204,7 +204,7 @@ public object Get(object target) /// The that the Field returns. public System.Type ReturnType { - get { return field.FieldType; } + get { return this.field.FieldType; } } /// @@ -322,7 +322,7 @@ public MethodInfo Method public System.Type Type { - get { return field.FieldType; } + get { return this.field.FieldType; } } #endregion diff --git a/src/NHibernate/Proxy/DynamicProxy/ProxyImplementor.cs b/src/NHibernate/Proxy/DynamicProxy/ProxyImplementor.cs index 42913cb50f6..bd34f326b36 100644 --- a/src/NHibernate/Proxy/DynamicProxy/ProxyImplementor.cs +++ b/src/NHibernate/Proxy/DynamicProxy/ProxyImplementor.cs @@ -27,7 +27,7 @@ internal class ProxyImplementor public FieldBuilder InterceptorField { - get { return field; } + get { return this.field; } } public void ImplementProxy(TypeBuilder typeBuilder) diff --git a/src/NHibernate/Util/ReflectionCache.cs b/src/NHibernate/Util/ReflectionCache.cs index 45f97559780..cf77224ae81 100644 --- a/src/NHibernate/Util/ReflectionCache.cs +++ b/src/NHibernate/Util/ReflectionCache.cs @@ -33,6 +33,9 @@ internal static class EnumerableMethods internal static readonly MethodInfo CastDefinition = ReflectHelper.FastGetMethodDefinition(Enumerable.Cast, default(IEnumerable)); + + internal static MethodInfo ContainsDefinition = + ReflectHelper.FastGetMethodDefinition(Enumerable.Contains, default(IEnumerable), default(object)); internal static readonly MethodInfo GroupByWithElementSelectorDefinition = ReflectHelper.FastGetMethodDefinition(Enumerable.GroupBy, default(IEnumerable), default(Func), default(Func)); @@ -89,6 +92,9 @@ internal static class QueryableMethods default(Expression>), default(Expression, object>>)); + internal static MethodInfo ContainsDefinition = + ReflectHelper.FastGetMethodDefinition(Queryable.Contains, default(IQueryable), default(object)); + internal static readonly MethodInfo CountDefinition = ReflectHelper.FastGetMethodDefinition(Queryable.Count, default(IQueryable)); internal static readonly MethodInfo CountWithPredicateDefinition = diff --git a/src/NHibernate/Util/TypeExtensions.cs b/src/NHibernate/Util/TypeExtensions.cs index e03b58a0890..b7191e983da 100644 --- a/src/NHibernate/Util/TypeExtensions.cs +++ b/src/NHibernate/Util/TypeExtensions.cs @@ -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 } }