23using namespace Qt::StringLiterals;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
43
44
45
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
65
66
67
68
69
70
71
73 : m_camelCaseModuleName(camelCaseModuleName),
74 m_physicalModuleName(camelCaseModuleName.toLower()),
76 m_root(
nullptr, QString())
78 m_root.setPhysicalModuleName(m_physicalModuleName);
83
84
85
86
87
88
89
90
91
92
95 qDeleteAll(m_nodesByTargetRef);
96 m_nodesByTargetRef.clear();
97 m_nodesByTargetTitle.clear();
103
104
105
106
107
108Node *
Tree::findNodeForInclude(
const QStringList &path)
const
110 Node *n = findClassNode(path);
112 n = findNamespaceNode(path);
117
118
119
120
121
122
123
126 QStringList path = name.split(QLatin1String(
"::"));
127 return static_cast<Aggregate *>(findNodeRecursive(path, 0,
const_cast<NamespaceNode *>(root()),
128 &Node::isFirstClassAggregate));
132
133
134
135
136
139 if (start ==
nullptr)
141 return static_cast<ClassNode *>(findNodeRecursive(path, 0, start, &Node::isClassNode));
145
146
147
148
152 return static_cast<NamespaceNode *>(findNodeRecursive(path, 0, start, &Node::isNamespace));
156
157
158
159
160
161
162
163
164
165
166
169 Node *n = findNodeRecursive(path, 0, root(), &Node::isRelatableType);
170 return (((n !=
nullptr) && n->isAggregate()) ?
static_cast<Aggregate *>(n) :
nullptr);
174
175
176
177void Tree::addPropertyFunction(
PropertyNode *property,
const QString &funcName,
180 m_unresolvedPropertyMap[property].insert(funcRole, funcName);
184
185
186
187
188
189
190
193 for (
auto it = n->constBegin(); it != n->constEnd(); ++it) {
194 if ((*it)->isClassNode()) {
195 auto *cn =
static_cast<
ClassNode *>(*it);
196 QList<RelatedClass> &bases = cn->baseClasses_mutable();
197 for (
auto &base : bases) {
198 if (base.m_node ==
nullptr) {
199 Node *n = m_qdb->findClassNode(base.m_path);
201
202
203
204
205
206
207
208
209
211 Aggregate *parent = cn->parent();
212 if (parent !=
nullptr)
214 if (parent->isNamespace() && !parent->name().isEmpty())
215 n = findClassNode(base.m_path, parent);
218 auto *bcn =
static_cast<ClassNode *>(n);
220 bcn->addDerivedClass(base.m_access, cn);
224 resolveBaseClasses(cn);
225 }
else if ((*it)->isNamespace()) {
232
235 for (
auto node = n->constBegin(); node != n->constEnd(); ++node) {
236 if ((*node)->isClassNode()) {
237 auto *cn =
static_cast<
ClassNode *>(*node);
238 for (
auto property = cn->constBegin(); property != cn->constEnd(); ++property) {
239 if ((*property)->isProperty())
240 cn->resolvePropertyOverriddenFromPtrs(
static_cast<
PropertyNode *>(*property));
242 resolvePropertyOverriddenFromPtrs(cn);
243 }
else if ((*node)->isNamespace()) {
244 resolvePropertyOverriddenFromPtrs(
static_cast<
NamespaceNode *>(*node));
250
251
252
253
254
255void Tree::resolveProperties()
257 for (
auto propEntry = m_unresolvedPropertyMap.constBegin();
258 propEntry != m_unresolvedPropertyMap.constEnd(); ++propEntry) {
267 for (
auto it = parent->constBegin(); it != parent->constEnd(); ++it) {
268 if ((*it)->isFunction()) {
270 if (function->access() == property
->access()
271 && (function->status() == property
->status() || function->doc().isEmpty())) {
272 if (function->name() == getterName) {
274 }
else if (function->name() == setterName) {
276 }
else if (function->name() == resetterName) {
278 }
else if (function->name() == notifierName) {
280 }
else if (function->name() == bindableName) {
288 for (
auto propEntry = m_unresolvedPropertyMap.constBegin();
289 propEntry != m_unresolvedPropertyMap.constEnd(); ++propEntry) {
296 m_unresolvedPropertyMap.clear();
300
301
302
303
304
305
306
307
308
309
310
311void Tree::validatePropertyDocumentation(
const Aggregate *aggregate)
const
313 const auto &config = Config::instance();
314 const InclusionPolicy policy = config.createInclusionPolicy();
315 validatePropertyDocumentation(aggregate, policy);
319
320
321
322
323
324
325void Tree::validatePropertyDocumentation(
const Aggregate *aggregate,
const InclusionPolicy &policy)
const
327 for (
auto it = aggregate->constBegin(); it != aggregate->constEnd(); ++it) {
333 node
->location().warning(u"Undocumented property '%1'"_s.arg(node->plainFullName()));
337 validatePropertyDocumentation(
static_cast<Aggregate *>(node), policy);
342
343
344
345
346void Tree::resolveCppToQmlLinks()
349 const NodeList &children = m_root.childNodes();
350 for (
auto *child : children) {
351 if (child->isQmlType()) {
352 auto *qcn =
static_cast<QmlTypeNode *>(child);
353 auto *cn =
const_cast<ClassNode *>(qcn->classNode());
355 cn->insertQmlNativeType(qcn);
361
362
363
364
365
366
367
368
371 for (
auto *child : aggregate.childNodes()) {
374 if (child->isEnumType())
375 resolveEnumValueSince(
static_cast<EnumNode&>(*child));
376 if (!child->isAggregate())
378 if (!child->since().isEmpty())
381 if (
const auto collectionNode = m_qdb->getModuleNode(child))
382 child->setSince(collectionNode->since());
384 resolveSince(
static_cast<Aggregate&>(*child));
389
390
391
392
393
394
395
396
399 const QStringList enumItems{en
.doc().enumItemNames()};
400 const Atom *atom = en
.doc().body().firstAtom();
406 if (
const auto &val = atom->string(); enumItems.contains(val)) {
414
415
416
417
418
419
420
421
424 if (rootNode ==
nullptr)
427 for (
auto node = rootNode->constBegin(); node != rootNode->constEnd(); ++node) {
428 if ((*node)->isClassNode())
430 else if ((*node)->isNamespace())
431 removePrivateAndInternalBases(
static_cast<
NamespaceNode *>(*node));
436
440 const auto &baseClasses = classNode->baseClasses();
441 for (
const auto &relatedClass : baseClasses) {
442 if (relatedClass.m_node !=
nullptr) {
443 result += relatedClass.m_node;
444 result += allBaseClasses(relatedClass.m_node);
451
452
453
454
455
456
459 return findNodeRecursive(path, 0, root(), isMatch);
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478Node *
Tree::findNodeRecursive(
const QStringList &path,
int pathIndex,
const Node *start,
479 bool (Node::*isMatch)()
const)
const
481 if (start ==
nullptr || path.isEmpty())
483 Node *node =
const_cast<
Node *>(start);
485 return ((pathIndex >= path.size()) ? node :
nullptr);
486 auto *current =
static_cast<Aggregate *>(node);
487 const NodeList &children = current->childNodes();
488 const QString &name = path.at(pathIndex);
489 for (
auto *node : children) {
492 if (node->name() == name) {
493 if (pathIndex + 1 >= path.size()) {
494 if ((node->*(isMatch))())
498 node = findNodeRecursive(path, pathIndex + 1, node, isMatch);
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523const Node *
Tree::findNodeForTarget(
const QStringList &path,
const QString &target,
524 const Node *start,
int flags, Genus genus,
527 const Node *node =
nullptr;
531 auto set_ref_from_target = [
this, &ref, &target](
const Node *n) ->
const Node* {
532 if (!target.isEmpty()) {
533 if (ref = getRef(target, n); ref.isEmpty())
539 if (genus == Genus::DontCare || genus == Genus::DOC) {
540 if (node = findPageNodeByTitle(path.at(0)); node) {
541 if (node = set_ref_from_target(node); node)
547
548
549
550
551
552 const bool prioritizeHierarchy = start &&
553 ((start
->isClassNode() && (genus == Genus::CPP || genus == Genus::DontCare)) ||
554 (start
->isQmlType() && (genus == Genus::QML || genus == Genus::DontCare)));
557 if (!prioritizeHierarchy) {
558 result = findUnambiguousTarget(path.join(QLatin1String(
"::")), genus);
561 if (node = set_ref_from_target(result
->m_node); node) {
574 const Node *current = start ? start : root();
576
577
578
579
580
582 if ((genus == Genus::QML || genus == Genus::DontCare)
583 && path.size() >= 2 && !path[0].isEmpty()) {
584 if (
auto *qcn = lookupQmlType(path.sliced(0, 2).join(QLatin1String(
"::")), start); qcn) {
587 if (path.size() == 2)
588 return set_ref_from_target(qcn);
595 if (
const Node *match = matchPathAndTarget(
596 path, path_idx, target, current, flags, genus, ref);
605 if (prioritizeHierarchy) {
606 result = findUnambiguousTarget(path.join(QLatin1String(
"::")), genus);
609 if (node = set_ref_from_target(result
->m_node); node) {
617 if (node && result) {
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646const Node *
Tree::matchPathAndTarget(
const QStringList &path,
int idx,
const QString &target,
647 const Node *node,
int flags, Genus genus,
648 QString &ref,
int duplicates)
const
651
652
653
654
655 if (idx == path.size()) {
656 if (!target.isEmpty()) {
657 ref = getRef(target, node);
682 QString name = path.at(idx);
685 static_cast<
const Aggregate *>(node)->findChildren(name, nodes);
686 for (
const auto *child : std::as_const(nodes)) {
687 if (genus != Genus::DontCare && !(hasCommonGenusType(genus, child->genus())))
689 const Node *t = matchPathAndTarget(path, idx + 1, target, child, flags, genus, ref, nodes.count() - 1);
690 if (t && !t->isPrivate() && !t->isInternal())
695 const auto *enumNode = node->isAggregate() ?
696 findEnumNode(
nullptr, node, path, idx) :
697 findEnumNode(node,
nullptr, path, idx);
701 if (((genus == Genus::CPP) || (genus == Genus::DontCare)) && node
->isClassNode()
703 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(node));
704 for (
const auto *base : bases) {
705 const Node *t = matchPathAndTarget(path, idx, target, base, flags, genus, ref);
706 if (t && !t->isPrivate() && !t->isInternal())
708 if (target.isEmpty() && (flags & SearchEnumValues)) {
709 if ((t = findEnumNode(base->findChildNode(path.at(idx), genus, flags), base, path, idx)))
714 if (((genus == Genus::QML) || (genus == Genus::DontCare)) && node
->isQmlType()
716 const QmlTypeNode *qtn =
static_cast<
const QmlTypeNode *>(node);
719 const Node *t = matchPathAndTarget(path, idx, target, qtn, flags, genus, ref);
728
729
730
731
732
733const Node *
Tree::findNode(
const QStringList &path,
const Node *start,
int flags,
736 const Node *current = start;
737 if (current ==
nullptr)
741 const Node *node = current;
746
747
748
749
750
751
752
753 if (((genus == Genus::QML) || (genus == Genus::DontCare)) && (path.size() >= 2)
754 && !path[0].isEmpty()) {
755 QmlTypeNode *qcn = lookupQmlType(QString(path[0] +
"::" + path[1]), start);
756 if (qcn !=
nullptr) {
758 if (path.size() == 2)
764 for (i = start_idx; i < path.size(); ++i) {
773 const Node *next =
static_cast<
const Aggregate *>(node)->findChildNode(path.at(i),
775 const Node *enumNode = (flags & SearchEnumValues) ?
776 findEnumNode(next, node, path, i) :
nullptr;
782 if (!next && ((genus == Genus::CPP) || (genus == Genus::DontCare))
784 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(node));
785 for (
const auto *base : bases) {
786 next = base->findChildNode(path.at(i), genus, tmpFlags);
787 if (flags & SearchEnumValues)
788 if ((enumNode = findEnumNode(next, base, path, i)))
794 if (!next && ((genus == Genus::QML) || (genus == Genus::DontCare))
796 const QmlTypeNode *qtn =
static_cast<
const QmlTypeNode *>(node);
799 next = qtn->findChildNode(path.at(i), genus, tmpFlags);
804 if ((node !=
nullptr) && i == path.size())
807 }
while (current !=
nullptr);
814
815
816
817
818
819
820
821const Node *
Tree::findEnumNode(
const Node *node,
const Node *aggregate,
const QStringList &path,
int offset)
const
825 const auto *en =
static_cast<
const EnumNode*>(node);
826 if (en->hasItem(path.last()))
831 return (!node && aggregate && offset == path.size() - 1) ?
832 static_cast<
const Aggregate *>(aggregate)->findEnumNodeForValue(path.last()) :
837
838
839
840
841
842QString
Tree::getRef(
const QString &target,
const Node *node)
const
844 auto it = m_nodesByTargetTitle.constFind(target);
845 if (it != m_nodesByTargetTitle.constEnd()) {
847 if (it.value()->m_node == node)
848 return it.value()->m_ref;
850 }
while (it != m_nodesByTargetTitle.constEnd() && it.key() == target);
852 QString key = Utilities::asAsciiPrintable(target);
853 it = m_nodesByTargetRef.constFind(key);
854 if (it != m_nodesByTargetRef.constEnd()) {
856 if (it.value()->m_node == node)
857 return it.value()->m_ref;
859 }
while (it != m_nodesByTargetRef.constEnd() && it.key() == key);
865
866
867
868
869
871 Node *node,
int priority)
873 auto *target =
new TargetRec(name, type, node, priority);
874 m_nodesByTargetRef.insert(name, target);
875 m_nodesByTargetTitle.insert(title, target);
879
880
881
882
883
884
885
888 for (
auto *child : root->childNodes()) {
889 addToPageNodeByTitleMap(child);
890 populateTocSectionTargetMap(child);
891 addKeywordsToTargetMaps(child);
892 addTargetsToTargetMap(child);
894 if (child->isAggregate())
895 resolveTargets(
static_cast<Aggregate *>(child));
900
901
902
903
904void Tree::addTargetsToTargetMap(
Node *node) {
908 for (Atom *i : std::as_const(node->doc().targets())) {
909 const QString ref = refForAtom(i);
910 const QString title = i->string();
911 if (!ref.isEmpty() && !title.isEmpty()) {
912 QString key = Utilities::asAsciiPrintable(title);
913 auto *target =
new TargetRec(std::move(ref), TargetRec::Target, node, 2);
914 m_nodesByTargetRef.insert(key, target);
915 m_nodesByTargetTitle.insert(title, target);
921
922
923
924
933
934
935
936
937void Tree::addKeywordsToTargetMaps(
Node *node) {
941 for (Atom *i : std::as_const(node->doc().keywords())) {
942 QString ref = refForAtom(i);
943 QString title = i->string();
944 if (!ref.isEmpty() && !title.isEmpty()) {
945 auto *target =
new TargetRec(ref, nextSection(i) ? TargetRec::ContentsKeyword : TargetRec::Keyword, node, 1);
946 m_nodesByTargetRef.insert(Utilities::asAsciiPrintable(title), target);
947 m_nodesByTargetTitle.insert(title, target);
948 if (!target->isEmpty())
949 i->append(target->m_ref);
955
956
957
958
959
960void Tree::populateTocSectionTargetMap(
Node *node) {
964 QStack<Atom *> tocLevels;
965 QSet<QString> anchors;
969 for (Atom *atom: std::as_const(node->doc().tableOfContents())) {
970 while (!tocLevels.isEmpty() && tocLevels.top()->string().toInt() >= atom->string().toInt())
973 tocLevels.push(atom);
975 QString ref = refForAtom(atom);
976 const QString &title = Text::sectionHeading(atom).toString();
977 if (ref.isEmpty() || title.isEmpty())
980 if (anchors.contains(ref)) {
981 QStringList refParts;
982 for (
const auto tocLevel : tocLevels)
983 refParts << refForAtom(tocLevel);
985 refParts << QString::number(index);
986 ref = refParts.join(QLatin1Char(
'-'));
990 if (atom->next(Atom::SectionHeadingLeft))
991 atom->next()->append(ref);
994 const QString &key = Utilities::asAsciiPrintable(title);
995 auto *target =
new TargetRec(ref, TargetRec::Contents, node, 3);
996 m_nodesByTargetRef.insert(key, target);
997 m_nodesByTargetTitle.insert(title, target);
1002
1003
1004
1005
1006
1007void Tree::addToPageNodeByTitleMap(
Node *node) {
1011 auto *pageNode =
static_cast<PageNode *>(node);
1012 QString key = pageNode->title();
1016 if (key.contains(QChar(
' ')))
1017 key = Utilities::asAsciiPrintable(key);
1018 const QList<PageNode *> nodes = m_pageNodesByTitle.values(key);
1020 bool alreadyThere =
std::any_of(nodes.cbegin(), nodes.cend(), [&](
const auto &knownNode) {
1021 return knownNode->isExternalPage() && knownNode->name() == pageNode->name();
1025 m_pageNodesByTitle.insert(key, pageNode);
1029
1030
1031
1032const TargetRec *
Tree::findUnambiguousTarget(
const QString &target, Genus genus)
const
1034 auto findBestCandidate = [&](
const TargetMap &tgtMap,
const QString &key) {
1036 auto [it, end] = tgtMap.equal_range(key);
1039 if ((genus == Genus::DontCare) || (hasCommonGenusType(genus, candidate
->genus()))) {
1048 TargetRec *bestTarget = findBestCandidate(m_nodesByTargetTitle, target);
1050 bestTarget = findBestCandidate(m_nodesByTargetRef, Utilities::asAsciiPrintable(target));
1056
1057
1058const PageNode *
Tree::findPageNodeByTitle(
const QString &title)
const
1060 PageNodeMultiMap::const_iterator it;
1061 if (title.contains(QChar(
' ')))
1062 it = m_pageNodesByTitle.constFind(Utilities::asAsciiPrintable(title));
1064 it = m_pageNodesByTitle.constFind(title);
1065 if (it != m_pageNodesByTitle.constEnd()) {
1067
1068
1069
1070
1071 PageNodeMultiMap::const_iterator j = it;
1073 if (j != m_pageNodesByTitle.constEnd() && j.key() == it.key()) {
1074 while (j != m_pageNodesByTitle.constEnd()) {
1075 if (j.key() == it.key() && j.value()->url().isEmpty()) {
1080 if (j != m_pageNodesByTitle.cend()) {
1081 it.value()->location().warning(
"This page title exists in more than one file: "
1083 j.value()->location().warning(
"[It also exists here]");
1092
1093
1094
1095
1096
1097
1107 if (atom->count() == 2)
1108 return atom->string(1);
1113 if (
const auto *section = nextSection(atom))
1114 return refForAtom(section);
1115 return Utilities::asAsciiPrintable(atom->string());
1122
1123
1124
1125
1128
1129
1130
1131
1134
1135
1136
1137
1140
1141
1142
1151 return &m_qmlModules;
1159
1160
1161
1162
1163
1166 CNMap *map = getCollectionMap(type);
1168 auto it = map->constFind(name);
1169 if (it != map->cend())
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1191 CNMap *m = getCollectionMap(type);
1194 auto it = m->constFind(name);
1195 if (it != m->cend())
1199 m->insert(name, cn);
1204
1205
1206
1207
1208
1209
1210
1213
1214
1215
1216
1217
1218
1219
1222
1223
1224
1225
1226
1227
1228
1231
1232
1233
1234
1235
1236
1239
1240
1241
1242
1243
1244
1247
1248
1249
1250
1251
1252
1255
1256
1257
1258
1259
1260
1261
1262
1268 node->appendGroupName(name);
1274
1275
1276
1277
1278
1279
1284 node->setPhysicalModuleName(name);
1289
1290
1291
1292
1293
1297 QStringList dotSplit;
1298 QStringList blankSplit = name.split(QLatin1Char(
' '));
1299 qmid.append(blankSplit[0]);
1300 if (blankSplit.size() > 1) {
1301 qmid.append(blankSplit[0] + blankSplit[1]);
1302 dotSplit = blankSplit[1].split(QLatin1Char(
'.'));
1303 qmid.append(blankSplit[0] + dotSplit[0]);
1310 QmlTypeNode *n =
static_cast<QmlTypeNode *>(node);
1311 for (
int i = 0; i < qmid.size(); ++i) {
1312 QString key = qmid[i] +
"::" + node->name();
1313 insertQmlType(key, n);
1316 insertQmlType(node->name(), n);
1322
1323
1324
1325
1328 m_qmlTypeMap.insert(key, n);
1332
1333
1334
1335
1336
1339 auto values = m_qmlTypeMap.values(name);
1340 if (values.isEmpty())
1344 if (!relative || values.size() == 1)
1345 return values.first();
1349 const auto *relativeQmlType =
static_cast<
const QmlTypeNode *>(relative);
1350 const CollectionNode *relativeModule = relativeQmlType->logicalModule();
1352 for (
auto *candidate : values) {
1353 if (candidate->logicalModule() == relativeModule)
1359 return values.first();
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1375 const Node *relative, Genus genus)
const
1377 if (path.size() == 3 && !path[0].isEmpty()
1378 && ((genus == Genus::QML) || (genus == Genus::DontCare))) {
1379 QmlTypeNode *qcn = lookupQmlType(QString(path[0] +
"::" + path[1]), relative);
1380 if (qcn ==
nullptr) {
1381 QStringList p(path[1]);
1382 Node *n = findNodeByNameAndType(p, &Node::isQmlType);
1383 if ((n !=
nullptr) && n->isQmlType())
1384 qcn =
static_cast<QmlTypeNode *>(n);
1390 if (relative ==
nullptr)
1392 else if (genus != Genus::DontCare) {
1393 if (!(hasCommonGenusType(genus, relative
->genus())))
1398 Node *node =
const_cast<
Node *>(relative);
1401 for (i = 0; i < path.size(); ++i) {
1405 Aggregate *aggregate =
static_cast<Aggregate *>(node);
1406 Node *next =
nullptr;
1407 if (i == path.size() - 1)
1410 next = aggregate->findChildNode(path.at(i), genus);
1413 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(aggregate));
1414 for (
auto *base : bases) {
1415 if (i == path.size() - 1)
1416 next = base->findFunctionChild(path.at(i), parameters);
1418 next = base->findChildNode(path.at(i), genus);
1420 if (next !=
nullptr)
1436 const FunctionNode *fn =
static_cast<
const FunctionNode *>(node);
1438 while (FN
->isPrivate() && !FN->overridesThis().isEmpty()) {
1439 QStringList path = FN->overridesThis().split(
"::");
1440 FN = m_qdb->findFunctionNode(path, parameters, relative, genus);
1454
1455
1456
1457
1460 if (parent ==
nullptr)
1463 for (Node *n : children) {
1464 if (n !=
nullptr && n->isFunction() && n->hasTag(tag))
1465 return static_cast<FunctionNode *>(n);
1467 for (Node *n : children) {
1468 if (n !=
nullptr && n->isAggregate()) {
1469 n = findFunctionNodeForTag(tag,
static_cast<Aggregate *>(n));
1471 return static_cast<FunctionNode *>(n);
1478
1479
1480
1483 if (parent ==
nullptr)
1486 for (Node *n : children) {
1487 if (n !=
nullptr && (n->isMacro() || n->isFunction()) && n->name() == t)
1488 return static_cast<FunctionNode *>(n);
1490 for (Node *n : children) {
1491 if (n !=
nullptr && n->isAggregate()) {
1492 FunctionNode *fn = findMacroNode(t,
static_cast<Aggregate *>(n));
1501
1502
1503
1506 arg.remove(QChar(
'('));
1507 arg.remove(QChar(
')'));
1508 QString t = arg.simplified();
1509 QStringList sl = t.split(QChar(
' '));
1512 for (
const QString &s : sl) {
1513 if (!m_dontDocumentMap.contains(s))
1514 m_dontDocumentMap.insert(s,
nullptr);
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1533 for (
auto it = m_dontDocumentMap.begin(); it != m_dontDocumentMap.end(); ++it) {
1534 Aggregate *node = findAggregate(it.key());
1535 if (node !=
nullptr)
FunctionNode * findFunctionChild(const FunctionNode *clone)
Returns the function node that is a child of this node, such that the function described has the same...
const NodeList & childNodes() const
Returns a const reference to the child list.
The Atom class is the fundamental unit for representing documents internally.
AtomType type() const
Return the type of this atom.
const Atom * next() const
Return the next atom in the atom list.
const Atom * next(AtomType t) const
Return the next Atom in the list if it is of AtomType t.
The ClassNode represents a C++ class.
void removePrivateAndInternalBases()
Remove private and internal bases classes from this class's list of base classes.
A class for holding the members of a collection of doc pages.
void addMember(Node *node) override
Appends node to the collection node's member list, if and only if it isn't already in the member list...
bool hasTableOfContents() const
This node is used to represent any kind of function being documented.
static bool requiresDocumentation(const InclusionPolicy &policy, const NodeContext &context)
This class represents a C++ namespace.
A PageNode is a Node that generates a documentation page.
This class describes one instance of using the Q_PROPERTY macro.
const PropertyNode * overriddenFrom() const
void addFunction(FunctionNode *function, FunctionRole role)
void setOverriddenFrom(const PropertyNode *baseProperty)
Sets this property's {overridden from} property to baseProperty, which indicates that this property o...
void addSignal(FunctionNode *function, FunctionRole role)
This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a...
Status
Specifies the status of the QQmlIncubator.
QmlTypeNode * qmlBaseNode() const override
If this Aggregate is a QmlTypeNode, this function returns a pointer to the QmlTypeNode that is its ba...
static Text sectionHeading(const Atom *sectionBegin)
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 ...
void addToDontDocumentMap(QString &arg)
Add the class and struct names in arg to the {don't document} map.
Node * findNodeByNameAndType(const QStringList &path, bool(Node::*isMatch)() const) const
Find the node with the specified path name that is of the specified type and subtype.
Combined button and popup list for selecting options.
QList< ClassNode * > ClassList
QList< Node * > NodeVector
QMap< QString, CollectionNode * > CNMap
The Node class is the base class for all the nodes in QDoc's parse tree.
const Doc & doc() const
Returns a reference to the node's Doc data member.
virtual bool isWrapper() const
Returns true if the node is a class node or a QML type node that is marked as being a wrapper class o...
bool isPrivate() const
Returns true if this node's access is Private.
virtual void setQmlModule(CollectionNode *)
If this is a QmlTypeNode, this function sets the QML type's QML module pointer to the CollectionNode ...
bool isQmlType() const
Returns true if the node type is QmlType or QmlValueType.
virtual bool isInternal() const
Returns true if the node's status is Internal, or if its parent is a class with Internal status.
Genus genus() const override
Returns this node's Genus.
bool isEnumType() const
Returns true if the node type is Enum.
virtual Status status() const
Returns the node's status value.
virtual bool isTextPageNode() const
Returns true if the node is a PageNode but not an Aggregate.
virtual bool isAttached() const
Returns true if the QML property or QML method node is marked as attached.
Aggregate * parent() const
Returns the node's parent pointer.
virtual bool isAggregate() const
Returns true if this node is an aggregate, which means it inherits Aggregate and can therefore have c...
const Location & location() const
If this node's definition location is empty, this function returns this node's declaration location.
Access access() const
Returns the node's Access setting, which can be Public, Protected, or Private.
bool isFunction(Genus g=Genus::DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
bool isProperty() const
Returns true if the node type is Property.
NodeContext createContext() const
bool hasDoc() const
Returns true if this node is documented, or it represents a documented node read from the index ('had...
virtual bool isClassNode() const
Returns true if this is an instance of ClassNode.
void setStatus(Status t)
Sets the node's status to t.
bool isQmlProperty() const
Returns true if the node type is QmlProperty.
A class for parsing and managing a function parameter list.
A record of a linkable target within the documentation.
TargetType
A type of a linkable target record.
static const Atom * nextSection(const Atom *a)
QMultiMap< QString, TargetRec * > TargetMap