6using System.Collections.Immutable;
11 [DiagnosticAnalyzer(LanguageNames.CSharp)]
15 private static readonly DiagnosticDescriptor completeCalledInAsyncBusinessRuleRule =
16 new DiagnosticDescriptor(
17 Constants.AnalyzerIdentifiers.CompleteInExecuteAsync,
18 IsCompleteCalledInAsynchronousBusinessRuleConstants.Title,
19 IsCompleteCalledInAsynchronousBusinessRuleConstants.Message,
20 Constants.Categories.Usage, DiagnosticSeverity.Error,
true,
21 helpLinkUri: HelpUrlBuilder.Build(
25 ImmutableArray.Create(completeCalledInAsyncBusinessRuleRule);
29 context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
30 context.EnableConcurrentExecution();
31 context.RegisterSyntaxNodeAction(AnalyzeMethodDeclaration, SyntaxKind.MethodDeclaration);
34 private static void AnalyzeMethodDeclaration(SyntaxNodeAnalysisContext context)
36 var methodNode = (MethodDeclarationSyntax)context.Node;
38 if (!methodNode.ContainsDiagnostics)
40 var methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodNode);
41 var typeSymbol = methodSymbol.ContainingType;
43 if (typeSymbol.IsBusinessRule() && methodSymbol.Name ==
"ExecuteAsync" &&
44 methodSymbol.Parameters.Length > 0)
46 var contextParameter = methodSymbol.Parameters[0];
47 var wasCompleteMethodCalled =
48 methodNode.DescendantNodes(_ =>
true).OfType<InvocationExpressionSyntax>()
51 return context.SemanticModel.GetSymbolInfo(invocation.Expression).Symbol is IMethodSymbol invocationSymbol &&
52 invocationSymbol.Name ==
"Complete" && Equals(invocationSymbol.ContainingType, contextParameter.Type);
55 if (wasCompleteMethodCalled)
57 context.ReportDiagnostic(Diagnostic.Create(
58 completeCalledInAsyncBusinessRuleRule, methodSymbol.Locations[0]));
override void Initialize(AnalysisContext context)
override ImmutableArray< DiagnosticDescriptor > SupportedDiagnostics