Skip to content

Commit

Permalink
Analyses query syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveDunn committed Oct 21, 2024
1 parent 457f26c commit 0b31eb3
Show file tree
Hide file tree
Showing 3 changed files with 333 additions and 112 deletions.
39 changes: 39 additions & 0 deletions src/Vogen/Rules/DoNotCompareWithPrimitivesInEfCoreAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public override void Initialize(AnalysisContext context)
context.EnableConcurrentExecution();

context.RegisterSyntaxNodeAction(AnalyzeInvocation, SyntaxKind.InvocationExpression);
context.RegisterSyntaxNodeAction(AnalyzeQieryExpression, SyntaxKind.QueryExpression);
}

private static void AnalyzeInvocation(SyntaxNodeAnalysisContext context)
Expand Down Expand Up @@ -68,6 +69,32 @@ private static void AnalyzeInvocation(SyntaxNodeAnalysisContext context)
}
}

private static void AnalyzeQieryExpression(SyntaxNodeAnalysisContext context)
{
var queryExpr = (QueryExpressionSyntax) context.Node;
var whereClauses = queryExpr.Body.DescendantNodes().OfType<WhereClauseSyntax>();
var fromClause = queryExpr.FromClause;

if (!IsAMemberOfDbSet(context, fromClause)) return;

foreach (var eachArgument in whereClauses)
{
foreach (BinaryExpressionSyntax eachBinaryExpression in eachArgument.DescendantNodes().OfType<BinaryExpressionSyntax>())
{
ITypeSymbol? left = context.SemanticModel.GetTypeInfo(eachBinaryExpression.Left).Type;
ITypeSymbol? right = context.SemanticModel.GetTypeInfo(eachBinaryExpression.Right).Type;

if (left is null || right is null) continue;

// Check if left is ValueObject and right is integer
if (IsValueObject(left) && right.SpecialType == SpecialType.System_Int32)
{
context.ReportDiagnostic(DiagnosticsCatalogue.BuildDiagnostic(_rule, left.Name, eachBinaryExpression.GetLocation()));
}
}
}
}

private static bool IsAMemberOfDbSet(SyntaxNodeAnalysisContext context, MemberAccessExpressionSyntax memberAccessExpr)
{
var symbolInfo = context.SemanticModel.GetSymbolInfo(memberAccessExpr.Expression);
Expand All @@ -80,6 +107,18 @@ private static bool IsAMemberOfDbSet(SyntaxNodeAnalysisContext context, MemberAc
return InheritsFrom(ps.Type, dbSetType);
}

private static bool IsAMemberOfDbSet(SyntaxNodeAnalysisContext context, FromClauseSyntax fromClauseSyntax)
{
var symbolInfo = context.SemanticModel.GetSymbolInfo(fromClauseSyntax.Expression);
if (symbolInfo.Symbol is not IPropertySymbol ps) return false;

var dbSetType = context.SemanticModel.Compilation.GetTypeByMetadataName("Microsoft.EntityFrameworkCore.DbSet`1");

if (dbSetType is null) return false;

return InheritsFrom(ps.Type, dbSetType);
}

private static bool IsValueObject(ITypeSymbol type) =>
type is INamedTypeSymbol symbol && VoFilter.IsTarget(symbol);

Expand Down
Loading

0 comments on commit 0b31eb3

Please sign in to comment.