1 /* 2 SPDX-FileCopyrightText: 2006-2008 Hamish Rodda <rodda@kde.org> 3 SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de> 4 5 SPDX-License-Identifier: LGPL-2.0-or-later 6 */ 7 8 #ifndef KDEVPLATFORM_CODECOMPLETIONITEMGROUPER_H 9 #define KDEVPLATFORM_CODECOMPLETIONITEMGROUPER_H 10 11 #include "codecompletionmodel.h" 12 #include "codecompletionitem.h" 13 #include <language/duchain/duchain.h> 14 #include <language/duchain/duchainlock.h> 15 16 namespace KDevelop { 17 ///Always the last item of a grouping chain: Only inserts the items 18 struct CodeCompletionItemLastGrouper 19 { CodeCompletionItemLastGrouperCodeCompletionItemLastGrouper20 CodeCompletionItemLastGrouper(QList<QExplicitlySharedDataPointer<CompletionTreeElement>>& tree, 21 CompletionTreeNode* parent, const QList<CompletionTreeItemPointer>& items) 22 { 23 tree.reserve(tree.size() + items.size()); 24 for (auto& item : items) { 25 item->setParent(parent); 26 tree << QExplicitlySharedDataPointer<CompletionTreeElement>(item.data()); 27 } 28 } 29 }; 30 31 ///Helper class that helps us grouping the completion-list. A chain of groupers can be built, by using NextGrouper. 32 template <class KeyExtractor, class NextGrouper = CodeCompletionItemLastGrouper> 33 struct CodeCompletionItemGrouper 34 { 35 using KeyType = typename KeyExtractor::KeyType; 36 CodeCompletionItemGrouperCodeCompletionItemGrouper37 CodeCompletionItemGrouper(QList<QExplicitlySharedDataPointer<CompletionTreeElement>>& tree, 38 CompletionTreeNode* parent, const QList<CompletionTreeItemPointer>& items) 39 { 40 using GroupMap = QMap<KeyType, QList<CompletionTreeItemPointer>>; 41 GroupMap groups; 42 43 for (auto& item : items) { 44 KeyType key = KeyExtractor::extract(item); 45 typename GroupMap::iterator it = groups.find(key); 46 if (it == groups.end()) 47 it = groups.insert(key, QList<CompletionTreeItemPointer>()); 48 49 (*it).append(item); 50 } 51 52 tree.reserve(tree.size() + groups.size()); 53 for (typename GroupMap::const_iterator it = groups.constBegin(); it != groups.constEnd(); ++it) { 54 QExplicitlySharedDataPointer<CompletionTreeNode> node(new CompletionTreeNode()); 55 node->setParent(parent); 56 node->role = ( KTextEditor::CodeCompletionModel::ExtraItemDataRoles )KeyExtractor::Role; 57 node->roleValue = QVariant(it.key()); 58 59 tree << QExplicitlySharedDataPointer<CompletionTreeElement>(node.data()); 60 61 NextGrouper nextGrouper(node->children, node.data(), *it); 62 } 63 } 64 }; 65 66 ///Extracts the argument-hint depth from completion-items, to be used in ItemGrouper for grouping by argument-hint depth. 67 struct ArgumentHintDepthExtractor 68 { 69 using KeyType = int; 70 enum { Role = KTextEditor::CodeCompletionModel::ArgumentHintDepth }; 71 extractArgumentHintDepthExtractor72 static KeyType extract(const CompletionTreeItemPointer& item) 73 { 74 return item->argumentHintDepth(); 75 } 76 }; 77 78 struct InheritanceDepthExtractor 79 { 80 using KeyType = int; 81 82 enum { Role = KTextEditor::CodeCompletionModel::InheritanceDepth }; 83 extractInheritanceDepthExtractor84 static KeyType extract(const CompletionTreeItemPointer& item) 85 { 86 return item->inheritanceDepth(); 87 } 88 }; 89 90 struct SimplifiedAttributesExtractor 91 { 92 using KeyType = int; 93 94 enum { Role = KTextEditor::CodeCompletionModel::CompletionRole }; 95 96 static const int groupingProperties; 97 extractSimplifiedAttributesExtractor98 static KeyType extract(const CompletionTreeItemPointer& item) 99 { 100 DUChainReadLocker lock(DUChain::lock()); 101 return item->completionProperties() & groupingProperties; 102 } 103 }; 104 } 105 106 #endif // KDEVPLATFORM_CODECOMPLETIONITEMGROUPER_H 107