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
656 const QString qmName = record.m_importUri.isEmpty() ?
657 record.m_moduleName : record.m_importUri;
658 const QStringList dotSplit{name.split(QLatin1Char(
'.'))};
659 for (
const auto &namePart : dotSplit) {
660 if (
auto *qcn = m_forest.lookupQmlType(qmName + u"::"_s + namePart); qcn)
668
669
670
671
672
673
677 return primaryTree()->lookupQmlType(qmid + u"::"_s + name);
682
683
684
685
686
687
700
701
702
703
704
707 Tree *t = m_forest.firstTree();
709 if (!m_completedFindFunctions.values(t).contains(func)) {
710 (
this->*(func))(t->root());
711 m_completedFindFunctions.insert(t, func);
713 t = m_forest.nextTree();
718
719
723 return m_legaleseTexts;
727
728
732 return s_classesWithObsoleteMembers;
736
737
741 return s_obsoleteQmlTypes;
745
746
750 return s_qmlTypesWithObsoleteMembers;
754
755
759 return s_qmlBasicTypes;
763
764
772
773
781
782
786 return m_attributions;
790
791
795 return s_obsoleteClasses;
799
800
808
809
810
814 return m_functionIndex;
818
819
820
823 for (
const auto &childNode : node->childNodes()) {
824 if (childNode->isPrivate())
826 if (!childNode->doc().legaleseText().isEmpty())
827 m_legaleseTexts.insert(childNode->doc().legaleseText(), childNode);
828 if (childNode->isAggregate())
829 findAllLegaleseTexts(
static_cast<Aggregate *>(childNode));
834
835
836
837
838
839
842
843
844
845
846
847
848
849
850
853
854
855
856
860 auto it = s_newClassMaps.constFind(key);
865
866
867
868
872 auto it = s_newQmlTypeMaps.constFind(key);
877
878
879
880
884 auto it = s_newSinceMaps.constFind(key);
889
890
891
892
895 const auto &config = Config::instance();
896 if (config.dualExec() || config.preparing()) {
911 if (config.singleExec() && config.generating()) {
918 if (!config.preparing()) {
924 if (config.dualExec())
930 Tree *t = m_forest.firstTree();
932 t->resolveBaseClasses(t->root());
933 t = m_forest.nextTree();
938
939
940
941
942
946 return m_namespaceIndex;
950
951
952
953
954
955
956
959 if (!m_namespaceIndex.isEmpty())
964 Tree *t = m_forest.firstTree();
967 t = m_forest.nextTree();
969 const QList<QString> keys = namespaceMultimap.uniqueKeys();
970 for (
const QString &key : keys) {
971 NamespaceNode *ns =
nullptr;
972 NamespaceNode *indexNamespace =
nullptr;
973 const NodeList namespaces = namespaceMultimap.values(key);
974 qsizetype count = namespaceMultimap.remove(key);
976 for (
auto *node : namespaces) {
977 ns =
static_cast<NamespaceNode *>(node);
978 if (ns->isDocumentedHere())
980 else if (ns->hadDoc())
985 for (
auto *node : namespaces) {
986 auto *nsNode =
static_cast<NamespaceNode *>(node);
987 if (nsNode->hadDoc() && nsNode != ns) {
988 ns->doc().location().warning(
989 QStringLiteral(
"Namespace %1 documented more than once")
990 .arg(nsNode->name()), QStringLiteral(
"also seen here: %1")
991 .arg(nsNode->doc().location().toString()));
994 }
else if (!indexNamespace) {
999 for (
auto *node : namespaces) {
1000 if (!node->isIndexNode())
1001 static_cast<NamespaceNode *>(node)->reportDocumentedChildrenInUndocumentedNamespace();
1005 for (
auto *node : namespaces) {
1006 auto *nsNode =
static_cast<NamespaceNode *>(node);
1007 if (nsNode != indexNamespace)
1008 nsNode->setDocNode(indexNamespace);
1013
1014
1015
1016
1017
1018 if (ns && count > 1) {
1019 for (
auto *node : namespaces) {
1020 auto *nameSpaceNode =
static_cast<NamespaceNode *>(node);
1021 if (nameSpaceNode != ns) {
1022 for (
auto it = nameSpaceNode->constBegin(); it != nameSpaceNode->constEnd();
1024 Node *anotherNs = *it;
1025 if (anotherNs && anotherNs->isPublic() && !anotherNs->isInternal())
1026 ns->includeChild(anotherNs);
1032
1033
1034
1036 ns = indexNamespace ? indexNamespace :
static_cast<NamespaceNode *>(namespaces.last());
1037 m_namespaceIndex.insert(ns->name(), ns);
1042
1043
1044
1045
1046
1047
1048
1049
1050
1055 Tree *t = m_forest.firstTree();
1056 t = m_forest.nextTree();
1059 if (!proxies.isEmpty()) {
1060 for (
auto *node : proxies) {
1061 const auto *pn =
static_cast<ProxyNode *>(node);
1062 if (pn->count() > 0) {
1063 Aggregate *aggregate = primaryTree()->findAggregate(pn->name());
1064 if (aggregate !=
nullptr)
1065 aggregate->appendToRelatedByProxy(pn->childNodes());
1069 t = m_forest.nextTree();
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1090 QString function = target;
1091 qsizetype length = target.size();
1092 if (function.endsWith(
"()"))
1094 if (function.endsWith(QChar(
')'))) {
1095 qsizetype position = function.lastIndexOf(QChar(
'('));
1096 signature = function.mid(position + 1, length - position - 2);
1097 function = function.left(position);
1099 QStringList path = function.split(
"::");
1100 return m_forest.findFunctionNode(path, Parameters(signature), relative, genus);
1104
1105
1106
1107
1108
1109
1110
1111
1112
1115 QStringList path = type.split(
"::");
1116 if ((path.size() == 1) && (path.at(0)[0].isLower() || path.at(0) == QString(
"T"))) {
1117 auto it = s_typeNodeMap.find(path.at(0));
1118 if (it != s_typeNodeMap.end())
1121 return m_forest.findTypeNode(path, relative, genus);
1125
1126
1127
1128
1129
1132 const Node *node =
nullptr;
1133 if (target.isEmpty())
1135 else if (target.endsWith(
".html"))
1136 node = findNodeByNameAndType(QStringList(target), &Node::isPageNode);
1138 QStringList path = target.split(
"::");
1140 for (
const auto *tree : searchOrder()) {
1141 const Node *n = tree->findNode(path, relative, flags, Node::DontCare);
1146 node = findPageNodeByTitle(target);
1159 for (
auto it = m->cbegin(); it != m->cend(); ++it)
1160 if (it.value()->members().contains(node))
1167
1168
1171 QStringList filesToRead;
1172 for (
const QString &file : indexFiles) {
1173 QString fn = file.mid(file.lastIndexOf(QChar(
'/')) + 1);
1175 filesToRead << file;
1177 qCCritical(lcQdoc) <<
"Index file" << file <<
"is already in memory.";
1183
1184
1185
1186
1190 QString t = fileName.mid(fileName.lastIndexOf(QChar(
'/')) + 1);
1192 QDocIndexFiles::qdocIndexFiles()->generateIndex(fileName, url, title, g);
1197
1198
1199
1200
1209 moduleName = relative->physicalModuleName();
1213 moduleName = relative->logicalModuleName();
1218 if (moduleName.isEmpty())
1221 return primaryTree()->getCollection(moduleName, moduleType);
1225
1226
1227
1228
1233 for (
auto *tree : searchOrder()) {
1234 CNMap *m = tree->getCollectionMap(type);
1235 if (m && !m->isEmpty()) {
1236 for (
auto it = m->cbegin(); it != m->cend(); ++it) {
1237 if (!it.value()->isInternal())
1238 cnmm.insert(it.key(), it.value());
1244 static const QRegularExpression singleDigit(
"\\b([0-9])\\b");
1245 const QStringList keys = cnmm.uniqueKeys();
1246 for (
const auto &key : keys) {
1247 const QList<CollectionNode *> values = cnmm.values(key);
1248 CollectionNode *n =
nullptr;
1249 for (
auto *value : values) {
1250 if (value && value->wasSeen() && value != relative) {
1256 if (values.size() > 1) {
1257 for (CollectionNode *value : values) {
1260 if ((n->isQmlModule())
1261 && n->logicalModuleIdentifier() != value->logicalModuleIdentifier()) {
1262 if (value->wasSeen() && value != relative)
1263 cnm.insert(value->fullTitle().toLower(), value);
1266 for (Node *t : value->members())
1271 QString sortKey = n->fullTitle().toLower();
1272 if (sortKey.startsWith(
"the "))
1273 sortKey.remove(0, 4);
1274 sortKey.replace(singleDigit,
"0\\1");
1275 cnm.insert(sortKey, n);
1281
1282
1283
1284
1285
1286
1287
1288
1333 for (
auto *tree : searchOrder()) {
1334 CollectionNode *cn = tree->getCollection(c->name(), c->nodeType());
1335 if (cn && cn != c) {
1336 if ((cn->isQmlModule())
1337 && cn->logicalModuleIdentifier() != c->logicalModuleIdentifier())
1340 for (
auto *node : cn->members())
1400 if (!c->wasSeen() && cn->wasSeen()) {
1402 c->setTitle(cn->title());
1403 c->setUrl(cn->url());
1412
1413
1414
1415
1416
1417
1418
1419
1423 const Node *node =
nullptr;
1425 Atom *atom =
const_cast<
Atom *>(a);
1426 QStringList targetPath = atom->string().split(QLatin1Char(
'#'));
1427 QString first = targetPath.first().trimmed();
1429 Tree *domain =
nullptr;
1436 if (first.isEmpty())
1439 if (first.endsWith(
".html"))
1440 node = domain->findNodeByNameAndType(QStringList(first), &
Node::isPageNode);
1441 else if (first.endsWith(QChar(
')'))) {
1443 QString function = first;
1444 qsizetype length = first.size();
1445 if (function.endsWith(
"()"))
1447 if (function.endsWith(QChar(
')'))) {
1448 qsizetype position = function.lastIndexOf(QChar(
'('));
1449 signature = function.mid(position + 1, length - position - 2);
1450 function = function.left(position);
1452 QStringList path = function.split(
"::");
1453 node = domain->findFunctionNode(path,
Parameters(signature),
nullptr, genus);
1455 if (node ==
nullptr) {
1457 QStringList nodePath = first.split(
"::");
1459 targetPath.removeFirst();
1460 if (!targetPath.isEmpty())
1461 target = targetPath.takeFirst();
1462 if (relative && relative
->tree()->physicalModuleName() != domain->physicalModuleName())
1464 return domain->findNodeForTarget(nodePath, target, relative, flags, genus, ref);
1467 if (first.endsWith(
".html"))
1468 node = findNodeByNameAndType(QStringList(first), &Node::isPageNode);
1469 else if (first.endsWith(QChar(
')')))
1470 node = findFunctionNode(first, relative, genus);
1471 if (node ==
nullptr)
1472 return findNodeForTarget(targetPath, relative, genus, ref);
1475 if (node !=
nullptr && ref.isEmpty()) {
1476 if (!node->url().isEmpty())
1478 targetPath.removeFirst();
1479 if (!targetPath.isEmpty()) {
1489
1490
1491
1492
1493
1494
1495
1496
1500 QList<Tree *> searchOrder =
this->searchOrder();
1519 bool inclusive{Config::instance().get(
1523 const auto tocTitles{Config::instance().get(configVar).asStringList()};
1525 for (
const auto &tocTitle : tocTitles) {
1526 if (
const auto candidateTarget = findNodeForTarget(tocTitle,
nullptr); candidateTarget && candidateTarget->isPageNode()) {
1527 auto tocPage{
static_cast<
const PageNode*>(candidateTarget)};
1529 Text body = tocPage->doc().body();
1531 auto *atom = body.firstAtom();
1533 std::pair<PageNode *, Atom *> prev {
nullptr,
nullptr };
1535 std::stack<
const PageNode *> tocStack;
1536 tocStack.push(inclusive ? tocPage :
nullptr);
1538 bool inItem =
false;
1545 switch (atom->type()) {
1546 case Atom::ListItemLeft:
1548 tocStack.push(
nullptr);
1551 case Atom::ListItemRight:
1591 auto candidatePage =
const_cast<Node *>(findNodeForAtom(atom,
nullptr, unused));
1592 if (!candidatePage || !candidatePage->isPageNode())
break;
1594 auto page{
static_cast<PageNode*>(candidatePage)};
1597 if (page == prev.first)
break;
1600 prev.first->setLink(
1641 prev.first->title(),
1643 prev.second->linkText()
1647 if (page == tocPage)
1652 qsizetype popped = 0;
1653 while (tocStack.size() > 1 && !tocStack.top()) {
1658 page->setNavigationParent(tocStack.empty() ?
nullptr : tocStack.top());
1660 while (--popped > 0)
1661 tocStack.push(
nullptr);
1663 tocStack.push(page);
1664 prev = { page, atom };
1671 atom = atom->next();
1674 Config::instance().get(configVar).location()
1675 .warning(QStringLiteral(
"Failed to find table of contents with title '%1'")
1681 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.