CppEditor: Improve performance of QuickFix 'Remove using directive in global scope'

Change-Id: Id929255b5bf39a25b66ea18855b0c3c1f01720f0
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Leander Schulten
2020-11-17 02:27:31 +01:00
parent bf852d8fed
commit 8795ecbf5e

View File

@@ -7643,9 +7643,10 @@ class RemoveUsingNamespaceOperation : public CppQuickFixOperation
struct Node struct Node
{ {
Document::Ptr document; Document::Ptr document;
bool processed = false;
bool hasGlobalUsingDirective = false; bool hasGlobalUsingDirective = false;
int unprocessedParents;
std::vector<std::reference_wrapper<Node>> includes; std::vector<std::reference_wrapper<Node>> includes;
std::vector<std::reference_wrapper<Node>> includedBy;
Node() = default; Node() = default;
Node(const Node &) = delete; Node(const Node &) = delete;
Node(Node &&) = delete; Node(Node &&) = delete;
@@ -7690,6 +7691,7 @@ private:
const auto filePath = FilePath::fromString(include.resolvedFileName()); const auto filePath = FilePath::fromString(include.resolvedFileName());
if (shouldHandle(filePath)) { if (shouldHandle(filePath)) {
Node &includedNode = includeGraph[filePath]; Node &includedNode = includeGraph[filePath];
includedNode.includedBy.push_back(node);
node.includes.push_back(includedNode); node.includes.push_back(includedNode);
} }
} }
@@ -7715,34 +7717,37 @@ private:
} }
} }
} }
for (auto &[_, node] : includeGraph) {
Q_UNUSED(_)
node.unprocessedParents = static_cast<int>(node.includes.size());
}
return includeGraph; return includeGraph;
} }
void removeAllUsingsAtGlobalScope(CppRefactoringChanges &refactoring) void removeAllUsingsAtGlobalScope(CppRefactoringChanges &refactoring)
{ {
auto includeGraph = buildIncludeGraph(refactoring); auto includeGraph = buildIncludeGraph(refactoring);
std::list<std::reference_wrapper<Node>> unprocessedNodes; std::vector<std::reference_wrapper<Node>> nodesWithProcessedParents;
for (auto &[_, node] : includeGraph) { for (auto &[_, node] : includeGraph) {
Q_UNUSED(_) Q_UNUSED(_)
unprocessedNodes.push_back(node); if (!node.unprocessedParents)
nodesWithProcessedParents.push_back(node);
} }
while (!unprocessedNodes.empty()) { while (!nodesWithProcessedParents.empty()) {
for (auto i = unprocessedNodes.begin(); i != unprocessedNodes.end();) { Node &node = nodesWithProcessedParents.back();
Node &node = *i; nodesWithProcessedParents.pop_back();
if (Utils::allOf(node.includes, &Node::processed)) {
CppRefactoringFilePtr file = refactoring.file(node.document->fileName()); CppRefactoringFilePtr file = refactoring.file(node.document->fileName());
const bool parentHasUsing = Utils::anyOf(node.includes, const bool parentHasUsing = Utils::anyOf(node.includes, &Node::hasGlobalUsingDirective);
&Node::hasGlobalUsingDirective);
const int startPos = parentHasUsing const int startPos = parentHasUsing
? 0 ? 0
: RemoveNamespaceVisitor::SearchGlobalUsingDirectivePos; : RemoveNamespaceVisitor::SearchGlobalUsingDirectivePos;
const bool noGlobalUsing = refactorFile(file, refactoring.snapshot(), startPos); const bool noGlobalUsing = refactorFile(file, refactoring.snapshot(), startPos);
node.hasGlobalUsingDirective = !noGlobalUsing || parentHasUsing; node.hasGlobalUsingDirective = !noGlobalUsing || parentHasUsing;
node.processed = true;
i = unprocessedNodes.erase(i); for (Node &subNode : node.includedBy) {
} else { --subNode.unprocessedParents;
++i; if (subNode.unprocessedParents == 0)
} nodesWithProcessedParents.push_back(subNode);
} }
} }
} }