File indexing completed on 2024-05-12 04:37:44

0001 /*
0002     SPDX-FileCopyrightText: 2009 Lior Mualem <lior.m.kde@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KDEVPLATFORM_DOCUMENTCLASSESFOLDER_H
0008 #define KDEVPLATFORM_DOCUMENTCLASSESFOLDER_H
0009 
0010 #include "classmodelnode.h"
0011 #include <boost/multi_index_container.hpp>
0012 #include <boost/multi_index/member.hpp>
0013 #include <boost/multi_index/ordered_index.hpp>
0014 
0015 namespace ClassModelNodes {
0016 class StaticNamespaceFolderNode;
0017 
0018 /// This folder displays all the classes that relate to a list of documents.
0019 class DocumentClassesFolder
0020     : public QObject
0021     , public DynamicFolderNode
0022 {
0023     Q_OBJECT
0024 
0025 public:
0026     DocumentClassesFolder(const QString& a_displayName, NodesModelInterface* a_model);
0027 
0028 public: // Operations
0029     /// Find a class node in the lists by its id.
0030     ClassNode* findClassNode(const KDevelop::IndexedQualifiedIdentifier& a_id);
0031 
0032 protected: // Documents list handling.
0033     /// Parse a single document for classes and add them to the list.
0034     void parseDocument(const KDevelop::IndexedString& a_file);
0035 
0036     /// Re-parse the given document - remove old declarations and add new declarations.
0037     bool updateDocument(const KDevelop::IndexedString& a_file);
0038 
0039     /// Close and remove all the nodes related to the specified document.
0040     void closeDocument(const KDevelop::IndexedString& a_file);
0041 
0042     /// Returns a list of documents we have monitored.
0043     QSet<KDevelop::IndexedString> allOpenDocuments() const;
0044 
0045 protected: // Overridables
0046     /// Override this to filter the found classes.
0047     virtual bool isClassFiltered(const KDevelop::QualifiedIdentifier&) { return false; }
0048 
0049 public: // Node overrides
0050     void nodeCleared() override;
0051     void populateNode() override;
0052     bool hasChildren() const override { return true; }
0053 
0054 private Q_SLOTS:
0055     // Files update.
0056     void updateChangedFiles();
0057 
0058 private: // File updates related.
0059     /// List of updated files we check this list when update timer expires.
0060     QSet<KDevelop::IndexedString> m_updatedFiles;
0061 
0062     /// Timer for batch updates.
0063     QTimer* m_updateTimer;
0064 
0065 private: // Opened class identifiers container definition.
0066     // An opened class item.
0067     struct OpenedFileClassItem
0068     {
0069         OpenedFileClassItem();
0070         OpenedFileClassItem(const KDevelop::IndexedString& a_file,
0071                             const KDevelop::IndexedQualifiedIdentifier& a_classIdentifier,
0072                             ClassNode* a_nodeItem);
0073 
0074         /// The file this class declaration comes from.
0075         KDevelop::IndexedString file;
0076 
0077         /// The identifier for this class.
0078         KDevelop::IndexedQualifiedIdentifier classIdentifier;
0079 
0080         /// An existing node item. It maybe 0 - meaning the class node is currently hidden.
0081         ClassNode* nodeItem;
0082     };
0083 
0084     // Index definitions.
0085     struct FileIndex {};
0086     struct ClassIdentifierIndex {};
0087 
0088     // Member types definitions.
0089     using FileMember = boost::multi_index::member<
0090         OpenedFileClassItem,
0091         KDevelop::IndexedString,
0092         & OpenedFileClassItem::file>;
0093     using ClassIdentifierMember = boost::multi_index::member<
0094         OpenedFileClassItem,
0095         KDevelop::IndexedQualifiedIdentifier,
0096         & OpenedFileClassItem::classIdentifier>;
0097 
0098     // Container definition.
0099     using OpenFilesContainer = boost::multi_index::multi_index_container<
0100         OpenedFileClassItem,
0101         boost::multi_index::indexed_by<
0102             boost::multi_index::ordered_non_unique<
0103                 boost::multi_index::tag<FileIndex>,
0104                 FileMember
0105             >,
0106             boost::multi_index::ordered_unique<
0107                 boost::multi_index::tag<ClassIdentifierIndex>,
0108                 ClassIdentifierMember
0109             >
0110         >
0111     >;
0112 
0113     // Iterators definition.
0114     using FileIterator = OpenFilesContainer::index_iterator<FileIndex>::type;
0115     using ClassIdentifierIterator = OpenFilesContainer::index_iterator<ClassIdentifierIndex>::type;
0116 
0117     /// Maps all displayed classes and their referenced files.
0118     OpenFilesContainer m_openFilesClasses;
0119 
0120     /// Holds a set of open files.
0121     QSet<KDevelop::IndexedString> m_openFiles;
0122 
0123 private:
0124     using NamespacesMap = QMap<KDevelop::IndexedQualifiedIdentifier, StaticNamespaceFolderNode*>;
0125     /// Holds a map between an identifier and a namespace folder we hold.
0126     NamespacesMap m_namespaces;
0127 
0128     /// Recursively create a namespace folder for the specified identifier if it doesn't
0129     /// exist, cache it and return it (or just return it from the cache).
0130     StaticNamespaceFolderNode* namespaceFolder(const KDevelop::QualifiedIdentifier& a_identifier);
0131 
0132     /// Removes the given namespace identifier recursively if it's empty.
0133     void removeEmptyNamespace(const KDevelop::QualifiedIdentifier& a_identifier);
0134 
0135     /// Remove a single class node from the lists.
0136     void removeClassNode(ClassNode* a_node);
0137 };
0138 } // namespace ClassModelNodes
0139 
0140 #endif // KDEVPLATFORM_DOCUMENTCLASSESFOLDER_H