private static void Handle(SyntaxNodeAnalysisContext context) { if (context.IsExcludedFromAnalysis()) { return; } if (context.Node is AccessorDeclarationSyntax setter && setter.Body == null && context.ContainingSymbol is IMethodSymbol setMethod && setMethod.DeclaredAccessibility == Accessibility.Private && setMethod.AssociatedSymbol is IPropertySymbol property && !property.IsIndexer) { using (var walker = MutationWalker.For(property, context.SemanticModel, context.CancellationToken)) { foreach (var value in walker.All()) { if (MeansPropertyIsMutable(value)) { return; } } } context.ReportDiagnostic(Diagnostic.Create(Descriptor, setter.GetLocation())); } }
private static bool ShouldUseParameter(SyntaxNodeAnalysisContext context, ISymbol left, ExpressionSyntax expression) { if (expression.FirstAncestor <AnonymousFunctionExpressionSyntax>() != null) { if (left is IFieldSymbol field && !field.IsReadOnly) { return(false); } if (left is IPropertySymbol property && !property.IsGetOnly()) { return(false); } } return(TryGetIdentifier(expression, out var identifierName) && identifierName.IsSymbol(left, context.SemanticModel, context.CancellationToken) && IsMutatedOnceBefore()); bool IsMutatedOnceBefore() { if (expression.TryFirstAncestor(out StatementSyntax statement)) { using (var walker = MutationWalker.For(left, context.SemanticModel, context.CancellationToken)) { return(walker.TrySingle(out var single) && single.TryFirstAncestor(out StatementSyntax singleStatement) && singleStatement.IsExecutedBefore(statement) == ExecutedBefore.Yes); } } return(false); } }