1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2019 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the tools applications of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 ** included in the packaging of this file. Please review the following 22 ** information to ensure the GNU General Public License requirements will 23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 ** 25 ** $QT_END_LICENSE$ 26 ** 27 ****************************************************************************/ 28 29 #ifndef QDOCDATABASE_H 30 #define QDOCDATABASE_H 31 32 #include "config.h" 33 #include "text.h" 34 #include "tree.h" 35 36 #include <QtCore/qdebug.h> 37 #include <QtCore/qmap.h> 38 #include <QtCore/qstring.h> 39 40 QT_BEGIN_NAMESPACE 41 42 typedef QMultiMap<Text, const Node *> TextToNodeMap; 43 44 class Atom; 45 class Generator; 46 class QDocDatabase; 47 48 enum FindFlag { 49 SearchBaseClasses = 0x1, 50 SearchEnumValues = 0x2, 51 TypesOnly = 0x4, 52 IgnoreModules = 0x8 53 }; 54 55 class QDocForest 56 { 57 private: 58 friend class QDocDatabase; QDocForest(QDocDatabase * qdb)59 QDocForest(QDocDatabase *qdb) : qdb_(qdb), primaryTree_(nullptr), currentIndex_(0) {} 60 ~QDocForest(); 61 62 NamespaceNode *firstRoot(); 63 NamespaceNode *nextRoot(); 64 Tree *firstTree(); 65 Tree *nextTree(); primaryTree()66 Tree *primaryTree() { return primaryTree_; } findTree(const QString & t)67 Tree *findTree(const QString &t) { return forest_.value(t); } keys()68 QStringList keys() { return forest_.keys(); } primaryTreeRoot()69 NamespaceNode *primaryTreeRoot() { return (primaryTree_ ? primaryTree_->root() : nullptr); } isEmpty()70 bool isEmpty() { return searchOrder().isEmpty(); } done()71 bool done() { return (currentIndex_ >= searchOrder().size()); } 72 const QVector<Tree *> &searchOrder(); 73 const QVector<Tree *> &indexSearchOrder(); 74 void setSearchOrder(const QStringList &t); isLoaded(const QString & fn)75 bool isLoaded(const QString &fn) 76 { 77 for (const auto *tree : searchOrder()) { 78 if (fn == tree->indexFileName()) 79 return true; 80 } 81 return false; 82 } 83 findNode(const QStringList & path,const Node * relative,int findFlags,Node::Genus genus)84 const Node *findNode(const QStringList &path, const Node *relative, int findFlags, 85 Node::Genus genus) 86 { 87 for (const auto *tree : searchOrder()) { 88 const Node *n = tree->findNode(path, relative, findFlags, genus); 89 if (n) 90 return n; 91 relative = nullptr; 92 } 93 return nullptr; 94 } 95 findNodeByNameAndType(const QStringList & path,bool (Node::* isMatch)()const)96 Node *findNodeByNameAndType(const QStringList &path, bool (Node::*isMatch)() const) 97 { 98 for (const auto *tree : searchOrder()) { 99 Node *n = tree->findNodeByNameAndType(path, isMatch); 100 if (n) 101 return n; 102 } 103 return nullptr; 104 } 105 findClassNode(const QStringList & path)106 ClassNode *findClassNode(const QStringList &path) 107 { 108 for (const auto *tree : searchOrder()) { 109 ClassNode *n = tree->findClassNode(path); 110 if (n) 111 return n; 112 } 113 return nullptr; 114 } 115 findNodeForInclude(const QStringList & path)116 Node *findNodeForInclude(const QStringList &path) 117 { 118 for (const auto *tree : searchOrder()) { 119 Node *n = tree->findNodeForInclude(path); 120 if (n) 121 return n; 122 } 123 return nullptr; 124 } 125 126 const FunctionNode *findFunctionNode(const QStringList &path, const Parameters ¶meters, 127 const Node *relative, Node::Genus genus); 128 const Node *findNodeForTarget(QStringList &targetPath, const Node *relative, Node::Genus genus, 129 QString &ref); 130 findTypeNode(const QStringList & path,const Node * relative,Node::Genus genus)131 const Node *findTypeNode(const QStringList &path, const Node *relative, Node::Genus genus) 132 { 133 int flags = SearchBaseClasses | SearchEnumValues | TypesOnly; 134 if (relative && genus == Node::DontCare && relative->genus() != Node::DOC) 135 genus = relative->genus(); 136 for (const auto *tree : searchOrder()) { 137 const Node *n = tree->findNode(path, relative, flags, genus); 138 if (n) 139 return n; 140 relative = nullptr; 141 } 142 return nullptr; 143 } 144 findPageNodeByTitle(const QString & title)145 const PageNode *findPageNodeByTitle(const QString &title) 146 { 147 for (const auto *tree : searchOrder()) { 148 const PageNode *n = tree->findPageNodeByTitle(title); 149 if (n) 150 return n; 151 } 152 return nullptr; 153 } 154 getCollectionNode(const QString & name,Node::NodeType type)155 const CollectionNode *getCollectionNode(const QString &name, Node::NodeType type) 156 { 157 for (auto *tree : searchOrder()) { 158 const CollectionNode *cn = tree->getCollection(name, type); 159 if (cn) 160 return cn; 161 } 162 return nullptr; 163 } 164 lookupQmlType(const QString & name)165 QmlTypeNode *lookupQmlType(const QString &name) 166 { 167 for (const auto *tree : searchOrder()) { 168 QmlTypeNode *qcn = tree->lookupQmlType(name); 169 if (qcn) 170 return qcn; 171 } 172 return nullptr; 173 } 174 lookupQmlBasicType(const QString & name)175 Aggregate *lookupQmlBasicType(const QString &name) 176 { 177 for (const auto *tree : searchOrder()) { 178 Aggregate *a = tree->lookupQmlBasicType(name); 179 if (a) 180 return a; 181 } 182 return nullptr; 183 } clearSearchOrder()184 void clearSearchOrder() { searchOrder_.clear(); } clearLinkCounts()185 void clearLinkCounts() 186 { 187 for (auto *tree : searchOrder()) 188 tree->clearLinkCount(); 189 } 190 void printLinkCounts(const QString &project); 191 QString getLinkCounts(QStringList &strings, QVector<int> &counts); 192 void newPrimaryTree(const QString &module); 193 void setPrimaryTree(const QString &t); 194 NamespaceNode *newIndexTree(const QString &module); 195 196 private: 197 QDocDatabase *qdb_; 198 Tree *primaryTree_; 199 int currentIndex_; 200 QMap<QString, Tree *> forest_; 201 QVector<Tree *> searchOrder_; 202 QVector<Tree *> indexSearchOrder_; 203 QVector<QString> moduleNames_; 204 }; 205 206 class QDocDatabase 207 { 208 Q_DECLARE_TR_FUNCTIONS(QDoc::QDocDatabase) 209 210 public: 211 static QDocDatabase *qdocDB(); 212 static void destroyQdocDB(); 213 ~QDocDatabase(); 214 findTree(const QString & t)215 Tree *findTree(const QString &t) { return forest_.findTree(t); } 216 groups()217 const CNMap &groups() { return primaryTree()->groups(); } modules()218 const CNMap &modules() { return primaryTree()->modules(); } qmlModules()219 const CNMap &qmlModules() { return primaryTree()->qmlModules(); } jsModules()220 const CNMap &jsModules() { return primaryTree()->jsModules(); } 221 addGroup(const QString & name)222 CollectionNode *addGroup(const QString &name) { return primaryTree()->addGroup(name); } addModule(const QString & name)223 CollectionNode *addModule(const QString &name) { return primaryTree()->addModule(name); } addQmlModule(const QString & name)224 CollectionNode *addQmlModule(const QString &name) { return primaryTree()->addQmlModule(name); } addJsModule(const QString & name)225 CollectionNode *addJsModule(const QString &name) { return primaryTree()->addJsModule(name); } 226 addToGroup(const QString & name,Node * node)227 CollectionNode *addToGroup(const QString &name, Node *node) 228 { 229 return primaryTree()->addToGroup(name, node); 230 } addToModule(const QString & name,Node * node)231 CollectionNode *addToModule(const QString &name, Node *node) 232 { 233 return primaryTree()->addToModule(name, node); 234 } addToQmlModule(const QString & name,Node * node)235 CollectionNode *addToQmlModule(const QString &name, Node *node) 236 { 237 return primaryTree()->addToQmlModule(name, node); 238 } addToJsModule(const QString & name,Node * node)239 CollectionNode *addToJsModule(const QString &name, Node *node) 240 { 241 return primaryTree()->addToJsModule(name, node); 242 } 243 addExampleNode(ExampleNode * n)244 void addExampleNode(ExampleNode *n) { primaryTree()->addExampleNode(n); } exampleNodeMap()245 ExampleNodeMap &exampleNodeMap() { return primaryTree()->exampleNodeMap(); } 246 247 QmlTypeNode *findQmlType(const QString &name); 248 QmlTypeNode *findQmlType(const QString &qmid, const QString &name); 249 QmlTypeNode *findQmlType(const ImportRec &import, const QString &name); 250 Aggregate *findQmlBasicType(const QString &qmid, const QString &name); 251 obsoleteClasses()252 static NodeMultiMap &obsoleteClasses() { return obsoleteClasses_; } obsoleteQmlTypes()253 static NodeMultiMap &obsoleteQmlTypes() { return obsoleteQmlTypes_; } classesWithObsoleteMembers()254 static NodeMultiMap &classesWithObsoleteMembers() { return classesWithObsoleteMembers_; } qmlTypesWithObsoleteMembers()255 static NodeMultiMap &qmlTypesWithObsoleteMembers() { return qmlTypesWithObsoleteMembers_; } cppClasses()256 static NodeMultiMap &cppClasses() { return cppClasses_; } qmlBasicTypes()257 static NodeMultiMap &qmlBasicTypes() { return qmlBasicTypes_; } qmlTypes()258 static NodeMultiMap &qmlTypes() { return qmlTypes_; } examples()259 static NodeMultiMap &examples() { return examples_; } newClassMaps()260 static NodeMapMap &newClassMaps() { return newClassMaps_; } newQmlTypeMaps()261 static NodeMapMap &newQmlTypeMaps() { return newQmlTypeMaps_; } newSinceMaps()262 static NodeMultiMapMap &newSinceMaps() { return newSinceMaps_; } 263 264 private: findAllClasses(Aggregate * node)265 void findAllClasses(Aggregate *node) { node->findAllClasses(); } findAllFunctions(Aggregate * node)266 void findAllFunctions(Aggregate *node) { node->findAllFunctions(functionIndex_); } findAllAttributions(Aggregate * node)267 void findAllAttributions(Aggregate *node) { node->findAllAttributions(attributions_); } 268 void findAllLegaleseTexts(Aggregate *node); findAllObsoleteThings(Aggregate * node)269 void findAllObsoleteThings(Aggregate *node) { node->findAllObsoleteThings(); } findAllSince(Aggregate * node)270 void findAllSince(Aggregate *node) { node->findAllSince(); } 271 272 public: 273 /******************************************************************* 274 special collection access functions 275 ********************************************************************/ 276 NodeMultiMap &getCppClasses(); 277 NodeMultiMap &getObsoleteClasses(); 278 NodeMultiMap &getClassesWithObsoleteMembers(); 279 NodeMultiMap &getObsoleteQmlTypes(); 280 NodeMultiMap &getQmlTypesWithObsoleteMembers(); 281 NodeMultiMap &getNamespaces(); 282 NodeMultiMap &getQmlBasicTypes(); 283 NodeMultiMap &getQmlTypes(); 284 NodeMultiMap &getExamples(); 285 NodeMultiMap &getAttributions(); 286 NodeMapMap &getFunctionIndex(); 287 TextToNodeMap &getLegaleseTexts(); 288 const NodeMap &getClassMap(const QString &key); 289 const NodeMap &getQmlTypeMap(const QString &key); 290 const NodeMap &getSinceMap(const QString &key); 291 292 /******************************************************************* 293 Many of these will be either eliminated or replaced. 294 ********************************************************************/ 295 void resolveStuff(); insertTarget(const QString & name,const QString & title,TargetRec::TargetType type,Node * node,int priority)296 void insertTarget(const QString &name, const QString &title, TargetRec::TargetType type, 297 Node *node, int priority) 298 { 299 primaryTree()->insertTarget(name, title, type, node, priority); 300 } 301 302 /******************************************************************* 303 The functions declared below are called for the current tree only. 304 ********************************************************************/ findRelatesNode(const QStringList & path)305 Aggregate *findRelatesNode(const QStringList &path) 306 { 307 return primaryTree()->findRelatesNode(path); 308 } 309 Node *findNodeInOpenNamespace(QStringList &path, bool (Node::*)() const); 310 /*******************************************************************/ 311 312 /***************************************************************************** 313 This function can handle parameters enclosed in '[' ']' (domanin and genus). 314 ******************************************************************************/ 315 const Node *findNodeForAtom(const Atom *atom, const Node *relative, QString &ref); 316 /*******************************************************************/ 317 318 /******************************************************************* 319 The functions declared below are called for all trees. 320 ********************************************************************/ findClassNode(const QStringList & path)321 ClassNode *findClassNode(const QStringList &path) { return forest_.findClassNode(path); } findNodeForInclude(const QStringList & path)322 Node *findNodeForInclude(const QStringList &path) { return forest_.findNodeForInclude(path); } 323 const FunctionNode *findFunctionNode(const QString &target, const Node *relative, 324 Node::Genus genus); 325 const Node *findTypeNode(const QString &type, const Node *relative, Node::Genus genus); 326 const Node *findNodeForTarget(const QString &target, const Node *relative); findPageNodeByTitle(const QString & title)327 const PageNode *findPageNodeByTitle(const QString &title) 328 { 329 return forest_.findPageNodeByTitle(title); 330 } findNodeByNameAndType(const QStringList & path,bool (Node::* isMatch)()const)331 Node *findNodeByNameAndType(const QStringList &path, bool (Node::*isMatch)() const) 332 { 333 return forest_.findNodeByNameAndType(path, isMatch); 334 } getCollectionNode(const QString & name,Node::NodeType type)335 const CollectionNode *getCollectionNode(const QString &name, Node::NodeType type) 336 { 337 return forest_.getCollectionNode(name, type); 338 } findFunctionNodeForTag(QString tag)339 FunctionNode *findFunctionNodeForTag(QString tag) 340 { 341 return primaryTree()->findFunctionNodeForTag(tag); 342 } findMacroNode(const QString & t)343 FunctionNode *findMacroNode(const QString &t) { return primaryTree()->findMacroNode(t); } 344 345 private: findNodeForTarget(QStringList & targetPath,const Node * relative,Node::Genus genus,QString & ref)346 const Node *findNodeForTarget(QStringList &targetPath, const Node *relative, Node::Genus genus, 347 QString &ref) 348 { 349 return forest_.findNodeForTarget(targetPath, relative, genus, ref); 350 } findFunctionNode(const QStringList & path,const Parameters & parameters,const Node * relative,Node::Genus genus)351 const FunctionNode *findFunctionNode(const QStringList &path, const Parameters ¶meters, 352 const Node *relative, Node::Genus genus) 353 { 354 return forest_.findFunctionNode(path, parameters, relative, genus); 355 } 356 357 /*******************************************************************/ 358 public: addPropertyFunction(PropertyNode * property,const QString & funcName,PropertyNode::FunctionRole funcRole)359 void addPropertyFunction(PropertyNode *property, const QString &funcName, 360 PropertyNode::FunctionRole funcRole) 361 { 362 primaryTree()->addPropertyFunction(property, funcName, funcRole); 363 } 364 setVersion(const QString & v)365 void setVersion(const QString &v) { version_ = v; } version()366 QString version() const { return version_; } 367 368 void generateTagFile(const QString &name, Generator *g); 369 void readIndexes(const QStringList &indexFiles); 370 void generateIndex(const QString &fileName, const QString &url, const QString &title, 371 Generator *g); 372 clearOpenNamespaces()373 void clearOpenNamespaces() { openNamespaces_.clear(); } insertOpenNamespace(const QString & path)374 void insertOpenNamespace(const QString &path) { openNamespaces_.insert(path); } setShowInternal(bool value)375 void setShowInternal(bool value) { showInternal_ = value; } setSingleExec(bool value)376 void setSingleExec(bool value) { singleExec_ = value; } 377 void processForest(); 378 379 // Try to make this function private. forest()380 QDocForest &forest() { return forest_; } primaryTreeRoot()381 NamespaceNode *primaryTreeRoot() { return forest_.primaryTreeRoot(); } newPrimaryTree(const QString & module)382 void newPrimaryTree(const QString &module) { forest_.newPrimaryTree(module); } setPrimaryTree(const QString & t)383 void setPrimaryTree(const QString &t) { forest_.setPrimaryTree(t); } newIndexTree(const QString & module)384 NamespaceNode *newIndexTree(const QString &module) { return forest_.newIndexTree(module); } searchOrder()385 const QVector<Tree *> &searchOrder() { return forest_.searchOrder(); } setLocalSearch()386 void setLocalSearch() { forest_.searchOrder_ = QVector<Tree *>(1, primaryTree()); } setSearchOrder(const QVector<Tree * > & searchOrder)387 void setSearchOrder(const QVector<Tree *> &searchOrder) { forest_.searchOrder_ = searchOrder; } setSearchOrder(QStringList & t)388 void setSearchOrder(QStringList &t) { forest_.setSearchOrder(t); } 389 void mergeCollections(Node::NodeType type, CNMap &cnm, const Node *relative); 390 void mergeCollections(CollectionNode *c); clearSearchOrder()391 void clearSearchOrder() { forest_.clearSearchOrder(); } incrementLinkCount(const Node * t)392 void incrementLinkCount(const Node *t) { t->tree()->incrementLinkCount(); } clearLinkCounts()393 void clearLinkCounts() { forest_.clearLinkCounts(); } printLinkCounts(const QString & t)394 void printLinkCounts(const QString &t) { forest_.printLinkCounts(t); } getLinkCounts(QStringList & strings,QVector<int> & counts)395 QString getLinkCounts(QStringList &strings, QVector<int> &counts) 396 { 397 return forest_.getLinkCounts(strings, counts); 398 } 399 QString getNewLinkTarget(const Node *locNode, const Node *t, const QString &fileName, 400 QString &text, bool broken = false) 401 { 402 return primaryTree()->getNewLinkTarget(locNode, t, fileName, text, broken); 403 } getTargetList(const QString & t)404 TargetList *getTargetList(const QString &t) { return primaryTree()->getTargetList(t); } getTargetListKeys()405 QStringList getTargetListKeys() { return primaryTree()->getTargetListKeys(); } keys()406 QStringList keys() { return forest_.keys(); } 407 void resolveNamespaces(); 408 void resolveProxies(); 409 void resolveBaseClasses(); 410 411 private: 412 friend class Tree; 413 findNode(const QStringList & path,const Node * relative,int findFlags,Node::Genus genus)414 const Node *findNode(const QStringList &path, const Node *relative, int findFlags, 415 Node::Genus genus) 416 { 417 return forest_.findNode(path, relative, findFlags, genus); 418 } 419 void processForest(void (QDocDatabase::*)(Aggregate *)); isLoaded(const QString & t)420 bool isLoaded(const QString &t) { return forest_.isLoaded(t); } 421 static void initializeDB(); 422 423 private: 424 QDocDatabase(); QDocDatabase(QDocDatabase const &)425 QDocDatabase(QDocDatabase const &) : showInternal_(false), forest_(this) {} 426 QDocDatabase &operator=(QDocDatabase const &); 427 428 public: 429 static bool debug; primaryTree()430 Tree *primaryTree() { return forest_.primaryTree(); } 431 432 private: 433 static QDocDatabase *qdocDB_; 434 static NodeMap typeNodeMap_; 435 static NodeMultiMap obsoleteClasses_; 436 static NodeMultiMap classesWithObsoleteMembers_; 437 static NodeMultiMap obsoleteQmlTypes_; 438 static NodeMultiMap qmlTypesWithObsoleteMembers_; 439 static NodeMultiMap cppClasses_; 440 static NodeMultiMap qmlBasicTypes_; 441 static NodeMultiMap qmlTypes_; 442 static NodeMultiMap examples_; 443 static NodeMapMap newClassMaps_; 444 static NodeMapMap newQmlTypeMaps_; 445 static NodeMultiMapMap newSinceMaps_; 446 447 bool showInternal_; 448 bool singleExec_; 449 QString version_; 450 QDocForest forest_; 451 452 NodeMultiMap namespaceIndex_; 453 NodeMultiMap attributions_; 454 NodeMapMap functionIndex_; 455 TextToNodeMap legaleseTexts_; 456 QSet<QString> openNamespaces_; 457 }; 458 459 QT_END_NAMESPACE 460 461 #endif 462