From 8795ecbf5eb1b48183125487f000b4522fc6a7a9 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Tue, 17 Nov 2020 02:27:31 +0100 Subject: [PATCH] CppEditor: Improve performance of QuickFix 'Remove using directive in global scope' Change-Id: Id929255b5bf39a25b66ea18855b0c3c1f01720f0 Reviewed-by: Christian Kandeler --- src/plugins/cppeditor/cppquickfixes.cpp | 45 ++++++++++++++----------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index bb0b781c3e8..a778caf3dc9 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -7643,9 +7643,10 @@ class RemoveUsingNamespaceOperation : public CppQuickFixOperation struct Node { Document::Ptr document; - bool processed = false; bool hasGlobalUsingDirective = false; + int unprocessedParents; std::vector> includes; + std::vector> includedBy; Node() = default; Node(const Node &) = delete; Node(Node &&) = delete; @@ -7690,6 +7691,7 @@ private: const auto filePath = FilePath::fromString(include.resolvedFileName()); if (shouldHandle(filePath)) { Node &includedNode = includeGraph[filePath]; + includedNode.includedBy.push_back(node); node.includes.push_back(includedNode); } } @@ -7715,34 +7717,37 @@ private: } } } + for (auto &[_, node] : includeGraph) { + Q_UNUSED(_) + node.unprocessedParents = static_cast(node.includes.size()); + } return includeGraph; } void removeAllUsingsAtGlobalScope(CppRefactoringChanges &refactoring) { auto includeGraph = buildIncludeGraph(refactoring); - std::list> unprocessedNodes; + std::vector> nodesWithProcessedParents; for (auto &[_, node] : includeGraph) { Q_UNUSED(_) - unprocessedNodes.push_back(node); + if (!node.unprocessedParents) + nodesWithProcessedParents.push_back(node); } - while (!unprocessedNodes.empty()) { - for (auto i = unprocessedNodes.begin(); i != unprocessedNodes.end();) { - Node &node = *i; - if (Utils::allOf(node.includes, &Node::processed)) { - CppRefactoringFilePtr file = refactoring.file(node.document->fileName()); - const bool parentHasUsing = Utils::anyOf(node.includes, - &Node::hasGlobalUsingDirective); - const int startPos = parentHasUsing - ? 0 - : RemoveNamespaceVisitor::SearchGlobalUsingDirectivePos; - const bool noGlobalUsing = refactorFile(file, refactoring.snapshot(), startPos); - node.hasGlobalUsingDirective = !noGlobalUsing || parentHasUsing; - node.processed = true; - i = unprocessedNodes.erase(i); - } else { - ++i; - } + while (!nodesWithProcessedParents.empty()) { + Node &node = nodesWithProcessedParents.back(); + nodesWithProcessedParents.pop_back(); + CppRefactoringFilePtr file = refactoring.file(node.document->fileName()); + const bool parentHasUsing = Utils::anyOf(node.includes, &Node::hasGlobalUsingDirective); + const int startPos = parentHasUsing + ? 0 + : RemoveNamespaceVisitor::SearchGlobalUsingDirectivePos; + const bool noGlobalUsing = refactorFile(file, refactoring.snapshot(), startPos); + node.hasGlobalUsingDirective = !noGlobalUsing || parentHasUsing; + + for (Node &subNode : node.includedBy) { + --subNode.unprocessedParents; + if (subNode.unprocessedParents == 0) + nodesWithProcessedParents.push_back(subNode); } } }