Example #1
0
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(
                c =>
            {
                var invocation   = (InvocationExpressionSyntax)c.Node;
                var memberAccess = invocation.Expression as MemberAccessExpressionSyntax;
                if (memberAccess == null)
                {
                    return;
                }

                var fieldSymbol = c.SemanticModel.GetSymbolInfo(memberAccess.Expression).Symbol as IFieldSymbol;
                if (fieldSymbol == null ||
                    !DisposableMemberInNonDisposableClass.IsNonStaticNonPublicDisposableField(fieldSymbol) ||
                    !DisposableMemberInNonDisposableClass.ImplementsIDisposable(fieldSymbol.ContainingType))
                {
                    return;
                }

                var methodSymbol = c.SemanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;
                if (methodSymbol == null)
                {
                    return;
                }

                var disposeMethod = DisposableNotDisposed.GetDisposeMethod(c.SemanticModel.Compilation);
                if (disposeMethod == null)
                {
                    return;
                }

                if (!methodSymbol.Equals(
                        methodSymbol.ContainingType.FindImplementationForInterfaceMember(disposeMethod)))
                {
                    return;
                }

                var enclosingSymbol = c.SemanticModel.GetEnclosingSymbol(invocation.SpanStart);
                if (enclosingSymbol == null)
                {
                    return;
                }

                var enclosingMethodSymbol = enclosingSymbol as IMethodSymbol;
                if (enclosingMethodSymbol == null ||
                    enclosingMethodSymbol.Name != DisposeMethodName)
                {
                    c.ReportDiagnostic(Diagnostic.Create(Rule, memberAccess.Name.GetLocation()));
                }
            },
                SyntaxKind.InvocationExpression);
        }
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                analysisContext =>
            {
                var disposeMethod = DisposableNotDisposed.GetDisposeMethod(analysisContext.Compilation);
                if (disposeMethod == null)
                {
                    return;
                }

                var disposeMethodsCalledFromDispose = MultiValueDictionary <INamedTypeSymbol, IMethodSymbol> .Create <HashSet <IMethodSymbol> >();
                var implementingDisposeMethods      = ImmutableHashSet <IMethodSymbol> .Empty;
                var allDisposeMethods = ImmutableHashSet <IMethodSymbol> .Empty;

                analysisContext.RegisterSymbolAction(c =>
                                                     CollectDisposeMethods(c, disposeMethod, ref allDisposeMethods, ref implementingDisposeMethods),
                                                     SymbolKind.Method);

                analysisContext.RegisterCodeBlockStartAction <SyntaxKind>(
                    cbc =>
                {
                    var methodDeclaration = cbc.CodeBlock as MethodDeclarationSyntax;
                    if (methodDeclaration == null ||
                        methodDeclaration.Identifier.ValueText != DisposeMethodName)
                    {
                        return;
                    }

                    var declaredMethodSymbol = cbc.SemanticModel.GetDeclaredSymbol(methodDeclaration);
                    if (declaredMethodSymbol == null ||
                        !MethodIsDisposeImplementation(declaredMethodSymbol, disposeMethod))
                    {
                        return;
                    }

                    var disposableType = declaredMethodSymbol.ContainingType;
                    cbc.RegisterSyntaxNodeAction(
                        c => CollectDisposeMethodsCalledFromDispose((InvocationExpressionSyntax)c.Node,
                                                                    c.SemanticModel, disposableType, disposeMethodsCalledFromDispose),
                        SyntaxKind.InvocationExpression);
                });

                analysisContext.RegisterCompilationEndAction(
                    c =>
                    ReportDisposeMethods(allDisposeMethods, implementingDisposeMethods,
                                         disposeMethodsCalledFromDispose, c));
            });
        }