private static bool ShouldCallBase(IMethodSymbol method, MethodDeclarationSyntax methodDeclaration, SyntaxNodeAnalysisContext context)
        {
            if (method.Parameters.TrySingle(out var parameter) &&
                parameter.Type == KnownSymbol.Boolean &&
                method.IsOverride &&
                method.OverriddenMethod is IMethodSymbol overridden &&
                !DisposeMethod.TryFindBaseCall(methodDeclaration, context.SemanticModel, context.CancellationToken, out _))
            {
                if (overridden.DeclaringSyntaxReferences.Length == 0)
                {
                    return(true);
                }
                else
                {
                    using (var disposeWalker = DisposeWalker.Borrow(overridden, context.SemanticModel, context.CancellationToken))
                    {
                        foreach (var disposeCall in disposeWalker)
                        {
                            if (DisposeCall.TryGetDisposed(disposeCall, context.SemanticModel, context.CancellationToken, out var disposed) &&
                                FieldOrProperty.TryCreate(disposed, out var fieldOrProperty) &&
                                !DisposableMember.IsDisposed(fieldOrProperty, method, context.SemanticModel, context.CancellationToken))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
        internal static bool IsDisposed(FieldOrProperty member, MethodDeclarationSyntax disposeMethod, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            using var walker = DisposeWalker.Borrow(disposeMethod, semanticModel, cancellationToken);
            if (Disposable.IsAssignableFrom(member.Type, semanticModel.Compilation))
            {
                foreach (var candidate in walker.Invocations)
                {
                    if (DisposeCall.IsDisposing(candidate, member.Symbol, semanticModel, cancellationToken))
                    {
                        return(true);
                    }
                }
            }

            foreach (var candidate in walker.Identifiers)
            {
                if (candidate.Identifier.Text == member.Name &&
                    semanticModel.TryGetSymbol(candidate, cancellationToken, out var candidateSymbol) &&
                    candidateSymbol.OriginalDefinition.Equals(member.Symbol))
                {
                    return(true);
                }
            }

            return(false);
        }
        internal static Result IsDisposed(FieldOrProperty member, INamedTypeSymbol context, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            if (context is null)
            {
                return(Result.Unknown);
            }

            using var walker = DisposeWalker.Borrow(context, semanticModel, cancellationToken);
            var isMemberDisposed = walker.IsMemberDisposed(member.Symbol);

            switch (isMemberDisposed)
            {
            case Result.Yes:
            case Result.AssumeYes:
                return(isMemberDisposed);

            default:
                if (context.IsAssignableTo(KnownSymbol.SystemWindowsFormsForm, semanticModel.Compilation) &&
                    Winform.IsAddedToComponents(member, context, semanticModel, cancellationToken))
                {
                    return(Result.Yes);
                }

                return(isMemberDisposed);
            }
        }
Beispiel #4
0
        internal static bool IsMemberDisposed(ISymbol member, IMethodSymbol disposeMethod, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            if (member == null ||
                disposeMethod == null)
            {
                return(false);
            }

            foreach (var reference in disposeMethod.DeclaringSyntaxReferences)
            {
                var node = reference.GetSyntax(cancellationToken) as MethodDeclarationSyntax;
                using (var pooled = DisposeWalker.Borrow(disposeMethod, semanticModel, cancellationToken))
                {
                    foreach (var invocation in pooled)
                    {
                        if (IsDisposing(invocation, member, semanticModel, cancellationToken))
                        {
                            return(true);
                        }
                    }
                }

                using (var walker = IdentifierNameWalker.Borrow(node))
                {
                    foreach (var identifier in walker.IdentifierNames)
                    {
                        var memberAccess = identifier.Parent as MemberAccessExpressionSyntax;
                        if (memberAccess?.Expression is BaseExpressionSyntax)
                        {
                            var baseMethod = semanticModel.GetSymbolSafe(identifier, cancellationToken) as IMethodSymbol;
                            if (baseMethod?.Name == "Dispose")
                            {
                                if (IsMemberDisposed(member, baseMethod, semanticModel, cancellationToken))
                                {
                                    return(true);
                                }
                            }
                        }

                        if (identifier.Identifier.ValueText != member.Name)
                        {
                            continue;
                        }

                        var symbol = semanticModel.GetSymbolSafe(identifier, cancellationToken);
                        if (member.Equals(symbol) || (member as IPropertySymbol)?.OverriddenProperty?.Equals(symbol) == true)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Beispiel #5
0
        internal static Result IsDisposed(FieldOrProperty member, ITypeSymbol context, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            if (context == null)
            {
                return(Result.Unknown);
            }

            using (var walker = DisposeWalker.Borrow(context, semanticModel, cancellationToken))
            {
                return(walker.IsMemberDisposed(member.Symbol));
            }
        }
Beispiel #6
0
        internal static Result IsMemberDisposed(ISymbol member, ITypeSymbol context, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            if (!(member is IFieldSymbol ||
                  member is IPropertySymbol) ||
                context == null)
            {
                return(Result.Unknown);
            }

            using (var pooled = DisposeWalker.Borrow(context, semanticModel, cancellationToken))
            {
                return(pooled.IsMemberDisposed(member));
            }
        }
Beispiel #7
0
        internal static bool IsDisposed(FieldOrProperty member, IMethodSymbol disposeMethod, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            if (disposeMethod == null)
            {
                return(false);
            }

            using (var walker = DisposeWalker.Borrow(disposeMethod, semanticModel, cancellationToken))
            {
                foreach (var invocation in walker)
                {
                    if (DisposeCall.IsDisposing(invocation, member.Symbol, semanticModel, cancellationToken))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }