Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
13 changes: 10 additions & 3 deletions src/Common/ITypeSymbolExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,18 @@ public bool Satisfies(ConstraintInfo? constraints, Compilation compilation)

foreach (var constraint in constraints.TypeConstraints)
{
if (compilation.ClassifyConversion(typeSymbol, constraint)
is not ({ IsIdentity: true } or { IsImplicit: true, IsReference: true }))
if (compilation.ClassifyConversion(typeSymbol, constraint) is { IsIdentity: true } or { IsImplicit: true, IsReference: true })
continue;

if (constraint is INamedTypeSymbol { TypeArguments: [ITypeParameterSymbol] } nts)
{
return false;
var constructed = nts.OriginalDefinition.Construct(typeSymbol);

if (compilation.ClassifyConversion(typeSymbol, constructed) is { IsIdentity: true } or { IsImplicit: true, IsReference: true })
continue;
}

return false;
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public override async ValueTask<IEnumerable<User>> HandleAsync(GetUsersQuery.Que

return response;
}
}
}

public class UsersService(ILogger<UsersService> logger)
{
Expand Down Expand Up @@ -102,7 +102,7 @@ public override async ValueTask<IEnumerable<User>> HandleAsync(int request, Canc

return response;
}
}
}

public class UsersService(ILogger<UsersService> logger)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using Immediate.Handlers.Analyzers;

namespace Immediate.Handlers.Tests.AnalyzerTests.HandlerClassAnalyzerTests;

[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1724:Type names should not match namespaces", Justification = "Not being consumed by other code")]
public sealed partial class Tests
{
[Fact]
public async Task CrtpBehaviorTypeIsValid_DoesNotAlert() =>
await AnalyzerTestHelpers.CreateAnalyzerTest<HandlerClassAnalyzer>(
"""
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Immediate.Handlers.Shared;
using Normal;

namespace Normal;

public class User { }
public interface IValidationTarget<T>;

public sealed class ValidationBehavior<TRequest, TResponse> : Behavior<TRequest, TResponse>
where TRequest : IValidationTarget<TRequest>
{
public override async ValueTask<TResponse> HandleAsync(TRequest request, CancellationToken cancellationToken)
{
return await Next(request, cancellationToken).ConfigureAwait(false);
}
}

public class UsersService
{
public ValueTask<IEnumerable<User>> GetUsers()
{
return ValueTask.FromResult(Enumerable.Empty<User>());
}
}

[Handler]
[Behaviors(
typeof(ValidationBehavior<,>)
)]
public sealed partial class GetUsersQuery(UsersService usersService)
{
public record Query : IValidationTarget<Query>;

private ValueTask<IEnumerable<User>> HandleAsync(
Query _,
CancellationToken token)
{
token.ThrowIfCancellationRequested();
return usersService.GetUsers();
}
}
""",
DriverReferenceAssemblies.Normal
).RunAsync(TestContext.Current.CancellationToken);
}