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); } }
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); }
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)); } }
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)); } }
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); }