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.
BusinessRuleDoesNotUseAddMethodsOnContextAnalyzer.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 usesAddMethodsOnContextRule =
16 new DiagnosticDescriptor(
17 Constants.AnalyzerIdentifiers.BusinessRuleContextUsage,
18 BusinessRuleDoesNotUseAddMethodsOnContextAnalyzerConstants.Title,
19 BusinessRuleDoesNotUseAddMethodsOnContextAnalyzerConstants.Message,
20 Constants.Categories.Usage, DiagnosticSeverity.Warning, true,
21 helpLinkUri: HelpUrlBuilder.Build(
22 Constants.AnalyzerIdentifiers.BusinessRuleContextUsage, nameof(BusinessRuleDoesNotUseAddMethodsOnContextAnalyzer)));
23
24 public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
25 ImmutableArray.Create(usesAddMethodsOnContextRule);
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() &&
44 (methodSymbol.Name == "Execute" || methodSymbol.Name == "ExecuteAsync") &&
45 methodSymbol.Parameters.Length > 0)
46 {
47 var contextParameter = methodSymbol.Parameters[0];
48 var wasAddMethodCalled =
49 methodNode.DescendantNodes(_ => true).OfType<InvocationExpressionSyntax>()
50 .Any(invocation =>
51 {
52 return context.SemanticModel.GetSymbolInfo(invocation.Expression).Symbol is IMethodSymbol invocationSymbol &&
53 invocationSymbol.Name.StartsWith("Add") && Equals(invocationSymbol.ContainingType, contextParameter.Type);
54 });
55
56 if (!wasAddMethodCalled)
57 {
58 context.ReportDiagnostic(Diagnostic.Create(
59 usesAddMethodsOnContextRule, contextParameter.Locations[0]));
60 }
61 }
62 }
63 }
64 }
65}