Пример #1
0
        private static void AnalyzeNodeWithinLocalDeclaration(CustomAnalysisContext context, string localVariableName)
        {
            if (!context.Node.TryFindParentScope(out var parentScope))
            {
                return;
            }

            var localVariableInsideUsing = parentScope
                                           .DescendantNodes <UsingStatementSyntax>()
                                           .SelectMany(@using => @using.DescendantNodes <IdentifierNameSyntax>())
                                           .Where(id => localVariableName != null && (string)id.Identifier.Value == localVariableName)
                                           .ToArray();

            if (localVariableInsideUsing.Any())
            {
                if (localVariableInsideUsing.Any(id => id.Parent is UsingStatementSyntax)) //using(mem))
                {
                    return;
                }
                if (IsArgumentInConstructorOfTrackingTypeWithinUsing(context, localVariableInsideUsing))
                {
                    return;
                }

                context.ReportNotDisposedLocalVariable();
                return;
            }
            var invocationExpressions = parentScope.DescendantNodes <InvocationExpressionSyntax>().ToArray();

            if (invocationExpressions.Any(ie => ie.IsInterlockedExchangeAssignExpressionFor(localVariableName)))
            {
                return;
            }
            if (ExistsDisposeCall(localVariableName, invocationExpressions, context.SemanticModel))
            {
                return;
            }
            if (IsArgumentInTrackingMethod(context, localVariableName, invocationExpressions))
            {
                return;
            }
            if (IsArgumentInConstructorOfTrackingType(context, localVariableName, parentScope))
            {
                return;
            }
            if (IsCallToMethodThatIsConsideredAsDisposeCall(invocationExpressions, context))
            {
                return;
            }

            context.ReportNotDisposedLocalVariable();
        }
Пример #2
0
        private static void AnalyzeInvocationExpressionInsideAwaitExpression(CustomAnalysisContext context)
        {
            var node                = context.Node;
            var awaitExpression     = node.Parent as AwaitExpressionSyntax;
            var awaitExpressionInfo = context.SemanticModel.GetAwaitExpressionInfo(awaitExpression);

            if (!(awaitExpressionInfo.GetResultMethod?.ReturnType is INamedTypeSymbol returnType))
            {
                return;
            }
            if (!returnType.IsDisposableOrImplementsDisposable())
            {
                return;
            }
            if (Detector.IsIgnoredTypeOrImplementsIgnoredInterface(returnType))
            {
                return;
            }
            if (awaitExpression.IsDescendantOfUsingHeader())
            {
                return;
            }
            if (awaitExpression.IsPartOfVariableDeclaratorInsideAUsingDeclaration())
            {
                return;
            }
            if (awaitExpression.IsPartOfReturnStatementInMethod())
            {
                return;
            }
            if (awaitExpression.IsReturnedLaterWithinMethod())
            {
                return;
            }
            if (awaitExpression.IsDescendantOfVariableDeclarator())
            {
                AnalyzeNodeWithinVariableDeclarator(context.NewWith(awaitExpression));
            }
            else if (awaitExpression.IsDescendantOfAssignmentExpressionSyntax())
            {
                if (node.TryFindParentClass(out var @class))
                {
                    var assignment = awaitExpression?.Parent as AssignmentExpressionSyntax;
                    var member     = (assignment?.Left as IdentifierNameSyntax)?.Identifier.Text;
                    var isDisposed = @class.ContainsDisposeCallFor(member, context.SemanticModel, Configuration);
                    if (isDisposed)
                    {
                        return;
                    }
                }
                context.ReportNotDisposedLocalVariable();
            }
            else
            {
                context.ReportNotDisposedAnonymousObject();
            }
        }
Пример #3
0
        private static void AnalyzeNodeInAssignmentExpression(CustomAnalysisContext context)
        {
            var node = context.Node;
            //is local or global variable
            var assignmentExpressionSyntax = node.Parent as AssignmentExpressionSyntax;
            var variableName = (assignmentExpressionSyntax?.Left as IdentifierNameSyntax)?.Identifier.Text;

            if (node.TryFindContainingMethod(out var containingMethod))
            {
                if (containingMethod.ContainsDisposeCallFor(variableName, context.SemanticModel, Configuration))
                {
                    return;
                }

                if (containingMethod.HasDecendentVariableDeclaratorFor(variableName))
                {
                    //local declaration in method
                    if (containingMethod.Returns(variableName))
                    {
                        return;
                    }
                    if (node.IsDescendantOfUsingHeader())
                    {
                        return;
                    }
                    if (node.IsArgumentInObjectCreation())
                    {
                        AnalyzeNodeInArgumentList(context);
                        return;
                    }

                    if (containingMethod.HasInterlockedExchangeWith(variableName))
                    {
                        return;
                    }
                    //is part of tracking call
                    context.ReportNotDisposedLocalVariable();
                    return;
                }
                if (node.IsDisposedInDisposingMethod(variableName, Configuration, context.SemanticModel))
                {
                    return;
                }
                if (node.IsArgumentInObjectCreation())
                {
                    AnalyzeNodeInArgumentList(context);
                    return;
                }

                //assignment to field or property
                ReportStaticOrNonStaticNotDisposedMember(context, variableName);

                return;
            }

            if (node.TryFindContainingCtor(out var ctor))
            {
                if (ctor.HasDecendentVariableDeclaratorFor(variableName))
                {
                    //local variable in ctor
                    if (ctor.HasInterlockedExchangeWith(variableName))
                    {
                        return;
                    }
                    if (node.IsDescendantOfUsingHeader())
                    {
                        return;
                    }
                    if (node.IsArgumentInObjectCreation())
                    {
                        AnalyzeNodeInArgumentList(context);
                        return;
                    }
                    if (ctor.ContainsDisposeCallFor(variableName, context.SemanticModel, Configuration))
                    {
                        return;
                    }
                    context.ReportNotDisposedLocalVariable();
                }
                else //field or property
                {
                    if (node.IsDisposedInDisposingMethod(variableName, Configuration, context.SemanticModel))
                    {
                        return;
                    }

                    if (node.IsAssignmentToProperty(variableName, out var isStatic))
                    {
                        if (isStatic)
                        {
                            context.ReportNotDisposedStaticProperty(variableName);
                        }
                        else
                        {
                            context.ReportNotDisposedProperty(variableName);
                        }
                    }
                    else
                    {
                        if (node.IsAssignmentToStaticField(variableName))
                        {
                            context.ReportNotDisposedStaticField(variableName);
                        }
                        else
                        {
                            context.ReportNotDisposedField(variableName);
                        }
                    }
                }
            }
        }