25using namespace Qt::StringLiterals;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
45
46
47
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
67
68
69
70
71
72
73
75 : m_camelCaseModuleName(camelCaseModuleName),
76 m_physicalModuleName(camelCaseModuleName.toLower()),
78 m_root(
nullptr, QString())
80 m_root.setPhysicalModuleName(m_physicalModuleName);
85
86
87
88
89
90
91
92
93
94
97 qDeleteAll(m_nodesByTargetRef);
98 m_nodesByTargetRef.clear();
99 m_nodesByTargetTitle.clear();
105
106
107
108
109
110Node *
Tree::findNodeForInclude(
const QStringList &path)
const
112 Node *n = findClassNode(path);
114 n = findNamespaceNode(path);
119
120
121
122
123
124
125
128 QStringList path = name.split(QLatin1String(
"::"));
129 return static_cast<Aggregate *>(findNodeRecursive(path, 0,
const_cast<NamespaceNode *>(root()),
130 &Node::isFirstClassAggregate));
134
135
136
137
138
141 if (start ==
nullptr)
143 return static_cast<ClassNode *>(findNodeRecursive(path, 0, start, &Node::isClassNode));
147
148
149
150
154 return static_cast<NamespaceNode *>(findNodeRecursive(path, 0, start, &Node::isNamespace));
158
159
160
161
162
163
164
165
166
167
168
171 Node *n = findNodeRecursive(path, 0, root(), &Node::isRelatableType);
172 return (((n !=
nullptr) && n->isAggregate()) ?
static_cast<Aggregate *>(n) :
nullptr);
176
177
178
182 m_unresolvedPropertyMap[property].insert(funcRole, funcName);
186
187
188
189
190
191
192
195 for (
auto it = n->constBegin(); it != n->constEnd(); ++it) {
196 if ((*it)->isClassNode()) {
197 auto *cn =
static_cast<
ClassNode *>(*it);
198 QList<RelatedClass> &bases = cn->baseClasses_mutable();
199 for (
auto &base : bases) {
200 if (base.m_node ==
nullptr) {
201 Node *n = m_qdb->findClassNode(base.m_path);
203
204
205
206
207
208
209
210
211
213 Aggregate *parent = cn->parent();
214 if (parent !=
nullptr)
216 if (parent->isNamespace() && !parent->name().isEmpty())
217 n = findClassNode(base.m_path, parent);
220 auto *bcn =
static_cast<ClassNode *>(n);
222 bcn->addDerivedClass(base.m_access, cn);
226 resolveBaseClasses(cn);
227 }
else if ((*it)->isNamespace()) {
234
237 for (
auto node = n->constBegin(); node != n->constEnd(); ++node) {
238 if ((*node)->isClassNode()) {
239 auto *cn =
static_cast<
ClassNode *>(*node);
240 for (
auto property = cn->constBegin(); property != cn->constEnd(); ++property) {
241 if ((*property)->isProperty())
242 cn->resolvePropertyOverriddenFromPtrs(
static_cast<
PropertyNode *>(*property));
244 resolvePropertyOverriddenFromPtrs(cn);
245 }
else if ((*node)->isNamespace()) {
246 resolvePropertyOverriddenFromPtrs(
static_cast<
NamespaceNode *>(*node));
252
253
254
255
256
259 for (
auto propEntry = m_unresolvedPropertyMap.constBegin();
260 propEntry != m_unresolvedPropertyMap.constEnd(); ++propEntry) {
269 for (
auto it = parent->constBegin(); it != parent->constEnd(); ++it) {
270 if ((*it)->isFunction()) {
272 if (function->access() == property
->access()
273 && (function->status() == property
->status() || function->doc().isEmpty())) {
274 if (function->name() == getterName) {
276 }
else if (function->name() == setterName) {
278 }
else if (function->name() == resetterName) {
280 }
else if (function->name() == notifierName) {
282 }
else if (function->name() == bindableName) {
290 for (
auto propEntry = m_unresolvedPropertyMap.constBegin();
291 propEntry != m_unresolvedPropertyMap.constEnd(); ++propEntry) {
298 m_unresolvedPropertyMap.clear();
302
303
304
305
306
307
308
309
310
311
312
313void Tree::validatePropertyDocumentation(
const Aggregate *aggregate)
const
315 const auto &config = Config::instance();
316 const InclusionPolicy policy = config.createInclusionPolicy();
317 validatePropertyDocumentation(aggregate, policy);
321
322
323
324
325
326
327void Tree::validatePropertyDocumentation(
const Aggregate *aggregate,
const InclusionPolicy &policy)
const
329 for (
auto it = aggregate->constBegin(); it != aggregate->constEnd(); ++it) {
335 node
->location().warning(u"Undocumented property '%1'"_s.arg(node->plainFullName()));
339 validatePropertyDocumentation(
static_cast<Aggregate *>(node), policy);
344
345
346
347
348void Tree::resolveCppToQmlLinks()
351 const NodeList &children = m_root.childNodes();
352 for (
auto *child : children) {
353 if (child->isQmlType()) {
354 auto *qcn =
static_cast<QmlTypeNode *>(child);
355 auto *cn =
const_cast<ClassNode *>(qcn->classNode());
357 cn->insertQmlNativeType(qcn);
363
364
365
366
367
368
369
370
373 for (
auto *child : aggregate.childNodes()) {
376 if (child->isEnumType())
377 resolveEnumValueSince(
static_cast<EnumNode&>(*child));
378 if (!child->isAggregate())
380 if (!child->since().isEmpty())
383 if (
const auto collectionNode = m_qdb->getModuleNode(child))
384 child->setSince(collectionNode->since());
386 resolveSince(
static_cast<Aggregate&>(*child));
391
392
393
394
395
396
397
398
401 const QStringList enumItems{en
.doc().enumItemNames()};
402 const Atom *atom = en
.doc().body().firstAtom();
408 if (
const auto &val = atom->string(); enumItems.contains(val)) {
416
417
418
419
420
421
422
423
426 if (rootNode ==
nullptr)
429 for (
auto node = rootNode->constBegin(); node != rootNode->constEnd(); ++node) {
430 if ((*node)->isClassNode())
432 else if ((*node)->isNamespace())
433 removePrivateAndInternalBases(
static_cast<
NamespaceNode *>(*node));
438
442 const auto &baseClasses = classNode->baseClasses();
443 for (
const auto &relatedClass : baseClasses) {
444 if (relatedClass.m_node !=
nullptr) {
445 result += relatedClass.m_node;
446 result += allBaseClasses(relatedClass.m_node);
453
454
455
456
457
458
461 return findNodeRecursive(path, 0, root(), isMatch);
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480Node *
Tree::findNodeRecursive(
const QStringList &path,
int pathIndex,
const Node *start,
481 bool (Node::*isMatch)()
const)
const
483 if (start ==
nullptr || path.isEmpty())
485 Node *node =
const_cast<
Node *>(start);
487 return ((pathIndex >= path.size()) ? node :
nullptr);
488 auto *current =
static_cast<Aggregate *>(node);
489 const NodeList &children = current->childNodes();
490 const QString &name = path.at(pathIndex);
491 for (
auto *node : children) {
494 if (node->name() == name) {
495 if (pathIndex + 1 >= path.size()) {
496 if ((node->*(isMatch))())
500 node = findNodeRecursive(path, pathIndex + 1, node, isMatch);
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525const Node *
Tree::findNodeForTarget(
const QStringList &path,
const QString &target,
526 const Node *start,
int flags, Genus genus,
529 const Node *node =
nullptr;
533 auto set_ref_from_target = [
this, &ref, &target](
const Node *n) ->
const Node* {
534 if (!target.isEmpty()) {
535 if (ref = getRef(target, n); ref.isEmpty())
541 if (genus == Genus::DontCare || genus == Genus::DOC) {
542 if (node = findPageNodeByTitle(path.at(0)); node) {
543 if (node = set_ref_from_target(node); node)
549
550
551
552
553
554 const bool prioritizeHierarchy = start &&
555 ((start
->isClassNode() && (genus == Genus::CPP || genus == Genus::DontCare)) ||
556 (start
->isQmlType() && (genus == Genus::QML || genus == Genus::DontCare)));
559 if (!prioritizeHierarchy) {
560 result = findUnambiguousTarget(path.join(QLatin1String(
"::")), genus);
563 if (node = set_ref_from_target(result
->m_node); node) {
576 const Node *current = start ? start : root();
578
579
580
581
582
584 if ((genus == Genus::QML || genus == Genus::DontCare)
585 && path.size() >= 2 && !path[0].isEmpty()) {
586 if (
auto *qcn = lookupQmlType(path.sliced(0, 2).join(QLatin1String(
"::")), start); qcn) {
589 if (path.size() == 2)
590 return set_ref_from_target(qcn);
597 if (
const Node *match = matchPathAndTarget(
598 path, path_idx, target, current, flags, genus, ref);
607 if (prioritizeHierarchy) {
608 result = findUnambiguousTarget(path.join(QLatin1String(
"::")), genus);
611 if (node = set_ref_from_target(result
->m_node); node) {
619 if (node && result) {
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648const Node *
Tree::matchPathAndTarget(
const QStringList &path,
int idx,
const QString &target,
649 const Node *node,
int flags, Genus genus,
650 QString &ref,
int duplicates)
const
653
654
655
656
657 if (idx == path.size()) {
658 if (!target.isEmpty()) {
659 ref = getRef(target, node);
684 QString name = path.at(idx);
687 static_cast<
const Aggregate *>(node)->findChildren(name, nodes);
688 for (
const auto *child : std::as_const(nodes)) {
689 if (genus != Genus::DontCare && !(hasCommonGenusType(genus, child->genus())))
691 const Node *t = matchPathAndTarget(path, idx + 1, target, child, flags, genus, ref, nodes.count() - 1);
692 if (t && !t->isPrivate() && !t->isInternal())
697 const auto *enumNode = node->isAggregate() ?
698 findEnumNode(
nullptr, node, path, idx) :
699 findEnumNode(node,
nullptr, path, idx);
703 if (((genus == Genus::CPP) || (genus == Genus::DontCare)) && node
->isClassNode()
705 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(node));
706 for (
const auto *base : bases) {
707 const Node *t = matchPathAndTarget(path, idx, target, base, flags, genus, ref);
708 if (t && !t->isPrivate() && !t->isInternal())
710 if (target.isEmpty() && (flags & SearchEnumValues)) {
711 if ((t = findEnumNode(base->findChildNode(path.at(idx), genus, flags), base, path, idx)))
716 if (((genus == Genus::QML) || (genus == Genus::DontCare)) && node
->isQmlType()
718 const QmlTypeNode *qtn =
static_cast<
const QmlTypeNode *>(node);
721 const Node *t = matchPathAndTarget(path, idx, target, qtn, flags, genus, ref);
730
731
732
733
734
735const Node *
Tree::findNode(
const QStringList &path,
const Node *start,
int flags,
738 const Node *current = start;
739 if (current ==
nullptr)
743 const Node *node = current;
748
749
750
751
752
753
754
755 if (((genus == Genus::QML) || (genus == Genus::DontCare)) && (path.size() >= 2)
756 && !path[0].isEmpty()) {
757 QmlTypeNode *qcn = lookupQmlType(QString(path[0] +
"::" + path[1]), start);
758 if (qcn !=
nullptr) {
760 if (path.size() == 2)
766 for (i = start_idx; i < path.size(); ++i) {
775 const Node *next =
static_cast<
const Aggregate *>(node)->findChildNode(path.at(i),
777 const Node *enumNode = (flags & SearchEnumValues) ?
778 findEnumNode(next, node, path, i) :
nullptr;
784 if (!next && ((genus == Genus::CPP) || (genus == Genus::DontCare))
786 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(node));
787 for (
const auto *base : bases) {
788 next = base->findChildNode(path.at(i), genus, tmpFlags);
789 if (flags & SearchEnumValues)
790 if ((enumNode = findEnumNode(next, base, path, i)))
796 if (!next && ((genus == Genus::QML) || (genus == Genus::DontCare))
798 const QmlTypeNode *qtn =
static_cast<
const QmlTypeNode *>(node);
801 next = qtn->findChildNode(path.at(i), genus, tmpFlags);
806 if ((node !=
nullptr) && i == path.size())
809 }
while (current !=
nullptr);
816
817
818
819
820
821
822
823const Node *
Tree::findEnumNode(
const Node *node,
const Node *aggregate,
const QStringList &path,
int offset)
const
827 const auto *en =
static_cast<
const EnumNode*>(node);
828 if (en->hasItem(path.last()))
833 return (!node && aggregate && offset == path.size() - 1) ?
834 static_cast<
const Aggregate *>(aggregate)->findEnumNodeForValue(path.last()) :
839
840
841
842
843
844QString
Tree::getRef(
const QString &target,
const Node *node)
const
846 auto it = m_nodesByTargetTitle.constFind(target);
847 if (it != m_nodesByTargetTitle.constEnd()) {
849 if (it.value()->m_node == node)
850 return it.value()->m_ref;
852 }
while (it != m_nodesByTargetTitle.constEnd() && it.key() == target);
854 QString key = TextUtils::asAsciiPrintable(target);
855 it = m_nodesByTargetRef.constFind(key);
856 if (it != m_nodesByTargetRef.constEnd()) {
858 if (it.value()->m_node == node)
859 return it.value()->m_ref;
861 }
while (it != m_nodesByTargetRef.constEnd() && it.key() == key);
867
868
869
870
871
873 Node *node,
int priority)
875 auto *target =
new TargetRec(name, type, node, priority);
876 m_nodesByTargetRef.insert(name, target);
877 m_nodesByTargetTitle.insert(title, target);
881
882
883
884
885
886
887
890 for (
auto *child : root->childNodes()) {
891 addToPageNodeByTitleMap(child);
892 populateTocSectionTargetMap(child);
893 addKeywordsToTargetMaps(child);
894 addTargetsToTargetMap(child);
896 if (child->isAggregate())
897 resolveTargets(
static_cast<Aggregate *>(child));
902
903
904
905
906void Tree::addTargetsToTargetMap(
Node *node) {
910 for (Atom *i : std::as_const(node->doc().targets())) {
911 const QString ref = refForAtom(i);
912 const QString title = i->string();
913 if (!ref.isEmpty() && !title.isEmpty()) {
914 QString key = TextUtils::asAsciiPrintable(title);
915 auto *target =
new TargetRec(std::move(ref), TargetRec::Target, node, 2);
916 m_nodesByTargetRef.insert(key, target);
917 m_nodesByTargetTitle.insert(title, target);
923
924
925
926
935
936
937
938
939void Tree::addKeywordsToTargetMaps(
Node *node) {
943 for (Atom *i : std::as_const(node->doc().keywords())) {
944 QString ref = refForAtom(i);
945 QString title = i->string();
946 if (!ref.isEmpty() && !title.isEmpty()) {
947 auto *target =
new TargetRec(ref, nextSection(i) ? TargetRec::ContentsKeyword : TargetRec::Keyword, node, 1);
948 m_nodesByTargetRef.insert(TextUtils::asAsciiPrintable(title), target);
949 m_nodesByTargetTitle.insert(title, target);
950 if (!target->isEmpty())
951 i->append(target->m_ref);
957
958
959
960
961
962void Tree::populateTocSectionTargetMap(
Node *node) {
966 QStack<Atom *> tocLevels;
967 QSet<QString> anchors;
971 for (Atom *atom: std::as_const(node->doc().tableOfContents())) {
972 while (!tocLevels.isEmpty() && tocLevels.top()->string().toInt() >= atom->string().toInt())
975 tocLevels.push(atom);
977 QString ref = refForAtom(atom);
978 const QString &title = Text::sectionHeading(atom).toString();
979 if (ref.isEmpty() || title.isEmpty())
982 if (anchors.contains(ref)) {
983 QStringList refParts;
984 for (
const auto tocLevel : tocLevels)
985 refParts << refForAtom(tocLevel);
987 refParts << QString::number(index);
988 ref = refParts.join(QLatin1Char(
'-'));
992 if (atom->next(Atom::SectionHeadingLeft))
993 atom->next()->append(ref);
996 const QString &key = TextUtils::asAsciiPrintable(title);
997 auto *target =
new TargetRec(ref, TargetRec::Contents, node, 3);
998 m_nodesByTargetRef.insert(key, target);
999 m_nodesByTargetTitle.insert(title, target);
1004
1005
1006
1007
1008
1009void Tree::addToPageNodeByTitleMap(
Node *node) {
1013 auto *pageNode =
static_cast<PageNode *>(node);
1014 QString key = pageNode->title();
1018 if (key.contains(QChar(
' ')))
1019 key = TextUtils::asAsciiPrintable(key);
1020 const QList<PageNode *> nodes = m_pageNodesByTitle.values(key);
1022 bool alreadyThere =
std::any_of(nodes.cbegin(), nodes.cend(), [&](
const auto &knownNode) {
1023 return knownNode->isExternalPage() && knownNode->name() == pageNode->name();
1027 m_pageNodesByTitle.insert(key, pageNode);
1031
1032
1033
1034const TargetRec *
Tree::findUnambiguousTarget(
const QString &target, Genus genus)
const
1036 auto findBestCandidate = [&](
const TargetMap &tgtMap,
const QString &key) {
1038 auto [it, end] = tgtMap.equal_range(key);
1041 if ((genus == Genus::DontCare) || (hasCommonGenusType(genus, candidate
->genus()))) {
1050 TargetRec *bestTarget = findBestCandidate(m_nodesByTargetTitle, target);
1052 bestTarget = findBestCandidate(m_nodesByTargetRef, TextUtils::asAsciiPrintable(target));
1058
1059
1060const PageNode *
Tree::findPageNodeByTitle(
const QString &title)
const
1062 PageNodeMultiMap::const_iterator it;
1063 if (title.contains(QChar(
' ')))
1064 it = m_pageNodesByTitle.constFind(TextUtils::asAsciiPrintable(title));
1066 it = m_pageNodesByTitle.constFind(title);
1067 if (it != m_pageNodesByTitle.constEnd()) {
1069
1070
1071
1072
1073 PageNodeMultiMap::const_iterator j = it;
1075 if (j != m_pageNodesByTitle.constEnd() && j.key() == it.key()) {
1076 while (j != m_pageNodesByTitle.constEnd()) {
1077 if (j.key() == it.key() && j.value()->url().isEmpty()) {
1082 if (j != m_pageNodesByTitle.cend()) {
1083 it.value()->location().warning(
"This page title exists in more than one file: "
1085 j.value()->location().warning(
"[It also exists here]");
1094
1095
1096
1097
1098
1099
1109 if (atom->count() == 2)
1110 return atom->string(1);
1115 if (
const auto *section = nextSection(atom))
1116 return refForAtom(section);
1117 return TextUtils::asAsciiPrintable(atom->string());
1124
1125
1126
1127
1130
1131
1132
1133
1136
1137
1138
1139
1142
1143
1144
1153 return &m_qmlModules;
1161
1162
1163
1164
1165
1168 CNMap *map = getCollectionMap(type);
1170 auto it = map->constFind(name);
1171 if (it != map->cend())
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1193 CNMap *m = getCollectionMap(type);
1196 auto it = m->constFind(name);
1197 if (it != m->cend())
1201 m->insert(name, cn);
1206
1207
1208
1209
1210
1211
1212
1215
1216
1217
1218
1219
1220
1221
1224
1225
1226
1227
1228
1229
1230
1233
1234
1235
1236
1237
1238
1241
1242
1243
1244
1245
1246
1249
1250
1251
1252
1253
1254
1257
1258
1259
1260
1261
1262
1263
1264
1270 node->appendGroupName(name);
1276
1277
1278
1279
1280
1281
1286 node->setPhysicalModuleName(name);
1291
1292
1293
1294
1295
1299 QStringList dotSplit;
1300 QStringList blankSplit = name.split(QLatin1Char(
' '));
1301 qmid.append(blankSplit[0]);
1302 if (blankSplit.size() > 1) {
1303 qmid.append(blankSplit[0] + blankSplit[1]);
1304 dotSplit = blankSplit[1].split(QLatin1Char(
'.'));
1305 qmid.append(blankSplit[0] + dotSplit[0]);
1312 QmlTypeNode *n =
static_cast<QmlTypeNode *>(node);
1313 for (
int i = 0; i < qmid.size(); ++i) {
1314 QString key = qmid[i] +
"::" + node->name();
1315 insertQmlType(key, n);
1318 insertQmlType(node->name(), n);
1324
1325
1326
1327
1330 m_qmlTypeMap.insert(key, n);
1334
1335
1336
1337
1338
1341 auto values = m_qmlTypeMap.values(name);
1342 if (values.isEmpty())
1346 if (!relative || values.size() == 1)
1347 return values.first();
1351 const auto *relativeQmlType =
static_cast<
const QmlTypeNode *>(relative);
1352 const CollectionNode *relativeModule = relativeQmlType->logicalModule();
1354 for (
auto *candidate : values) {
1355 if (candidate->logicalModule() == relativeModule)
1361 return values.first();
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1377 const Node *relative, Genus genus)
const
1379 if (path.size() == 3 && !path[0].isEmpty()
1380 && ((genus == Genus::QML) || (genus == Genus::DontCare))) {
1381 QmlTypeNode *qcn = lookupQmlType(QString(path[0] +
"::" + path[1]), relative);
1382 if (qcn ==
nullptr) {
1383 QStringList p(path[1]);
1384 Node *n = findNodeByNameAndType(p, &Node::isQmlType);
1385 if ((n !=
nullptr) && n->isQmlType())
1386 qcn =
static_cast<QmlTypeNode *>(n);
1392 if (relative ==
nullptr)
1394 else if (genus != Genus::DontCare) {
1395 if (!(hasCommonGenusType(genus, relative
->genus())))
1400 Node *node =
const_cast<
Node *>(relative);
1403 for (i = 0; i < path.size(); ++i) {
1407 Aggregate *aggregate =
static_cast<Aggregate *>(node);
1408 Node *next =
nullptr;
1409 if (i == path.size() - 1)
1412 next = aggregate->findChildNode(path.at(i), genus);
1415 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(aggregate));
1416 for (
auto *base : bases) {
1417 if (i == path.size() - 1)
1418 next = base->findFunctionChild(path.at(i), parameters);
1420 next = base->findChildNode(path.at(i), genus);
1422 if (next !=
nullptr)
1438 const FunctionNode *fn =
static_cast<
const FunctionNode *>(node);
1440 while (FN
->isPrivate() && !FN->overridesThis().isEmpty()) {
1441 QStringList path = FN->overridesThis().split(
"::");
1442 FN = m_qdb->findFunctionNode(path, parameters, relative, genus);
1456
1457
1458
1459
1462 if (parent ==
nullptr)
1465 for (Node *n : children) {
1466 if (n !=
nullptr && n->isFunction() && n->hasTag(tag))
1467 return static_cast<FunctionNode *>(n);
1469 for (Node *n : children) {
1470 if (n !=
nullptr && n->isAggregate()) {
1471 n = findFunctionNodeForTag(tag,
static_cast<Aggregate *>(n));
1473 return static_cast<FunctionNode *>(n);
1480
1481
1482
1485 if (parent ==
nullptr)
1488 for (Node *n : children) {
1489 if (n !=
nullptr && (n->isMacro() || n->isFunction()) && n->name() == t)
1490 return static_cast<FunctionNode *>(n);
1492 for (Node *n : children) {
1493 if (n !=
nullptr && n->isAggregate()) {
1494 FunctionNode *fn = findMacroNode(t,
static_cast<Aggregate *>(n));
1503
1504
1505
1508 arg.remove(QChar(
'('));
1509 arg.remove(QChar(
')'));
1510 QString t = arg.simplified();
1511 QStringList sl = t.split(QChar(
' '));
1514 for (
const QString &s : sl) {
1515 if (!m_dontDocumentMap.contains(s))
1516 m_dontDocumentMap.insert(s,
nullptr);
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1535 for (
auto it = m_dontDocumentMap.begin(); it != m_dontDocumentMap.end(); ++it) {
1536 Aggregate *node = findAggregate(it.key());
1537 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 and updates the new member's status.
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.
void resolveProperties()
Resolves access functions associated with each PropertyNode stored in m_unresolvedPropertyMap,...
void addPropertyFunction(PropertyNode *property, const QString &funcName, PropertyNode::FunctionRole funcRole)
Inserts function name funcName and function role funcRole into the property function map for the spec...
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.
virtual 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