CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
IsCompleteCalledInAsynchronousBusinessRuleAnalyzer.cs
Go to the documentation of this file.
2using Microsoft.CodeAnalysis;
3using Microsoft.CodeAnalysis.CSharp;
4using Microsoft.CodeAnalysis.CSharp.Syntax;
5using Microsoft.CodeAnalysis.Diagnostics;
6using System.Collections.Immutable;
7using System.Linq;
8
9namespace Csla.Analyzers
10{
11 [DiagnosticAnalyzer(LanguageNames.CSharp)]
13 : DiagnosticAnalyzer
14 {
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(
22 Constants.AnalyzerIdentifiers.CompleteInExecuteAsync, nameof(IsCompleteCalledInAsynchronousBusinessRuleAnalyzer)));
23
24 public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
25 ImmutableArray.Create(completeCalledInAsyncBusinessRuleRule);
26
27 public override void Initialize(AnalysisContext context)
28 {
29 context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
30 context.EnableConcurrentExecution();
31 context.RegisterSyntaxNodeAction(AnalyzeMethodDeclaration, SyntaxKind.MethodDeclaration);
32 }
33
34 private static void AnalyzeMethodDeclaration(SyntaxNodeAnalysisContext context)
35 {
36 var methodNode = (MethodDeclarationSyntax)context.Node;
37
38 if (!methodNode.ContainsDiagnostics)
39 {
40 var methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodNode);
41 var typeSymbol = methodSymbol.ContainingType;
42
43 if (typeSymbol.IsBusinessRule() && methodSymbol.Name == "ExecuteAsync" &&
44 methodSymbol.Parameters.Length > 0)
45 {
46 var contextParameter = methodSymbol.Parameters[0];
47 var wasCompleteMethodCalled =
48 methodNode.DescendantNodes(_ => true).OfType<InvocationExpressionSyntax>()
49 .Any(invocation =>
50 {
51 return context.SemanticModel.GetSymbolInfo(invocation.Expression).Symbol is IMethodSymbol invocationSymbol &&
52 invocationSymbol.Name == "Complete" && Equals(invocationSymbol.ContainingType, contextParameter.Type);
53 });
54
55 if (wasCompleteMethodCalled)
56 {
57 context.ReportDiagnostic(Diagnostic.Create(
58 completeCalledInAsyncBusinessRuleRule, methodSymbol.Locations[0]));
59 }
60 }
61 }
62 }
63 }
64}