private static bool IsAddedToFieldOrProperty(ILocalSymbol symbol, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            using (var pooledInvocations = InvocationWalker.Create(block))
            {
                foreach (var invocation in pooledInvocations.Item.Invocations)
                {
                    var method = semanticModel.GetSymbolSafe(invocation, cancellationToken) as IMethodSymbol;
                    if (method?.Name == "Add")
                    {
                        using (var pooledIdentifiers = IdentifierNameWalker.Create(invocation.ArgumentList))
                        {
                            foreach (var identifierName in pooledIdentifiers.Item.IdentifierNames)
                            {
                                var argSymbol = semanticModel.GetSymbolSafe(identifierName, cancellationToken);
                                if (symbol.Equals(argSymbol))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 2
0
        private static void HandleDisposeMethod(SyntaxNodeAnalysisContext context)
        {
            if (context.IsExcludedFromAnalysis())
            {
                return;
            }

            if (context.ContainingSymbol is IMethodSymbol method &&
                method.IsOverride &&
                method.Name == "Dispose")
            {
                var overridden = method.OverriddenMethod;
                if (overridden == null)
                {
                    return;
                }

                using (var invocations = InvocationWalker.Create(context.Node))
                {
                    foreach (var invocation in invocations.Item)
                    {
                        if (
                            SymbolComparer.Equals(
                                context.SemanticModel.GetSymbolSafe(invocation, context.CancellationToken), overridden))
                        {
                            return;
                        }
                    }
                }

                if (overridden.DeclaringSyntaxReferences.Length == 0)
                {
                    context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
                    return;
                }

                using (
                    var disposeWalker = Disposable.DisposeWalker.Create(overridden, context.SemanticModel, context.CancellationToken))
                {
                    foreach (var disposeCall in disposeWalker.Item)
                    {
                        if (Disposable.TryGetDisposedRootMember(disposeCall, context.SemanticModel, context.CancellationToken, out ExpressionSyntax disposed))
                        {
                            var member = context.SemanticModel.GetSymbolSafe(disposed, context.CancellationToken);
                            if (
                                !Disposable.IsMemberDisposed(member, method, context.SemanticModel, context.CancellationToken))
                            {
                                context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
                                return;
                            }
                        }
                    }
                }
            }
        }
        private static bool IsDisposedAfter(ISymbol symbol, ExpressionSyntax assignment, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            using (var pooled = InvocationWalker.Create(assignment.FirstAncestorOrSelf <MemberDeclarationSyntax>()))
            {
                foreach (var invocation in pooled.Item.Invocations)
                {
                    if (!IsAfter(invocation, assignment))
                    {
                        continue;
                    }

                    if (Disposable.IsDisposing(invocation, symbol, semanticModel, cancellationToken))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 4
0
        private static bool IsDisposedBefore(ISymbol symbol, ExpressionSyntax assignment, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            using (var pooled = InvocationWalker.Create(assignment.FirstAncestorOrSelf <MemberDeclarationSyntax>()))
            {
                foreach (var invocation in pooled.Item.Invocations)
                {
                    if (invocation.IsBeforeInScope(assignment) != Result.Yes)
                    {
                        continue;
                    }

                    var invokedSymbol = semanticModel.GetSymbolSafe(invocation, cancellationToken);
                    if (invokedSymbol?.Name != "Dispose")
                    {
                        continue;
                    }

                    var statement = invocation.FirstAncestorOrSelf <StatementSyntax>();
                    if (statement != null)
                    {
                        using (var pooledNames = IdentifierNameWalker.Create(statement))
                        {
                            foreach (var identifierName in pooledNames.Item.IdentifierNames)
                            {
                                var otherSymbol = semanticModel.GetSymbolSafe(identifierName, cancellationToken);
                                if (symbol.Equals(otherSymbol))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
        private static bool IsReturned(ILocalSymbol symbol, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            using (var pooled = ReturnValueWalker.Create(block, Search.TopLevel, semanticModel, cancellationToken))
            {
                foreach (var value in pooled.Item)
                {
                    var returnedSymbol = semanticModel.GetSymbolSafe(value, cancellationToken);
                    if (SymbolComparer.Equals(symbol, returnedSymbol))
                    {
                        return(true);
                    }

                    if (value is ObjectCreationExpressionSyntax objectCreation)
                    {
                        if (objectCreation.ArgumentList != null)
                        {
                            foreach (var argument in objectCreation.ArgumentList.Arguments)
                            {
                                var arg = semanticModel.GetSymbolSafe(argument.Expression, cancellationToken);
                                if (SymbolComparer.Equals(symbol, arg))
                                {
                                    return(true);
                                }
                            }
                        }

                        if (objectCreation.Initializer != null)
                        {
                            foreach (var argument in objectCreation.Initializer.Expressions)
                            {
                                var arg = semanticModel.GetSymbolSafe(argument, cancellationToken);
                                if (SymbolComparer.Equals(symbol, arg))
                                {
                                    return(true);
                                }
                            }
                        }
                    }

                    if (value is InvocationExpressionSyntax invocation)
                    {
                        if (returnedSymbol == KnownSymbol.RxDisposable.Create &&
                            invocation.ArgumentList != null &&
                            invocation.ArgumentList.Arguments.TryGetSingle(out ArgumentSyntax argument))
                        {
                            var body = (argument.Expression as ParenthesizedLambdaExpressionSyntax)?.Body;
                            using (var pooledInvocations = InvocationWalker.Create(body))
                            {
                                foreach (var candidate in pooledInvocations.Item.Invocations)
                                {
                                    if (Disposable.IsDisposing(candidate, symbol, semanticModel, cancellationToken))
                                    {
                                        return(true);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }