private static bool CanIgnore(InvocationExpressionSyntax invocation, SemanticModel semanticModel, CancellationToken cancellationToken) { if (!(invocation.Parent is StatementSyntax)) { return(true); } if (invocation.Parent is ExpressionStatementSyntax && invocation.Parent.Parent is BlockSyntax && semanticModel.GetSymbolSafe(invocation, cancellationToken) is IMethodSymbol method) { if (method.ReturnsVoid) { return(true); } if (method == KnownSymbol.StringBuilder.Append || method == KnownSymbol.StringBuilder.AppendLine || method == KnownSymbol.StringBuilder.AppendFormat || method == KnownSymbol.IList.Add || method == KnownSymbol.IList.Remove) { return(true); } if (method.TryGetSingleDeclaration(cancellationToken, out MethodDeclarationSyntax declaration)) { using (var walker = ReturnValueWalker.Borrow(declaration, Search.Recursive, semanticModel, cancellationToken)) { if (method.IsExtensionMethod) { var identifier = declaration.ParameterList.Parameters[0].Identifier; foreach (var returnValue in walker) { if ((returnValue as IdentifierNameSyntax)?.Identifier.ValueText != identifier.ValueText) { return(false); } } return(true); } foreach (var returnValue in walker) { if (!returnValue.IsKind(SyntaxKind.ThisExpression)) { return(false); } } return(true); } } return(method.ReturnsVoid); } return(true); }
private static bool CanIgnore(InvocationExpressionSyntax invocation, SemanticModel semanticModel, CancellationToken cancellationToken) { if (semanticModel.GetSymbolSafe(invocation, cancellationToken) is IMethodSymbol method) { if (method.ReturnsVoid || method.ReturnType == KnownSymbol.MoqIReturnsResult) { return(true); } if (ReferenceEquals(method.ContainingType, method.ReturnType) && method.ContainingType == KnownSymbol.StringBuilder) { return(true); } if ((method.Name == "Add" || method.Name == "Remove" || method.Name == "RemoveAll" || method.Name == "TryAdd" || method.Name == "TryRemove") && method.ReturnType.IsEither(KnownSymbol.Boolean, KnownSymbol.Int32, KnownSymbol.Int64)) { return(true); } if (method.IsExtensionMethod) { method = method.ReducedFrom; } if (method.TrySingleDeclaration(cancellationToken, out MethodDeclarationSyntax declaration)) { using (var walker = ReturnValueWalker.Borrow(declaration, Search.Recursive, semanticModel, cancellationToken)) { foreach (var returnValue in walker) { if (returnValue is IdentifierNameSyntax identifierName && method.Parameters.TryFirst(x => x.Name == identifierName.Identifier.ValueText, out _)) { return(true); } if (returnValue is InstanceExpressionSyntax) { return(true); } } } } return(false); } return(true); }
private static void Handle(SyntaxNodeAnalysisContext context) { if (context.IsExcludedFromAnalysis()) { return; } if (context.Node is PropertyDeclarationSyntax propertyDeclaration && context.ContainingSymbol is IPropertySymbol property) { { if (propertyDeclaration.ExpressionBody is ArrowExpressionClauseSyntax expressionBody) { if (property.Type.IsReferenceType && expressionBody.Expression is ObjectCreationExpressionSyntax) { context.ReportDiagnostic(Diagnostic.Create(GU0021CalculatedPropertyAllocates.Descriptor, expressionBody.GetLocation())); } else if (expressionBody.Expression is MemberAccessExpressionSyntax memberAccess && IsRelayReturn(memberAccess, context.SemanticModel, context.CancellationToken)) { context.ReportDiagnostic(Diagnostic.Create(GU0008AvoidRelayProperties.Descriptor, memberAccess.GetLocation())); } } else if (propertyDeclaration.TryGetGetter(out var getter)) { using (var walker = ReturnValueWalker.Borrow(getter, Search.Recursive, context.SemanticModel, context.CancellationToken)) { if (walker.TrySingle(out var returnValue)) { if (property.Type.IsReferenceType && returnValue is ObjectCreationExpressionSyntax) { if (getter.Contains(returnValue) && returnValue.FirstAncestor <ReturnStatementSyntax>() is ReturnStatementSyntax returnStatement) { context.ReportDiagnostic(Diagnostic.Create(GU0021CalculatedPropertyAllocates.Descriptor, returnStatement.GetLocation())); } else { context.ReportDiagnostic(Diagnostic.Create(GU0021CalculatedPropertyAllocates.Descriptor, getter.GetLocation())); } } else if (returnValue is MemberAccessExpressionSyntax memberAccess && IsRelayReturn(memberAccess, context.SemanticModel, context.CancellationToken)) { if (getter.Contains(returnValue) && returnValue.FirstAncestor <ReturnStatementSyntax>() is ReturnStatementSyntax returnStatement) { context.ReportDiagnostic(Diagnostic.Create(GU0008AvoidRelayProperties.Descriptor, returnStatement.GetLocation())); } else { context.ReportDiagnostic(Diagnostic.Create(GU0008AvoidRelayProperties.Descriptor, getter.GetLocation())); } } } } } } } }