Skip to content

Commit

Permalink
Target .NET 8 (#380)
Browse files Browse the repository at this point in the history
Motivation
----------
General modernization.

Modifications
-------------
- Add global.json to require the .NET 8 SDK
- Use LangVersion 12 in Directory.Build.props
- Drop the deprecated .NET Standard 2.1 build target and add .NET 8
- Update to Couchbase SDK 3.5.5
- Upgrade various NuGet dependencies, especially for unit tests, and
  drop some unnecessary dependencies
- Use the in-box SourceLink in .NET 8 SDK rather than the OOB package
- Target net8.0 for unit tests
- Fix a LOT of nullable reference type warnings due to improved
  annotations in .NET 8
  • Loading branch information
brantburnett authored Nov 11, 2024
1 parent 1cb678c commit 8a59c4b
Show file tree
Hide file tree
Showing 59 changed files with 183 additions and 174 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<LangVersion>10</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand All @@ -14,15 +13,12 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="CouchbaseNetClient" Version="3.4.8" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
</ItemGroup>

<ItemGroup>
Expand Down
22 changes: 9 additions & 13 deletions Src/Couchbase.Linq.UnitTests/Couchbase.Linq.UnitTests.csproj
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<LangVersion>10</LangVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Couchbase.Linq\Couchbase.Linq.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="CouchbaseNetClient" Version="3.4.8" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="NUnit" Version="3.14.0" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Src/Couchbase.Linq/Clauses/ConsistentWithExpressionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ protected override void ApplyNodeSpecificSemantics(QueryModel queryModel,
ClauseGenerationContext clauseGenerationContext)
{
queryModel.BodyClauses.Add(new ConsistentWithClause(
(MutationState) MutationState.Value,
(MutationState) MutationState.Value!,
(TimeSpan?) ScanWait?.Value));
}
}
Expand Down
6 changes: 3 additions & 3 deletions Src/Couchbase.Linq/Clauses/NestExpressionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ internal class NestExpressionNode : MethodCallExpressionNodeBase, IQuerySourceEx
{
public static readonly MethodInfo[] SupportedMethods =
{
typeof(QueryExtensions).GetMethod("Nest"),
typeof(QueryExtensions).GetMethod("LeftOuterNest")
typeof(QueryExtensions).GetMethod("Nest")!,
typeof(QueryExtensions).GetMethod("LeftOuterNest")!
};

private readonly ResolvedExpressionCache<Expression> _cachedKeySelector;
Expand Down Expand Up @@ -92,7 +92,7 @@ protected override void ApplyNodeSpecificSemantics(QueryModel queryModel,
ClauseGenerationContext clauseGenerationContext)
{
var nestClause = new NestClause(
ResultSelector.Parameters[1].Name,
ResultSelector.Parameters[1].Name!,
ResultSelector.Parameters[1].Type,
InnerSequence,
GetResolvedKeySelector(clauseGenerationContext),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ protected override void ApplyNodeSpecificSemantics(QueryModel queryModel,
ClauseGenerationContext clauseGenerationContext)
{
queryModel.BodyClauses.Add(new ScanConsistencyClause(
(QueryScanConsistency) ScanConsistency.Value,
(QueryScanConsistency) ScanConsistency.Value!,
(TimeSpan?) ScanWait?.Value));
}
}
Expand Down
2 changes: 1 addition & 1 deletion Src/Couchbase.Linq/Clauses/UseHashExpressionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public override Expression Resolve(ParameterExpression inputParameter, Expressio
protected override void ApplyNodeSpecificSemantics(QueryModel queryModel,
ClauseGenerationContext clauseGenerationContext)
{
queryModel.BodyClauses.Add(new UseHashClause((HashHintType) HashHintType.Value));
queryModel.BodyClauses.Add(new UseHashClause((HashHintType) HashHintType.Value!));
}
}
}
2 changes: 1 addition & 1 deletion Src/Couchbase.Linq/Clauses/UseIndexExpressionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public override Expression Resolve(ParameterExpression inputParameter, Expressio
protected override void ApplyNodeSpecificSemantics(QueryModel queryModel,
ClauseGenerationContext clauseGenerationContext)
{
queryModel.BodyClauses.Add(new UseIndexClause((string) IndexName.Value, (N1QlIndexType) IndexType.Value));
queryModel.BodyClauses.Add(new UseIndexClause((string) IndexName.Value!, (N1QlIndexType) IndexType.Value!));
}
}
}
2 changes: 1 addition & 1 deletion Src/Couchbase.Linq/Clauses/UseKeysExpressionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ internal class UseKeysExpressionNode : MethodCallExpressionNodeBase
{
public static readonly MethodInfo[] SupportedMethods =
{
typeof (QueryExtensions).GetMethod("UseKeys")
typeof (QueryExtensions).GetMethod("UseKeys")!
};

public UseKeysExpressionNode(MethodCallExpressionParseInfo parseInfo, Expression keys)
Expand Down
13 changes: 4 additions & 9 deletions Src/Couchbase.Linq/Couchbase.Linq.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageProjectUrl>https://github.com/couchbaselabs/Linq2Couchbase</PackageProjectUrl>
<PackageIconUrl></PackageIconUrl>

<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net6.0;net8.0</TargetFrameworks>
<RootNamespace>Couchbase.Linq</RootNamespace>
<AssemblyName>Couchbase.Linq</AssemblyName>

Expand All @@ -22,7 +22,6 @@
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>

<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
<SignAssembly>false</SignAssembly>
<Version>2.0.1-beta.1</Version>
Expand All @@ -32,16 +31,12 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CouchbaseNetClient" Version="3.4.8" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="CouchbaseNetClient" Version="3.5.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Remotion.Linq" Version="2.2.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' OR '$(TargetFramework)' == 'netstandard2.1' ">
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
</ItemGroup>

Expand Down
10 changes: 6 additions & 4 deletions Src/Couchbase.Linq/Execution/ClusterQueryExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,17 @@ public T ExecuteScalar<T>(QueryModel queryModel)=>
: ExecuteCollection<T>(queryModel).Single();

public Task<T> ExecuteScalarAsync<T>(QueryModel queryModel, CancellationToken cancellationToken = default) =>
ExecuteSingleAsync<T>(queryModel, false, cancellationToken);
ExecuteSingleAsync<T>(queryModel, false, cancellationToken)!;

public Task<T> ExecuteSingleAsync<T>(QueryModel queryModel, bool returnDefaultWhenEmpty, CancellationToken cancellationToken = default)
public Task<T?> ExecuteSingleAsync<T>(QueryModel queryModel, bool returnDefaultWhenEmpty, CancellationToken cancellationToken = default)
{
// ReSharper disable MethodSupportsCancellation
var result = returnDefaultWhenEmpty
#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type.
ValueTask<T?> result = returnDefaultWhenEmpty
? ExecuteCollectionAsync<T>(queryModel).SingleOrDefaultAsync(cancellationToken)
: ExecuteCollectionAsync<T>(queryModel).SingleAsync(cancellationToken);
// ReSharper restore MethodSupportsCancellation
#pragma warning restore CS8619 // Nullability of reference types in value doesn't match target type.
// ReSharper restore MethodSupportsCancellation

return result.AsTask();
}
Expand Down
2 changes: 1 addition & 1 deletion Src/Couchbase.Linq/Execution/IAsyncQueryExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal interface IAsyncQueryExecutor : IQueryExecutor
{
IAsyncEnumerable<T> ExecuteCollectionAsync<T>(QueryModel queryModel, CancellationToken cancellationToken = default);

Task<T> ExecuteSingleAsync<T>(QueryModel queryModel, bool returnDefaultWhenEmpty, CancellationToken cancellationToken = default);
Task<T?> ExecuteSingleAsync<T>(QueryModel queryModel, bool returnDefaultWhenEmpty, CancellationToken cancellationToken = default);

Task<T> ExecuteScalarAsync<T>(QueryModel queryModel, CancellationToken cancellationToken = default);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ protected override AsyncStreamedValueInfo CloneWithNewDataType(Type dataType) =>
new AsyncStreamedScalarValueInfo(dataType);

/// <inheritdoc />
#pragma warning disable CS8609 // Nullability of reference types in return type doesn't match overridden member.
public override Task<T> ExecuteQueryModelAsync<T>(QueryModel queryModel, IAsyncQueryExecutor executor,
#pragma warning restore CS8609 // Nullability of reference types in return type doesn't match overridden member.
CancellationToken cancellationToken = default)
where T : default
{
if (queryModel == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ public AsyncStreamedSingleValueInfo(Type dataType, bool returnDefaultWhenEmpty)
protected override AsyncStreamedValueInfo CloneWithNewDataType(Type dataType) =>
new AsyncStreamedSingleValueInfo (dataType, ReturnDefaultWhenEmpty);

public override Task<T> ExecuteQueryModelAsync<T>(QueryModel queryModel, IAsyncQueryExecutor executor,
public override Task<T?> ExecuteQueryModelAsync<T>(QueryModel queryModel, IAsyncQueryExecutor executor,
CancellationToken cancellationToken = default)
where T : default
{
if (queryModel == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal abstract class AsyncStreamedValueInfo : IStreamedDataInfo
{
private static readonly MethodInfo ExecuteMethod =
typeof(AsyncStreamedValueInfo).GetMethod(nameof(ExecuteQueryModelAsync),
new[] {typeof(QueryModel), typeof(IAsyncQueryExecutor), typeof(CancellationToken)});
new[] {typeof(QueryModel), typeof(IAsyncQueryExecutor), typeof(CancellationToken)})!;

/// <inheritdoc />
/// <remarks>
Expand Down Expand Up @@ -70,7 +70,7 @@ public IStreamedData ExecuteQueryModel(QueryModel queryModel, IQueryExecutor exe
return new AsyncStreamedValue(result, this);
}

public abstract Task<T> ExecuteQueryModelAsync<T>(QueryModel queryModel, IAsyncQueryExecutor executor,
public abstract Task<T?> ExecuteQueryModelAsync<T>(QueryModel queryModel, IAsyncQueryExecutor executor,
CancellationToken cancellationToken = default);

protected abstract AsyncStreamedValueInfo CloneWithNewDataType (Type dataType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ namespace Couchbase.Linq.Operators
internal abstract class AsyncValueFromSequenceResultOperatorBase : ResultOperatorBase
{
private static readonly MethodInfo ExecuteMethod = typeof(AsyncValueFromSequenceResultOperatorBase)
.GetMethod(nameof(ExecuteInMemory), new[] {typeof(StreamedSequence)});
.GetMethod(nameof(ExecuteInMemory), new[] {typeof(StreamedSequence)})!;

public abstract AsyncStreamedValue ExecuteInMemory<T>(StreamedSequence sequence);
public abstract AsyncStreamedValue? ExecuteInMemory<T>(StreamedSequence sequence);

/// <inheritdoc />
public sealed override IStreamedData ExecuteInMemory(IStreamedData input)
Expand Down
4 changes: 2 additions & 2 deletions Src/Couchbase.Linq/Operators/FirstAsyncResultOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ public FirstAsyncResultOperator (bool returnDefaultWhenEmpty)
public override ResultOperatorBase Clone(CloneContext cloneContext) =>
new FirstAsyncResultOperator(ReturnDefaultWhenEmpty);

public override AsyncStreamedValue ExecuteInMemory<T>(StreamedSequence input)
public override AsyncStreamedValue? ExecuteInMemory<T>(StreamedSequence input)
{
var sequence = input.GetTypedSequence<T>();
T result = ReturnDefaultWhenEmpty ? sequence.FirstOrDefault() : sequence.First();
T? result = ReturnDefaultWhenEmpty ? sequence.FirstOrDefault() : sequence.First();
return new AsyncStreamedValue (Task.FromResult(result), GetOutputDataInfo (input.DataInfo));
}

Expand Down
4 changes: 2 additions & 2 deletions Src/Couchbase.Linq/Operators/SingleAsyncResultOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ public override ResultOperatorBase Clone(CloneContext cloneContext) =>
new SingleAsyncResultOperator(ReturnDefaultWhenEmpty);

/// <inheritdoc />
public override AsyncStreamedValue ExecuteInMemory<T>(StreamedSequence input)
public override AsyncStreamedValue? ExecuteInMemory<T>(StreamedSequence input)
{
var sequence = input.GetTypedSequence<T>();
T result = ReturnDefaultWhenEmpty ? sequence.SingleOrDefault() : sequence.Single();
T? result = ReturnDefaultWhenEmpty ? sequence.SingleOrDefault() : sequence.Single();
return new AsyncStreamedValue (Task.FromResult(result), GetOutputDataInfo (input.DataInfo));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private static Dictionary<MethodInfo, IMethodCallTranslator> CreateDefaultRegist
type.GetConstructor(Type.EmptyTypes) != null)
.SelectMany(type =>
{
var instance = (IMethodCallTranslator) Activator.CreateInstance(type);
var instance = (IMethodCallTranslator) Activator.CreateInstance(type)!;

return instance.SupportMethods
.Where(method => method != null)
Expand Down Expand Up @@ -232,7 +232,7 @@ private static bool ArgsMatch(ParameterInfo[] args, MethodInfo method, Type[] cl
if (parameterType.IsGenericParameter)
{
// This parameter is a generic from the class (not a method generic), so convert before comparing
var genericArgs = method.DeclaringType.GetGenericArguments();
var genericArgs = method.DeclaringType!.GetGenericArguments();

for (var genericIndex = 0; genericIndex < genericArgs.Length; genericIndex++)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ internal class DateTimeComparisonExpressionTransformer : IExpressionTransformer<
};

private static readonly HashSet<MethodInfo> ConversionMethods = new HashSet<MethodInfo>(
Types.Select(type => typeof(ISerializationConverter<>).MakeGenericType(type).GetMethod("ConvertTo", new[] {type})));
Types.Select(type => typeof(ISerializationConverter<>).MakeGenericType(type).GetMethod("ConvertTo", new[] {type}))!);
private static readonly HashSet<MethodInfo> InverseConversionMethods = new HashSet<MethodInfo>(
Types.Select(type => typeof(ISerializationConverter<>).MakeGenericType(type).GetMethod("ConvertFrom", new[] {type})));
Types.Select(type => typeof(ISerializationConverter<>).MakeGenericType(type).GetMethod("ConvertFrom", new[] {type}))!);

private static readonly ExpressionType[] StaticSupportedExpressionTypes =
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ internal class DateTimeSortExpressionTransformer : IExpressionTransformer<Method

private static readonly HashSet<MethodInfo> InverseConversionMethods = new HashSet<MethodInfo>(
Types.Select(type => typeof(ISerializationConverter<>).MakeGenericType(type)
.GetMethod(nameof(ISerializationConverter<DateTime>.ConvertFrom), new[] {type})));
.GetMethod(nameof(ISerializationConverter<DateTime>.ConvertFrom), new[] {type}))!);

private static readonly ExpressionType[] StaticSupportedExpressionTypes =
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private bool IsEnumConversion(Expression expression)

if (name != null)
{
comparisonValue = Expression.Constant(enumType.GetField(name).GetValue(null));
comparisonValue = Expression.Constant(enumType.GetField(name)!.GetValue(null));

if (isNullable)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ public KeyExpressionTransfomer(QuerySourceReferenceExpression querySourceReferen
}

_querySourceReference = querySourceReference;
_keyPropertyInfo = querySourceReference.ReferencedQuerySource.ItemType.GetProperty("Key");
_keyPropertyInfo = querySourceReference.ReferencedQuerySource.ItemType.GetProperty("Key")!;
_replacementExpression = replacementExpression;
}

public Expression Transform(MemberExpression expression)
{
if (expression.Expression.Equals(_querySourceReference) && (expression.Member == _keyPropertyInfo))
if (expression.Expression!.Equals(_querySourceReference) && (expression.Member == _keyPropertyInfo))
{
return _replacementExpression;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@ public MultiKeyExpressionTransfomer(QuerySourceReferenceExpression querySourceRe
}

_querySourceReference = querySourceReference;
_keyPropertyInfo = querySourceReference.ReferencedQuerySource.ItemType.GetProperty("Key");
_keyPropertyInfo = querySourceReference.ReferencedQuerySource.ItemType.GetProperty("Key")!;
_newExpression = newExpression;
}

public Expression Transform(MemberExpression expression)
{
var keyExpression = expression.Expression as MemberExpression;

if ((keyExpression != null) && keyExpression.Expression.Equals(_querySourceReference)
if ((keyExpression != null) && keyExpression.Expression!.Equals(_querySourceReference)
&& (keyExpression.Member == _keyPropertyInfo))
{
for (var i = 0; i < _newExpression.Members.Count; i++)
for (var i = 0; i < _newExpression.Members!.Count; i++)
{
if (_newExpression.Members[i] == expression.Member)
{
Expand Down
Loading

0 comments on commit 8a59c4b

Please sign in to comment.