1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#ifndef QDOCDATABASE_H
5#define QDOCDATABASE_H
6
7#include "config.h"
8#include "examplenode.h"
9#include "propertynode.h"
10#include "text.h"
11#include "tree.h"
12
13#include <QtCore/qdebug.h>
14#include <QtCore/qmap.h>
15#include <QtCore/qstring.h>
16
17QT_BEGIN_NAMESPACE
18
19typedef QMultiMap<Text, const Node *> TextToNodeMap;
20
21class Atom;
22class FunctionNode;
23class Generator;
24class QDocDatabase;
25
26enum FindFlag {
27 SearchBaseClasses = 0x1,
28 SearchEnumValues = 0x2,
29 TypesOnly = 0x4,
30 IgnoreModules = 0x8
31};
32
33class QDocForest
34{
35private:
36 friend class QDocDatabase;
37 explicit QDocForest(QDocDatabase *qdb) : m_qdb(qdb), m_primaryTree(nullptr), m_currentIndex(0)
38 {
39 }
40 ~QDocForest();
41
42 Tree *firstTree();
43 Tree *nextTree();
44 Tree *primaryTree() { return m_primaryTree; }
45 Tree *findTree(const QString &t) { return m_forest.value(key: t); }
46 QStringList keys() { return m_forest.keys(); }
47 NamespaceNode *primaryTreeRoot() { return (m_primaryTree ? m_primaryTree->root() : nullptr); }
48 bool isEmpty() { return searchOrder().isEmpty(); }
49 bool done() { return (m_currentIndex >= searchOrder().size()); }
50 const QList<Tree *> &searchOrder();
51 const QList<Tree *> &indexSearchOrder();
52 void setSearchOrder(const QStringList &t);
53 bool isLoaded(const QString &fn)
54 {
55 return std::any_of(first: searchOrder().constBegin(), last: searchOrder().constEnd(),
56 pred: [fn](Tree *tree) { return fn == tree->indexFileName(); });
57 }
58
59 const Node *findNode(const QStringList &path, const Node *relative, int findFlags,
60 Node::Genus genus)
61 {
62 for (const auto *tree : searchOrder()) {
63 const Node *n = tree->findNode(path, relative, flags: findFlags, genus);
64 if (n)
65 return n;
66 relative = nullptr;
67 }
68 return nullptr;
69 }
70
71 Node *findNodeByNameAndType(const QStringList &path, bool (Node::*isMatch)() const)
72 {
73 for (const auto *tree : searchOrder()) {
74 Node *n = tree->findNodeByNameAndType(path, isMatch);
75 if (n)
76 return n;
77 }
78 return nullptr;
79 }
80
81 ClassNode *findClassNode(const QStringList &path)
82 {
83 for (const auto *tree : searchOrder()) {
84 ClassNode *n = tree->findClassNode(path);
85 if (n)
86 return n;
87 }
88 return nullptr;
89 }
90
91 Node *findNodeForInclude(const QStringList &path)
92 {
93 for (const auto *tree : searchOrder()) {
94 Node *n = tree->findNodeForInclude(path);
95 if (n)
96 return n;
97 }
98 return nullptr;
99 }
100
101 const FunctionNode *findFunctionNode(const QStringList &path, const Parameters &parameters,
102 const Node *relative, Node::Genus genus);
103 const Node *findNodeForTarget(QStringList &targetPath, const Node *relative, Node::Genus genus,
104 QString &ref);
105
106 const Node *findTypeNode(const QStringList &path, const Node *relative, Node::Genus genus)
107 {
108 int flags = SearchBaseClasses | SearchEnumValues | TypesOnly;
109 if (relative && genus == Node::DontCare && relative->genus() != Node::DOC)
110 genus = relative->genus();
111 for (const auto *tree : searchOrder()) {
112 const Node *n = tree->findNode(path, relative, flags, genus);
113 if (n)
114 return n;
115 relative = nullptr;
116 }
117 return nullptr;
118 }
119
120 const PageNode *findPageNodeByTitle(const QString &title)
121 {
122 for (const auto *tree : searchOrder()) {
123 const PageNode *n = tree->findPageNodeByTitle(title);
124 if (n)
125 return n;
126 }
127 return nullptr;
128 }
129
130 const CollectionNode *getCollectionNode(const QString &name, Node::NodeType type)
131 {
132 for (auto *tree : searchOrder()) {
133 const CollectionNode *cn = tree->getCollection(name, type);
134 if (cn)
135 return cn;
136 }
137 return nullptr;
138 }
139
140 QmlTypeNode *lookupQmlType(const QString &name)
141 {
142 for (const auto *tree : searchOrder()) {
143 QmlTypeNode *qcn = tree->lookupQmlType(name);
144 if (qcn)
145 return qcn;
146 }
147 return nullptr;
148 }
149
150 void clearSearchOrder() { m_searchOrder.clear(); }
151 void newPrimaryTree(const QString &module);
152 void setPrimaryTree(const QString &t);
153 NamespaceNode *newIndexTree(const QString &module);
154
155private:
156 QDocDatabase *m_qdb;
157 Tree *m_primaryTree;
158 int m_currentIndex;
159 QMap<QString, Tree *> m_forest;
160 QList<Tree *> m_searchOrder;
161 QList<Tree *> m_indexSearchOrder;
162 QList<QString> m_moduleNames;
163};
164
165class QDocDatabase
166{
167public:
168 static QDocDatabase *qdocDB();
169 static void destroyQdocDB();
170 ~QDocDatabase() = default;
171
172 using FindFunctionPtr = void (QDocDatabase::*)(Aggregate *);
173
174 Tree *findTree(const QString &t) { return m_forest.findTree(t); }
175
176 const CNMap &groups() { return primaryTree()->groups(); }
177 const CNMap &modules() { return primaryTree()->modules(); }
178 const CNMap &qmlModules() { return primaryTree()->qmlModules(); }
179
180 CollectionNode *addGroup(const QString &name) { return primaryTree()->addGroup(name); }
181 CollectionNode *addModule(const QString &name) { return primaryTree()->addModule(name); }
182 CollectionNode *addQmlModule(const QString &name) { return primaryTree()->addQmlModule(name); }
183
184 CollectionNode *addToGroup(const QString &name, Node *node)
185 {
186 return primaryTree()->addToGroup(name, node);
187 }
188 CollectionNode *addToModule(const QString &name, Node *node)
189 {
190 return primaryTree()->addToModule(name, node);
191 }
192 CollectionNode *addToQmlModule(const QString &name, Node *node)
193 {
194 return primaryTree()->addToQmlModule(name, node);
195 }
196
197 void addExampleNode(ExampleNode *n) { primaryTree()->addExampleNode(n); }
198 ExampleNodeMap &exampleNodeMap() { return primaryTree()->exampleNodeMap(); }
199
200 QmlTypeNode *findQmlType(const QString &name);
201 QmlTypeNode *findQmlType(const QString &qmid, const QString &name);
202 QmlTypeNode *findQmlType(const ImportRec &import, const QString &name);
203
204 static NodeMultiMap &obsoleteClasses() { return s_obsoleteClasses; }
205 static NodeMultiMap &obsoleteQmlTypes() { return s_obsoleteQmlTypes; }
206 static NodeMultiMap &classesWithObsoleteMembers() { return s_classesWithObsoleteMembers; }
207 static NodeMultiMap &qmlTypesWithObsoleteMembers() { return s_qmlTypesWithObsoleteMembers; }
208 static NodeMultiMap &cppClasses() { return s_cppClasses; }
209 static NodeMultiMap &qmlBasicTypes() { return s_qmlBasicTypes; }
210 static NodeMultiMap &qmlTypes() { return s_qmlTypes; }
211 static NodeMultiMap &examples() { return s_examples; }
212 static NodeMultiMapMap &newClassMaps() { return s_newClassMaps; }
213 static NodeMultiMapMap &newQmlTypeMaps() { return s_newQmlTypeMaps; }
214 static NodeMultiMapMap &newEnumValueMaps() { return s_newEnumValueMaps; }
215 static NodeMultiMapMap &newSinceMaps() { return s_newSinceMaps; }
216
217private:
218 void findAllClasses(Aggregate *node) { node->findAllClasses(); }
219 void findAllFunctions(Aggregate *node) { node->findAllFunctions(functionIndex&: m_functionIndex); }
220 void findAllAttributions(Aggregate *node) { node->findAllAttributions(attributions&: m_attributions); }
221 void findAllLegaleseTexts(Aggregate *node);
222 void findAllObsoleteThings(Aggregate *node) { node->findAllObsoleteThings(); }
223 void findAllSince(Aggregate *node) { node->findAllSince(); }
224
225public:
226 /*******************************************************************
227 special collection access functions
228 ********************************************************************/
229 NodeMultiMap &getCppClasses();
230 NodeMultiMap &getObsoleteClasses();
231 NodeMultiMap &getClassesWithObsoleteMembers();
232 NodeMultiMap &getObsoleteQmlTypes();
233 NodeMultiMap &getQmlTypesWithObsoleteMembers();
234 NodeMultiMap &getNamespaces();
235 NodeMultiMap &getQmlValueTypes();
236 NodeMultiMap &getQmlTypes();
237 NodeMultiMap &getExamples();
238 NodeMultiMap &getAttributions();
239 NodeMapMap &getFunctionIndex();
240 TextToNodeMap &getLegaleseTexts();
241 const NodeMultiMap &getClassMap(const QString &key);
242 const NodeMultiMap &getQmlTypeMap(const QString &key);
243 const NodeMultiMap &getSinceMap(const QString &key);
244
245 /*******************************************************************
246 Many of these will be either eliminated or replaced.
247 ********************************************************************/
248 void resolveStuff();
249 void insertTarget(const QString &name, const QString &title, TargetRec::TargetType type,
250 Node *node, int priority)
251 {
252 primaryTree()->insertTarget(name, title, type, node, priority);
253 }
254
255 /*******************************************************************
256 The functions declared below are called for the current tree only.
257 ********************************************************************/
258 Aggregate *findRelatesNode(const QStringList &path)
259 {
260 return primaryTree()->findRelatesNode(path);
261 }
262 Node *findNodeInOpenNamespace(QStringList &path, bool (Node::*)() const);
263 /*******************************************************************/
264
265 /*****************************************************************************
266 This function can handle parameters enclosed in '[' ']' (domain and genus).
267 ******************************************************************************/
268 const Node *findNodeForAtom(const Atom *atom, const Node *relative, QString &ref,
269 Node::Genus genus = Node::DontCare);
270 /*******************************************************************/
271
272 /*******************************************************************
273 The functions declared below are called for all trees.
274 ********************************************************************/
275 ClassNode *findClassNode(const QStringList &path) { return m_forest.findClassNode(path); }
276 Node *findNodeForInclude(const QStringList &path) { return m_forest.findNodeForInclude(path); }
277 const FunctionNode *findFunctionNode(const QString &target, const Node *relative,
278 Node::Genus genus);
279 const Node *findTypeNode(const QString &type, const Node *relative, Node::Genus genus);
280 const Node *findNodeForTarget(const QString &target, const Node *relative);
281 const PageNode *findPageNodeByTitle(const QString &title)
282 {
283 return m_forest.findPageNodeByTitle(title);
284 }
285 Node *findNodeByNameAndType(const QStringList &path, bool (Node::*isMatch)() const)
286 {
287 return m_forest.findNodeByNameAndType(path, isMatch);
288 }
289 const CollectionNode *getCollectionNode(const QString &name, Node::NodeType type)
290 {
291 return m_forest.getCollectionNode(name, type);
292 }
293 const CollectionNode *getModuleNode(const Node *relative);
294
295 FunctionNode *findFunctionNodeForTag(const QString &tag)
296 {
297 return primaryTree()->findFunctionNodeForTag(tag);
298 }
299 FunctionNode *findMacroNode(const QString &t) { return primaryTree()->findMacroNode(t); }
300
301 QStringList groupNamesForNode(Node *node);
302
303private:
304 const Node *findNodeForTarget(QStringList &targetPath, const Node *relative, Node::Genus genus,
305 QString &ref)
306 {
307 return m_forest.findNodeForTarget(targetPath, relative, genus, ref);
308 }
309 const FunctionNode *findFunctionNode(const QStringList &path, const Parameters &parameters,
310 const Node *relative, Node::Genus genus)
311 {
312 return m_forest.findFunctionNode(path, parameters, relative, genus);
313 }
314
315 /*******************************************************************/
316public:
317 void addPropertyFunction(PropertyNode *property, const QString &funcName,
318 PropertyNode::FunctionRole funcRole)
319 {
320 primaryTree()->addPropertyFunction(property, funcName, funcRole);
321 }
322
323 void setVersion(const QString &v) { m_version = v; }
324 [[nodiscard]] QString version() const { return m_version; }
325
326 void readIndexes(const QStringList &indexFiles);
327 void generateIndex(const QString &fileName, const QString &url, const QString &title,
328 Generator *g);
329
330 void clearOpenNamespaces() { m_openNamespaces.clear(); }
331 void insertOpenNamespace(const QString &path) { m_openNamespaces.insert(value: path); }
332 void processForest();
333
334 NamespaceNode *primaryTreeRoot() { return m_forest.primaryTreeRoot(); }
335 void newPrimaryTree(const QString &module) { m_forest.newPrimaryTree(module); }
336 void setPrimaryTree(const QString &t) { m_forest.setPrimaryTree(t); }
337 NamespaceNode *newIndexTree(const QString &module) { return m_forest.newIndexTree(module); }
338 const QList<Tree *> &searchOrder() { return m_forest.searchOrder(); }
339 void setLocalSearch() { m_forest.m_searchOrder = QList<Tree *>(1, primaryTree()); }
340 void setSearchOrder(const QList<Tree *> &searchOrder) { m_forest.m_searchOrder = searchOrder; }
341 void setSearchOrder(QStringList &t) { m_forest.setSearchOrder(t); }
342 void mergeCollections(Node::NodeType type, CNMap &cnm, const Node *relative);
343 void mergeCollections(CollectionNode *c);
344 void clearSearchOrder() { m_forest.clearSearchOrder(); }
345 QStringList keys() { return m_forest.keys(); }
346 void resolveNamespaces();
347 void resolveProxies();
348 void resolveBaseClasses();
349 void updateNavigation();
350
351private:
352 friend class Tree;
353
354 void processForest(FindFunctionPtr func);
355 bool isLoaded(const QString &t) { return m_forest.isLoaded(fn: t); }
356 static void initializeDB();
357
358private:
359 QDocDatabase();
360 QDocDatabase(QDocDatabase const &) : m_forest(this) { }
361 QDocDatabase &operator=(QDocDatabase const &);
362
363public:
364 Tree *primaryTree() { return m_forest.primaryTree(); }
365
366private:
367 static QDocDatabase *s_qdocDB;
368 static NodeMap s_typeNodeMap;
369 static NodeMultiMap s_obsoleteClasses;
370 static NodeMultiMap s_classesWithObsoleteMembers;
371 static NodeMultiMap s_obsoleteQmlTypes;
372 static NodeMultiMap s_qmlTypesWithObsoleteMembers;
373 static NodeMultiMap s_cppClasses;
374 static NodeMultiMap s_qmlBasicTypes;
375 static NodeMultiMap s_qmlTypes;
376 static NodeMultiMap s_examples;
377 static NodeMultiMapMap s_newClassMaps;
378 static NodeMultiMapMap s_newQmlTypeMaps;
379 static NodeMultiMapMap s_newEnumValueMaps;
380 static NodeMultiMapMap s_newSinceMaps;
381
382 QString m_version {};
383 QDocForest m_forest;
384
385 NodeMultiMap m_namespaceIndex {};
386 NodeMultiMap m_attributions {};
387 NodeMapMap m_functionIndex {};
388 TextToNodeMap m_legaleseTexts {};
389 QSet<QString> m_openNamespaces {};
390 QMultiHash<Tree*, FindFunctionPtr> m_completedFindFunctions {};
391};
392
393QT_END_NAMESPACE
394
395#endif
396

source code of qttools/src/qdoc/qdoc/qdocdatabase.h