private static void Handle(SyntaxNodeAnalysisContext context)
        {
            if (context.IsExcludedFromAnalysis())
            {
                return;
            }

            if (context.Node is PropertyDeclarationSyntax propertyDeclaration &&
                context.ContainingSymbol is IPropertySymbol property &&
                property.GetMethod != null &&
                ReturnValueWalker.TrySingle(propertyDeclaration, out var returnValue))
            {
                if (property.Type.IsReferenceType &&
                    property.SetMethod == null &&
                    returnValue is ObjectCreationExpressionSyntax)
                {
                    context.ReportDiagnostic(Diagnostic.Create(Descriptors.GU0021CalculatedPropertyAllocates, returnValue.GetLocation()));
                }
                else if (returnValue is MemberAccessExpressionSyntax memberAccess &&
                         IsRelayReturn(memberAccess, context.SemanticModel, context.CancellationToken))
                {
                    context.ReportDiagnostic(Diagnostic.Create(Descriptors.GU0008AvoidRelayProperties, memberAccess.GetLocation()));
                }
            }
        }
Exemplo n.º 2
0
        private static bool CanIgnore(InvocationExpressionSyntax invocation, SyntaxNodeAnalysisContext context)
        {
            if (context.SemanticModel.TryGetSymbol(invocation, context.CancellationToken, out var method))
            {
                if (method.ReturnsVoid ||
                    method.ContainingType.IsAssignableTo(KnownSymbol.MoqMockOfT, context.Compilation) ||
                    method.ContainingType.IsAssignableTo(KnownSymbol.MoqIFluentInterface, context.Compilation) ||
                    method.ContainingType.IsAssignableTo(KnownSymbol.NinjectIFluentSyntax, context.Compilation))
                {
                    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(context.CancellationToken, out MethodDeclarationSyntax declaration) &&
                    ReturnValueWalker.TrySingle(declaration, out var returnValue))
                {
                    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);
        }
 internal static bool TryGetReturnExpression(this BlockSyntax body, SemanticModel semanticModel, CancellationToken cancellationToken, out ExpressionSyntax returnValue)
 {
     return(ReturnValueWalker.TrySingle(body, semanticModel, cancellationToken, out returnValue));
 }