5using System.Collections.Immutable;
11 [DiagnosticAnalyzer(LanguageNames.CSharp)]
15 private static readonly DiagnosticDescriptor onlyUseCslaPropertyMethodsInGetSetRule =
16 new DiagnosticDescriptor(
17 Constants.AnalyzerIdentifiers.OnlyUseCslaPropertyMethodsInGetSetRule, OnlyUseCslaPropertyMethodsInGetSetRuleConstants.Title,
18 OnlyUseCslaPropertyMethodsInGetSetRuleConstants.Message, Constants.Categories.Usage,
19 DiagnosticSeverity.Warning,
true,
20 helpLinkUri: HelpUrlBuilder.Build(
23 public override ImmutableArray<DiagnosticDescriptor>
SupportedDiagnostics => ImmutableArray.Create(onlyUseCslaPropertyMethodsInGetSetRule);
27 context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
28 context.EnableConcurrentExecution();
29 context.RegisterSyntaxNodeAction(AnalyzePropertyDeclaration, SyntaxKind.PropertyDeclaration);
32 private static void AnalyzePropertyDeclaration(SyntaxNodeAnalysisContext context)
34 var propertyNode = (PropertyDeclarationSyntax)context.Node;
36 if(!propertyNode.ContainsDiagnostics)
38 var propertySymbol = context.SemanticModel.GetDeclaredSymbol(propertyNode);
39 var classSymbol = propertySymbol.ContainingType;
41 if (propertySymbol !=
null && classSymbol !=
null &&
42 classSymbol.IsStereotype() && !propertySymbol.IsAbstract &&
43 !propertySymbol.IsStatic)
45 if (propertySymbol.GetMethod !=
null)
47 AnalyzePropertyGetter(propertyNode, context);
50 if (propertySymbol.SetMethod !=
null)
52 AnalyzePropertySetter(propertyNode, context);
58 private static void AnalyzePropertyGetter(PropertyDeclarationSyntax propertyNode, SyntaxNodeAnalysisContext context)
60 if (propertyNode.ExpressionBody ==
null)
62 AnalyzePropertyGetterWithGet(propertyNode, context);
66 AnalyzePropertyGetterWithExpressionBody(propertyNode, context);
70 private static void AnalyzePropertyGetterWithExpressionBody(PropertyDeclarationSyntax propertyNode, SyntaxNodeAnalysisContext context)
72 var getterExpression = propertyNode.ExpressionBody.Expression;
73 var getterChildren = getterExpression.DescendantNodes(_ =>
true).ToImmutableArray();
75 if (getterChildren.Length > 1)
77 var getterWalker =
new FindGetOrReadInvocationsWalker(
78 getterExpression, context.SemanticModel);
80 if (getterWalker.Invocation !=
null &&
81 getterChildren.Contains(getterWalker.Invocation))
83 context.ReportDiagnostic(Diagnostic.Create(
84 onlyUseCslaPropertyMethodsInGetSetRule,
85 getterExpression.GetLocation()));
90 private static void AnalyzePropertyGetterWithGet(PropertyDeclarationSyntax propertyNode, SyntaxNodeAnalysisContext context)
92 var getter = propertyNode.AccessorList.Accessors.Single(
93 _ => _.IsKind(SyntaxKind.GetAccessorDeclaration)).Body;
95 var getterWalker =
new FindGetOrReadInvocationsWalker(getter, context.SemanticModel);
97 if (getterWalker.Invocation !=
null)
99 var getterStatements = getter.Statements;
101 if (getterStatements.Count != 1)
103 context.ReportDiagnostic(Diagnostic.Create(
104 onlyUseCslaPropertyMethodsInGetSetRule,
105 getter.GetLocation()));
110 if (!(getterStatements[0] is ReturnStatementSyntax returnNode))
112 context.ReportDiagnostic(Diagnostic.Create(
113 onlyUseCslaPropertyMethodsInGetSetRule,
114 getter.GetLocation()));
119 if (!(returnNode.ChildNodes().SingleOrDefault(
120 _ => _.IsKind(SyntaxKind.InvocationExpression)) is InvocationExpressionSyntax invocation) || invocation != getterWalker.Invocation)
122 context.ReportDiagnostic(Diagnostic.Create(
123 onlyUseCslaPropertyMethodsInGetSetRule,
124 getter.GetLocation()));
131 private static void AnalyzePropertySetter(PropertyDeclarationSyntax propertyNode, SyntaxNodeAnalysisContext context)
133 var setter = propertyNode.AccessorList.Accessors.Single(
134 _ => _.IsKind(SyntaxKind.SetAccessorDeclaration)).Body;
136 var setterWalker =
new FindSetOrLoadInvocationsWalker(setter, context.SemanticModel);
138 if (setterWalker.Invocation !=
null)
140 var setterStatements = setter.Statements;
142 if (setterStatements.Count() != 1)
144 context.ReportDiagnostic(Diagnostic.Create(
145 onlyUseCslaPropertyMethodsInGetSetRule,
146 setter.GetLocation()));
151 if (!(setterStatements[0] is ExpressionStatementSyntax expressionNode))
153 context.ReportDiagnostic(Diagnostic.Create(
154 onlyUseCslaPropertyMethodsInGetSetRule,
155 setter.GetLocation()));
160 if (!(expressionNode.ChildNodes().SingleOrDefault(
161 _ => _.IsKind(SyntaxKind.InvocationExpression)) is InvocationExpressionSyntax invocation) || invocation != setterWalker.Invocation)
163 context.ReportDiagnostic(Diagnostic.Create(
164 onlyUseCslaPropertyMethodsInGetSetRule,
165 setter.GetLocation()));
override void Initialize(AnalysisContext context)
override ImmutableArray< DiagnosticDescriptor > SupportedDiagnostics