protected override IEnumerable <FieldData> FindFieldAssignments(IPropertySymbol property, Compilation compilation) { if (!(property.SetMethod.GetFirstSyntaxRef() is AccessorStatementSyntax setter)) { return(Enumerable.Empty <FieldData>()); } // we only keep information for the first location of the symbol var assignments = new Dictionary <IFieldSymbol, FieldData>(); FillAssignments(setter, true); // If there're no candidate variables, we'll try to inspect one local method invocation with value as argument if (assignments.Count == 0 && SingleInvocation(setter) is { } expression && FindInvokedMethod(compilation, property.ContainingType, expression) is MethodBaseSyntax invokedMethod) { FillAssignments(invokedMethod, false); } return(assignments.Values); void FillAssignments(SyntaxNode root, bool useFieldLocation) { // The ".Parent" is to go from the accessor statement to the accessor block foreach (var node in root.Parent.DescendantNodes()) { FieldData?foundField = null; if (node is AssignmentStatementSyntax assignment && assignment.IsKind(SyntaxKind.SimpleAssignmentStatement)) { foundField = assignment.Left.DescendantNodesAndSelf().OfType <ExpressionSyntax>() .Select(x => ExtractFieldFromExpression(AccessorKind.Setter, x, compilation, useFieldLocation)) .FirstOrDefault(x => x != null); }
private static void FillAssignments(IDictionary <IFieldSymbol, FieldData> assignments, Compilation compilation, SyntaxNode root, bool useFieldLocation) { foreach (var node in root.DescendantNodes()) { FieldData?foundField = null; if (node is AssignmentExpressionSyntax assignment && node.IsAnyKind(SyntaxKind.SimpleAssignmentExpression, SyntaxKindEx.CoalesceAssignmentExpression)) { foundField = assignment.Left.DescendantNodesAndSelf().OfType <ExpressionSyntax>() .Select(x => ExtractFieldFromExpression(AccessorKind.Setter, x, compilation, useFieldLocation)) .FirstOrDefault(x => x != null); }
protected void CheckExpectedFieldIsUsed(IFieldSymbol expectedField, FieldData?actualField, SymbolAnalysisContext context) { if (actualField.HasValue && actualField.Value.Field != expectedField) { context.ReportDiagnosticWhenActive(Diagnostic.Create( Rule, actualField.Value.LocationNode.GetLocation(), actualField.Value.AccessorKind == AccessorKind.Getter ? "getter" : "setter", expectedField.Name )); } }
protected override IEnumerable <FieldData> FindFieldAssignments(IPropertySymbol property, Compilation compilation) { if (!(property.SetMethod?.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() is AccessorDeclarationSyntax setter)) { return(Enumerable.Empty <FieldData>()); } // we only keep information for the first location of the symbol var assignments = new Dictionary <IFieldSymbol, FieldData>(); foreach (var node in setter.DescendantNodes()) { FieldData?foundField = null; if (node is AssignmentExpressionSyntax assignment && node.IsKind(SyntaxKind.SimpleAssignmentExpression)) { foundField = ExtractFieldFromExpression(AccessorKind.Setter, assignment.Left, compilation); }
public PropertyData(IPropertySymbol propertySymbol, FieldData?returned, FieldData?updated) { PropertySymbol = propertySymbol; FieldReturned = returned; FieldUpdated = updated; }