private static void Handle(SyntaxNodeAnalysisContext context)
        {
            if (context.ContainingSymbol is IMethodSymbol method &&
                context.Node is MethodDeclarationSyntax methodDeclaration &&
                Disposable.IsAssignableFrom(method.ReturnType, context.Compilation))
            {
                using var walker = ReturnValueWalker.Borrow(methodDeclaration, ReturnValueSearch.RecursiveInside, context.SemanticModel, context.CancellationToken);
                if (walker.TryFirst(x => IsCreated(x), out _) &&
                    walker.TryFirst(x => IsCachedOrInjected(x) && !IsNop(x), out _))
                {
                    context.ReportDiagnostic(Diagnostic.Create(Descriptors.IDISP015DoNotReturnCachedAndCreated, methodDeclaration.Identifier.GetLocation()));
                }
            }

            bool IsCreated(ExpressionSyntax expression)
            {
                return(Disposable.IsCreation(expression, context.SemanticModel, context.CancellationToken) == Result.Yes);
            }

            bool IsCachedOrInjected(ExpressionSyntax expression)
            {
                return(Disposable.IsCachedOrInjected(expression, expression, context.SemanticModel, context.CancellationToken));
            }

            bool IsNop(ExpressionSyntax expression)
            {
                return(Disposable.IsNop(expression, context.SemanticModel, context.CancellationToken));
            }
        }
        private static void Handle(SyntaxNodeAnalysisContext context)
        {
            if (!context.IsExcludedFromAnalysis() &&
                context.Node is InvocationExpressionSyntax invocation &&
                DisposeCall.IsIDisposableDispose(invocation, context.SemanticModel, context.CancellationToken) &&
                !invocation.TryFirstAncestorOrSelf <AnonymousFunctionExpressionSyntax>(out _) &&
                DisposeCall.TryGetDisposedRootMember(invocation, context.SemanticModel, context.CancellationToken, out var root))
            {
                if (Disposable.IsCachedOrInjected(root, invocation, context.SemanticModel, context.CancellationToken))
                {
                    context.ReportDiagnostic(Diagnostic.Create(IDISP007DontDisposeInjected.Descriptor, invocation.FirstAncestorOrSelf <StatementSyntax>()?.GetLocation() ?? invocation.GetLocation()));
                }
                else if (context.SemanticModel.TryGetSymbol(root, context.CancellationToken, out ILocalSymbol local))
                {
                    if (IsUsedAfter(local, invocation, context, out var locations))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(IDISP016DontUseDisposedInstance.Descriptor, invocation.FirstAncestorOrSelf <StatementSyntax>()?.GetLocation() ?? invocation.GetLocation(), additionalLocations: locations));
                    }

                    if (IsPreferUsing(local, invocation, context))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(IDISP017PreferUsing.Descriptor, invocation.GetLocation()));
                    }
                }
            }
        }
예제 #3
0
        private static void Handle(SyntaxNodeAnalysisContext context)
        {
            if (context.IsExcludedFromAnalysis())
            {
                return;
            }

            if (context.Node is UsingStatementSyntax usingStatement)
            {
                if (usingStatement.Declaration is VariableDeclarationSyntax variableDeclaration)
                {
                    foreach (var variableDeclarator in variableDeclaration.Variables)
                    {
                        if (variableDeclarator.Initializer == null)
                        {
                            continue;
                        }

                        var value = variableDeclarator.Initializer.Value;
                        if (Disposable.IsCachedOrInjected(value, value, context.SemanticModel, context.CancellationToken))
                        {
                            context.ReportDiagnostic(Diagnostic.Create(IDISP007DontDisposeInjected.Descriptor, value.GetLocation()));
                        }
                    }
                }
                else if (usingStatement.Expression is ExpressionSyntax expression)
                {
                    if (Disposable.IsCachedOrInjected(expression, expression, context.SemanticModel, context.CancellationToken))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(IDISP007DontDisposeInjected.Descriptor, usingStatement.Expression.GetLocation()));
                    }
                }
            }
        }