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); }
private static void DisposeInVirtualDisposeMethod(DocumentEditor editor, ISymbol memberSymbol, MethodDeclarationSyntax disposeMethodDeclaration, CancellationToken cancellationToken) { var disposeStatement = Snippet.DisposeStatement(memberSymbol, editor.SemanticModel, cancellationToken); if (TryFindIfDisposing(disposeMethodDeclaration, out var ifDisposing)) { if (ifDisposing.Statement is BlockSyntax block) { var statements = block.Statements.Add(disposeStatement); var newBlock = block.WithStatements(statements); editor.ReplaceNode(block, newBlock); } else if (ifDisposing.Statement is StatementSyntax statement) { editor.ReplaceNode( ifDisposing, ifDisposing.WithStatement(SyntaxFactory.Block(statement, disposeStatement))); } else { editor.ReplaceNode( ifDisposing, ifDisposing.WithStatement(SyntaxFactory.Block(disposeStatement))); } } else if (disposeMethodDeclaration.Body is BlockSyntax block) { ifDisposing = SyntaxFactory.IfStatement( SyntaxFactory.IdentifierName(disposeMethodDeclaration.ParameterList.Parameters[0].Identifier), SyntaxFactory.Block(disposeStatement)); if (DisposeMethod.TryFindBaseCall(disposeMethodDeclaration, editor.SemanticModel, cancellationToken, out var baseCall)) { if (baseCall.TryFirstAncestor(out ExpressionStatementSyntax expressionStatement)) { editor.InsertBefore(expressionStatement, ifDisposing); } } else { editor.ReplaceNode( block, block.AddStatements(ifDisposing)); } } }