private static void AnalyzeObjectCreationExpressionStatement(SyntaxNodeAnalysisContext context) { if (!(context.Node is ObjectCreationExpressionSyntax node)) { return; //something went wrong } var symbolInfo = context.SemanticModel.GetSymbolInfo(node); var t = (symbolInfo.Symbol as IMethodSymbol)?.ReceiverType as INamedTypeSymbol; var ctx = CustomAnalysisContext.WithOriginalNode(context, DisposableSource.ObjectCreation, t, Detector, Configuration); if (!ctx.CouldDetectType()) { } else if (!ctx.IsDisposableOrImplementsDisposable()) { return; } else if (node.IsParentADisposeCallIgnoringParenthesis()) { return; //(new MemoryStream()).Dispose() } else if (Detector.IsIgnoredTypeOrImplementsIgnoredInterface(ctx.Type)) { } else if (node.IsReturnedInProperty()) { AnalyzeNodeInReturnStatementOfProperty(ctx); } else if (node.IsPartOfReturnStatementInBlock()) { AnalyzeForHiddenDisposables(node, ctx); } // return new MemoryStream() or return Task.FromResult(new MemoryStream()) else if (node.IsArrowExpressionClauseOfMethod())// void/IDisposable/object Create()=>CreateMemoryStream() { AnalyzeArrowExpressionOfMethod(ctx); } else if (node.IsArrowExpressionClauseOfLocalFunction()) { AnalyzeArrowExpressionOfLocalFunction(ctx); } else if (node.IsPartOfLocalFunction(out var localFunctionStatement) && node.IsReturnedValue()) { var returnTypeSyntax = localFunctionStatement.ReturnType; var returnType = ctx.SemanticModel.GetSymbolInfo(returnTypeSyntax); }
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 } }
private static void AnalyzeObjectCreationExpressionStatement(SyntaxNodeAnalysisContext context) { if (!(context.Node is ObjectCreationExpressionSyntax node)) { return; //something went wrong } var symbolInfo = context.SemanticModel.GetSymbolInfo(node); var t = (symbolInfo.Symbol as IMethodSymbol)?.ReceiverType as INamedTypeSymbol; var ctx = CustomAnalysisContext.WithOriginalNode(context, DisposableSource.ObjectCreation, t, Detector, Configuration); if (!ctx.CouldDetectType()) { } else if (!ctx.IsDisposableOrImplementsDisposable()) { return; } else if (node.IsParentADisposeCallIgnoringParenthesis()) { return; //(new MemoryStream()).Dispose() } else if (Detector.IsIgnoredTypeOrImplementsIgnoredInterface(ctx.Type)) { } else if (node.IsReturnedInProperty()) { AnalyzeNodeInReturnStatementOfProperty(ctx); } else if (node.IsPartOfReturnStatementInBlock()) { } // return new MemoryStream() or return Task.FromResult(new MemoryStream()) else if (node.IsPartOfYieldReturnStatementInBlock()) { } //yield return new MemoryStream() else if (node.IsArrowExpressionClauseOfMethod()) { } // void Create()=>CreateMemoryStream() else if (node.IsReturnValueInLambdaExpression()) { } else if (node.IsReturnedLaterWithinMethod()) { } else if (node.IsReturnedLaterWithinParenthesizedLambdaExpression()) { } else if (node.IsPartOfMethodCall()) { AnalyzePartOfMethodCall(ctx); } else if (node.IsMaybePartOfMethodChainUsingTrackingExtensionMethod()) { var methodInvocation = node.Parent.Parent as InvocationExpressionSyntax; if (Detector.IsTrackingMethodCall(methodInvocation, context.SemanticModel)) { return; } } 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()) { } //this have to be checked after IsArgumentInObjectCreation else if (node.IsDescendantOfVariableDeclarator()) { AnalyzeNodeWithinVariableDeclarator(ctx); } else if (node.IsPartOfAssignmentExpression()) { AnalyzeNodeInAssignmentExpression(ctx); } else if (node.IsPartOfPropertyExpressionBody()) { AnalyzeNodeInAutoPropertyOrPropertyExpressionBody(ctx); } else if (node.IsPartOfAutoProperty()) { AnalyzeNodeInAutoPropertyOrPropertyExpressionBody(ctx); } else { ctx.ReportNotDisposedAnonymousObject(); //new MemoryStream(); } }