private static void AnalyzeInvocationExpressionStatement(SyntaxNodeAnalysisContext context)
        {
            if (!(context.Node is InvocationExpressionSyntax node))
            {
                return;
            }

            var symbolInfo = context.SemanticModel.GetSymbolInfo(node);
            var symbol     = symbolInfo.Symbol as IMethodSymbol;

            var type = symbol?.ReturnType as INamedTypeSymbol;
            var ctx  = CustomAnalysisContext.WithOriginalNode(context, DisposableSource.InvocationExpression, type, Detector, Configuration);

            if (!ctx.CouldDetectType())
            {
            }
            else if (node.IsParentADisposeCallIgnoringParenthesis())
            {
                return;                                                      //(new object()).AsDisposable().Dispose()
            }
            else if (node.IsPartOfAwaitExpression())
            {
                AnalyzeInvocationExpressionInsideAwaitExpression(ctx);
            }
            else if (!ctx.IsDisposableOrImplementsDisposable())
            {
                return;
            }
            else if (node.IsReturnedInProperty())
            {
                AnalyzeNodeInReturnStatementOfProperty(ctx);
            }
            else if (ctx.IsTypeIgnoredOrImplementsIgnoredInterface())
            {
            }                                                             //GetEnumerator()
            else if (Detector.IsTrackingMethodCall(node, context.SemanticModel))
            {
            }                                                                       //ignored extension methods
            else if (Detector.IsIgnoredFactoryMethod(node, context.SemanticModel))
            {
                return;                                                                    //A.Fake<IDisposable>
            }
            else if (node.IsMaybePartOfMethodChainUsingTrackingExtensionMethod())
            {
                //there maybe multiple method invocations within one chain
                var baseNode = node;
                while (baseNode?.Parent is MemberAccessExpressionSyntax && baseNode?.Parent?.Parent is InvocationExpressionSyntax parentIes)
                {
                    baseNode = parentIes;
                    if (Detector.IsTrackingMethodCall(baseNode, context.SemanticModel))
                    {
                        return;
                    }
                }
            }
            else if (node.IsPartOfMethodCall())
            {
                AnalyzePartOfMethodCall(ctx);
            }
            else if (node.IsPartOfReturnStatementInBlock())
            {
            }                                                   // return new MemoryStream() or return Task.FromResult(new MemoryStream())
            else if (node.IsPartOfYieldReturnStatementInBlock())
            {
            }                                                        //yield return CreateMemoryStream()
            else if (node.IsArrowExpressionClauseOfMethod())
            {
            }                                                    // void Create()=>new MemoryStream()
            else if (node.IsReturnValueInLambdaExpression())
            {
            }                                                    //e.g. ()=> new MemoryStream
            else if (node.IsReturnedLaterWithinMethod())
            {
            }
            else if (node.IsReturnedLaterWithinParenthesizedLambdaExpression())
            {
            }
            else if (node.IsArgumentInObjectCreation())
            {
                AnalyzeNodeInArgumentList(ctx);
            }
            else if (node.IsPartIfArrayInitializerThatIsPartOfObjectCreation())
            {
                var objectCreation = node.Parent.Parent.Parent.Parent.Parent as ObjectCreationExpressionSyntax;
                CheckIfObjectCreationTracksNode(ctx, objectCreation);
            }
            else if (node.IsDescendantOfUsingHeader())
            {
            }                                              //using(memstream) or using(new MemoryStream())
            else if (node.IsDescendantOfVariableDeclarator())
            {
                AnalyzeNodeWithinVariableDeclarator(ctx);
            }
            else if (node.IsPartOfAssignmentExpression())
            {
                AnalyzeNodeInAssignmentExpression(ctx);
            }
            else if (node.IsPartOfAutoProperty())
            {
                AnalyzeNodeInAutoPropertyOrPropertyExpressionBody(ctx);
            }
            else if (node.IsPartOfPropertyExpressionBody())
            {
                AnalyzeNodeInAutoPropertyOrPropertyExpressionBody(ctx);
            }
            else
            {
                ctx.ReportNotDisposedAnonymousObject();  //call to Create(): MemeoryStream
            }
        }
