public override void Initialize(AnalysisContext context) { context.RegisterCompilationStartAction( analysisContext => { var disposeMethod = DisposableNotDisposed.GetDisposeMethod(analysisContext.Compilation); if (disposeMethod == null) { return; } var disposeMethodsCalledFromDispose = ImmutableDictionary <INamedTypeSymbol, ImmutableHashSet <IMethodSymbol> > .Empty; 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; if (!disposeMethodsCalledFromDispose.ContainsKey(disposableType)) { disposeMethodsCalledFromDispose = disposeMethodsCalledFromDispose.Add(disposableType, ImmutableHashSet <IMethodSymbol> .Empty); } cbc.RegisterSyntaxNodeAction( c => CollectDisposeMethodsCalledFromDispose((InvocationExpressionSyntax)c.Node, c.SemanticModel, disposableType, ref disposeMethodsCalledFromDispose), SyntaxKind.InvocationExpression); }); analysisContext.RegisterCompilationEndAction( c => ReportDisposeMethods(allDisposeMethods, implementingDisposeMethods, disposeMethodsCalledFromDispose, c)); }); }
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); }