24using namespace Qt::StringLiterals;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
44
45
46
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
66
67
68
69
70
71
72
74 : m_camelCaseModuleName(camelCaseModuleName),
75 m_physicalModuleName(camelCaseModuleName.toLower()),
77 m_root(
nullptr, QString())
79 m_root.setPhysicalModuleName(m_physicalModuleName);
84
85
86
87
88
89
90
91
92
93
96 qDeleteAll(m_nodesByTargetRef);
97 m_nodesByTargetRef.clear();
98 m_nodesByTargetTitle.clear();
104
105
106
107
108
109Node *
Tree::findNodeForInclude(
const QStringList &path)
const
111 Node *n = findClassNode(path);
113 n = findNamespaceNode(path);
118
119
120
121
122
123
124
127 QStringList path = name.split(QLatin1String(
"::"));
128 return static_cast<Aggregate *>(findNodeRecursive(path, 0,
const_cast<NamespaceNode *>(root()),
129 &Node::isFirstClassAggregate));
133
134
135
136
137
140 if (start ==
nullptr)
142 return static_cast<ClassNode *>(findNodeRecursive(path, 0, start, &Node::isClassNode));
146
147
148
149
153 return static_cast<NamespaceNode *>(findNodeRecursive(path, 0, start, &Node::isNamespace));
157
158
159
160
161
162
163
164
165
166
167
170 Node *n = findNodeRecursive(path, 0, root(), &Node::isRelatableType);
171 return (((n !=
nullptr) && n->isAggregate()) ?
static_cast<Aggregate *>(n) :
nullptr);
175
176
177
181 m_unresolvedPropertyMap[property].insert(funcRole, funcName);
185
186
187
188
189
190
191
194 for (
auto it = n->constBegin(); it != n->constEnd(); ++it) {
195 if ((*it)->isClassNode()) {
196 auto *cn =
static_cast<
ClassNode *>(*it);
197 QList<RelatedClass> &bases = cn->baseClasses_mutable();
198 for (
auto &base : bases) {
199 if (base.m_node ==
nullptr) {
200 Node *n = m_qdb->findClassNode(base.m_path);
202
203
204
205
206
207
208
209
210
212 Aggregate *parent = cn->parent();
213 if (parent !=
nullptr)
215 if (parent->isNamespace() && !parent->name().isEmpty())
216 n = findClassNode(base.m_path, parent);
219 auto *bcn =
static_cast<ClassNode *>(n);
221 bcn->addDerivedClass(base.m_access, cn);
225 resolveBaseClasses(cn);
226 }
else if ((*it)->isNamespace()) {
233
236 for (
auto node = n->constBegin(); node != n->constEnd(); ++node) {
237 if ((*node)->isClassNode()) {
238 auto *cn =
static_cast<
ClassNode *>(*node);
239 for (
auto property = cn->constBegin(); property != cn->constEnd(); ++property) {
240 if ((*property)->isProperty())
241 cn->resolvePropertyOverriddenFromPtrs(
static_cast<
PropertyNode *>(*property));
243 resolvePropertyOverriddenFromPtrs(cn);
244 }
else if ((*node)->isNamespace()) {
245 resolvePropertyOverriddenFromPtrs(
static_cast<
NamespaceNode *>(*node));
251
252
253
254
255
258 for (
auto propEntry = m_unresolvedPropertyMap.constBegin();
259 propEntry != m_unresolvedPropertyMap.constEnd(); ++propEntry) {
268 for (
auto it = parent->constBegin(); it != parent->constEnd(); ++it) {
269 if ((*it)->isFunction()) {
271 if (function->access() == property
->access()
272 && (function->status() == property
->status() || function->doc().isEmpty())) {
273 if (function->name() == getterName) {
275 }
else if (function->name() == setterName) {
277 }
else if (function->name() == resetterName) {
279 }
else if (function->name() == notifierName) {
281 }
else if (function->name() == bindableName) {
289 for (
auto propEntry = m_unresolvedPropertyMap.constBegin();
290 propEntry != m_unresolvedPropertyMap.constEnd(); ++propEntry) {
297 m_unresolvedPropertyMap.clear();
301
302
303
304
305
306
307
308
309
310
311
312void Tree::validatePropertyDocumentation(
const Aggregate *aggregate)
const
314 const auto &config = Config::instance();
315 const InclusionPolicy policy = config.createInclusionPolicy();
316 validatePropertyDocumentation(aggregate, policy);
320
321
322
323
324
325
326void Tree::validatePropertyDocumentation(
const Aggregate *aggregate,
const InclusionPolicy &policy)
const
328 for (
auto it = aggregate->constBegin(); it != aggregate->constEnd(); ++it) {
334 node
->location().warning(u"Undocumented property '%1'"_s.arg(node->plainFullName()));
338 validatePropertyDocumentation(
static_cast<Aggregate *>(node), policy);
343
344
345
346
347void Tree::resolveCppToQmlLinks()
350 const NodeList &children = m_root.childNodes();
351 for (
auto *child : children) {
352 if (child->isQmlType()) {
353 auto *qcn =
static_cast<QmlTypeNode *>(child);
354 auto *cn =
const_cast<ClassNode *>(qcn->classNode());
356 cn->insertQmlNativeType(qcn);
362
363
364
365
366
367
368
369
372 for (
auto *child : aggregate.childNodes()) {
375 if (child->isEnumType())
376 resolveEnumValueSince(
static_cast<EnumNode&>(*child));
377 if (!child->isAggregate())
379 if (!child->since().isEmpty())
382 if (
const auto collectionNode = m_qdb->getModuleNode(child))
383 child->setSince(collectionNode->since());
385 resolveSince(
static_cast<Aggregate&>(*child));
390
391
392
393
394
395
396
397
400 const QStringList enumItems{en
.doc().enumItemNames()};
401 const Atom *atom = en
.doc().body().firstAtom();
407 if (
const auto &val = atom->string(); enumItems.contains(val)) {
415
416
417
418
419
420
421
422
425 if (rootNode ==
nullptr)
428 for (
auto node = rootNode->constBegin(); node != rootNode->constEnd(); ++node) {
429 if ((*node)->isClassNode())
431 else if ((*node)->isNamespace())
432 removePrivateAndInternalBases(
static_cast<
NamespaceNode *>(*node));
437
441 const auto &baseClasses = classNode->baseClasses();
442 for (
const auto &relatedClass : baseClasses) {
443 if (relatedClass.m_node !=
nullptr) {
444 result += relatedClass.m_node;
445 result += allBaseClasses(relatedClass.m_node);
452
453
454
455
456
457
460 return findNodeRecursive(path, 0, root(), isMatch);
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479Node *
Tree::findNodeRecursive(
const QStringList &path,
int pathIndex,
const Node *start,
480 bool (Node::*isMatch)()
const)
const
482 if (start ==
nullptr || path.isEmpty())
484 Node *node =
const_cast<
Node *>(start);
486 return ((pathIndex >= path.size()) ? node :
nullptr);
487 auto *current =
static_cast<Aggregate *>(node);
488 const NodeList &children = current->childNodes();
489 const QString &name = path.at(pathIndex);
490 for (
auto *node : children) {
493 if (node->name() == name) {
494 if (pathIndex + 1 >= path.size()) {
495 if ((node->*(isMatch))())
499 node = findNodeRecursive(path, pathIndex + 1, node, isMatch);
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524const Node *
Tree::findNodeForTarget(
const QStringList &path,
const QString &target,
525 const Node *start,
int flags, Genus genus,
528 const Node *node =
nullptr;
532 auto set_ref_from_target = [
this, &ref, &target](
const Node *n) ->
const Node* {
533 if (!target.isEmpty()) {
534 if (ref = getRef(target, n); ref.isEmpty())
540 if (genus == Genus::DontCare || genus == Genus::DOC) {
541 if (node = findPageNodeByTitle(path.at(0)); node) {
542 if (node = set_ref_from_target(node); node)
548
549
550
551
552
553 const bool prioritizeHierarchy = start &&
554 ((start
->isClassNode() && (genus == Genus::CPP || genus == Genus::DontCare)) ||
555 (start
->isQmlType() && (genus == Genus::QML || genus == Genus::DontCare)));
558 if (!prioritizeHierarchy) {
559 result = findUnambiguousTarget(path.join(QLatin1String(
"::")), genus);
562 if (node = set_ref_from_target(result
->m_node); node) {
575 const Node *current = start ? start : root();
577
578
579
580
581
583 if ((genus == Genus::QML || genus == Genus::DontCare)
584 && path.size() >= 2 && !path[0].isEmpty()) {
585 if (
auto *qcn = lookupQmlType(path.sliced(0, 2).join(QLatin1String(
"::")), start); qcn) {
588 if (path.size() == 2)
589 return set_ref_from_target(qcn);
596 if (
const Node *match = matchPathAndTarget(
597 path, path_idx, target, current, flags, genus, ref);
606 if (prioritizeHierarchy) {
607 result = findUnambiguousTarget(path.join(QLatin1String(
"::")), genus);
610 if (node = set_ref_from_target(result
->m_node); node) {
618 if (node && result) {
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647const Node *
Tree::matchPathAndTarget(
const QStringList &path,
int idx,
const QString &target,
648 const Node *node,
int flags, Genus genus,
649 QString &ref,
int duplicates)
const
652
653
654
655
656 if (idx == path.size()) {
657 if (!target.isEmpty()) {
658 ref = getRef(target, node);
683 QString name = path.at(idx);
686 static_cast<
const Aggregate *>(node)->findChildren(name, nodes);
687 for (
const auto *child : std::as_const(nodes)) {
688 if (genus != Genus::DontCare && !(hasCommonGenusType(genus, child->genus())))
690 const Node *t = matchPathAndTarget(path, idx + 1, target, child, flags, genus, ref, nodes.count() - 1);
691 if (t && !t->isPrivate() && !t->isInternal())
696 const auto *enumNode = node->isAggregate() ?
697 findEnumNode(
nullptr, node, path, idx) :
698 findEnumNode(node,
nullptr, path, idx);
702 if (((genus == Genus::CPP) || (genus == Genus::DontCare)) && node
->isClassNode()
704 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(node));
705 for (
const auto *base : bases) {
706 const Node *t = matchPathAndTarget(path, idx, target, base, flags, genus, ref);
707 if (t && !t->isPrivate() && !t->isInternal())
709 if (target.isEmpty() && (flags & SearchEnumValues)) {
710 if ((t = findEnumNode(base->findChildNode(path.at(idx), genus, flags), base, path, idx)))
715 if (((genus == Genus::QML) || (genus == Genus::DontCare)) && node
->isQmlType()
717 const QmlTypeNode *qtn =
static_cast<
const QmlTypeNode *>(node);
720 const Node *t = matchPathAndTarget(path, idx, target, qtn, flags, genus, ref);
729
730
731
732
733
734const Node *
Tree::findNode(
const QStringList &path,
const Node *start,
int flags,
737 const Node *current = start;
738 if (current ==
nullptr)
742 const Node *node = current;
747
748
749
750
751
752
753
754 if (((genus == Genus::QML) || (genus == Genus::DontCare)) && (path.size() >= 2)
755 && !path[0].isEmpty()) {
756 QmlTypeNode *qcn = lookupQmlType(QString(path[0] +
"::" + path[1]), start);
757 if (qcn !=
nullptr) {
759 if (path.size() == 2)
765 for (i = start_idx; i < path.size(); ++i) {
774 const Node *next =
static_cast<
const Aggregate *>(node)->findChildNode(path.at(i),
776 const Node *enumNode = (flags & SearchEnumValues) ?
777 findEnumNode(next, node, path, i) :
nullptr;
783 if (!next && ((genus == Genus::CPP) || (genus == Genus::DontCare))
785 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(node));
786 for (
const auto *base : bases) {
787 next = base->findChildNode(path.at(i), genus, tmpFlags);
788 if (flags & SearchEnumValues)
789 if ((enumNode = findEnumNode(next, base, path, i)))
795 if (!next && ((genus == Genus::QML) || (genus == Genus::DontCare))
797 const QmlTypeNode *qtn =
static_cast<
const QmlTypeNode *>(node);
800 next = qtn->findChildNode(path.at(i), genus, tmpFlags);
805 if ((node !=
nullptr) && i == path.size())
808 }
while (current !=
nullptr);
815
816
817
818
819
820
821
822const Node *
Tree::findEnumNode(
const Node *node,
const Node *aggregate,
const QStringList &path,
int offset)
const
826 const auto *en =
static_cast<
const EnumNode*>(node);
827 if (en->hasItem(path.last()))
832 return (!node && aggregate && offset == path.size() - 1) ?
833 static_cast<
const Aggregate *>(aggregate)->findEnumNodeForValue(path.last()) :
838
839
840
841
842
843QString
Tree::getRef(
const QString &target,
const Node *node)
const
845 auto it = m_nodesByTargetTitle.constFind(target);
846 if (it != m_nodesByTargetTitle.constEnd()) {
848 if (it.value()->m_node == node)
849 return it.value()->m_ref;
851 }
while (it != m_nodesByTargetTitle.constEnd() && it.key() == target);
853 QString key = Utilities::asAsciiPrintable(target);
854 it = m_nodesByTargetRef.constFind(key);
855 if (it != m_nodesByTargetRef.constEnd()) {
857 if (it.value()->m_node == node)
858 return it.value()->m_ref;
860 }
while (it != m_nodesByTargetRef.constEnd() && it.key() == key);
866
867
868
869
870
872 Node *node,
int priority)
874 auto *target =
new TargetRec(name, type, node, priority);
875 m_nodesByTargetRef.insert(name, target);
876 m_nodesByTargetTitle.insert(title, target);
880
881
882
883
884
885
886
889 for (
auto *child : root->childNodes()) {
890 addToPageNodeByTitleMap(child);
891 populateTocSectionTargetMap(child);
892 addKeywordsToTargetMaps(child);
893 addTargetsToTargetMap(child);
895 if (child->isAggregate())
896 resolveTargets(
static_cast<Aggregate *>(child));
901
902
903
904
905void Tree::addTargetsToTargetMap(
Node *node) {
909 for (Atom *i : std::as_const(node->doc().targets())) {
910 const QString ref = refForAtom(i);
911 const QString title = i->string();
912 if (!ref.isEmpty() && !title.isEmpty()) {
913 QString key = Utilities::asAsciiPrintable(title);
914 auto *target =
new TargetRec(std::move(ref), TargetRec::Target, node, 2);
915 m_nodesByTargetRef.insert(key, target);
916 m_nodesByTargetTitle.insert(title, target);
922
923
924
925
934
935
936
937
938void Tree::addKeywordsToTargetMaps(
Node *node) {
942 for (Atom *i : std::as_const(node->doc().keywords())) {
943 QString ref = refForAtom(i);
944 QString title = i->string();
945 if (!ref.isEmpty() && !title.isEmpty()) {
946 auto *target =
new TargetRec(ref, nextSection(i) ? TargetRec::ContentsKeyword : TargetRec::Keyword, node, 1);
947 m_nodesByTargetRef.insert(Utilities::asAsciiPrintable(title), target);
948 m_nodesByTargetTitle.insert(title, target);
949 if (!target->isEmpty())
950 i->append(target->m_ref);
956
957
958
959
960
961void Tree::populateTocSectionTargetMap(
Node *node) {
965 QStack<Atom *> tocLevels;
966 QSet<QString> anchors;
970 for (Atom *atom: std::as_const(node->doc().tableOfContents())) {
971 while (!tocLevels.isEmpty() && tocLevels.top()->string().toInt() >= atom->string().toInt())
974 tocLevels.push(atom);
976 QString ref = refForAtom(atom);
977 const QString &title = Text::sectionHeading(atom).toString();
978 if (ref.isEmpty() || title.isEmpty())
981 if (anchors.contains(ref)) {
982 QStringList refParts;
983 for (
const auto tocLevel : tocLevels)
984 refParts << refForAtom(tocLevel);
986 refParts << QString::number(index);
987 ref = refParts.join(QLatin1Char(
'-'));
991 if (atom->next(Atom::SectionHeadingLeft))
992 atom->next()->append(ref);
995 const QString &key = Utilities::asAsciiPrintable(title);
996 auto *target =
new TargetRec(ref, TargetRec::Contents, node, 3);
997 m_nodesByTargetRef.insert(key, target);
998 m_nodesByTargetTitle.insert(title, target);
1003
1004
1005
1006
1007
1008void Tree::addToPageNodeByTitleMap(
Node *node) {
1012 auto *pageNode =
static_cast<PageNode *>(node);
1013 QString key = pageNode->title();
1017 if (key.contains(QChar(
' ')))
1018 key = Utilities::asAsciiPrintable(key);
1019 const QList<PageNode *> nodes = m_pageNodesByTitle.values(key);
1021 bool alreadyThere =
std::any_of(nodes.cbegin(), nodes.cend(), [&](
const auto &knownNode) {
1022 return knownNode->isExternalPage() && knownNode->name() == pageNode->name();
1026 m_pageNodesByTitle.insert(key, pageNode);
1030
1031
1032
1033const TargetRec *
Tree::findUnambiguousTarget(
const QString &target, Genus genus)
const
1035 auto findBestCandidate = [&](
const TargetMap &tgtMap,
const QString &key) {
1037 auto [it, end] = tgtMap.equal_range(key);
1040 if ((genus == Genus::DontCare) || (hasCommonGenusType(genus, candidate
->genus()))) {
1049 TargetRec *bestTarget = findBestCandidate(m_nodesByTargetTitle, target);
1051 bestTarget = findBestCandidate(m_nodesByTargetRef, Utilities::asAsciiPrintable(target));
1057
1058
1059const PageNode *
Tree::findPageNodeByTitle(
const QString &title)
const
1061 PageNodeMultiMap::const_iterator it;
1062 if (title.contains(QChar(
' ')))
1063 it = m_pageNodesByTitle.constFind(Utilities::asAsciiPrintable(title));
1065 it = m_pageNodesByTitle.constFind(title);
1066 if (it != m_pageNodesByTitle.constEnd()) {
1068
1069
1070
1071
1072 PageNodeMultiMap::const_iterator j = it;
1074 if (j != m_pageNodesByTitle.constEnd() && j.key() == it.key()) {
1075 while (j != m_pageNodesByTitle.constEnd()) {
1076 if (j.key() == it.key() && j.value()->url().isEmpty()) {
1081 if (j != m_pageNodesByTitle.cend()) {
1082 it.value()->location().warning(
"This page title exists in more than one file: "
1084 j.value()->location().warning(
"[It also exists here]");
1093
1094
1095
1096
1097
1098
1108 if (atom->count() == 2)
1109 return atom->string(1);
1114 if (
const auto *section = nextSection(atom))
1115 return refForAtom(section);
1116 return Utilities::asAsciiPrintable(atom->string());
1123
1124
1125
1126
1129
1130
1131
1132
1135
1136
1137
1138
1141
1142
1143
1152 return &m_qmlModules;
1160
1161
1162
1163
1164
1167 CNMap *map = getCollectionMap(type);
1169 auto it = map->constFind(name);
1170 if (it != map->cend())
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1192 CNMap *m = getCollectionMap(type);
1195 auto it = m->constFind(name);
1196 if (it != m->cend())
1200 m->insert(name, cn);
1205
1206
1207
1208
1209
1210
1211
1214
1215
1216
1217
1218
1219
1220
1223
1224
1225
1226
1227
1228
1229
1232
1233
1234
1235
1236
1237
1240
1241
1242
1243
1244
1245
1248
1249
1250
1251
1252
1253
1256
1257
1258
1259
1260
1261
1262
1263
1269 node->appendGroupName(name);
1275
1276
1277
1278
1279
1280
1285 node->setPhysicalModuleName(name);
1290
1291
1292
1293
1294
1298 QStringList dotSplit;
1299 QStringList blankSplit = name.split(QLatin1Char(
' '));
1300 qmid.append(blankSplit[0]);
1301 if (blankSplit.size() > 1) {
1302 qmid.append(blankSplit[0] + blankSplit[1]);
1303 dotSplit = blankSplit[1].split(QLatin1Char(
'.'));
1304 qmid.append(blankSplit[0] + dotSplit[0]);
1311 QmlTypeNode *n =
static_cast<QmlTypeNode *>(node);
1312 for (
int i = 0; i < qmid.size(); ++i) {
1313 QString key = qmid[i] +
"::" + node->name();
1314 insertQmlType(key, n);
1317 insertQmlType(node->name(), n);
1323
1324
1325
1326
1329 m_qmlTypeMap.insert(key, n);
1333
1334
1335
1336
1337
1340 auto values = m_qmlTypeMap.values(name);
1341 if (values.isEmpty())
1345 if (!relative || values.size() == 1)
1346 return values.first();
1350 const auto *relativeQmlType =
static_cast<
const QmlTypeNode *>(relative);
1351 const CollectionNode *relativeModule = relativeQmlType->logicalModule();
1353 for (
auto *candidate : values) {
1354 if (candidate->logicalModule() == relativeModule)
1360 return values.first();
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1376 const Node *relative, Genus genus)
const
1378 if (path.size() == 3 && !path[0].isEmpty()
1379 && ((genus == Genus::QML) || (genus == Genus::DontCare))) {
1380 QmlTypeNode *qcn = lookupQmlType(QString(path[0] +
"::" + path[1]), relative);
1381 if (qcn ==
nullptr) {
1382 QStringList p(path[1]);
1383 Node *n = findNodeByNameAndType(p, &Node::isQmlType);
1384 if ((n !=
nullptr) && n->isQmlType())
1385 qcn =
static_cast<QmlTypeNode *>(n);
1391 if (relative ==
nullptr)
1393 else if (genus != Genus::DontCare) {
1394 if (!(hasCommonGenusType(genus, relative
->genus())))
1399 Node *node =
const_cast<
Node *>(relative);
1402 for (i = 0; i < path.size(); ++i) {
1406 Aggregate *aggregate =
static_cast<Aggregate *>(node);
1407 Node *next =
nullptr;
1408 if (i == path.size() - 1)
1411 next = aggregate->findChildNode(path.at(i), genus);
1414 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(aggregate));
1415 for (
auto *base : bases) {
1416 if (i == path.size() - 1)
1417 next = base->findFunctionChild(path.at(i), parameters);
1419 next = base->findChildNode(path.at(i), genus);
1421 if (next !=
nullptr)
1437 const FunctionNode *fn =
static_cast<
const FunctionNode *>(node);
1439 while (FN
->isPrivate() && !FN->overridesThis().isEmpty()) {
1440 QStringList path = FN->overridesThis().split(
"::");
1441 FN = m_qdb->findFunctionNode(path, parameters, relative, genus);
1455
1456
1457
1458
1461 if (parent ==
nullptr)
1464 for (Node *n : children) {
1465 if (n !=
nullptr && n->isFunction() && n->hasTag(tag))
1466 return static_cast<FunctionNode *>(n);
1468 for (Node *n : children) {
1469 if (n !=
nullptr && n->isAggregate()) {
1470 n = findFunctionNodeForTag(tag,
static_cast<Aggregate *>(n));
1472 return static_cast<FunctionNode *>(n);
1479
1480
1481
1484 if (parent ==
nullptr)
1487 for (Node *n : children) {
1488 if (n !=
nullptr && (n->isMacro() || n->isFunction()) && n->name() == t)
1489 return static_cast<FunctionNode *>(n);
1491 for (Node *n : children) {
1492 if (n !=
nullptr && n->isAggregate()) {
1493 FunctionNode *fn = findMacroNode(t,
static_cast<Aggregate *>(n));
1502
1503
1504
1507 arg.remove(QChar(
'('));
1508 arg.remove(QChar(
')'));
1509 QString t = arg.simplified();
1510 QStringList sl = t.split(QChar(
' '));
1513 for (
const QString &s : sl) {
1514 if (!m_dontDocumentMap.contains(s))
1515 m_dontDocumentMap.insert(s,
nullptr);
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1534 for (
auto it = m_dontDocumentMap.begin(); it != m_dontDocumentMap.end(); ++it) {
1535 Aggregate *node = findAggregate(it.key());
1536 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