Beispiel #2
0
        private void InvocationAction(SyntaxNodeAnalysisContext context)
        {
            var node = context.Node as InvocationExpressionSyntax;

            if (node == null)
            {
                return;
            }

            var symbolInfo = context.SemanticModel.GetSymbolInfo(node);
            var symbol     = symbolInfo.Symbol as IMethodSymbol;
            var type       = symbol?.ReturnType as INamedTypeSymbol;

            if (type == null)
            {
            }
            else if (node.IsParentADisposeCallIgnoringParenthesis())
            {
                return;                                                      //(new object()).AsDisposable().Dispose()
            }
            else if (node.IsPartOfAwaitExpression())
            {
                AnalyseInvokationExpressionInsideAwaitExpression(context, node);
            }
            else if (!type.IsDisposeableOrImplementsDisposable())
            {
                return;
            }
            else if (node.IsReturnedInProperty())
            {
                AnalyseNodeInReturnStatementOfProperty(context, node, DisposableSource.InvokationExpression);
            }
            else if (Detector.IsIgnoredTypeOrImplementsIgnoredInterface(type))
            {
            } //GetEnumerator()
            else if (Detector.IsTrackingMethodCall(node, context.SemanticModel))
            {
            } //ignored extension methods
            else if (Detector.IsIgnoredFactoryMethod(node, context.SemanticModel))
            {
                return;                                                                    //A.Fake<IDisposable>
            }
            else if (node.IsMaybePartOfMethodChainUsingTrackingExtensionMethod())
            {
                //there maybe multiple method invocations within one chain
                var baseNode = node;
                while (baseNode?.Parent is MemberAccessExpressionSyntax &&
                       baseNode?.Parent?.Parent is InvocationExpressionSyntax)
                {
                    baseNode = baseNode.Parent.Parent as InvocationExpressionSyntax;
                    if (Detector.IsTrackingMethodCall(baseNode, context.SemanticModel))
                    {
                        return;
                    }
                }
            }
            else if (!type.IsDisposeableOrImplementsDisposable())
            {
            }
            else if (node.IsPartOfMethodCall())
            {
                var methodInvocation = node.Parent.Parent.Parent as InvocationExpressionSyntax;
                if (Detector.IsTrackingMethodCall(methodInvocation, context.SemanticModel))
                {
                    return;
                }

                var rule = GetRule(DiagnosticId, CurrentSeverity);
                context.ReportNotDisposedAnonymousObject(rule, DisposableSource.ObjectCreation);
            }
            else if (node.IsPartOfReturnStatementInBlock())
            {
            } // return new MemoryStream() or return Task.FromResult(new MemoryStream())
            else if (node.IsArrowExpressionClauseOfMethod())
            {
            } // void Create()=>new MemoryStream()
            else if (node.IsReturnValueInLambdaExpression())
            {
            } //e.g. ()=> new MemoryStream
            else if (node.IsReturnedLaterWithinMethod())
            {
            }
            else if (node.IsReturnedLaterWithinParenthesizedLambdaExpression())
            {
            }
            else if (node.IsArgumentInObjectCreation())
            {
                AnalyseNodeInArgumentList(context, node, DisposableSource.InvokationExpression);
            }
            else if (node.IsPartIfArrayInitializerThatIsPartOfObjectCreation())
            {
                var objectCreation = node.Parent.Parent.Parent.Parent.Parent as ObjectCreationExpressionSyntax;
                CheckIfObjectCreationTracksNode(context, objectCreation, DisposableSource.ObjectCreation);
            }
            else if (node.IsDescendantOfUsingHeader())
            {
            } //using(memstream) or using(new MemoryStream())
            else if (node.IsDescendantOfVariableDeclarator())
            {
                AnalyseNodeWithinVariableDeclarator(context, node, DisposableSource.InvokationExpression);
            }
            else if (node.IsPartOfAssignmentExpression())
            {
                AnalyseNodeInAssignmentExpression(context, node, DisposableSource.InvokationExpression);
            }
            else if (node.IsPartOfAutoProperty())
            {
                AnalyseNodeInAutoPropertyOrPropertyExpressionBody(context, node, DisposableSource.InvokationExpression);
            }
            else if (node.IsPartOfPropertyExpressionBody())
            {
                AnalyseNodeInAutoPropertyOrPropertyExpressionBody(context, node, DisposableSource.InvokationExpression);
            }
            else
            {
                var rule = GetRule(DiagnosticId, CurrentSeverity);
                context.ReportNotDisposedAnonymousObject(rule, DisposableSource
                                                         .InvokationExpression); //call to Create(): MemeoryStream
            }
        }