diff --git a/.editorconfig b/.editorconfig index e0412088..d6b1d968 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,3 +5,6 @@ dotnet_diagnostic.RS2008.severity = none # IDE0290: Use primary constructor dotnet_diagnostic.IDE0290.severity = none + +# CA1860: Avoid IEnumerable.Count() +dotnet_diagnostic.CA1860.severity = none diff --git a/.github/workflows/dotnet-integration.yml b/.github/workflows/dotnet-integration.yml index ddef954b..bb7816b3 100644 --- a/.github/workflows/dotnet-integration.yml +++ b/.github/workflows/dotnet-integration.yml @@ -22,7 +22,8 @@ jobs: with: dotnet-version: | 6.0.x - 8.0.x + 8.0.x + 9.0.x - name: Build run: dotnet build Dapper.AOT.sln -c Debug diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4991b89e..7cc88435 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -23,6 +23,7 @@ jobs: dotnet-version: | 6.0.x 8.0.x + 9.0.x - uses: dotnet/nbgv@master with: @@ -37,8 +38,11 @@ jobs: - name: Build run: dotnet build Build.csproj --no-restore -c Release - - name: Test - run: dotnet test Build.csproj --no-build --verbosity normal -c Release -f net6.0 --filter FullyQualifiedName!~Integration + - name: Test .NET 8 + run: dotnet test Build.csproj --no-build --verbosity normal -c Release -f net8.0 --filter FullyQualifiedName!~Integration + + - name: Test .NET 9 + run: dotnet test Build.csproj --no-build --verbosity normal -c Release -f net9.0 --filter FullyQualifiedName!~Integration - name: Pack if: ${{ success() && !github.base_ref }} diff --git a/Directory.Build.props b/Directory.Build.props index 5c837ce4..6efc588b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -27,6 +27,7 @@ preview ($Features);strict true + true diff --git a/Directory.Packages.props b/Directory.Packages.props index 6e583e05..081d78e8 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,40 +1,40 @@ - + - - - - - - - - + + + + + + + + - + - - - - - - - - - + + + + + + + + + - - - - + + + + diff --git a/global.json b/global.json index 7da27634..d1c554a8 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100", + "version": "9.0.102", "rollForward": "latestMajor" } } \ No newline at end of file diff --git a/src/Dapper.AOT.Analyzers/CodeAnalysis/DapperInterceptorGenerator.cs b/src/Dapper.AOT.Analyzers/CodeAnalysis/DapperInterceptorGenerator.cs index 951a1060..47a2358b 100644 --- a/src/Dapper.AOT.Analyzers/CodeAnalysis/DapperInterceptorGenerator.cs +++ b/src/Dapper.AOT.Analyzers/CodeAnalysis/DapperInterceptorGenerator.cs @@ -212,9 +212,11 @@ static string BuildParameterMap(in ParseState ctx, IInvocationOperation op, stri internal static class FeatureKeys { - public const string InterceptorsPreviewNamespaces = nameof(InterceptorsPreviewNamespaces), + public const string InterceptorsNamespaces = nameof(InterceptorsNamespaces), + InterceptorsPreviewNamespaces = nameof(InterceptorsPreviewNamespaces), CodegenNamespace = "Dapper.AOT"; public static KeyValuePair InterceptorsPreviewNamespacePair => new(InterceptorsPreviewNamespaces, CodegenNamespace); + public static KeyValuePair InterceptorsNamespacePair => new(InterceptorsNamespaces, CodegenNamespace); } private static bool CheckPrerequisites(in GenerateState ctx) diff --git a/src/Dapper.AOT/CommandT.Batch.cs b/src/Dapper.AOT/CommandT.Batch.cs index 8c32d823..06e7b136 100644 --- a/src/Dapper.AOT/CommandT.Batch.cs +++ b/src/Dapper.AOT/CommandT.Batch.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Data; using System.Data.Common; using System.Diagnostics; using System.Linq; @@ -222,6 +223,7 @@ private int ExecuteMultiBatch(ReadOnlySpan source, int batchSize) // TODO { Debug.Assert(source.Length > 1); UnifiedCommand batch = default; + bool closeConnection = false; try { foreach (var arg in source) @@ -231,6 +233,12 @@ private int ExecuteMultiBatch(ReadOnlySpan source, int batchSize) // TODO } if (!batch.HasBatch) return 0; + if (connection.State != ConnectionState.Open) + { + connection.Open(); + closeConnection = true; + } + var result = batch.AssertBatch.ExecuteNonQuery(); if (commandFactory.RequirePostProcess) @@ -241,9 +249,14 @@ private int ExecuteMultiBatch(ReadOnlySpan source, int batchSize) // TODO } finally { + if (closeConnection) + { + connection.Close(); + } batch.Cleanup(); } } + private int ExecuteMultiBatch(IEnumerable source, int batchSize) // TODO: sub-batching { if (commandFactory.RequirePostProcess) @@ -253,6 +266,7 @@ private int ExecuteMultiBatch(IEnumerable source, int batchSize) // TODO: } UnifiedCommand batch = default; + bool closeConnection = false; try { foreach (var arg in source) @@ -262,6 +276,12 @@ private int ExecuteMultiBatch(IEnumerable source, int batchSize) // TODO: } if (!batch.HasBatch) return 0; + if (connection.State != ConnectionState.Open) + { + connection.Open(); + closeConnection = true; + } + var result = batch.AssertBatch.ExecuteNonQuery(); if (commandFactory.RequirePostProcess) { @@ -271,6 +291,10 @@ private int ExecuteMultiBatch(IEnumerable source, int batchSize) // TODO: } finally { + if (closeConnection) + { + connection.Close(); + } batch.Cleanup(); } } diff --git a/src/Dapper.AOT/Internal/SyncCommandState.cs b/src/Dapper.AOT/Internal/SyncCommandState.cs index 85594995..90674cbb 100644 --- a/src/Dapper.AOT/Internal/SyncCommandState.cs +++ b/src/Dapper.AOT/Internal/SyncCommandState.cs @@ -38,7 +38,7 @@ private void OnBeforeExecute(DbCommand command) Debug.Assert(command?.Connection is not null); Command = command!; connection = command!.Connection; - + if (connection.State != ConnectionState.Open) { connection.Open(); diff --git a/src/Dapper.AOT/UnifiedCommand.cs b/src/Dapper.AOT/UnifiedCommand.cs index ad618a24..f7b69500 100644 --- a/src/Dapper.AOT/UnifiedCommand.cs +++ b/src/Dapper.AOT/UnifiedCommand.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; +using System.Diagnostics.CodeAnalysis; +using System.Diagnostics; using System.Runtime.CompilerServices; namespace Dapper; @@ -16,8 +18,8 @@ namespace Dapper; #pragma warning restore IDE0079 public readonly struct UnifiedCommand - { + /// /// The associated with the current operation; this may be null for batch commands. /// diff --git a/test/Dapper.AOT.Test.Integration.Executables/Dapper.AOT.Test.Integration.Executables.csproj b/test/Dapper.AOT.Test.Integration.Executables/Dapper.AOT.Test.Integration.Executables.csproj index b996bea0..7935596b 100644 --- a/test/Dapper.AOT.Test.Integration.Executables/Dapper.AOT.Test.Integration.Executables.csproj +++ b/test/Dapper.AOT.Test.Integration.Executables/Dapper.AOT.Test.Integration.Executables.csproj @@ -2,12 +2,13 @@ net8.0;net6.0 Dapper.AOT.Test.Integration.Executables + $(NoWarn);CS8002 + - diff --git a/test/Dapper.AOT.Test.Integration/Dapper.AOT.Test.Integration.csproj b/test/Dapper.AOT.Test.Integration/Dapper.AOT.Test.Integration.csproj index e69aaed0..dc0071a5 100644 --- a/test/Dapper.AOT.Test.Integration/Dapper.AOT.Test.Integration.csproj +++ b/test/Dapper.AOT.Test.Integration/Dapper.AOT.Test.Integration.csproj @@ -6,6 +6,7 @@ enable false true + $(NoWarn);CS8002 diff --git a/test/Dapper.AOT.Test.Integration/Setup/IntegrationTestsBase.cs b/test/Dapper.AOT.Test.Integration/Setup/IntegrationTestsBase.cs index 3ea3ec41..806e6265 100644 --- a/test/Dapper.AOT.Test.Integration/Setup/IntegrationTestsBase.cs +++ b/test/Dapper.AOT.Test.Integration/Setup/IntegrationTestsBase.cs @@ -23,6 +23,7 @@ public abstract class IntegrationTestsBase .WithFeatures(new[] { new KeyValuePair("InterceptorsPreviewNamespaces", "$(InterceptorsPreviewNamespaces);Dapper.AOT"), + new KeyValuePair("InterceptorsNamespaces", "$(InterceptorsNamespaces);Dapper.AOT"), }); protected readonly IDbConnection DbConnection; diff --git a/test/Dapper.AOT.Test/Dapper.AOT.Test.csproj b/test/Dapper.AOT.Test/Dapper.AOT.Test.csproj index f447d516..bd4ee085 100644 --- a/test/Dapper.AOT.Test/Dapper.AOT.Test.csproj +++ b/test/Dapper.AOT.Test/Dapper.AOT.Test.csproj @@ -1,6 +1,6 @@  - net6.0;net48 + net8.0;net48;net9.0 $(NoWarn);IDE0042;CS8002;CA1816 Dapper.AOT.Test $(DefineConstants);DAPPERAOT_INTERNAL @@ -23,23 +23,19 @@ $([System.String]::Copy(%(Filename)).Replace('.output.netfx', '.input.cs')) - - $([System.String]::Copy(%(Filename)).Replace('.VB.cs', '.cs')) - + + $([System.String]::Copy(%(Filename)).Replace('.VB.cs', '.cs')) + - + - - - + + - - - @@ -48,7 +44,6 @@ runtime; build; native; contentfiles; analyzers - @@ -56,9 +51,18 @@ - + - + + + + + + + + + + diff --git a/test/Dapper.AOT.Test/DapperApiTests.cs b/test/Dapper.AOT.Test/DapperApiTests.cs index 2e3d3bf1..a559c4aa 100644 --- a/test/Dapper.AOT.Test/DapperApiTests.cs +++ b/test/Dapper.AOT.Test/DapperApiTests.cs @@ -27,10 +27,10 @@ public void DiscoveredMethodsAreExpected() var names = string.Join(",", methods); Log.WriteLine(names); - Assert.Equal("AsList<,AsTableValuedParameter,AsTableValuedParameter<,Execute,ExecuteAsync,ExecuteReader,ExecuteReaderAsync,ExecuteScalar,ExecuteScalar<,ExecuteScalarAsync,ExecuteScalarAsync<,GetRowParser,GetRowParser<,GetTypeName,Parse,Parse<,Query,Query<,QueryAsync,QueryAsync<,QueryFirst,QueryFirst<,QueryFirstAsync,QueryFirstAsync<,QueryFirstOrDefault,QueryFirstOrDefault<,QueryFirstOrDefaultAsync,QueryFirstOrDefaultAsync<,QueryMultiple,QueryMultipleAsync,QuerySingle,QuerySingle<,QuerySingleAsync,QuerySingleAsync<,QuerySingleOrDefault,QuerySingleOrDefault<,QuerySingleOrDefaultAsync,QuerySingleOrDefaultAsync<" + (IsNetFx ? "" : ",QueryUnbufferedAsync,QueryUnbufferedAsync<") + ",ReplaceLiterals,SetTypeName", names); + Assert.Equal("AsList<,AsTableValuedParameter,AsTableValuedParameter<,Execute,ExecuteAsync,ExecuteReader,ExecuteReaderAsync,ExecuteScalar,ExecuteScalar<,ExecuteScalarAsync,ExecuteScalarAsync<,GetRowParser,GetRowParser<,GetTypeName,Parse,Parse<,Query,Query<,QueryAsync,QueryAsync<,QueryFirst,QueryFirst<,QueryFirstAsync,QueryFirstAsync<,QueryFirstOrDefault,QueryFirstOrDefault<,QueryFirstOrDefaultAsync,QueryFirstOrDefaultAsync<,QueryMultiple,QueryMultipleAsync,QuerySingle,QuerySingle<,QuerySingleAsync,QuerySingleAsync<,QuerySingleOrDefault,QuerySingleOrDefault<,QuerySingleOrDefaultAsync,QuerySingleOrDefaultAsync<,QueryUnbufferedAsync,QueryUnbufferedAsync<,ReplaceLiterals,SetTypeName", names); var candidates = string.Join(",", methods.Where(DapperInterceptorGenerator.IsCandidate)); Log.WriteLine(candidates); - Assert.Equal("Execute,ExecuteAsync,ExecuteReader,ExecuteReaderAsync,ExecuteScalar,ExecuteScalar<,ExecuteScalarAsync,ExecuteScalarAsync<,GetRowParser,GetRowParser<,Query,Query<,QueryAsync,QueryAsync<,QueryFirst,QueryFirst<,QueryFirstAsync,QueryFirstAsync<,QueryFirstOrDefault,QueryFirstOrDefault<,QueryFirstOrDefaultAsync,QueryFirstOrDefaultAsync<,QueryMultiple,QueryMultipleAsync,QuerySingle,QuerySingle<,QuerySingleAsync,QuerySingleAsync<,QuerySingleOrDefault,QuerySingleOrDefault<,QuerySingleOrDefaultAsync,QuerySingleOrDefaultAsync<" + (IsNetFx ? "" : ",QueryUnbufferedAsync,QueryUnbufferedAsync<"), candidates); + Assert.Equal("Execute,ExecuteAsync,ExecuteReader,ExecuteReaderAsync,ExecuteScalar,ExecuteScalar<,ExecuteScalarAsync,ExecuteScalarAsync<,GetRowParser,GetRowParser<,Query,Query<,QueryAsync,QueryAsync<,QueryFirst,QueryFirst<,QueryFirstAsync,QueryFirstAsync<,QueryFirstOrDefault,QueryFirstOrDefault<,QueryFirstOrDefaultAsync,QueryFirstOrDefaultAsync<,QueryMultiple,QueryMultipleAsync,QuerySingle,QuerySingle<,QuerySingleAsync,QuerySingleAsync<,QuerySingleOrDefault,QuerySingleOrDefault<,QuerySingleOrDefaultAsync,QuerySingleOrDefaultAsync<,QueryUnbufferedAsync,QueryUnbufferedAsync<", candidates); } } diff --git a/test/Dapper.AOT.Test/GeneratorTestBase.cs b/test/Dapper.AOT.Test/GeneratorTestBase.cs index bf5d86f1..aefb1451 100644 --- a/test/Dapper.AOT.Test/GeneratorTestBase.cs +++ b/test/Dapper.AOT.Test/GeneratorTestBase.cs @@ -1,4 +1,4 @@ -using Dapper.TestCommon; +using Dapper.AOT.Test.TestCommon; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using System; @@ -67,7 +67,7 @@ void Output(string message, bool force = false) ShowDiagnostics("Input code", inputCompilation, diagnosticsTo, "CS8795", "CS1701", "CS1702"); // Create the driver that will control the generation, passing in our generator - GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { generator.AsSourceGenerator() }, parseOptions: RoslynTestHelpers.ParseOptionsLatestLangVer); + GeneratorDriver driver = CSharpGeneratorDriver.Create([generator.AsSourceGenerator()], parseOptions: RoslynTestHelpers.ParseOptionsLatestLangVer); // Run the generation pass // (Note: the generator driver itself is immutable, and all calls return an updated version of the driver that you should use for subsequent calls) @@ -79,7 +79,7 @@ void Output(string message, bool force = false) if (result.Exception is not null) throw result.Exception; } - var dn = Normalize(diagnostics, Array.Empty()); + var dn = Normalize(diagnostics, []); if (dn.Any()) { Output($"Generator produced {dn.Count} diagnostics:"); @@ -131,11 +131,11 @@ void OutputDiagnostic(Diagnostic d) } } - static List Normalize(ImmutableArray diagnostics, string[] ignore) => ( + static List Normalize(ImmutableArray diagnostics, string[] ignore) => [.. from d in diagnostics where !ignore.Contains(d.Id) let loc = d.Location orderby loc.SourceTree?.FilePath, loc.SourceSpan.Start, d.Id, d.ToString() - select d).ToList(); + select d]; } } diff --git a/test/Dapper.AOT.Test/Helpers/TestFramework.cs b/test/Dapper.AOT.Test/Helpers/TestFramework.cs index 107af8a1..ff4fe80e 100644 --- a/test/Dapper.AOT.Test/Helpers/TestFramework.cs +++ b/test/Dapper.AOT.Test/Helpers/TestFramework.cs @@ -6,23 +6,34 @@ namespace Dapper.AOT.Test.Helpers { internal static class TestFramework { - public static readonly ISet NetVersions - = ((Net[])Enum.GetValues(typeof(Net))) + public static readonly ISet NetVersions = +#if NET48 + ((Net[])Enum.GetValues(typeof(Net))) +#else + Enum.GetValues() +#endif .Select(static x => x.ToString()) - .ToHashSet(); + .ToHashSet(StringComparer.OrdinalIgnoreCase); public static Net DetermineNetVersion() { -#if NET6_0_OR_GREATER +#if NET9_0_OR_GREATER + return Net.Net9; +#elif NET8_0_OR_GREATER + return Net.Net8; +#elif NET6_0_OR_GREATER return Net.Net6; -#endif +#else return Net.Net48; +#endif } public enum Net { Net48, - Net6 + Net6, + Net8, + Net9, } } } diff --git a/test/Dapper.AOT.Test/InGeneration/DbStringHelpersTests.cs b/test/Dapper.AOT.Test/InGeneration/DbStringHelpersTests.cs index bcaa4e2c..ad404b9a 100644 --- a/test/Dapper.AOT.Test/InGeneration/DbStringHelpersTests.cs +++ b/test/Dapper.AOT.Test/InGeneration/DbStringHelpersTests.cs @@ -1,6 +1,6 @@ using System.Data; using System.Data.Common; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using Xunit; namespace Dapper.AOT.Test.InGeneration @@ -30,6 +30,6 @@ public void ConfigureDbString_ShouldProperlySetupDbParameter(bool isAnsi, bool i Assert.Equal(expectedDbType, param.DbType); } - DbParameter CreateDbParameter() => new SqlParameter(); + private static SqlParameter CreateDbParameter() => new(); } } diff --git a/test/Dapper.AOT.Test/InterceptorTests.cs b/test/Dapper.AOT.Test/InterceptorTests.cs index 2f863dad..9410ed24 100644 --- a/test/Dapper.AOT.Test/InterceptorTests.cs +++ b/test/Dapper.AOT.Test/InterceptorTests.cs @@ -28,7 +28,11 @@ public static IEnumerable GetFiles() if (TestFramework.NetVersions.Contains(fileNetVersionStr)) { // it has to be the same or greater version - var fileNetVersion = (TestFramework.Net)Enum.Parse(typeof(TestFramework.Net), fileNetVersionStr); +#if NET48 + var fileNetVersion = (TestFramework.Net)Enum.Parse(typeof(TestFramework.Net), fileNetVersionStr, true); +#else + var fileNetVersion = Enum.Parse(fileNetVersionStr, true); +#endif if (currentNetVersion < fileNetVersion) { // skip if current version is lower than specified in the input file name diff --git a/test/Dapper.AOT.Test/Interceptors/Blame.output.txt b/test/Dapper.AOT.Test/Interceptors/Blame.output.txt index 4be5fa8a..982dcd28 100644 --- a/test/Dapper.AOT.Test/Interceptors/Blame.output.txt +++ b/test/Dapper.AOT.Test/Interceptors/Blame.output.txt @@ -1,4 +1,12 @@ +Input code has 1 diagnostics from 'Interceptors/Blame.input.cs': + +Warning CS0618 Interceptors/Blame.input.cs L8 C28 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' Generator produced 1 diagnostics: Hidden DAP000 L1 C1 Dapper.AOT handled 23 of 23 possible call-sites using 1 interceptors, 0 commands and 0 readers +Output code has 1 diagnostics from 'Interceptors/Blame.input.cs': + +Warning CS0618 Interceptors/Blame.input.cs L8 C28 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' diff --git a/test/Dapper.AOT.Test/Interceptors/DateOnly.net6.output.netfx.cs b/test/Dapper.AOT.Test/Interceptors/DateOnly.net6.output.netfx.cs new file mode 100644 index 00000000..c1abf85c --- /dev/null +++ b/test/Dapper.AOT.Test/Interceptors/DateOnly.net6.output.netfx.cs @@ -0,0 +1,190 @@ +#nullable enable +namespace Dapper.AOT // interceptors must be in a known namespace +{ + file static class DapperGeneratedInterceptors + { + [global::System.Runtime.CompilerServices.InterceptsLocationAttribute("Interceptors\\DateOnly.net6.input.cs", 12, 30)] + internal static global::System.Threading.Tasks.Task> QueryAsync0(this global::System.Data.IDbConnection cnn, string sql, object? param, global::System.Data.IDbTransaction? transaction, int? commandTimeout, global::System.Data.CommandType? commandType) + { + // Query, Async, TypedResult, HasParameters, Buffered, Text, BindResultsByName, KnownParameters + // takes parameter: + // parameter map: BirthDate + // returns data: global::Foo.User + global::System.Diagnostics.Debug.Assert(!string.IsNullOrWhiteSpace(sql)); + global::System.Diagnostics.Debug.Assert((commandType ?? global::Dapper.DapperAotExtensions.GetCommandType(sql)) == global::System.Data.CommandType.Text); + global::System.Diagnostics.Debug.Assert(param is not null); + + return global::Dapper.DapperAotExtensions.AsEnumerableAsync( + global::Dapper.DapperAotExtensions.Command(cnn, transaction, sql, global::System.Data.CommandType.Text, commandTimeout.GetValueOrDefault(), CommandFactory0.Instance).QueryBufferedAsync(param, RowFactory0.Instance)); + + } + + [global::System.Runtime.CompilerServices.InterceptsLocationAttribute("Interceptors\\DateOnly.net6.input.cs", 17, 30)] + internal static global::System.Threading.Tasks.Task> QueryAsync1(this global::System.Data.IDbConnection cnn, string sql, object? param, global::System.Data.IDbTransaction? transaction, int? commandTimeout, global::System.Data.CommandType? commandType) + { + // Query, Async, TypedResult, HasParameters, Buffered, Text, BindResultsByName, KnownParameters + // takes parameter: global::Foo.QueryModel + // parameter map: BirthDate + // returns data: global::Foo.User + global::System.Diagnostics.Debug.Assert(!string.IsNullOrWhiteSpace(sql)); + global::System.Diagnostics.Debug.Assert((commandType ?? global::Dapper.DapperAotExtensions.GetCommandType(sql)) == global::System.Data.CommandType.Text); + global::System.Diagnostics.Debug.Assert(param is not null); + + return global::Dapper.DapperAotExtensions.AsEnumerableAsync( + global::Dapper.DapperAotExtensions.Command(cnn, transaction, sql, global::System.Data.CommandType.Text, commandTimeout.GetValueOrDefault(), CommandFactory1.Instance).QueryBufferedAsync((global::Foo.QueryModel)param!, RowFactory0.Instance)); + + } + + private class CommonCommandFactory : global::Dapper.CommandFactory + { + public override global::System.Data.Common.DbCommand GetCommand(global::System.Data.Common.DbConnection connection, string sql, global::System.Data.CommandType commandType, T args) + { + var cmd = base.GetCommand(connection, sql, commandType, args); + // apply special per-provider command initialization logic for OracleCommand + if (cmd is global::Oracle.ManagedDataAccess.Client.OracleCommand cmd0) + { + cmd0.BindByName = true; + cmd0.InitialLONGFetchSize = -1; + + } + return cmd; + } + + } + + private static readonly CommonCommandFactory DefaultCommandFactory = new(); + + private sealed class RowFactory0 : global::Dapper.RowFactory + { + internal static readonly RowFactory0 Instance = new(); + private RowFactory0() {} + public override object? Tokenize(global::System.Data.Common.DbDataReader reader, global::System.Span tokens, int columnOffset) + { + for (int i = 0; i < tokens.Length; i++) + { + int token = -1; + var name = reader.GetName(columnOffset); + var type = reader.GetFieldType(columnOffset); + switch (NormalizedHash(name)) + { + case 926444256U when NormalizedEquals(name, "id"): + token = type == typeof(int) ? 0 : 3; // two tokens for right-typed and type-flexible + break; + case 2369371622U when NormalizedEquals(name, "name"): + token = type == typeof(string) ? 1 : 4; + break; + case 4237030186U when NormalizedEquals(name, "birthdate"): + token = type == typeof(DateOnly) ? 2 : 5; + break; + + } + tokens[i] = token; + columnOffset++; + + } + return null; + } + public override global::Foo.User Read(global::System.Data.Common.DbDataReader reader, global::System.ReadOnlySpan tokens, int columnOffset, object? state) + { + global::Foo.User result = new(); + foreach (var token in tokens) + { + switch (token) + { + case 0: + result.Id = reader.GetInt32(columnOffset); + break; + case 3: + result.Id = GetValue(reader, columnOffset); + break; + case 1: + result.Name = reader.IsDBNull(columnOffset) ? (string?)null : reader.GetString(columnOffset); + break; + case 4: + result.Name = reader.IsDBNull(columnOffset) ? (string?)null : GetValue(reader, columnOffset); + break; + case 2: + result.BirthDate = reader.IsDBNull(columnOffset) ? (DateOnly?)null : reader.GetFieldValue(columnOffset); + break; + case 5: + result.BirthDate = reader.IsDBNull(columnOffset) ? (DateOnly?)null : GetValue(reader, columnOffset); + break; + + } + columnOffset++; + + } + return result; + + } + + } + + private sealed class CommandFactory0 : CommonCommandFactory // + { + internal static readonly CommandFactory0 Instance = new(); + public override void AddParameters(in global::Dapper.UnifiedCommand cmd, object? args) + { + var typed = Cast(args, static () => new { BirthDate = default()! }); // expected shape + var ps = cmd.Parameters; + global::System.Data.Common.DbParameter p; + p = cmd.CreateParameter(); + p.ParameterName = "BirthDate"; + p.Direction = global::System.Data.ParameterDirection.Input; + p.Value = AsValue(typed.BirthDate); + ps.Add(p); + + } + public override void UpdateParameters(in global::Dapper.UnifiedCommand cmd, object? args) + { + var typed = Cast(args, static () => new { BirthDate = default()! }); // expected shape + var ps = cmd.Parameters; + ps[0].Value = AsValue(typed.BirthDate); + + } + + } + + private sealed class CommandFactory1 : CommonCommandFactory + { + internal static readonly CommandFactory1 Instance = new(); + public override void AddParameters(in global::Dapper.UnifiedCommand cmd, global::Foo.QueryModel args) + { + var ps = cmd.Parameters; + global::System.Data.Common.DbParameter p; + p = cmd.CreateParameter(); + p.ParameterName = "BirthDate"; + p.Direction = global::System.Data.ParameterDirection.Input; + p.Value = AsValue(args.BirthDate); + ps.Add(p); + + } + public override void UpdateParameters(in global::Dapper.UnifiedCommand cmd, global::Foo.QueryModel args) + { + var ps = cmd.Parameters; + ps[0].Value = AsValue(args.BirthDate); + + } + + } + + + } +} +namespace System.Runtime.CompilerServices +{ + // this type is needed by the compiler to implement interceptors - it doesn't need to + // come from the runtime itself, though + + [global::System.Diagnostics.Conditional("DEBUG")] // not needed post-build, so: evaporate + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)] + sealed file class InterceptsLocationAttribute : global::System.Attribute + { + public InterceptsLocationAttribute(string path, int lineNumber, int columnNumber) + { + _ = path; + _ = lineNumber; + _ = columnNumber; + } + } +} \ No newline at end of file diff --git a/test/Dapper.AOT.Test/Interceptors/DateOnly.net6.output.netfx.txt b/test/Dapper.AOT.Test/Interceptors/DateOnly.net6.output.netfx.txt new file mode 100644 index 00000000..5ba1f0dd --- /dev/null +++ b/test/Dapper.AOT.Test/Interceptors/DateOnly.net6.output.netfx.txt @@ -0,0 +1,52 @@ +Input code has 4 diagnostics from 'Interceptors/DateOnly.net6.input.cs': + +Error CS0103 Interceptors/DateOnly.net6.input.cs L14 C25 +The name 'DateOnly' does not exist in the current context + +Error CS0103 Interceptors/DateOnly.net6.input.cs L19 C25 +The name 'DateOnly' does not exist in the current context + +Error CS0246 Interceptors/DateOnly.net6.input.cs L25 C16 +The type or namespace name 'DateOnly' could not be found (are you missing a using directive or an assembly reference?) + +Error CS0246 Interceptors/DateOnly.net6.input.cs L32 C16 +The type or namespace name 'DateOnly' could not be found (are you missing a using directive or an assembly reference?) +Generator produced 1 diagnostics: + +Hidden DAP000 L1 C1 +Dapper.AOT handled 2 of 2 possible call-sites using 2 interceptors, 2 commands and 1 readers +Output code has 4 diagnostics from 'Interceptors/DateOnly.net6.input.cs': + +Error CS0103 Interceptors/DateOnly.net6.input.cs L14 C25 +The name 'DateOnly' does not exist in the current context + +Error CS0103 Interceptors/DateOnly.net6.input.cs L19 C25 +The name 'DateOnly' does not exist in the current context + +Error CS0246 Interceptors/DateOnly.net6.input.cs L25 C16 +The type or namespace name 'DateOnly' could not be found (are you missing a using directive or an assembly reference?) + +Error CS0246 Interceptors/DateOnly.net6.input.cs L32 C16 +The type or namespace name 'DateOnly' could not be found (are you missing a using directive or an assembly reference?) +Output code has 7 diagnostics from 'Dapper.AOT.Analyzers/Dapper.CodeAnalysis.DapperInterceptorGenerator/Test.generated.cs': + +Error CS0246 Dapper.AOT.Analyzers/Dapper.CodeAnalysis.DapperInterceptorGenerator/Test.generated.cs L77 C52 +The type or namespace name 'DateOnly' could not be found (are you missing a using directive or an assembly reference?) + +Error CS0246 Dapper.AOT.Analyzers/Dapper.CodeAnalysis.DapperInterceptorGenerator/Test.generated.cs L107 C81 +The type or namespace name 'DateOnly' could not be found (are you missing a using directive or an assembly reference?) + +Error CS0246 Dapper.AOT.Analyzers/Dapper.CodeAnalysis.DapperInterceptorGenerator/Test.generated.cs L107 C119 +The type or namespace name 'DateOnly' could not be found (are you missing a using directive or an assembly reference?) + +Error CS0246 Dapper.AOT.Analyzers/Dapper.CodeAnalysis.DapperInterceptorGenerator/Test.generated.cs L110 C81 +The type or namespace name 'DateOnly' could not be found (are you missing a using directive or an assembly reference?) + +Error CS0246 Dapper.AOT.Analyzers/Dapper.CodeAnalysis.DapperInterceptorGenerator/Test.generated.cs L110 C107 +The type or namespace name 'DateOnly' could not be found (are you missing a using directive or an assembly reference?) + +Error CS1031 Dapper.AOT.Analyzers/Dapper.CodeAnalysis.DapperInterceptorGenerator/Test.generated.cs L128 C79 +Type expected + +Error CS1031 Dapper.AOT.Analyzers/Dapper.CodeAnalysis.DapperInterceptorGenerator/Test.generated.cs L140 C79 +Type expected diff --git a/test/Dapper.AOT.Test/Interceptors/IncludeSqlSource.output.txt b/test/Dapper.AOT.Test/Interceptors/IncludeSqlSource.output.txt index e9f5184f..3264e727 100644 --- a/test/Dapper.AOT.Test/Interceptors/IncludeSqlSource.output.txt +++ b/test/Dapper.AOT.Test/Interceptors/IncludeSqlSource.output.txt @@ -1,4 +1,12 @@ +Input code has 1 diagnostics from 'Interceptors/IncludeSqlSource.input.cs': + +Warning CS0618 Interceptors/IncludeSqlSource.input.cs L8 C28 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' Generator produced 1 diagnostics: Hidden DAP000 L1 C1 Dapper.AOT handled 1 of 1 possible call-sites using 1 interceptors, 0 commands and 0 readers +Output code has 1 diagnostics from 'Interceptors/IncludeSqlSource.input.cs': + +Warning CS0618 Interceptors/IncludeSqlSource.input.cs L8 C28 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' diff --git a/test/Dapper.AOT.Test/Interceptors/OmitAttribute.output.txt b/test/Dapper.AOT.Test/Interceptors/OmitAttribute.output.txt index e9f5184f..8f34ad06 100644 --- a/test/Dapper.AOT.Test/Interceptors/OmitAttribute.output.txt +++ b/test/Dapper.AOT.Test/Interceptors/OmitAttribute.output.txt @@ -1,4 +1,12 @@ +Input code has 1 diagnostics from 'Interceptors/OmitAttribute.input.cs': + +Warning CS0618 Interceptors/OmitAttribute.input.cs L7 C28 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' Generator produced 1 diagnostics: Hidden DAP000 L1 C1 Dapper.AOT handled 1 of 1 possible call-sites using 1 interceptors, 0 commands and 0 readers +Output code has 1 diagnostics from 'Interceptors/OmitAttribute.input.cs': + +Warning CS0618 Interceptors/OmitAttribute.input.cs L7 C28 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' diff --git a/test/Dapper.AOT.Test/Interceptors/QueryDetection.output.txt b/test/Dapper.AOT.Test/Interceptors/QueryDetection.output.txt index 2d9f6fa7..d68a7a53 100644 --- a/test/Dapper.AOT.Test/Interceptors/QueryDetection.output.txt +++ b/test/Dapper.AOT.Test/Interceptors/QueryDetection.output.txt @@ -1,4 +1,12 @@ +Input code has 1 diagnostics from 'Interceptors/QueryDetection.input.cs': + +Warning CS0618 Interceptors/QueryDetection.input.cs L7 C28 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' Generator produced 1 diagnostics: Hidden DAP000 L1 C1 Dapper.AOT handled 11 of 11 possible call-sites using 7 interceptors, 1 commands and 1 readers +Output code has 1 diagnostics from 'Interceptors/QueryDetection.input.cs': + +Warning CS0618 Interceptors/QueryDetection.input.cs L7 C28 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' diff --git a/test/Dapper.AOT.Test/Interceptors/SqlParse.output.txt b/test/Dapper.AOT.Test/Interceptors/SqlParse.output.txt index 22e5109a..5d63a89f 100644 --- a/test/Dapper.AOT.Test/Interceptors/SqlParse.output.txt +++ b/test/Dapper.AOT.Test/Interceptors/SqlParse.output.txt @@ -1,4 +1,12 @@ +Input code has 1 diagnostics from 'Interceptors/SqlParse.input.cs': + +Warning CS0618 Interceptors/SqlParse.input.cs L50 C28 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' Generator produced 1 diagnostics: Hidden DAP000 L1 C1 Dapper.AOT handled 10 of 10 possible call-sites using 3 interceptors, 2 commands and 0 readers +Output code has 1 diagnostics from 'Interceptors/SqlParse.input.cs': + +Warning CS0618 Interceptors/SqlParse.input.cs L50 C28 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' diff --git a/test/Dapper.AOT.Test/Interceptors/TsqlTips.output.txt b/test/Dapper.AOT.Test/Interceptors/TsqlTips.output.txt index 2e652be2..fde70f28 100644 --- a/test/Dapper.AOT.Test/Interceptors/TsqlTips.output.txt +++ b/test/Dapper.AOT.Test/Interceptors/TsqlTips.output.txt @@ -1,4 +1,42 @@ +Input code has 6 diagnostics from 'Interceptors/TsqlTips.input.cs': + +Warning CS0618 Interceptors/TsqlTips.input.cs L6 C27 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' + +Warning CS0618 Interceptors/TsqlTips.input.cs L47 C24 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' + +Warning CS0618 Interceptors/TsqlTips.input.cs L108 C29 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' + +Warning CS0618 Interceptors/TsqlTips.input.cs L114 C30 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' + +Warning CS0618 Interceptors/TsqlTips.input.cs L120 C30 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' + +Warning CS0618 Interceptors/TsqlTips.input.cs L166 C27 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' Generator produced 1 diagnostics: Hidden DAP000 L1 C1 Dapper.AOT handled 54 of 54 possible call-sites using 10 interceptors, 3 commands and 1 readers +Output code has 6 diagnostics from 'Interceptors/TsqlTips.input.cs': + +Warning CS0618 Interceptors/TsqlTips.input.cs L6 C27 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' + +Warning CS0618 Interceptors/TsqlTips.input.cs L47 C24 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' + +Warning CS0618 Interceptors/TsqlTips.input.cs L108 C29 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' + +Warning CS0618 Interceptors/TsqlTips.input.cs L114 C30 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' + +Warning CS0618 Interceptors/TsqlTips.input.cs L120 C30 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' + +Warning CS0618 Interceptors/TsqlTips.input.cs L166 C27 +'SqlConnection' is obsolete: 'Use the Microsoft.Data.SqlClient package instead.' diff --git a/test/Dapper.AOT.Test/Internal/Roslyn/TypeSymbolExtensionTests.cs b/test/Dapper.AOT.Test/Internal/Roslyn/TypeSymbolExtensionTests.cs index 9e2792e5..063e9be7 100644 --- a/test/Dapper.AOT.Test/Internal/Roslyn/TypeSymbolExtensionTests.cs +++ b/test/Dapper.AOT.Test/Internal/Roslyn/TypeSymbolExtensionTests.cs @@ -3,10 +3,11 @@ using Xunit; using System.Linq; using Microsoft.CodeAnalysis.Operations; -using Dapper.TestCommon; +using Dapper.AOT.Test.TestCommon; +using Dapper.Internal.Roslyn; using static Dapper.Internal.Inspection; -namespace Dapper.Internal.Roslyn +namespace Dapper.AOT.Test.Internal.Roslyn { public class TypeSymbolExtensionsTests { diff --git a/test/Dapper.AOT.Test/TSqlParserTests.cs b/test/Dapper.AOT.Test/TSqlParserTests.cs index 0cb5c82d..a5c3c255 100644 --- a/test/Dapper.AOT.Test/TSqlParserTests.cs +++ b/test/Dapper.AOT.Test/TSqlParserTests.cs @@ -306,7 +306,7 @@ from Customers var args = parser.GetParameters(out var errors); Assert.Equal("@id", Assert.Single(args)); - Assert.Equal("Incorrect syntax near garbage. (#46010) L5 C27", Assert.Single(errors)); + Assert.Equal("Incorrect syntax near 'garbage'. (#46010) L5 C27", Assert.Single(errors)); } [Fact] diff --git a/test/Dapper.AOT.Test/TestCommon/RoslynTestHelpers.cs b/test/Dapper.AOT.Test/TestCommon/RoslynTestHelpers.cs index 02172345..6555826a 100644 --- a/test/Dapper.AOT.Test/TestCommon/RoslynTestHelpers.cs +++ b/test/Dapper.AOT.Test/TestCommon/RoslynTestHelpers.cs @@ -14,7 +14,7 @@ using System.Runtime.Serialization; using System.Threading.Tasks; -namespace Dapper.TestCommon; +namespace Dapper.AOT.Test.TestCommon; internal static class RoslynTestHelpers { @@ -43,12 +43,14 @@ internal static class RoslynTestHelpers "RELEASE", #endif }) - .WithFeatures(new[] { DapperInterceptorGenerator.FeatureKeys.InterceptorsPreviewNamespacePair }); + .WithFeatures([ + DapperInterceptorGenerator.FeatureKeys.InterceptorsPreviewNamespacePair, + DapperInterceptorGenerator.FeatureKeys.InterceptorsNamespacePair]); public static Compilation CreateCompilation(string source, string name, string fileName) => CSharpCompilation.Create(name, - syntaxTrees: new[] { CSharpSyntaxTree.ParseText(source, ParseOptionsLatestLangVer).WithFilePath(fileName) }, - references: new[] { + syntaxTrees: [CSharpSyntaxTree.ParseText(source, ParseOptionsLatestLangVer).WithFilePath(fileName)], + references: [ MetadataReference.CreateFromFile(typeof(Binder).Assembly.Location), #if !NET48 MetadataReference.CreateFromFile(Assembly.Load("System.Runtime").Location), @@ -59,7 +61,9 @@ public static Compilation CreateCompilation(string source, string name, string f #endif MetadataReference.CreateFromFile(typeof(Console).Assembly.Location), MetadataReference.CreateFromFile(typeof(DbConnection).Assembly.Location), +#pragma warning disable CS0618 MetadataReference.CreateFromFile(typeof(System.Data.SqlClient.SqlConnection).Assembly.Location), +#pragma warning restore CS0618 MetadataReference.CreateFromFile(typeof(Microsoft.Data.SqlClient.SqlConnection).Assembly.Location), MetadataReference.CreateFromFile(typeof(OracleConnection).Assembly.Location), MetadataReference.CreateFromFile(typeof(ValueTask).Assembly.Location), @@ -75,6 +79,6 @@ public static Compilation CreateCompilation(string source, string name, string f MetadataReference.CreateFromFile(typeof(SqlMapper).Assembly.Location), MetadataReference.CreateFromFile(typeof(DynamicAttribute).Assembly.Location), MetadataReference.CreateFromFile(typeof(IValidatableObject).Assembly.Location), - }, + ], options: new CSharpCompilationOptions(OutputKind.ConsoleApplication, allowUnsafe: true)); } \ No newline at end of file diff --git a/test/Dapper.AOT.Test/Verifiers/DAP206.cs b/test/Dapper.AOT.Test/Verifiers/DAP206.cs index b34dd7c6..83455845 100644 --- a/test/Dapper.AOT.Test/Verifiers/DAP206.cs +++ b/test/Dapper.AOT.Test/Verifiers/DAP206.cs @@ -13,5 +13,5 @@ public class DAP206 : Verifier [Fact] public Task ParseError() => SqlVerifyAsync("{|#0:|}111 invalid", Diagnostic(Diagnostics.ParseError) - .WithLocation(0).WithArguments(46010, "Incorrect syntax near 111.")); + .WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'.")); } \ No newline at end of file diff --git a/test/Dapper.AOT.Test/Verifiers/SqlDetection.cs b/test/Dapper.AOT.Test/Verifiers/SqlDetection.cs index 27667381..d6140880 100644 --- a/test/Dapper.AOT.Test/Verifiers/SqlDetection.cs +++ b/test/Dapper.AOT.Test/Verifiers/SqlDetection.cs @@ -21,7 +21,7 @@ public void Foo(DbConnection conn) } } """, DefaultConfig, [Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(0).WithArguments(46010, "Incorrect syntax near 111.")]); + .WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'.")]); [Fact] public Task CSVerifyQuestionMarkInQuery_LikePseudoPositional() => CSVerifyAsync(""" @@ -79,9 +79,9 @@ public void Foo(DbCommand cmd) public string Blap {get;set;} } """, DefaultConfig, [Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(0).WithArguments(46010, "Incorrect syntax near 111."), + .WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(1).WithArguments(46010, "Incorrect syntax near 444.")]); + .WithLocation(1).WithArguments(46010, "Incorrect syntax near '444'.")]); [Fact] public Task CSViaParam() => CSVerifyAsync(""" @@ -104,10 +104,10 @@ public void Usage() """, DefaultConfig, [Diagnostic(DapperAnalyzer.Diagnostics.ParseError) .WithLocation(0) - .WithArguments(46010, "Incorrect syntax near 111."), + .WithArguments(46010, "Incorrect syntax near '111'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) .WithLocation(1) - .WithArguments(46010, "Incorrect syntax near 333.")]); + .WithArguments(46010, "Incorrect syntax near '333'.")]); [Fact] public Task VBViaDapper() => VBVerifyAsync(""" @@ -122,7 +122,7 @@ Public Sub Foo(conn As DbConnection) End Sub End Class """, DefaultConfig, [Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(0).WithArguments(46010, "Incorrect syntax near 111.")]); + .WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'.")]); [Fact] public Task VBViaProperty() => VBVerifyAsync(""" @@ -145,9 +145,9 @@ Public Property Bar As String Public Property Blap As String End Class """, DefaultConfig, [Diagnostic(DapperAnalyzer.Diagnostics.ParseError) -.WithLocation(0).WithArguments(46010, "Incorrect syntax near 111."), +.WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) -.WithLocation(1).WithArguments(46010, "Incorrect syntax near 444.")]); +.WithLocation(1).WithArguments(46010, "Incorrect syntax near '444'.")]); [Fact] public Task VBViaParam() => VBVerifyAsync(""" @@ -171,10 +171,10 @@ End Class """, DefaultConfig, [Diagnostic(DapperAnalyzer.Diagnostics.ParseError) .WithLocation(0) - .WithArguments(46010, "Incorrect syntax near 111."), + .WithArguments(46010, "Incorrect syntax near '111'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) .WithLocation(1) - .WithArguments(46010, "Incorrect syntax near 333.")]); + .WithArguments(46010, "Incorrect syntax near '333'.")]); [Fact] public Task CSharpSmokeTestVanilla() => CSVerifyAsync("""" diff --git a/test/Dapper.AOT.Test/Verifiers/SqlSyntaxDetection.cs b/test/Dapper.AOT.Test/Verifiers/SqlSyntaxDetection.cs index 5685c70c..740c0fcc 100644 --- a/test/Dapper.AOT.Test/Verifiers/SqlSyntaxDetection.cs +++ b/test/Dapper.AOT.Test/Verifiers/SqlSyntaxDetection.cs @@ -28,11 +28,11 @@ public void Foo(Microsoft.Data.SqlClient.SqlConnection conn) } """, DefaultConfig, [ Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(0).WithArguments(46010, "Incorrect syntax near 111."), + .WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(1).WithArguments(46010, "Incorrect syntax near 222."), + .WithLocation(1).WithArguments(46010, "Incorrect syntax near '222'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(2).WithArguments(46010, "Incorrect syntax near 333."), + .WithLocation(2).WithArguments(46010, "Incorrect syntax near '333'."), ], SqlSyntax.SqlServer); [Fact] @@ -57,9 +57,9 @@ public void Foo(Microsoft.Data.SqlClient.SqlConnection conn) // still picked up } """, DefaultConfig, [ Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(1).WithArguments(46010, "Incorrect syntax near 222."), + .WithLocation(1).WithArguments(46010, "Incorrect syntax near '222'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(2).WithArguments(46010, "Incorrect syntax near 333."), + .WithLocation(2).WithArguments(46010, "Incorrect syntax near '333'."), ], SqlSyntax.General); [Fact] @@ -87,11 +87,11 @@ public void Foo(Microsoft.Data.SqlClient.SqlConnection conn) } """, DefaultConfig, [ Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(0).WithArguments(46010, "Incorrect syntax near 111."), + .WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(1).WithArguments(46010, "Incorrect syntax near 222."), + .WithLocation(1).WithArguments(46010, "Incorrect syntax near '222'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(2).WithArguments(46010, "Incorrect syntax near 333."), + .WithLocation(2).WithArguments(46010, "Incorrect syntax near '333'."), ], SqlSyntax.General); [Fact] @@ -116,11 +116,11 @@ public void Foo(Microsoft.Data.SqlClient.SqlConnection conn) } """, DefaultConfig, [ Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(0).WithArguments(46010, "Incorrect syntax near 111."), + .WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(1).WithArguments(46010, "Incorrect syntax near 222."), + .WithLocation(1).WithArguments(46010, "Incorrect syntax near '222'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(2).WithArguments(46010, "Incorrect syntax near 333."), + .WithLocation(2).WithArguments(46010, "Incorrect syntax near '333'."), ], SqlSyntax.General); [Fact] @@ -148,11 +148,11 @@ public void Foo(Microsoft.Data.SqlClient.SqlConnection conn) } """, DefaultConfig, [ Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(0).WithArguments(46010, "Incorrect syntax near 111."), + .WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(1).WithArguments(46010, "Incorrect syntax near 222."), + .WithLocation(1).WithArguments(46010, "Incorrect syntax near '222'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(2).WithArguments(46010, "Incorrect syntax near 333."), + .WithLocation(2).WithArguments(46010, "Incorrect syntax near '333'."), ], SqlSyntax.General); [Fact] @@ -177,11 +177,11 @@ public void Foo(Microsoft.Data.SqlClient.SqlConnection conn) } """, DefaultConfig, [ Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(0).WithArguments(46010, "Incorrect syntax near 111."), + .WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(1).WithArguments(46010, "Incorrect syntax near 222."), + .WithLocation(1).WithArguments(46010, "Incorrect syntax near '222'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) - .WithLocation(2).WithArguments(46010, "Incorrect syntax near 333."), + .WithLocation(2).WithArguments(46010, "Incorrect syntax near '333'."), ], SqlSyntax.General); [Fact] @@ -206,11 +206,11 @@ public void Foo(Microsoft.Data.SqlClient.SqlConnection conn) } """, DefaultConfig, [ Diagnostic(DapperAnalyzer.Diagnostics.ParseError) -.WithLocation(0).WithArguments(46010, "Incorrect syntax near 111."), +.WithLocation(0).WithArguments(46010, "Incorrect syntax near '111'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) -.WithLocation(1).WithArguments(46010, "Incorrect syntax near 222."), +.WithLocation(1).WithArguments(46010, "Incorrect syntax near '222'."), Diagnostic(DapperAnalyzer.Diagnostics.ParseError) -.WithLocation(2).WithArguments(46010, "Incorrect syntax near 333."), +.WithLocation(2).WithArguments(46010, "Incorrect syntax near '333'."), ], SqlSyntax.General); diff --git a/test/Dapper.AOT.Test/Verifiers/Verifier.cs b/test/Dapper.AOT.Test/Verifiers/Verifier.cs index 9d163b25..c92f22ee 100644 --- a/test/Dapper.AOT.Test/Verifiers/Verifier.cs +++ b/test/Dapper.AOT.Test/Verifiers/Verifier.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis.VisualBasic.Testing; using System; using System.Collections.Generic; +using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -77,6 +78,10 @@ internal Task ExecuteAsync(AnalyzerTest test, string source, } #if NETFRAMEWORK test.ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net472.Default; +#elif NET9_0_OR_GREATER + test.ReferenceAssemblies = new ReferenceAssemblies("net9.0", + new PackageIdentity("Microsoft.NETCore.App.Ref", "9.0.0"), + Path.Combine("ref", "net9.0")); #elif NET8_0_OR_GREATER test.ReferenceAssemblies = new ReferenceAssemblies("net8.0", new PackageIdentity("Microsoft.NETCore.App.Ref", "8.0.0"), @@ -101,7 +106,9 @@ internal Task ExecuteAsync(AnalyzerTest test, string source, { test.TestState.AdditionalReferences.Add(typeof(DapperAotAttribute).Assembly); } +#pragma warning disable CS0618 test.TestState.AdditionalReferences.Add(typeof(System.Data.SqlClient.SqlConnection).Assembly); +#pragma warning restore CS0618 test.TestState.AdditionalReferences.Add(typeof(Microsoft.Data.SqlClient.SqlConnection).Assembly); test.TestState.AdditionalReferences.Add(typeof(System.ComponentModel.DataAnnotations.Schema.ColumnAttribute).Assembly); if (transforms is not null) @@ -122,7 +129,8 @@ static SourceText CreateEditorConfig(SqlSyntax syntax, SqlParseInputFlags sqlPar private static readonly SourceText AssumeSqlServer = CreateEditorConfig(SqlSyntax.SqlServer, SqlParseInputFlags.None); protected static readonly Func InterceptorsEnabled = WithFeatures( - DapperInterceptorGenerator.FeatureKeys.InterceptorsPreviewNamespacePair + DapperInterceptorGenerator.FeatureKeys.InterceptorsPreviewNamespacePair, + DapperInterceptorGenerator.FeatureKeys.InterceptorsNamespacePair ); protected static readonly Func CSharpPreview = WithCSharpLanguageVersion(Microsoft.CodeAnalysis.CSharp.LanguageVersion.Preview); diff --git a/test/UsageBenchmark/UsageBenchmark.csproj b/test/UsageBenchmark/UsageBenchmark.csproj index b3eff8e1..02add5ad 100644 --- a/test/UsageBenchmark/UsageBenchmark.csproj +++ b/test/UsageBenchmark/UsageBenchmark.csproj @@ -4,6 +4,7 @@ net8.0 False $(InterceptorsPreviewNamespaces);Dapper.AOT + $(InterceptorsNamespaces);Dapper.AOT