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

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