From 6e3216e0678620e14b54276639807f12322b7768 Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Mon, 27 Nov 2017 10:57:26 +0100 Subject: [PATCH] src: replaced filters with NodeTypeSet --- src/lib/CMakeLists.txt | 2 + .../controller/ActivationController.cpp | 2 +- .../component/controller/CodeController.cpp | 2 +- .../component/controller/GraphController.cpp | 7 +- .../component/controller/SearchController.cpp | 6 +- .../controller/UndoRedoController.cpp | 6 +- src/lib/data/NodeType.cpp | 11 ++ src/lib/data/NodeType.h | 2 + src/lib/data/NodeTypeSet.cpp | 133 ++++++++++++++++++ src/lib/data/NodeTypeSet.h | 40 ++++++ src/lib/data/access/StorageAccess.h | 11 +- src/lib/data/access/StorageAccessProxy.cpp | 8 +- src/lib/data/access/StorageAccessProxy.h | 86 +++++------ src/lib/data/search/SearchIndex.cpp | 22 +-- src/lib/data/search/SearchIndex.h | 11 +- src/lib/data/search/SearchMatch.cpp | 21 ++- src/lib/data/search/SearchMatch.h | 3 +- src/lib/data/storage/PersistentStorage.cpp | 36 ++--- src/lib/data/storage/PersistentStorage.h | 8 +- .../messaging/type/MessageActivateAll.h | 7 +- .../utility/messaging/type/MessageSearch.h | 6 +- .../type/MessageSearchAutocomplete.h | 19 ++- src/lib_gui/qt/element/QtSmartSearchBox.cpp | 17 ++- src/lib_gui/qt/element/QtSmartSearchBox.h | 3 +- src/test/SearchIndexTestSuite.h | 14 +- 25 files changed, 346 insertions(+), 137 deletions(-) create mode 100644 src/lib/data/NodeTypeSet.cpp create mode 100644 src/lib/data/NodeTypeSet.h diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 6a85fc2a..da52c0fe 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -268,6 +268,8 @@ add_files( data/HierarchyCache.h data/NodeType.cpp data/NodeType.h + data/NodeTypeSet.cpp + data/NodeTypeSet.h data/TaskCleanStorage.cpp data/TaskCleanStorage.h data/TaskFinishParsing.cpp diff --git a/src/lib/component/controller/ActivationController.cpp b/src/lib/component/controller/ActivationController.cpp index 31df60e5..5552c329 100644 --- a/src/lib/component/controller/ActivationController.cpp +++ b/src/lib/component/controller/ActivationController.cpp @@ -100,7 +100,7 @@ void ActivationController::handleMessage(MessageSearch* message) case SearchMatch::COMMAND_ALL: case SearchMatch::COMMAND_NODE_FILTER: { - MessageActivateAll(message->filter).dispatchImmediately(); + MessageActivateAll(message->acceptedNodeTypes).dispatchImmediately(); return; } diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 45d62f06..780d96ba 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -34,7 +34,7 @@ void CodeController::handleMessage(MessageActivateAll* message) clear(); Project* currentProject = Application::getInstance()->getCurrentProject().get(); - if (!currentProject || message->filter) + if (!currentProject || message->acceptedNodeTypes != NodeTypeSet::all()) { return; } diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index 0e48cd86..79430f19 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -39,10 +39,11 @@ void GraphController::handleMessage(MessageActivateAll* message) m_dummyGraphNodes.clear(); - if (message->filter) + if (message->acceptedNodeTypes != NodeTypeSet::all()) { createDummyGraphAndSetActiveAndVisibility( - std::vector(), m_storageAccess->getGraphForFilter(message->filter)); + std::vector(), m_storageAccess->getGraphForNodeTypes(message->acceptedNodeTypes) + ); addCharacterIndex(); layoutNesting(); @@ -59,7 +60,7 @@ void GraphController::handleMessage(MessageActivateAll* message) layoutGraph(); } - buildGraph(message, false, true, message->filter); + buildGraph(message, false, true, message->acceptedNodeTypes != NodeTypeSet::all()); } void GraphController::handleMessage(MessageActivateTokens* message) diff --git a/src/lib/component/controller/SearchController.cpp b/src/lib/component/controller/SearchController.cpp index c34b0194..17878e71 100644 --- a/src/lib/component/controller/SearchController.cpp +++ b/src/lib/component/controller/SearchController.cpp @@ -16,11 +16,11 @@ SearchController::~SearchController() void SearchController::handleMessage(MessageActivateAll* message) { - if (message->filter) + if (message->acceptedNodeTypes != NodeTypeSet::all()) { if (message->isReplayed()) { - getView()->setMatches(SearchMatch::createCommandsForFilter(message->filter)); + getView()->setMatches(SearchMatch::createCommandsForNodeTypes(message->acceptedNodeTypes)); } return; } @@ -87,7 +87,7 @@ void SearchController::handleMessage(MessageSearchAutocomplete* message) } LOG_INFO("autocomplete string: \"" + message->query + "\""); - view->setAutocompletionList(m_storageAccess->getAutocompletionMatches(message->query, message->filter)); + view->setAutocompletionList(m_storageAccess->getAutocompletionMatches(message->query, message->acceptedNodeTypes)); } void SearchController::handleMessage(MessageSearchFullText* message) diff --git a/src/lib/component/controller/UndoRedoController.cpp b/src/lib/component/controller/UndoRedoController.cpp index f5e5664b..d6462995 100644 --- a/src/lib/component/controller/UndoRedoController.cpp +++ b/src/lib/component/controller/UndoRedoController.cpp @@ -45,7 +45,7 @@ UndoRedoController::Command::Command(std::shared_ptr message, Order void UndoRedoController::handleMessage(MessageActivateAll* message) { if (sameMessageTypeAsLast(message) && - static_cast(lastMessage())->filter == message->filter) + static_cast(lastMessage())->acceptedNodeTypes == message->acceptedNodeTypes) { return; } @@ -603,9 +603,9 @@ SearchMatch UndoRedoController::getSearchMatchForMessage(MessageBase* message) c if (message->getType() == MessageActivateAll::getStaticType()) { SearchMatch match = SearchMatch::createCommand(SearchMatch::COMMAND_ALL); - if (dynamic_cast(message)->filter) + if (dynamic_cast(message)->acceptedNodeTypes != NodeTypeSet::all()) { - match.name = match.text = "filter"; // TODO: show filter names + match.name = match.text = "filter"; // TODO: show acceptedNodeTypes names or at least type ids } return match; } diff --git a/src/lib/data/NodeType.cpp b/src/lib/data/NodeType.cpp index f29dc298..fb50795b 100644 --- a/src/lib/data/NodeType.cpp +++ b/src/lib/data/NodeType.cpp @@ -13,11 +13,22 @@ bool NodeType::operator==(const NodeType& o) const return m_type == o.m_type; } +bool NodeType::operator<(const NodeType& o) const +{ + return m_type < o.m_type; +} + NodeType::Type NodeType::getType() const { return m_type; } +Id NodeType::getId() const +{ + // TODO: add id in constructor and return it here + return utility::nodeTypeToInt(m_type); +} + bool NodeType::isFile() const { const NodeType::TypeMask mask = diff --git a/src/lib/data/NodeType.h b/src/lib/data/NodeType.h index 053f5e8c..179e3b2d 100644 --- a/src/lib/data/NodeType.h +++ b/src/lib/data/NodeType.h @@ -52,9 +52,11 @@ public: NodeType(Type type); bool operator==(const NodeType& o) const; + bool operator<(const NodeType& o) const; Type getType() const; + Id getId() const; bool isFile() const; bool isBuiltin() const; bool isUnknownSymbol() const; diff --git a/src/lib/data/NodeTypeSet.cpp b/src/lib/data/NodeTypeSet.cpp new file mode 100644 index 00000000..2429517e --- /dev/null +++ b/src/lib/data/NodeTypeSet.cpp @@ -0,0 +1,133 @@ +#include "data/NodeTypeSet.h" + +#include "utility/utility.h" + +NodeTypeSet NodeTypeSet::all() +{ + NodeTypeSet ret; + + ret.add(NodeType(NodeType::NODE_SYMBOL)); + ret.add(NodeType(NodeType::NODE_TYPE)); + ret.add(NodeType(NodeType::NODE_BUILTIN_TYPE)); + ret.add(NodeType(NodeType::NODE_NAMESPACE)); + ret.add(NodeType(NodeType::NODE_PACKAGE)); + ret.add(NodeType(NodeType::NODE_STRUCT)); + ret.add(NodeType(NodeType::NODE_CLASS)); + ret.add(NodeType(NodeType::NODE_INTERFACE)); + ret.add(NodeType(NodeType::NODE_GLOBAL_VARIABLE)); + ret.add(NodeType(NodeType::NODE_FIELD)); + ret.add(NodeType(NodeType::NODE_FUNCTION)); + ret.add(NodeType(NodeType::NODE_METHOD)); + ret.add(NodeType(NodeType::NODE_ENUM)); + ret.add(NodeType(NodeType::NODE_ENUM_CONSTANT)); + ret.add(NodeType(NodeType::NODE_TYPEDEF)); + ret.add(NodeType(NodeType::NODE_TEMPLATE_PARAMETER_TYPE)); + ret.add(NodeType(NodeType::NODE_TYPE_PARAMETER)); + ret.add(NodeType(NodeType::NODE_FILE)); + ret.add(NodeType(NodeType::NODE_MACRO)); + ret.add(NodeType(NodeType::NODE_UNION)); + + return ret; +} + +NodeTypeSet NodeTypeSet::none() +{ + return NodeTypeSet(); +} + +NodeTypeSet::NodeTypeSet() +{ + std::string i; +} + +NodeTypeSet::NodeTypeSet(const NodeType& type) +{ + m_nodeTypes.insert(type); +} + +bool NodeTypeSet::operator==(const NodeTypeSet& other) const +{ + return utility::isPermutation(getNodeTypeIds(), other.getNodeTypeIds()); // TODO: reimplement using mask +} + +bool NodeTypeSet::operator!=(const NodeTypeSet& other) const +{ + return !operator==(other); +} + +void NodeTypeSet::invert() +{ + NodeTypeSet inverse = NodeTypeSet::all().getWithRemoved(*this); + m_nodeTypes = std::move(inverse.m_nodeTypes); +} + +NodeTypeSet NodeTypeSet::getInverse() const +{ + NodeTypeSet ret(*this); + ret.invert(); + return ret; +} + +void NodeTypeSet::add(const NodeTypeSet& typeSet) +{ + utility::append(m_nodeTypes, typeSet.m_nodeTypes); +} + +std::set NodeTypeSet::getNodeTypes() const +{ + return m_nodeTypes; +} + +void NodeTypeSet::remove(const NodeTypeSet& typeSet) +{ + for (const NodeType& type : typeSet.getNodeTypes()) + { + std::set::const_iterator it = m_nodeTypes.find(type); + if (it != m_nodeTypes.end()) + { + m_nodeTypes.erase(it); + } + } +} + +NodeTypeSet NodeTypeSet::getWithRemoved(const NodeTypeSet& typeSet) const +{ + NodeTypeSet ret(*this); + ret.remove(typeSet); + return ret; +} + +bool NodeTypeSet::isEmpty() const +{ + return m_nodeTypes.empty(); +} + +bool NodeTypeSet::contains(const NodeType& type) const +{ + return m_nodeTypes.find(type) != m_nodeTypes.end(); +} + +bool NodeTypeSet::intersectsWith(const NodeTypeSet& typeSet) const +{ + for (const NodeType& type : typeSet.getNodeTypes()) + { + std::set::const_iterator it = m_nodeTypes.find(type); + if (it != m_nodeTypes.end()) + { + return true; + } + } + return false; +} + +std::vector NodeTypeSet::getNodeTypeIds() const +{ + std::vector ids; + + for (const NodeType type : m_nodeTypes) + { + ids.push_back(type.getId()); + } + + return ids; +} diff --git a/src/lib/data/NodeTypeSet.h b/src/lib/data/NodeTypeSet.h new file mode 100644 index 00000000..86c016aa --- /dev/null +++ b/src/lib/data/NodeTypeSet.h @@ -0,0 +1,40 @@ +#ifndef NODE_TYPE_SET_H +#define NODE_TYPE_SET_H + +#include +#include + +#include "data/NodeType.h" +#include "utility/types.h" + +class NodeTypeSet +{ +public: + static NodeTypeSet all(); + static NodeTypeSet none(); + + NodeTypeSet(); + NodeTypeSet(const NodeType& type); + + bool operator==(const NodeTypeSet& other) const; + bool operator!=(const NodeTypeSet& other) const; + + void invert(); + NodeTypeSet getInverse() const; + + void add(const NodeTypeSet& typeSet); + std::set getNodeTypes() const; + + void remove(const NodeTypeSet& typeSet); + NodeTypeSet getWithRemoved(const NodeTypeSet& typeSet) const; + + bool isEmpty() const; + bool contains(const NodeType& type) const; + bool intersectsWith(const NodeTypeSet& typeSet) const; + std::vector getNodeTypeIds() const; + +private: + std::set m_nodeTypes; +}; + +#endif // NODE_TYPE_SET_H diff --git a/src/lib/data/access/StorageAccess.h b/src/lib/data/access/StorageAccess.h index 711dbb3a..92d77446 100644 --- a/src/lib/data/access/StorageAccess.h +++ b/src/lib/data/access/StorageAccess.h @@ -13,12 +13,13 @@ #include "data/graph/Node.h" #include "data/search/SearchMatch.h" #include "data/storage/type/StorageEdge.h" -#include "data/ErrorCountInfo.h" -#include "data/ErrorFilter.h" -#include "data/ErrorInfo.h" #include "data/storage/StorageStats.h" #include "data/tooltip/TooltipInfo.h" #include "data/tooltip/TooltipOrigin.h" +#include "data/ErrorCountInfo.h" +#include "data/ErrorFilter.h" +#include "data/ErrorInfo.h" +#include "data/NodeTypeSet.h" class FilePath; class Graph; @@ -48,11 +49,11 @@ public: virtual std::shared_ptr getFullTextSearchLocations( const std::string& searchTerm, bool caseSensitive) const = 0; - virtual std::vector getAutocompletionMatches(const std::string& query, NodeType::TypeMask filter) const = 0; + virtual std::vector getAutocompletionMatches(const std::string& query, NodeTypeSet acceptedNodeTypes) const = 0; virtual std::vector getSearchMatchesForTokenIds(const std::vector& tokenIds) const = 0; virtual std::shared_ptr getGraphForAll() const = 0; - virtual std::shared_ptr getGraphForFilter(NodeType::TypeMask filter) const = 0; + virtual std::shared_ptr getGraphForNodeTypes(NodeTypeSet nodeTypes) const = 0; virtual std::shared_ptr getGraphForActiveTokenIds( const std::vector& tokenIds, const std::vector& expandedNodeIds, bool* isActiveNamespace = nullptr) const = 0; virtual std::shared_ptr getGraphForChildrenOfNodeId(Id nodeId) const = 0; diff --git a/src/lib/data/access/StorageAccessProxy.cpp b/src/lib/data/access/StorageAccessProxy.cpp index 55ec7a41..4d1abc52 100644 --- a/src/lib/data/access/StorageAccessProxy.cpp +++ b/src/lib/data/access/StorageAccessProxy.cpp @@ -125,11 +125,11 @@ std::shared_ptr StorageAccessProxy::getFullTextSearchL return std::make_shared(); } -std::vector StorageAccessProxy::getAutocompletionMatches(const std::string& query, NodeType::TypeMask filter) const +std::vector StorageAccessProxy::getAutocompletionMatches(const std::string& query, NodeTypeSet acceptedNodeTypes) const { if (hasSubject()) { - return m_subject->getAutocompletionMatches(query, filter); + return m_subject->getAutocompletionMatches(query, acceptedNodeTypes); } return std::vector(); @@ -155,11 +155,11 @@ std::shared_ptr StorageAccessProxy::getGraphForAll() const return std::make_shared(); } -std::shared_ptr StorageAccessProxy::getGraphForFilter(NodeType::TypeMask filter) const +std::shared_ptr StorageAccessProxy::getGraphForNodeTypes(NodeTypeSet nodeTypes) const { if (hasSubject()) { - return m_subject->getGraphForFilter(filter); + return m_subject->getGraphForNodeTypes(nodeTypes); } return std::make_shared(); diff --git a/src/lib/data/access/StorageAccessProxy.h b/src/lib/data/access/StorageAccessProxy.h index 6b88c7f7..51451e46 100644 --- a/src/lib/data/access/StorageAccessProxy.h +++ b/src/lib/data/access/StorageAccessProxy.h @@ -18,77 +18,79 @@ public: void setSubject(StorageAccess* subject); // StorageAccess implementation - virtual Id getNodeIdForFileNode(const FilePath& filePath) const; - virtual Id getNodeIdForNameHierarchy(const NameHierarchy& nameHierarchy) const; - virtual std::vector getNodeIdsForNameHierarchies(const std::vector nameHierarchies) const; + virtual Id getNodeIdForFileNode(const FilePath& filePath) const override; + virtual Id getNodeIdForNameHierarchy(const NameHierarchy& nameHierarchy) const override; + virtual std::vector getNodeIdsForNameHierarchies(const std::vector nameHierarchies) const override; - virtual NameHierarchy getNameHierarchyForNodeId(Id id) const; - virtual std::vector getNameHierarchiesForNodeIds(const std::vector& nodeIds) const; + virtual NameHierarchy getNameHierarchyForNodeId(Id id) const override; + virtual std::vector getNameHierarchiesForNodeIds(const std::vector& nodeIds) const override; - virtual NodeType getNodeTypeForNodeWithId(Id id) const; + virtual NodeType getNodeTypeForNodeWithId(Id id) const override; virtual Id getIdForEdge( - Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy) const; - virtual StorageEdge getEdgeById(Id edgeId) const; + Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy) const override; + virtual StorageEdge getEdgeById(Id edgeId) const override; virtual std::shared_ptr getFullTextSearchLocations( - const std::string& searchTerm, bool caseSensitive) const; - virtual std::vector getAutocompletionMatches(const std::string& query, NodeType::TypeMask filter) const; - virtual std::vector getSearchMatchesForTokenIds(const std::vector& tokenIds) const; + const std::string& searchTerm, bool caseSensitive) const override; + virtual std::vector getAutocompletionMatches(const std::string& query, NodeTypeSet acceptedNodeTypes) const override; + virtual std::vector getSearchMatchesForTokenIds(const std::vector& tokenIds) const override; - virtual std::shared_ptr getGraphForAll() const; - virtual std::shared_ptr getGraphForFilter(NodeType::TypeMask filter) const; + virtual std::shared_ptr getGraphForAll() const override; + virtual std::shared_ptr getGraphForNodeTypes(NodeTypeSet nodeTypes) const override; virtual std::shared_ptr getGraphForActiveTokenIds( - const std::vector& tokenIds, const std::vector& expandedNodeIds, bool* isActiveNamespace = nullptr) const; - virtual std::shared_ptr getGraphForChildrenOfNodeId(Id nodeId) const; - virtual std::shared_ptr getGraphForTrail(Id originId, Id targetId, Edge::TypeMask trailType, size_t depth) const; + const std::vector& tokenIds, const std::vector& expandedNodeIds, bool* isActiveNamespace = nullptr) const override; + virtual std::shared_ptr getGraphForChildrenOfNodeId(Id nodeId) const override; + virtual std::shared_ptr getGraphForTrail(Id originId, Id targetId, Edge::TypeMask trailType, size_t depth) const override; - virtual std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const; - virtual std::vector getNodeIdsForLocationIds(const std::vector& locationIds) const; + virtual std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const override; + virtual std::vector getNodeIdsForLocationIds(const std::vector& locationIds) const override; virtual std::shared_ptr getSourceLocationsForTokenIds( const std::vector& tokenIds - ) const; + ) const override; virtual std::shared_ptr getSourceLocationsForLocationIds( const std::vector& locationIds - ) const; - virtual std::shared_ptr getSourceLocationsForFile(const FilePath& filePath) const; + ) const override; + virtual std::shared_ptr getSourceLocationsForFile(const FilePath& filePath) const override; virtual std::shared_ptr getSourceLocationsForLinesInFile( const FilePath& filePath, uint firstLineNumber, uint lastLineNumber - ) const; + ) const override; - virtual std::shared_ptr getCommentLocationsInFile(const FilePath& filePath) const; + virtual std::shared_ptr getCommentLocationsInFile(const FilePath& filePath) const override; - virtual std::shared_ptr getFileContent(const FilePath& filePath) const; + virtual std::shared_ptr getFileContent(const FilePath& filePath) const override; - virtual FileInfo getFileInfoForFilePath(const FilePath& filePath) const; - virtual std::vector getFileInfosForFilePaths(const std::vector& filePaths) const; + virtual FileInfo getFileInfoForFilePath(const FilePath& filePath) const override; + virtual std::vector getFileInfosForFilePaths(const std::vector& filePaths) const override; - virtual StorageStats getStorageStats() const; + virtual StorageStats getStorageStats() const override; - virtual ErrorCountInfo getErrorCount() const; - virtual std::vector getErrorsLimited() const; - virtual std::shared_ptr getErrorSourceLocationsLimited(std::vector* errors) const; + virtual ErrorCountInfo getErrorCount() const override; + virtual std::vector getErrorsLimited() const override; + virtual std::shared_ptr getErrorSourceLocationsLimited(std::vector* errors) const override; - virtual Id addNodeBookmark(const NodeBookmark& bookmark); - virtual Id addEdgeBookmark(const EdgeBookmark& bookmark); - virtual Id addBookmarkCategory(const std::string& categoryName); + // TODO: remove these from access because it's not a getter! + virtual Id addNodeBookmark(const NodeBookmark& bookmark) override; + virtual Id addEdgeBookmark(const EdgeBookmark& bookmark) override; + virtual Id addBookmarkCategory(const std::string& categoryName) override; virtual void updateBookmark( - const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName); - virtual void removeBookmark(const Id id); - virtual void removeBookmarkCategory(const Id id); + const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName) override; + virtual void removeBookmark(const Id id) override; + virtual void removeBookmarkCategory(const Id id) override; + // END TODO - virtual std::vector getAllNodeBookmarks() const; - virtual std::vector getAllEdgeBookmarks() const; - virtual std::vector getAllBookmarkCategories() const; + virtual std::vector getAllNodeBookmarks() const override; + virtual std::vector getAllEdgeBookmarks() const override; + virtual std::vector getAllBookmarkCategories() const override; - virtual TooltipInfo getTooltipInfoForTokenIds(const std::vector& tokenIds, TooltipOrigin origin) const; + virtual TooltipInfo getTooltipInfoForTokenIds(const std::vector& tokenIds, TooltipOrigin origin) const override; virtual TooltipInfo getTooltipInfoForSourceLocationIdsAndLocalSymbolIds( - const std::vector& locationIds, const std::vector& localSymbolIds) const; + const std::vector& locationIds, const std::vector& localSymbolIds) const override; protected: - virtual void setErrorFilter(const ErrorFilter& filter); + virtual void setErrorFilter(const ErrorFilter& filter) override; private: void handleMessage(MessageErrorFilterChanged* message); diff --git a/src/lib/data/search/SearchIndex.cpp b/src/lib/data/search/SearchIndex.cpp index aa2e3a91..7dfee333 100644 --- a/src/lib/data/search/SearchIndex.cpp +++ b/src/lib/data/search/SearchIndex.cpp @@ -16,7 +16,7 @@ SearchIndex::~SearchIndex() { } -void SearchIndex::addNode(Id id, const std::string& name, NodeType::TypeMask type) +void SearchIndex::addNode(Id id, const std::string& name, NodeTypeSet typeSet) { SearchNode* currentNode = m_root; @@ -77,7 +77,7 @@ void SearchIndex::addNode(Id id, const std::string& name, NodeType::TypeMask typ } currentNode->elementIds.insert(id); - currentNode->mask |= type; + currentNode->containedTypes.add(typeSet); } void SearchIndex::finishSetup() @@ -100,17 +100,17 @@ void SearchIndex::clear() } std::vector SearchIndex::search( - const std::string& query, NodeType::TypeMask filter, size_t maxResultCount, size_t maxBestScoredResultsLength) const + const std::string& query, NodeTypeSet acceptedNodeTypes, size_t maxResultCount, size_t maxBestScoredResultsLength) const { // find paths containing query SearchPath startPath; startPath.node = m_root; std::vector paths; - searchRecursive(startPath, utility::toLowerCase(query), filter, &paths); + searchRecursive(startPath, utility::toLowerCase(query), acceptedNodeTypes, &paths); // create scored search results - std::multiset searchResults = createScoredResults(paths, filter, maxResultCount * 3); + std::multiset searchResults = createScoredResults(paths, acceptedNodeTypes, maxResultCount * 3); // find best scores std::map scoresCache; @@ -147,10 +147,10 @@ void SearchIndex::populateEdgeGate(SearchEdge* e) } void SearchIndex::searchRecursive( - const SearchPath& path, const std::string& remainingQuery, NodeType::TypeMask filter, + const SearchPath& path, const std::string& remainingQuery, NodeTypeSet acceptedNodeTypes, std::vector* results) const { - if (remainingQuery.size() == 0 && (!filter || (path.node->mask & filter))) + if (remainingQuery.size() == 0 && (acceptedNodeTypes.intersectsWith(path.node->containedTypes))) { results->push_back(std::move(path)); return; @@ -191,13 +191,13 @@ void SearchIndex::searchRecursive( } } - searchRecursive(currentPath, remainingQuery.substr(j), filter, results); + searchRecursive(currentPath, remainingQuery.substr(j), acceptedNodeTypes, results); } } } std::multiset SearchIndex::createScoredResults( - const std::vector& paths, NodeType::TypeMask filter, size_t maxResultCount) const + const std::vector& paths, NodeTypeSet acceptedNodeTypes, size_t maxResultCount) const { // score and order initial paths std::multimap> scoredPaths; @@ -213,13 +213,13 @@ std::multiset SearchIndex::createScoredResults( std::vector currentPaths; currentPaths.push_back(p.second); - while (currentPaths.size()) + while (!currentPaths.empty()) { std::vector nextPaths; for (const SearchPath& path : currentPaths) { - if (path.node->elementIds.size() && (!filter || (path.node->mask & filter))) + if (!path.node->elementIds.empty() && (acceptedNodeTypes.intersectsWith(path.node->containedTypes))) { SearchResult result; result.text = path.text; diff --git a/src/lib/data/search/SearchIndex.h b/src/lib/data/search/SearchIndex.h index f6951b7c..886c6c9d 100644 --- a/src/lib/data/search/SearchIndex.h +++ b/src/lib/data/search/SearchIndex.h @@ -10,6 +10,7 @@ #include "utility/types.h" #include "data/graph/Node.h" +#include "data/NodeTypeSet.h" struct SearchResult { @@ -30,13 +31,13 @@ public: SearchIndex(); virtual ~SearchIndex(); - void addNode(Id id, const std::string& name, NodeType::TypeMask type = 0); + void addNode(Id id, const std::string& name, NodeTypeSet typeSet = NodeTypeSet::all()); void finishSetup(); void clear(); // maxResultCount == 0 means "no restriction". std::vector search( - const std::string& query, NodeType::TypeMask filter, size_t maxResultCount, size_t maxBestScoredResultsLength = 0) const; + const std::string& query, NodeTypeSet acceptedNodeTypes, size_t maxResultCount, size_t maxBestScoredResultsLength = 0) const; private: struct SearchEdge; @@ -44,7 +45,7 @@ private: struct SearchNode { std::set elementIds; - NodeType::TypeMask mask = 0; + NodeTypeSet containedTypes; std::map edges; }; @@ -63,11 +64,11 @@ private: }; void populateEdgeGate(SearchEdge* e); - void searchRecursive(const SearchPath& path, const std::string& remainingQuery, NodeType::TypeMask filter, + void searchRecursive(const SearchPath& path, const std::string& remainingQuery, NodeTypeSet acceptedNodeTypes, std::vector* results) const; std::multiset createScoredResults( - const std::vector& paths, NodeType::TypeMask filter, size_t maxResultCount) const; + const std::vector& paths, NodeTypeSet acceptedNodeTypes, size_t maxResultCount) const; static SearchResult bestScoredResult( SearchResult result, std::map* scoresCache, size_t maxBestScoredResultsLength); diff --git a/src/lib/data/search/SearchMatch.cpp b/src/lib/data/search/SearchMatch.cpp index f99bcb59..d1d8eb87 100644 --- a/src/lib/data/search/SearchMatch.cpp +++ b/src/lib/data/search/SearchMatch.cpp @@ -56,22 +56,19 @@ SearchMatch SearchMatch::createCommand(CommandType type) return match; } -std::vector SearchMatch::createCommandsForFilter(NodeType::TypeMask filter) +std::vector SearchMatch::createCommandsForNodeTypes(NodeTypeSet types) { std::vector matches; - for (NodeType::TypeMask type = 1; type <= filter; type *= 2) + for (const NodeType& type: types.getNodeTypes()) { - if (type & filter) - { - SearchMatch match; - match.name = NodeType(utility::intToType(type)).getReadableTypeString(); - match.text = match.name; - match.typeName = "filter"; - match.searchType = SEARCH_COMMAND; - match.nodeType = NodeType(utility::intToType(type)); - matches.push_back(match); - } + SearchMatch match; + match.name = type.getReadableTypeString(); + match.text = match.name; + match.typeName = "filter"; + match.searchType = SEARCH_COMMAND; + match.nodeType = type; + matches.push_back(match); } return matches; diff --git a/src/lib/data/search/SearchMatch.h b/src/lib/data/search/SearchMatch.h index c61f4c8f..c42a6b60 100644 --- a/src/lib/data/search/SearchMatch.h +++ b/src/lib/data/search/SearchMatch.h @@ -7,6 +7,7 @@ #include #include "data/graph/Node.h" +#include "data/NodeTypeSet.h" #include "utility/types.h" struct SearchMatch @@ -33,7 +34,7 @@ struct SearchMatch static std::string searchMatchesToString(const std::vector& matches); static SearchMatch createCommand(CommandType type); - static std::vector createCommandsForFilter(NodeType::TypeMask filter); + static std::vector createCommandsForNodeTypes(NodeTypeSet types); static std::string getCommandName(CommandType type); static const char FULLTEXT_SEARCH_CHARACTER = '?'; diff --git a/src/lib/data/storage/PersistentStorage.cpp b/src/lib/data/storage/PersistentStorage.cpp index 3eb2a155..a7eb906e 100644 --- a/src/lib/data/storage/PersistentStorage.cpp +++ b/src/lib/data/storage/PersistentStorage.cpp @@ -548,7 +548,7 @@ std::shared_ptr PersistentStorage::getFullTextSearchLo return collection; } -std::vector PersistentStorage::getAutocompletionMatches(const std::string& query, NodeType::TypeMask filter) const +std::vector PersistentStorage::getAutocompletionMatches(const std::string& query, NodeTypeSet acceptedNodeTypes) const { TRACE(); @@ -559,17 +559,17 @@ std::vector PersistentStorage::getAutocompletionMatches(const std:: // create SearchMatches std::vector matches; - if (!filter || (filter & ~NodeType::NODE_FILE)) + if (!acceptedNodeTypes.getWithRemoved(NodeType(NodeType::NODE_FILE)).isEmpty()) { - utility::append(matches, getAutocompletionSymbolMatches(query, filter, maxResultsCount, maxBestScoredResultsLength)); + utility::append(matches, getAutocompletionSymbolMatches(query, acceptedNodeTypes, maxResultsCount, maxBestScoredResultsLength)); } - if (!filter || (filter & NodeType::NODE_FILE)) + if (acceptedNodeTypes.contains(NodeType(NodeType::NODE_FILE))) { utility::append(matches, getAutocompletionFileMatches(query, maxResultsCount)); } - utility::append(matches, getAutocompletionCommandMatches(query, filter)); + utility::append(matches, getAutocompletionCommandMatches(query, acceptedNodeTypes)); std::set matchesSet; for (SearchMatch& match : matches) @@ -596,11 +596,11 @@ std::vector PersistentStorage::getAutocompletionMatches(const std:: } std::vector PersistentStorage::getAutocompletionSymbolMatches( - const std::string& query, NodeType::TypeMask filter, size_t maxResultsCount, size_t maxBestScoredResultsLength) const + const std::string& query, const NodeTypeSet& acceptedNodeTypes, size_t maxResultsCount, size_t maxBestScoredResultsLength) const { // search in indices std::vector results = - m_symbolIndex.search(query, filter, maxResultsCount, maxBestScoredResultsLength); + m_symbolIndex.search(query, acceptedNodeTypes, maxResultsCount, maxBestScoredResultsLength); // fetch StorageNodes for node ids std::map storageNodeMap; @@ -637,7 +637,7 @@ std::vector PersistentStorage::getAutocompletionSymbolMatches( { match.tokenIds.push_back(elementId); - if (!match.hasChildren && !filter) // TODO: apply filter to children + if (!match.hasChildren && acceptedNodeTypes == NodeTypeSet::all()) // TODO: check if node types of children match { match.hasChildren = m_hierarchyCache.nodeHasChildren(elementId); } @@ -681,7 +681,7 @@ std::vector PersistentStorage::getAutocompletionSymbolMatches( std::vector PersistentStorage::getAutocompletionFileMatches(const std::string& query, size_t maxResultsCount) const { - std::vector results = m_fileIndex.search(query, NodeType::NODE_FILE, maxResultsCount, 100); + std::vector results = m_fileIndex.search(query, NodeTypeSet(NodeType::NODE_FILE), maxResultsCount, 100); // create SearchMatches std::vector matches; @@ -713,10 +713,10 @@ std::vector PersistentStorage::getAutocompletionFileMatches(const s } std::vector PersistentStorage::getAutocompletionCommandMatches( - const std::string& query, NodeType::TypeMask filter) const + const std::string& query, NodeTypeSet acceptedNodeTypes) const { // search in indices - std::vector results = m_commandIndex.search(query, 0, 0); + std::vector results = m_commandIndex.search(query, NodeTypeSet::all(), 0); // create SearchMatches std::vector matches; @@ -741,7 +741,7 @@ std::vector PersistentStorage::getAutocompletionCommandMatches( match.typeName = "filter"; } - if (!filter || (match.getCommandType() == SearchMatch::COMMAND_NODE_FILTER && !(filter & match.nodeType.getType()))) + if (acceptedNodeTypes == NodeTypeSet::all() || match.getCommandType() == SearchMatch::COMMAND_NODE_FILTER && (acceptedNodeTypes.contains(match.nodeType))) { matches.push_back(match); } @@ -823,7 +823,7 @@ std::shared_ptr PersistentStorage::getGraphForAll() const return graph; } -std::shared_ptr PersistentStorage::getGraphForFilter(NodeType::TypeMask filter) const +std::shared_ptr PersistentStorage::getGraphForNodeTypes(NodeTypeSet nodeTypes) const { TRACE(); @@ -832,7 +832,7 @@ std::shared_ptr PersistentStorage::getGraphForFilter(NodeType::TypeMask f std::vector tokenIds; for (StorageNode& node: m_sqliteIndexStorage.getAll()) { - if ((filter & utility::intToType(node.type))) + if (nodeTypes.contains(utility::intToType(node.type))) { auto it = m_symbolDefinitionKinds.find(node.id); if (it != m_symbolDefinitionKinds.end() && it->second == DEFINITION_EXPLICIT) @@ -842,7 +842,7 @@ std::shared_ptr PersistentStorage::getGraphForFilter(NodeType::TypeMask f } } - if (!filter || (filter & NodeType::NODE_FILE)) + if (nodeTypes.contains(NodeType(NodeType::NODE_FILE))) { for (const auto& p : m_fileNodePaths) { @@ -2522,7 +2522,7 @@ void PersistentStorage::buildSearchIndex() for (StorageNode& node : m_sqliteIndexStorage.getAll()) { - NodeType::Type type = utility::intToType(node.type); + NodeType type = utility::intToType(node.type); if (type == NodeType::NODE_FILE) { auto it = m_fileNodePaths.find(node.id); @@ -2535,7 +2535,7 @@ void PersistentStorage::buildSearchIndex() filePath = filePath.relativeTo(dbPath); } - m_fileIndex.addNode(node.id, filePath.str(), node.type); + m_fileIndex.addNode(node.id, filePath.str(), type); } } else @@ -2556,7 +2556,7 @@ void PersistentStorage::buildSearchIndex() name = utility::replaceBetween(name, '<', '>', ".."); } - m_symbolIndex.addNode(node.id, name, node.type); + m_symbolIndex.addNode(node.id, name, type); } } } diff --git a/src/lib/data/storage/PersistentStorage.h b/src/lib/data/storage/PersistentStorage.h index 1596130b..2069eed8 100644 --- a/src/lib/data/storage/PersistentStorage.h +++ b/src/lib/data/storage/PersistentStorage.h @@ -86,15 +86,15 @@ public: virtual std::shared_ptr getFullTextSearchLocations( const std::string& searchTerm, bool caseSensitive) const override; - virtual std::vector getAutocompletionMatches(const std::string& query, NodeType::TypeMask filter) const override; + virtual std::vector getAutocompletionMatches(const std::string& query, NodeTypeSet acceptedNodeTypes) const override; std::vector getAutocompletionSymbolMatches( - const std::string& query, NodeType::TypeMask filter, size_t maxResultsCount, size_t maxBestScoredResultsLength) const; + const std::string& query, const NodeTypeSet& acceptedNodeTypes, size_t maxResultsCount, size_t maxBestScoredResultsLength) const; std::vector getAutocompletionFileMatches(const std::string& query, size_t maxResultsCount) const; - std::vector getAutocompletionCommandMatches(const std::string& query, NodeType::TypeMask filter) const; + std::vector getAutocompletionCommandMatches(const std::string& query, NodeTypeSet acceptedNodeTypes) const; virtual std::vector getSearchMatchesForTokenIds(const std::vector& elementIds) const override; virtual std::shared_ptr getGraphForAll() const override; - virtual std::shared_ptr getGraphForFilter(NodeType::TypeMask filter) const override; + virtual std::shared_ptr getGraphForNodeTypes(NodeTypeSet nodeTypes) const override; virtual std::shared_ptr getGraphForActiveTokenIds( const std::vector& tokenIds, const std::vector& expandedNodeIds, bool* isActiveNamespace = nullptr) const override; virtual std::shared_ptr getGraphForChildrenOfNodeId(Id nodeId) const override; diff --git a/src/lib/utility/messaging/type/MessageActivateAll.h b/src/lib/utility/messaging/type/MessageActivateAll.h index b0d56030..d5a0d9df 100644 --- a/src/lib/utility/messaging/type/MessageActivateAll.h +++ b/src/lib/utility/messaging/type/MessageActivateAll.h @@ -2,14 +2,15 @@ #define MESSAGE_ACTIVATE_ALL_H #include "data/graph/Node.h" +#include "data/NodeTypeSet.h" #include "utility/messaging/Message.h" class MessageActivateAll : public Message { public: - MessageActivateAll(NodeType::TypeMask filter = 0) - : filter(filter) + MessageActivateAll(NodeTypeSet acceptedNodeTypes = NodeTypeSet::all()) + : acceptedNodeTypes(acceptedNodeTypes) { setIsParallel(true); } @@ -19,7 +20,7 @@ public: return "MessageActivateAll"; } - NodeType::TypeMask filter; + NodeTypeSet acceptedNodeTypes; }; #endif // MESSAGE_ACTIVATE_ALL_H diff --git a/src/lib/utility/messaging/type/MessageSearch.h b/src/lib/utility/messaging/type/MessageSearch.h index 9fa9c074..a69b149c 100644 --- a/src/lib/utility/messaging/type/MessageSearch.h +++ b/src/lib/utility/messaging/type/MessageSearch.h @@ -9,9 +9,9 @@ class MessageSearch : public Message { public: - MessageSearch(const std::vector& matches, NodeType::TypeMask filter = 0) + MessageSearch(const std::vector& matches, NodeTypeSet acceptedNodeTypes = NodeTypeSet::all()) : isFromSearch(true) - , filter(filter) + , acceptedNodeTypes(acceptedNodeTypes) , m_matches(matches) { } @@ -72,7 +72,7 @@ public: } bool isFromSearch; - NodeType::TypeMask filter; + NodeTypeSet acceptedNodeTypes; private: const std::vector m_matches; diff --git a/src/lib/utility/messaging/type/MessageSearchAutocomplete.h b/src/lib/utility/messaging/type/MessageSearchAutocomplete.h index ce102d76..8c90635a 100644 --- a/src/lib/utility/messaging/type/MessageSearchAutocomplete.h +++ b/src/lib/utility/messaging/type/MessageSearchAutocomplete.h @@ -2,15 +2,16 @@ #define MESSAGE_SEARCH_AUTOCOMPLETE_H #include "data/graph/Node.h" +#include "data/NodeTypeSet.h" #include "utility/messaging/Message.h" class MessageSearchAutocomplete : public Message { public: - MessageSearchAutocomplete(const std::string& query, NodeType::TypeMask filter) + MessageSearchAutocomplete(const std::string& query, NodeTypeSet acceptedNodeTypes) : query(query) - , filter(filter) + , acceptedNodeTypes(acceptedNodeTypes) { } @@ -21,11 +22,21 @@ public: virtual void print(std::ostream& os) const { - os << query << " " << filter; + os << query << "["; + std::vector nodeTypeIds = acceptedNodeTypes.getNodeTypeIds(); + for (size_t i = 0; i < nodeTypeIds.size(); i++) + { + if (i != 0) + { + os << ", "; + } + os << std::to_string(nodeTypeIds[i]); + } + os << "]"; } const std::string query; - const NodeType::TypeMask filter; + const NodeTypeSet acceptedNodeTypes; }; #endif // MESSAGE_SEARCH_AUTOCOMPLETE_H diff --git a/src/lib_gui/qt/element/QtSmartSearchBox.cpp b/src/lib_gui/qt/element/QtSmartSearchBox.cpp index f150d153..082bea50 100644 --- a/src/lib_gui/qt/element/QtSmartSearchBox.cpp +++ b/src/lib_gui/qt/element/QtSmartSearchBox.cpp @@ -68,7 +68,7 @@ void QtSmartSearchBox::search() std::vector matches = utility::toVector(m_matches); - MessageSearch(matches, getMatchFilter()).dispatch(); + MessageSearch(matches, getMatchAcceptedNodeTypes()).dispatch(); } void QtSmartSearchBox::fullTextSearch() @@ -1033,7 +1033,7 @@ void QtSmartSearchBox::requestAutoCompletions() { if (text().size() && !text().startsWith(SearchMatch::FULLTEXT_SEARCH_CHARACTER)) { - MessageSearchAutocomplete(text().toStdString(), getMatchFilter()).dispatch(); + MessageSearchAutocomplete(text().toStdString(), getMatchAcceptedNodeTypes()).dispatch(); } else { @@ -1056,15 +1056,15 @@ std::deque QtSmartSearchBox::getMatchesForInput(const std::string& return matches; } -NodeType::TypeMask QtSmartSearchBox::getMatchFilter() const +NodeTypeSet QtSmartSearchBox::getMatchAcceptedNodeTypes() const { - NodeType::TypeMask filter = 0; + NodeTypeSet types; for (const SearchMatch& match : m_matches) { if (match.isFilterCommand()) { - filter |= match.nodeType.getType(); + types.add(match.nodeType); } else { @@ -1072,7 +1072,12 @@ NodeType::TypeMask QtSmartSearchBox::getMatchFilter() const } } - return filter; + if (types.isEmpty()) + { + types.invert(); + } + + return types; } bool QtSmartSearchBox::lastMatchIsNoFilter() const diff --git a/src/lib_gui/qt/element/QtSmartSearchBox.h b/src/lib_gui/qt/element/QtSmartSearchBox.h index e0b10fa0..2e4b7c91 100644 --- a/src/lib_gui/qt/element/QtSmartSearchBox.h +++ b/src/lib_gui/qt/element/QtSmartSearchBox.h @@ -8,6 +8,7 @@ #include #include "data/search/SearchMatch.h" +#include "data/NodeTypeSet.h" #include "qt/element/QtAutocompletionList.h" class QtSearchElement @@ -99,7 +100,7 @@ private: std::deque getMatchesForInput(const std::string& text) const; - NodeType::TypeMask getMatchFilter() const; + NodeTypeSet getMatchAcceptedNodeTypes() const; bool lastMatchIsNoFilter() const; bool m_allowTextChange; diff --git a/src/test/SearchIndexTestSuite.h b/src/test/SearchIndexTestSuite.h index fe1d048c..ed26c74b 100644 --- a/src/test/SearchIndexTestSuite.h +++ b/src/test/SearchIndexTestSuite.h @@ -12,7 +12,7 @@ public: SearchIndex index; index.addNode(1, NameHierarchy::deserialize("::\tmfoo\tsvoid\tp() const").getQualifiedName()); index.finishSetup(); - std::vector results = index.search("oo", 0, 0); + std::vector results = index.search("oo", NodeTypeSet::all(), 0); TS_ASSERT_EQUALS(1, results.size()); TS_ASSERT_EQUALS(1, results[0].elementIds.size()); @@ -24,7 +24,7 @@ public: SearchIndex index; index.addNode(1, NameHierarchy::deserialize("::\tmfoo\tsvoid\tp() const").getQualifiedName()); index.finishSetup(); - std::vector results = index.search("oo", 0, 0); + std::vector results = index.search("oo", NodeTypeSet::all(), 0); TS_ASSERT_EQUALS(1, results.size()); TS_ASSERT_EQUALS(2, results[0].indices.size()); @@ -38,7 +38,7 @@ public: index.addNode(1, NameHierarchy::deserialize("::\tmfor\tsvoid\tp() const").getQualifiedName()); index.addNode(2, NameHierarchy::deserialize("::\tmfos\tsvoid\tp() const").getQualifiedName()); index.finishSetup(); - std::vector results = index.search("fo", 0, 0); + std::vector results = index.search("fo", NodeTypeSet::all(), 0); TS_ASSERT_EQUALS(2, results.size()); TS_ASSERT_EQUALS(1, results[0].elementIds.size()); @@ -53,7 +53,7 @@ public: index.addNode(1, NameHierarchy::deserialize("::\tmfoo\tsvoid\tp() const").getQualifiedName()); index.finishSetup(); index.clear(); - std::vector results = index.search("oo", 0, 0); + std::vector results = index.search("oo", NodeTypeSet::all(), 0); TS_ASSERT_EQUALS(0, results.size()); } @@ -64,7 +64,7 @@ public: index.addNode(1, NameHierarchy::deserialize("::\tmfoo1\tsvoid\tp() const").getQualifiedName()); index.addNode(2, NameHierarchy::deserialize("::\tmfoo2\tsvoid\tp() const").getQualifiedName()); index.finishSetup(); - std::vector results = index.search("oo", 0, 1); + std::vector results = index.search("oo", NodeTypeSet::all(), 1); TS_ASSERT_EQUALS(1, results.size()); } @@ -75,7 +75,7 @@ public: index.addNode(1, NameHierarchy::deserialize("::\tmfoo1\tsvoid\tp() const").getQualifiedName()); index.addNode(2, NameHierarchy::deserialize("::\tmFOO2\tsvoid\tp() const").getQualifiedName()); index.finishSetup(); - std::vector results = index.search("oo", 0, 0); + std::vector results = index.search("oo", NodeTypeSet::all(), 0); TS_ASSERT_EQUALS(2, results.size()); } @@ -87,7 +87,7 @@ public: index.addNode(1, NameHierarchy::deserialize("::\tmoaabbcc\tsvoid\tp() const").getQualifiedName()); index.addNode(2, NameHierarchy::deserialize("::\tmocbcabc\tsvoid\tp() const").getQualifiedName()); index.finishSetup(); - std::vector results = index.search("abc", 0, 0); + std::vector results = index.search("abc", NodeTypeSet::all(), 0); TS_ASSERT_EQUALS(2, results.size()); TS_ASSERT_EQUALS("ocbcabc", results[0].text);