private static void HandleProperty(SyntaxNodeAnalysisContext context) { if (context.IsExcludedFromAnalysis()) { return; } AccessorDeclarationSyntax setter = (AccessorDeclarationSyntax)context.Node; if (setter.Body != null) { return; } var propertySymbol = context.ContainingProperty(); if (propertySymbol.SetMethod?.DeclaredAccessibility != Accessibility.Private || propertySymbol.IsIndexer) { return; } using (var walker = MutationWalker.Borrow(propertySymbol, context.SemanticModel, context.CancellationToken)) { foreach (var value in walker) { if (MeansPropertyIsMutable(value)) { return; } } } context.ReportDiagnostic(Diagnostic.Create(Descriptor, setter.GetLocation())); }
private static bool IsInjected(ISymbol member, SemanticModel semanticModel, CancellationToken cancellationToken) { if (member is IFieldSymbol field) { using (var walker = MutationWalker.Borrow(field, semanticModel, cancellationToken)) { foreach (var assignedValue in walker) { if (assignedValue.FirstAncestorOrSelf <ConstructorDeclarationSyntax>() == null) { continue; } if (semanticModel.GetSymbolSafe(assignedValue, cancellationToken) is IParameterSymbol) { return(true); } } } } if (member is IPropertySymbol property) { using (var walker = MutationWalker.Borrow(property, semanticModel, cancellationToken)) { foreach (var assignedValue in walker) { if (assignedValue.FirstAncestorOrSelf <ConstructorDeclarationSyntax>() == null) { continue; } if (semanticModel.GetSymbolSafe(assignedValue, cancellationToken) is IParameterSymbol) { return(true); } } } } return(false); }
private void AddReturnValue(ExpressionSyntax value) { if (this.awaits) { if (AsyncAwait.TryAwaitTaskRun(value, this.semanticModel, this.cancellationToken, out ExpressionSyntax awaited)) { using (var walker = this.GetRecursive(awaited)) { if (walker.values.Count == 0) { this.values.Add(awaited); } else { foreach (var returnValue in walker.values) { this.AddReturnValue(returnValue); } } } return; } if (AsyncAwait.TryAwaitTaskFromResult(value, this.semanticModel, this.cancellationToken, out awaited)) { this.AddReturnValue(awaited); return; } if (this.search == Search.Recursive && value is AwaitExpressionSyntax @await) { value = @await.Expression; } } if (this.search == Search.Recursive) { if (value is InvocationExpressionSyntax invocation) { var method = this.semanticModel.GetSymbolSafe(invocation, this.cancellationToken); if (method == null || method.DeclaringSyntaxReferences.Length == 0) { this.values.Add(value); } else { using (var walker = this.GetRecursive(value)) { foreach (var returnValue in walker.values) { this.AddReturnValue(returnValue); } } } } else if (this.recursionLoop.Add(value) && this.semanticModel.IsEither <IParameterSymbol, ILocalSymbol>(value, this.cancellationToken)) { using (var assignedValues = MutationWalker.Borrow(value, this.semanticModel, this.cancellationToken)) { if (assignedValues.Count == 0) { this.values.Add(value); } else { foreach (var assignment in assignedValues) { this.AddReturnValue(assignment); } } } } else { this.values.Add(value); } } else { this.values.Add(value); } }