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.
CheckConstructorsAnalyzer.cs
Go to the documentation of this file.
1using Microsoft.CodeAnalysis;
2using Microsoft.CodeAnalysis.CSharp;
3using Microsoft.CodeAnalysis.CSharp.Syntax;
4using Microsoft.CodeAnalysis.Diagnostics;
5using System.Collections.Generic;
6using System.Collections.Immutable;
8
9namespace Csla.Analyzers
10{
11 [DiagnosticAnalyzer(LanguageNames.CSharp)]
12 public sealed class CheckConstructorsAnalyzer
13 : DiagnosticAnalyzer
14 {
15 private static readonly DiagnosticDescriptor publicNoArgumentConstructorIsMissingRule =
16 new DiagnosticDescriptor(
17 Constants.AnalyzerIdentifiers.PublicNoArgumentConstructorIsMissing, PublicNoArgumentConstructorIsMissingConstants.Title,
18 PublicNoArgumentConstructorIsMissingConstants.Message, Constants.Categories.Usage,
19 DiagnosticSeverity.Error, true,
20 helpLinkUri: HelpUrlBuilder.Build(
21 Constants.AnalyzerIdentifiers.PublicNoArgumentConstructorIsMissing, nameof(CheckConstructorsAnalyzer)));
22 private static readonly DiagnosticDescriptor constructorHasParametersRule =
23 new DiagnosticDescriptor(
24 Constants.AnalyzerIdentifiers.ConstructorHasParameters, ConstructorHasParametersConstants.Title,
25 ConstructorHasParametersConstants.Message, Constants.Categories.Usage,
26 DiagnosticSeverity.Warning, true,
27 helpLinkUri: HelpUrlBuilder.Build(
28 Constants.AnalyzerIdentifiers.ConstructorHasParameters, nameof(CheckConstructorsAnalyzer)));
29
30 public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
31 ImmutableArray.Create(
32 publicNoArgumentConstructorIsMissingRule,
33 constructorHasParametersRule);
34
35 public override void Initialize(AnalysisContext context)
36 {
37 context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
38 context.EnableConcurrentExecution();
39 context.RegisterSyntaxNodeAction(AnalyzeClassDeclaration, SyntaxKind.ClassDeclaration);
40 }
41
42 private static void AnalyzeClassDeclaration(SyntaxNodeAnalysisContext context)
43 {
44 var hasPublicNoArgumentConstructor = false;
45 var hasNonPublicNoArgumentConstructor = false;
46 var classNode = (ClassDeclarationSyntax)context.Node;
47 var classSymbol = context.SemanticModel.GetDeclaredSymbol(classNode);
48
49 if (classSymbol.IsStereotype() && !(classSymbol?.IsAbstract).Value)
50 {
51 foreach (var constructor in classSymbol?.Constructors)
52 {
53 if (!constructor.IsStatic)
54 {
55 if (constructor.DeclaredAccessibility == Accessibility.Public)
56 {
57 if (constructor.Parameters.Length == 0)
58 {
59 hasPublicNoArgumentConstructor = true;
60 }
61 else if(classSymbol.IsEditableStereotype())
62 {
63 foreach (var location in constructor.Locations)
64 {
65 context.ReportDiagnostic(Diagnostic.Create(
66 constructorHasParametersRule, location));
67 }
68 }
69 }
70 else if (constructor.Parameters.Length == 0)
71 {
72 hasNonPublicNoArgumentConstructor = true;
73 }
74 }
75 }
76
77 if (!hasPublicNoArgumentConstructor)
78 {
79 var properties = new Dictionary<string, string>()
80 {
81 [PublicNoArgumentConstructorIsMissingConstants.HasNonPublicNoArgumentConstructor] = hasNonPublicNoArgumentConstructor.ToString()
82 }.ToImmutableDictionary();
83
84 context.ReportDiagnostic(Diagnostic.Create(
85 publicNoArgumentConstructorIsMissingRule,
86 classNode.Identifier.GetLocation(), properties));
87 }
88 }
89 }
90 }
91}
override ImmutableArray< DiagnosticDescriptor > SupportedDiagnostics
override void Initialize(AnalysisContext context)