13#include <QtCore/qregularexpression.h>
18using namespace Qt::StringLiterals;
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
59
60
61
62
63
64
67 for (
auto *entry : m_searchOrder)
70 m_searchOrder.clear();
71 m_indexSearchOrder.clear();
72 m_moduleNames.clear();
73 m_primaryTree =
nullptr;
77
78
79
80
84 return (!searchOrder().isEmpty() ? searchOrder()[0] :
nullptr);
88
89
90
91
95 return (m_currentIndex < searchOrder().size() ? searchOrder()[m_currentIndex] :
nullptr);
99
100
101
102
105
106
107
108
109
110
111
112
113void QDocForest::setPrimaryTree(
const QString &t)
115 QString T = t.toLower();
116 m_primaryTree = findTree(T);
118 if (m_primaryTree ==
nullptr)
119 qCCritical(lcQdoc) <<
"Error: Could not set primary tree to" << t;
123
124
125
126void QDocForest::setSearchOrder(
const QStringList &t)
128 if (!m_searchOrder.isEmpty())
132 m_searchOrder.reserve(m_forest.size() + 1);
133 m_searchOrder.clear();
134 m_moduleNames.reserve(m_forest.size() + 1);
135 m_moduleNames.clear();
138 QString primaryName = primaryTree()->physicalModuleName();
139 m_searchOrder.append(m_primaryTree);
140 m_moduleNames.append(primaryName);
141 m_forest.remove(primaryName);
143 for (
const QString &m : t) {
144 if (primaryName != m) {
145 auto it = m_forest.find(m);
146 if (it != m_forest.end()) {
147 m_searchOrder.append(it.value());
148 m_moduleNames.append(m);
154
155
156
157
158 if (!m_forest.isEmpty()) {
159 for (
auto it = m_forest.begin(); it != m_forest.end(); ++it) {
160 m_searchOrder.append(it.value());
161 m_moduleNames.append(it.key());
167
168
169
170
171
172
173
174 for (
int i = 0; i < m_searchOrder.size(); ++i) {
175 if (!m_forest.contains(m_moduleNames.at(i))) {
176 m_forest.insert(m_moduleNames.at(i), m_searchOrder.at(i));
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
208 if (m_searchOrder.isEmpty())
209 return indexSearchOrder();
210 return m_searchOrder;
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228const QList<Tree *> &
QDocForest::indexSearchOrder()
230 if (m_forest.size() > m_indexSearchOrder.size())
231 m_indexSearchOrder.prepend(m_primaryTree);
232 return m_indexSearchOrder;
236
237
238
239
242 m_primaryTree =
new Tree(module, m_qdb);
243 m_forest.insert(module.toLower(), m_primaryTree);
244 return m_primaryTree->root();
248
249
250
251void QDocForest::newPrimaryTree(
const QString &module)
253 m_primaryTree =
new Tree(module, m_qdb);
257
258
259
260
261
262
263
264
265
266
267
268
269
270const Node *
QDocForest::findNodeForTarget(QStringList &targetPath,
const Node *relative,
275 QString entity = targetPath.takeFirst();
276 QStringList entityPath = entity.split(
"::");
279 if (!targetPath.isEmpty())
280 target = targetPath.takeFirst();
283 const Node *tocNode =
nullptr;
284 for (
const auto *tree : searchOrder()) {
285 const Node *n = tree->findNodeForTarget(entityPath, target, relative, flags, genus, ref, &type);
288 if (type != TargetRec::Contents)
299
300
301
302
303
304
305
306
307
312 for (
const auto *tree : searchOrder()) {
313 const FunctionNode *fn = tree->findFunctionNode(path, parameters, relative, genus);
322
323
324
325
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
364
365
366
369 if (s_qdocDB ==
nullptr) {
377
378
381 if (s_qdocDB !=
nullptr) {
388
389
390
391
392
393
394
395
396
397
398
399
400
403 s_typeNodeMap.insert(
"accepted",
nullptr);
404 s_typeNodeMap.insert(
"actionPerformed",
nullptr);
405 s_typeNodeMap.insert(
"activated",
nullptr);
406 s_typeNodeMap.insert(
"alias",
nullptr);
407 s_typeNodeMap.insert(
"anchors",
nullptr);
408 s_typeNodeMap.insert(
"any",
nullptr);
409 s_typeNodeMap.insert(
"array",
nullptr);
410 s_typeNodeMap.insert(
"autoSearch",
nullptr);
411 s_typeNodeMap.insert(
"axis",
nullptr);
412 s_typeNodeMap.insert(
"backClicked",
nullptr);
413 s_typeNodeMap.insert(
"boomTime",
nullptr);
414 s_typeNodeMap.insert(
"border",
nullptr);
415 s_typeNodeMap.insert(
"buttonClicked",
nullptr);
416 s_typeNodeMap.insert(
"callback",
nullptr);
417 s_typeNodeMap.insert(
"char",
nullptr);
418 s_typeNodeMap.insert(
"clicked",
nullptr);
419 s_typeNodeMap.insert(
"close",
nullptr);
420 s_typeNodeMap.insert(
"closed",
nullptr);
421 s_typeNodeMap.insert(
"cond",
nullptr);
422 s_typeNodeMap.insert(
"data",
nullptr);
423 s_typeNodeMap.insert(
"dataReady",
nullptr);
424 s_typeNodeMap.insert(
"dateString",
nullptr);
425 s_typeNodeMap.insert(
"dateTimeString",
nullptr);
426 s_typeNodeMap.insert(
"datetime",
nullptr);
427 s_typeNodeMap.insert(
"day",
nullptr);
428 s_typeNodeMap.insert(
"deactivated",
nullptr);
429 s_typeNodeMap.insert(
"drag",
nullptr);
430 s_typeNodeMap.insert(
"easing",
nullptr);
431 s_typeNodeMap.insert(
"error",
nullptr);
432 s_typeNodeMap.insert(
"exposure",
nullptr);
433 s_typeNodeMap.insert(
"fatalError",
nullptr);
434 s_typeNodeMap.insert(
"fileSelected",
nullptr);
435 s_typeNodeMap.insert(
"flags",
nullptr);
436 s_typeNodeMap.insert(
"float",
nullptr);
437 s_typeNodeMap.insert(
"focus",
nullptr);
438 s_typeNodeMap.insert(
"focusZone",
nullptr);
439 s_typeNodeMap.insert(
"format",
nullptr);
440 s_typeNodeMap.insert(
"framePainted",
nullptr);
441 s_typeNodeMap.insert(
"from",
nullptr);
442 s_typeNodeMap.insert(
"frontClicked",
nullptr);
443 s_typeNodeMap.insert(
"function",
nullptr);
444 s_typeNodeMap.insert(
"hasOpened",
nullptr);
445 s_typeNodeMap.insert(
"hovered",
nullptr);
446 s_typeNodeMap.insert(
"hoveredTitle",
nullptr);
447 s_typeNodeMap.insert(
"hoveredUrl",
nullptr);
448 s_typeNodeMap.insert(
"imageCapture",
nullptr);
449 s_typeNodeMap.insert(
"imageProcessing",
nullptr);
450 s_typeNodeMap.insert(
"index",
nullptr);
451 s_typeNodeMap.insert(
"initialized",
nullptr);
452 s_typeNodeMap.insert(
"isLoaded",
nullptr);
453 s_typeNodeMap.insert(
"item",
nullptr);
454 s_typeNodeMap.insert(
"key",
nullptr);
455 s_typeNodeMap.insert(
"keysequence",
nullptr);
456 s_typeNodeMap.insert(
"listViewClicked",
nullptr);
457 s_typeNodeMap.insert(
"loadRequest",
nullptr);
458 s_typeNodeMap.insert(
"locale",
nullptr);
459 s_typeNodeMap.insert(
"location",
nullptr);
460 s_typeNodeMap.insert(
"long",
nullptr);
461 s_typeNodeMap.insert(
"message",
nullptr);
462 s_typeNodeMap.insert(
"messageReceived",
nullptr);
463 s_typeNodeMap.insert(
"mode",
nullptr);
464 s_typeNodeMap.insert(
"month",
nullptr);
465 s_typeNodeMap.insert(
"name",
nullptr);
466 s_typeNodeMap.insert(
"number",
nullptr);
467 s_typeNodeMap.insert(
"object",
nullptr);
468 s_typeNodeMap.insert(
"offset",
nullptr);
469 s_typeNodeMap.insert(
"ok",
nullptr);
470 s_typeNodeMap.insert(
"openCamera",
nullptr);
471 s_typeNodeMap.insert(
"openImage",
nullptr);
472 s_typeNodeMap.insert(
"openVideo",
nullptr);
473 s_typeNodeMap.insert(
"padding",
nullptr);
474 s_typeNodeMap.insert(
"parent",
nullptr);
475 s_typeNodeMap.insert(
"path",
nullptr);
476 s_typeNodeMap.insert(
"photoModeSelected",
nullptr);
477 s_typeNodeMap.insert(
"position",
nullptr);
478 s_typeNodeMap.insert(
"precision",
nullptr);
479 s_typeNodeMap.insert(
"presetClicked",
nullptr);
480 s_typeNodeMap.insert(
"preview",
nullptr);
481 s_typeNodeMap.insert(
"previewSelected",
nullptr);
482 s_typeNodeMap.insert(
"progress",
nullptr);
483 s_typeNodeMap.insert(
"puzzleLost",
nullptr);
484 s_typeNodeMap.insert(
"qmlSignal",
nullptr);
485 s_typeNodeMap.insert(
"rectangle",
nullptr);
486 s_typeNodeMap.insert(
"request",
nullptr);
487 s_typeNodeMap.insert(
"requestId",
nullptr);
488 s_typeNodeMap.insert(
"section",
nullptr);
489 s_typeNodeMap.insert(
"selected",
nullptr);
490 s_typeNodeMap.insert(
"send",
nullptr);
491 s_typeNodeMap.insert(
"settingsClicked",
nullptr);
492 s_typeNodeMap.insert(
"shoe",
nullptr);
493 s_typeNodeMap.insert(
"short",
nullptr);
494 s_typeNodeMap.insert(
"signed",
nullptr);
495 s_typeNodeMap.insert(
"sizeChanged",
nullptr);
496 s_typeNodeMap.insert(
"size_t",
nullptr);
497 s_typeNodeMap.insert(
"sockaddr",
nullptr);
498 s_typeNodeMap.insert(
"someOtherSignal",
nullptr);
499 s_typeNodeMap.insert(
"sourceSize",
nullptr);
500 s_typeNodeMap.insert(
"startButtonClicked",
nullptr);
501 s_typeNodeMap.insert(
"state",
nullptr);
502 s_typeNodeMap.insert(
"std::initializer_list",
nullptr);
503 s_typeNodeMap.insert(
"std::list",
nullptr);
504 s_typeNodeMap.insert(
"std::map",
nullptr);
505 s_typeNodeMap.insert(
"std::pair",
nullptr);
506 s_typeNodeMap.insert(
"std::string",
nullptr);
507 s_typeNodeMap.insert(
"std::vector",
nullptr);
508 s_typeNodeMap.insert(
"stringlist",
nullptr);
509 s_typeNodeMap.insert(
"swapPlayers",
nullptr);
510 s_typeNodeMap.insert(
"symbol",
nullptr);
511 s_typeNodeMap.insert(
"t",
nullptr);
512 s_typeNodeMap.insert(
"T",
nullptr);
513 s_typeNodeMap.insert(
"tagChanged",
nullptr);
514 s_typeNodeMap.insert(
"timeString",
nullptr);
515 s_typeNodeMap.insert(
"timeout",
nullptr);
516 s_typeNodeMap.insert(
"to",
nullptr);
517 s_typeNodeMap.insert(
"toggled",
nullptr);
518 s_typeNodeMap.insert(
"type",
nullptr);
519 s_typeNodeMap.insert(
"unsigned",
nullptr);
520 s_typeNodeMap.insert(
"urllist",
nullptr);
521 s_typeNodeMap.insert(
"va_list",
nullptr);
522 s_typeNodeMap.insert(
"value",
nullptr);
523 s_typeNodeMap.insert(
"valueEmitted",
nullptr);
524 s_typeNodeMap.insert(
"videoFramePainted",
nullptr);
525 s_typeNodeMap.insert(
"videoModeSelected",
nullptr);
526 s_typeNodeMap.insert(
"videoRecorder",
nullptr);
527 s_typeNodeMap.insert(
"void",
nullptr);
528 s_typeNodeMap.insert(
"volatile",
nullptr);
529 s_typeNodeMap.insert(
"wchar_t",
nullptr);
530 s_typeNodeMap.insert(
"x",
nullptr);
531 s_typeNodeMap.insert(
"y",
nullptr);
532 s_typeNodeMap.insert(
"zoom",
nullptr);
533 s_typeNodeMap.insert(
"zoomTo",
nullptr);
537
538
541
542
543
544
547
548
549
550
553
554
555
556
559
560
561
562
563
564
565
568
569
570
571
572
573
574
577
578
579
580
581
582
585
586
587
588
589
590
593
594
595
596
597
598
601
602
603
604
605
606
607
608
611
612
613
614
615
616
619
620
621
622
625
626
627
630
631
632
633
634
635
636
639 if (!qmid.isEmpty()) {
640 if (
auto *qcn = m_forest.lookupQmlType(qmid + u"::"_s + name); qcn)
644 QStringList path(name);
645 return static_cast<QmlTypeNode *>(m_forest.findNodeByNameAndType(path, &Node::isQmlType));
649
650
651
652
662 if (!record.m_importId.isEmpty()) {
663 const QString namespacePrefix{
"%1."_L1.arg(record.m_importId)};
664 if (!type.startsWith(namespacePrefix))
666 type.remove(0, namespacePrefix.size());
669 const QString qmName = record.m_importUri.isEmpty() ? record.m_moduleName : record.m_importUri;
670 return m_forest.lookupQmlType(qmName + u"::"_s + type);
674
675
676
677
678
679
683 return primaryTree()->lookupQmlType(qmid + u"::"_s + name);
688
689
690
691
692
693
706
707
708
709
710
713 Tree *t = m_forest.firstTree();
715 if (!m_completedFindFunctions.values(t).contains(func)) {
716 (
this->*(func))(t->root());
717 m_completedFindFunctions.insert(t, func);
719 t = m_forest.nextTree();
724
725
729 return m_legaleseTexts;
733
734
738 return s_classesWithObsoleteMembers;
742
743
747 return s_obsoleteQmlTypes;
751
752
756 return s_qmlTypesWithObsoleteMembers;
760
761
765 return s_qmlBasicTypes;
769
770
778
779
787
788
792 return m_attributions;
796
797
801 return s_obsoleteClasses;
805
806
814
815
816
820 return m_functionIndex;
824
825
826
829 for (
const auto &childNode : node->childNodes()) {
830 if (childNode->isPrivate())
832 if (!childNode->doc().legaleseText().isEmpty())
833 m_legaleseTexts.insert(childNode->doc().legaleseText(), childNode);
834 if (childNode->isAggregate())
835 findAllLegaleseTexts(
static_cast<Aggregate *>(childNode));
840
841
842
843
844
845
848
849
850
851
852
853
854
855
856
859
860
861
862
866 auto it = s_newClassMaps.constFind(key);
871
872
873
874
878 auto it = s_newQmlTypeMaps.constFind(key);
883
884
885
886
890 auto it = s_newSinceMaps.constFind(key);
895
896
897
898
901 const auto &config = Config::instance();
902 if (config.dualExec() || config.preparing()) {
917 if (config.singleExec() && config.generating()) {
924 if (!config.preparing()) {
930 if (config.dualExec())
936 Tree *t = m_forest.firstTree();
938 t->resolveBaseClasses(t->root());
939 t = m_forest.nextTree();
944
945
946
947
948
952 return m_namespaceIndex;
956
957
958
959
960
961
962
965 if (!m_namespaceIndex.isEmpty())
970 Tree *t = m_forest.firstTree();
973 t = m_forest.nextTree();
975 const QList<QString> keys = namespaceMultimap.uniqueKeys();
976 for (
const QString &key : keys) {
977 NamespaceNode *ns =
nullptr;
978 NamespaceNode *indexNamespace =
nullptr;
979 const NodeList namespaces = namespaceMultimap.values(key);
980 qsizetype count = namespaceMultimap.remove(key);
982 for (
auto *node : namespaces) {
983 ns =
static_cast<NamespaceNode *>(node);
984 if (ns->isDocumentedHere())
986 else if (ns->hadDoc())
991 for (
auto *node : namespaces) {
992 auto *nsNode =
static_cast<NamespaceNode *>(node);
993 if (nsNode->hadDoc() && nsNode != ns) {
994 ns->doc().location().warning(
995 QStringLiteral(
"Namespace %1 documented more than once")
996 .arg(nsNode->name()), QStringLiteral(
"also seen here: %1")
997 .arg(nsNode->doc().location().toString()));
1000 }
else if (!indexNamespace) {
1005 for (
auto *node : namespaces) {
1006 if (!node->isIndexNode())
1007 static_cast<NamespaceNode *>(node)->reportDocumentedChildrenInUndocumentedNamespace();
1011 for (
auto *node : namespaces) {
1012 auto *nsNode =
static_cast<NamespaceNode *>(node);
1013 if (nsNode != indexNamespace)
1014 nsNode->setDocNode(indexNamespace);
1019
1020
1021
1022
1023
1024 if (ns && count > 1) {
1025 for (
auto *node : namespaces) {
1026 auto *nameSpaceNode =
static_cast<NamespaceNode *>(node);
1027 if (nameSpaceNode != ns) {
1028 for (
auto it = nameSpaceNode->constBegin(); it != nameSpaceNode->constEnd();
1030 Node *anotherNs = *it;
1031 if (anotherNs && anotherNs->isPublic() && !anotherNs->isInternal())
1032 ns->includeChild(anotherNs);
1038
1039
1040
1042 ns = indexNamespace ? indexNamespace :
static_cast<NamespaceNode *>(namespaces.last());
1043 m_namespaceIndex.insert(ns->name(), ns);
1048
1049
1050
1051
1052
1053
1054
1055
1056
1061 Tree *t = m_forest.firstTree();
1062 t = m_forest.nextTree();
1065 if (!proxies.isEmpty()) {
1066 for (
auto *node : proxies) {
1067 const auto *pn =
static_cast<ProxyNode *>(node);
1068 if (pn->count() > 0) {
1069 Aggregate *aggregate = primaryTree()->findAggregate(pn->name());
1070 if (aggregate !=
nullptr)
1071 aggregate->appendToRelatedByProxy(pn->childNodes());
1075 t = m_forest.nextTree();
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1096 QString function = target;
1097 qsizetype length = target.size();
1098 if (function.endsWith(
"()"))
1100 if (function.endsWith(QChar(
')'))) {
1101 qsizetype position = function.lastIndexOf(QChar(
'('));
1102 signature = function.mid(position + 1, length - position - 2);
1103 function = function.left(position);
1105 QStringList path = function.split(
"::");
1106 return m_forest.findFunctionNode(path, Parameters(signature), relative, genus);
1110
1111
1112
1113
1114
1115
1116
1117
1118
1121 QStringList path = type.split(
"::");
1122 if ((path.size() == 1) && (path.at(0)[0].isLower() || path.at(0) == QString(
"T"))) {
1123 auto it = s_typeNodeMap.find(path.at(0));
1124 if (it != s_typeNodeMap.end())
1127 return m_forest.findTypeNode(path, relative, genus);
1131
1132
1133
1134
1135
1138 const Node *node =
nullptr;
1139 if (target.isEmpty())
1141 else if (target.endsWith(
".html"))
1142 node = findNodeByNameAndType(QStringList(target), &Node::isPageNode);
1144 QStringList path = target.split(
"::");
1146 for (
const auto *tree : searchOrder()) {
1147 const Node *n = tree->findNode(path, relative, flags, Node::DontCare);
1152 node = findPageNodeByTitle(target);
1165 for (
auto it = m->cbegin(); it != m->cend(); ++it)
1166 if (it.value()->members().contains(node))
1173
1174
1177 QStringList filesToRead;
1178 for (
const QString &file : indexFiles) {
1179 QString fn = file.mid(file.lastIndexOf(QChar(
'/')) + 1);
1181 filesToRead << file;
1183 qCCritical(lcQdoc) <<
"Index file" << file <<
"is already in memory.";
1189
1190
1191
1192
1196 QString t = fileName.mid(fileName.lastIndexOf(QChar(
'/')) + 1);
1198 QDocIndexFiles::qdocIndexFiles()->generateIndex(fileName, url, title, g);
1203
1204
1205
1206
1215 moduleName = relative->physicalModuleName();
1219 moduleName = relative->logicalModuleName();
1224 if (moduleName.isEmpty())
1227 return primaryTree()->getCollection(moduleName, moduleType);
1231
1232
1233
1234
1239 for (
auto *tree : searchOrder()) {
1240 CNMap *m = tree->getCollectionMap(type);
1241 if (m && !m->isEmpty()) {
1242 for (
auto it = m->cbegin(); it != m->cend(); ++it) {
1243 if (!it.value()->isInternal())
1244 cnmm.insert(it.key(), it.value());
1250 static const QRegularExpression singleDigit(
"\\b([0-9])\\b");
1251 const QStringList keys = cnmm.uniqueKeys();
1252 for (
const auto &key : keys) {
1253 const QList<CollectionNode *> values = cnmm.values(key);
1254 CollectionNode *n =
nullptr;
1255 for (
auto *value : values) {
1256 if (value && value->wasSeen() && value != relative) {
1262 if (values.size() > 1) {
1263 for (CollectionNode *value : values) {
1266 if ((n->isQmlModule())
1267 && n->logicalModuleIdentifier() != value->logicalModuleIdentifier()) {
1268 if (value->wasSeen() && value != relative)
1269 cnm.insert(value->fullTitle().toLower(), value);
1272 for (Node *t : value->members())
1277 QString sortKey = n->fullTitle().toLower();
1278 if (sortKey.startsWith(
"the "))
1279 sortKey.remove(0, 4);
1280 sortKey.replace(singleDigit,
"0\\1");
1281 cnm.insert(sortKey, n);
1287
1288
1289
1290
1291
1292
1293
1294
1339 for (
auto *tree : searchOrder()) {
1340 CollectionNode *cn = tree->getCollection(c->name(), c->nodeType());
1341 if (cn && cn != c) {
1342 if ((cn->isQmlModule())
1343 && cn->logicalModuleIdentifier() != c->logicalModuleIdentifier())
1346 for (
auto *node : cn->members())
1406 if (!c->wasSeen() && cn->wasSeen()) {
1408 c->setTitle(cn->title());
1409 c->setUrl(cn->url());
1418
1419
1420
1421
1422
1423
1424
1425
1429 const Node *node =
nullptr;
1431 Atom *atom =
const_cast<
Atom *>(a);
1432 QStringList targetPath = atom->string().split(QLatin1Char(
'#'));
1433 QString first = targetPath.first().trimmed();
1435 Tree *domain =
nullptr;
1442 if (first.isEmpty())
1445 if (first.endsWith(
".html"))
1446 node = domain->findNodeByNameAndType(QStringList(first), &
Node::isPageNode);
1447 else if (first.endsWith(QChar(
')'))) {
1449 QString function = first;
1450 qsizetype length = first.size();
1451 if (function.endsWith(
"()"))
1453 if (function.endsWith(QChar(
')'))) {
1454 qsizetype position = function.lastIndexOf(QChar(
'('));
1455 signature = function.mid(position + 1, length - position - 2);
1456 function = function.left(position);
1458 QStringList path = function.split(
"::");
1459 node = domain->findFunctionNode(path,
Parameters(signature),
nullptr, genus);
1461 if (node ==
nullptr) {
1463 QStringList nodePath = first.split(
"::");
1465 targetPath.removeFirst();
1466 if (!targetPath.isEmpty())
1467 target = targetPath.takeFirst();
1468 if (relative && relative
->tree()->physicalModuleName() != domain->physicalModuleName())
1470 return domain->findNodeForTarget(nodePath, target, relative, flags, genus, ref);
1473 if (first.endsWith(
".html"))
1474 node = findNodeByNameAndType(QStringList(first), &Node::isPageNode);
1475 else if (first.endsWith(QChar(
')')))
1476 node = findFunctionNode(first, relative, genus);
1477 if (node ==
nullptr)
1478 return findNodeForTarget(targetPath, relative, genus, ref);
1481 if (node !=
nullptr && ref.isEmpty()) {
1482 if (!node->url().isEmpty())
1484 targetPath.removeFirst();
1485 if (!targetPath.isEmpty()) {
1495
1496
1497
1498
1499
1500
1501
1502
1506 QList<Tree *> searchOrder =
this->searchOrder();
1525 bool inclusive{Config::instance().get(
1529 const auto tocTitles{Config::instance().get(configVar).asStringList()};
1531 for (
const auto &tocTitle : tocTitles) {
1532 if (
const auto candidateTarget = findNodeForTarget(tocTitle,
nullptr); candidateTarget && candidateTarget->isPageNode()) {
1533 auto tocPage{
static_cast<
const PageNode*>(candidateTarget)};
1535 Text body = tocPage->doc().body();
1537 auto *atom = body.firstAtom();
1539 std::pair<PageNode *, Atom *> prev {
nullptr,
nullptr };
1541 std::stack<
const PageNode *> tocStack;
1542 tocStack.push(inclusive ? tocPage :
nullptr);
1544 bool inItem =
false;
1551 switch (atom->type()) {
1552 case Atom::ListItemLeft:
1554 tocStack.push(
nullptr);
1557 case Atom::ListItemRight:
1597 auto candidatePage =
const_cast<Node *>(findNodeForAtom(atom,
nullptr, unused));
1598 if (!candidatePage || !candidatePage->isPageNode())
break;
1600 auto page{
static_cast<PageNode*>(candidatePage)};
1603 if (page == prev.first)
break;
1606 prev.first->setLink(
1647 prev.first->title(),
1649 prev.second->linkText()
1653 if (page == tocPage)
1658 qsizetype popped = 0;
1659 while (tocStack.size() > 1 && !tocStack.top()) {
1664 page->setNavigationParent(tocStack.empty() ?
nullptr : tocStack.top());
1666 while (--popped > 0)
1667 tocStack.push(
nullptr);
1669 tocStack.push(page);
1670 prev = { page, atom };
1677 atom = atom->next();
1680 Config::instance().get(configVar).location()
1681 .warning(QStringLiteral(
"Failed to find table of contents with title '%1'")
1687 setSearchOrder(searchOrder);
void resolveRelates()
Adopts each non-aggregate C++ node (function/macro, typedef, enum, variable, or a shared comment node...
void resolveQmlInheritance()
Resolves the inheritance information for all QML type children of this aggregate.
void normalizeOverloads()
Sorts the lists of overloads in the function map and assigns overload numbers.
void findAllNamespaces(NodeMultiMap &namespaces)
For each child of this node, if the child is a namespace node, insert the child into the namespaces m...
void markUndocumentedChildrenInternal()
Mark all child nodes that have no documentation as having private access and internal status.
The Atom class is the fundamental unit for representing documents internally.
virtual Node::Genus genus()
virtual bool isLinkAtom() const
A class for holding the members of a collection of doc pages.
This node is used to represent any kind of function being documented.
This class represents a C++ namespace.
NodeType
An unsigned char value that identifies an object as a particular subclass of Node.
virtual bool isPageNode() const
Returns true if this node represents something that generates a documentation page.
Genus
An unsigned char value that specifies whether the Node represents a C++ element, a QML element,...
virtual Tree * tree() const
Returns a pointer to the Tree this node is in.
Genus genus() const
Returns this node's Genus.
LinkType
An unsigned char value that probably should be moved out of the Node base class.
A class for parsing and managing a function parameter list.
This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a...
NodeMapMap & getFunctionIndex()
Returns the function index.
const NodeMultiMap & getClassMap(const QString &key)
Find the key in the map of new class maps, and return a reference to the value, which is a NodeMap.
const NodeMultiMap & getQmlTypeMap(const QString &key)
Find the key in the map of new QML type maps, and return a reference to the value,...
void resolveNamespaces()
Multiple namespace nodes for namespace X can exist in the qdoc database in different trees.
TextToNodeMap & getLegaleseTexts()
Returns a reference to the collection of legalese texts.
QmlTypeNode * findQmlType(const QString &qmid, const QString &name)
Returns the QML type node identified by the QML module id qmid and QML type name, or nullptr if no ty...
NodeMultiMap & getAttributions()
Returns a reference to the multimap of attribution nodes.
static void destroyQdocDB()
Destroys the singleton.
NodeMultiMap & getQmlTypesWithObsoleteMembers()
Returns a reference to the map of QML types with obsolete members.
NodeMultiMap & getObsoleteQmlTypes()
Returns a reference to the map of obsolete QML types.
static QDocDatabase * qdocDB()
Creates the singleton.
void resolveBaseClasses()
NodeMultiMap & getQmlTypes()
Returns a reference to the multimap of QML types.
NodeMultiMap & getClassesWithObsoleteMembers()
Returns a reference to the map of C++ classes with obsolete members.
QmlTypeNode * findQmlType(const ImportRec &import, const QString &name)
Returns the QML type node identified by the QML module id constructed from the strings in the import ...
NodeMultiMap & getQmlValueTypes()
Returns a reference to the map of QML basic types.
NodeMultiMap & getCppClasses()
Returns a reference to the map of all C++ classes.
QStringList groupNamesForNode(Node *node)
NamespaceNode * primaryTreeRoot()
Returns a pointer to the root node of the primary tree.
void readIndexes(const QStringList &indexFiles)
Reads and parses the qdoc index files listed in indexFiles.
const Node * findNodeForTarget(const QString &target, const Node *relative)
Finds the node that will generate the documentation that contains the target and returns a pointer to...
NodeMultiMap & getNamespaces()
Returns a reference to the namespace map.
QmlTypeNode * findQmlTypeInPrimaryTree(const QString &qmid, const QString &name)
Returns the QML node identified by the QML module id qmid and name, searching in the primary tree onl...
const NodeMultiMap & getSinceMap(const QString &key)
Find the key in the map of new {since} maps, and return a reference to the value, which is a NodeMult...
const Node * findNodeForAtom(const Atom *atom, const Node *relative, QString &ref, Node::Genus genus=Node::DontCare)
Searches for the node that matches the path in atom and the specified genus.
NodeMultiMap & getExamples()
Returns a reference to the multimap of example nodes.
void processForest()
This function calls a set of functions for each tree in the forest that has not already been analyzed...
void updateNavigation()
Updates navigation (previous/next page links and the navigation parent) for pages listed in the TOC,...
void resolveStuff()
Performs several housekeeping tasks prior to generating the documentation.
void generateIndex(const QString &fileName, const QString &url, const QString &title, Generator *g)
Generates a qdoc index file and write it to fileName.
NodeMultiMap & getObsoleteClasses()
Returns a reference to the map of obsolete C++ clases.
const CollectionNode * getModuleNode(const Node *relative)
Returns the collection node representing the module that relative node belongs to,...
void resolveProxies()
Each instance of class Tree that represents an index file must be traversed to find all instances of ...
void mergeCollections(Node::NodeType type, CNMap &cnm, const Node *relative)
Finds all the collection nodes of the specified type and merges them into the collection node map cnm...
void mergeCollections(CollectionNode *c)
Finds all the collection nodes with the same name and type as c and merges their members into the mem...
const FunctionNode * findFunctionNode(const QString &target, const Node *relative, Node::Genus genus)
Finds the function node for the qualified function path in target and returns a pointer to it.
const Node * findTypeNode(const QString &type, const Node *relative, Node::Genus genus)
This function is called for autolinking to a type, which could be a function return type or a paramet...
A class representing a forest of Tree objects.
This class handles qdoc index files.
This class constructs and maintains a tree of instances of the subclasses of Node.
void markDontDocumentNodes()
The {don't document} map has been loaded with the names of classes and structs in the current module ...
#define CONFIG_NOLINKERRORS
#define CONFIG_NAVIGATION
QMultiMap< QString, CollectionNode * > CNMultiMap
QMap< QString, NodeMultiMap > NodeMultiMapMap
QMap< QString, Node * > NodeMap
QMap< QString, NodeMap > NodeMapMap
QMap< QString, CollectionNode * > CNMap
static NodeMultiMap emptyNodeMultiMap_
QT_BEGIN_NAMESPACE typedef QMultiMap< Text, const Node * > TextToNodeMap
A record of a linkable target within the documentation.
TargetType
A type of a linkable target record.