Exemple #1
0
        private static void HandleDisposeMethod(SyntaxNodeAnalysisContext context)
        {
            if (context.IsExcludedFromAnalysis())
            {
                return;
            }

            if (context.ContainingSymbol is IMethodSymbol method &&
                method.IsOverride &&
                method.Name == "Dispose")
            {
                var overridden = method.OverriddenMethod;
                if (overridden == null)
                {
                    return;
                }

                using (var invocations = InvocationWalker.Create(context.Node))
                {
                    foreach (var invocation in invocations.Item)
                    {
                        if (
                            SymbolComparer.Equals(
                                context.SemanticModel.GetSymbolSafe(invocation, context.CancellationToken), overridden))
                        {
                            return;
                        }
                    }
                }

                if (overridden.DeclaringSyntaxReferences.Length == 0)
                {
                    context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
                    return;
                }

                using (
                    var disposeWalker = Disposable.DisposeWalker.Create(overridden, context.SemanticModel, context.CancellationToken))
                {
                    foreach (var disposeCall in disposeWalker.Item)
                    {
                        if (Disposable.TryGetDisposedRootMember(disposeCall, context.SemanticModel, context.CancellationToken, out ExpressionSyntax disposed))
                        {
                            var member = context.SemanticModel.GetSymbolSafe(disposed, context.CancellationToken);
                            if (
                                !Disposable.IsMemberDisposed(member, method, context.SemanticModel, context.CancellationToken))
                            {
                                context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
                                return;
                            }
                        }
                    }
                }
            }
        }