diff --git a/src/Akka.Analyzers.Tests/Analyzers/AK2000/MustNotHandleAutomaticallyHandledMessagesInMessageExtractorAnalyzerSpecs.cs b/src/Akka.Analyzers.Tests/Analyzers/AK2000/MustNotHandleAutomaticallyHandledMessagesInMessageExtractorAnalyzerSpecs.cs index 2e389ef..013a1a2 100644 --- a/src/Akka.Analyzers.Tests/Analyzers/AK2000/MustNotHandleAutomaticallyHandledMessagesInMessageExtractorAnalyzerSpecs.cs +++ b/src/Akka.Analyzers.Tests/Analyzers/AK2000/MustNotHandleAutomaticallyHandledMessagesInMessageExtractorAnalyzerSpecs.cs @@ -333,7 +333,47 @@ IMessageExtractor Create(){ """, new[] { (10, 26, 10, 48) -}) +}), + + ( + // Simple message extractor edge case - using expression body instead of block +""" +// 01 +using Akka.Cluster.Sharding; +public sealed class ShardMessageExtractor : HashCodeMessageExtractor +{ + /// + /// We only ever run with a maximum of two nodes, so ~10 shards per node + /// + public ShardMessageExtractor(int shardCount = 20) : base(shardCount) + { + } + + public override string EntityId(object message) + => (message as ShardingEnvelope)?.EntityId ?? null; +} +""", new[]{(13, 13, 13, 40)}), + + ( + // Simple message extractor edge case - using `as` +""" +// 02 +using Akka.Cluster.Sharding; +public sealed class ShardMessageExtractor : HashCodeMessageExtractor +{ + /// + /// We only ever run with a maximum of two nodes, so ~10 shards per node + /// + public ShardMessageExtractor(int shardCount = 20) : base(shardCount) + { + } + + public override string EntityId(object message) + { + return (message as ShardingEnvelope)?.EntityId ?? null; + } +} +""", new[]{(14, 17, 14, 44)}), }; [Theory] diff --git a/src/Akka.Analyzers/AK2000/MustNotUseAutomaticallyHandledMessagesInsideMessageExtractorAnalyzer.cs b/src/Akka.Analyzers/AK2000/MustNotUseAutomaticallyHandledMessagesInsideMessageExtractorAnalyzer.cs index b7e444d..42d8f7d 100644 --- a/src/Akka.Analyzers/AK2000/MustNotUseAutomaticallyHandledMessagesInsideMessageExtractorAnalyzer.cs +++ b/src/Akka.Analyzers/AK2000/MustNotUseAutomaticallyHandledMessagesInsideMessageExtractorAnalyzer.cs @@ -159,6 +159,24 @@ private static void AnalyzeDeclaredVariableNodes(SyntaxNodeAnalysisContext ctx, break; } + + case BinaryExpressionSyntax binaryExpressionSyntax when binaryExpressionSyntax.IsKind(SyntaxKind.AsExpression) && binaryExpressionSyntax.Right is TypeSyntax typeSyntax: + var typeSymbol = semanticModel.GetTypeInfo(typeSyntax).Type; + if (forbiddenTypes.Any(t => SymbolEqualityComparer.Default.Equals(t, typeSymbol))) + { + var location = binaryExpressionSyntax.GetLocation(); + + // duplicate + if (reportedLocations.Contains(location)) + break; + var diagnostic = Diagnostic.Create( + RuleDescriptors + .Ak2001DoNotUseAutomaticallyHandledMessagesInShardMessageExtractor, + location); + ctx.ReportDiagnostic(diagnostic); + reportedLocations.Add(location); + } + break; } } } \ No newline at end of file