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);
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) {
332 if (InclusionFilter::requiresDocumentation(policy, context))
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);
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,
651
652
653
654
655 if (idx == path.size()) {
656 if (!target.isEmpty()) {
657 ref = getRef(target, node);
666 QString name = path.at(idx);
669 static_cast<
const Aggregate *>(node)->findChildren(name, nodes);
670 for (
const auto *child : std::as_const(nodes)) {
671 if (genus != Genus::DontCare && !(hasCommonGenusType(genus, child->genus())))
673 const Node *t = matchPathAndTarget(path, idx + 1, target, child, flags, genus, ref);
674 if (t && !t->isPrivate() && !t->isInternal())
679 const auto *enumNode = node->isAggregate() ?
680 findEnumNode(
nullptr, node, path, idx) :
681 findEnumNode(node,
nullptr, path, idx);
685 if (((genus == Genus::CPP) || (genus == Genus::DontCare)) && node
->isClassNode()
688 for (
const auto *base : bases) {
689 const Node *t = matchPathAndTarget(path, idx, target, base, flags, genus, ref);
690 if (t && !t->isPrivate() && !t->isInternal())
692 if (target.isEmpty() && (flags & SearchEnumValues)) {
693 if ((t = findEnumNode(base->findChildNode(path.at(idx), genus, flags), base, path, idx)))
698 if (((genus == Genus::QML) || (genus == Genus::DontCare)) && node
->isQmlType()
703 const Node *t = matchPathAndTarget(path, idx, target, qtn, flags, genus, ref);
712
713
714
715
716
717const Node *
Tree::findNode(
const QStringList &path,
const Node *start,
int flags,
720 const Node *current = start;
721 if (current ==
nullptr)
725 const Node *node = current;
730
731
732
733
734
735
736
737 if (((genus == Genus::QML) || (genus == Genus::DontCare)) && (path.size() >= 2)
738 && !path[0].isEmpty()) {
739 QmlTypeNode *qcn = lookupQmlType(QString(path[0] +
"::" + path[1]), start);
740 if (qcn !=
nullptr) {
742 if (path.size() == 2)
748 for (i = start_idx; i < path.size(); ++i) {
757 const Node *next =
static_cast<
const Aggregate *>(node)->findChildNode(path.at(i),
759 const Node *enumNode = (flags & SearchEnumValues) ?
760 findEnumNode(next, node, path, i) :
nullptr;
766 if (!next && ((genus == Genus::CPP) || (genus == Genus::DontCare))
769 for (
const auto *base : bases) {
770 next = base->findChildNode(path.at(i), genus, tmpFlags);
771 if (flags & SearchEnumValues)
772 if ((enumNode = findEnumNode(next, base, path, i)))
778 if (!next && ((genus == Genus::QML) || (genus == Genus::DontCare))
783 next = qtn->findChildNode(path.at(i), genus, tmpFlags);
788 if ((node !=
nullptr) && i == path.size())
791 }
while (current !=
nullptr);
798
799
800
801
802
803
804
805const Node *
Tree::findEnumNode(
const Node *node,
const Node *aggregate,
const QStringList &path,
int offset)
const
809 const auto *en =
static_cast<
const EnumNode*>(node);
815 return (!node && aggregate && offset == path.size() - 1) ?
816 static_cast<
const Aggregate *>(aggregate)->findEnumNodeForValue(path.last()) :
821
822
823
824
825
826QString
Tree::getRef(
const QString &target,
const Node *node)
const
828 auto it = m_nodesByTargetTitle.constFind(target);
829 if (it != m_nodesByTargetTitle.constEnd()) {
831 if (it.value()->m_node == node)
832 return it.value()->m_ref;
834 }
while (it != m_nodesByTargetTitle.constEnd() && it.key() == target);
836 QString key = Utilities::asAsciiPrintable(target);
837 it = m_nodesByTargetRef.constFind(key);
838 if (it != m_nodesByTargetRef.constEnd()) {
840 if (it.value()->m_node == node)
841 return it.value()->m_ref;
843 }
while (it != m_nodesByTargetRef.constEnd() && it.key() == key);
849
850
851
852
853
855 Node *node,
int priority)
857 auto *target =
new TargetRec(name, type, node, priority);
858 m_nodesByTargetRef.insert(name, target);
859 m_nodesByTargetTitle.insert(title, target);
863
864
865
866
867
868
869
872 for (
auto *child : root->childNodes()) {
873 addToPageNodeByTitleMap(child);
874 populateTocSectionTargetMap(child);
875 addKeywordsToTargetMaps(child);
876 addTargetsToTargetMap(child);
878 if (child->isAggregate())
879 resolveTargets(
static_cast<Aggregate *>(child));
884
885
886
887
888void Tree::addTargetsToTargetMap(
Node *node) {
892 for (Atom *i : std::as_const(node->doc().targets())) {
893 const QString ref = refForAtom(i);
894 const QString title = i->string();
895 if (!ref.isEmpty() && !title.isEmpty()) {
896 QString key = Utilities::asAsciiPrintable(title);
897 auto *target =
new TargetRec(std::move(ref), TargetRec::Target, node, 2);
898 m_nodesByTargetRef.insert(key, target);
899 m_nodesByTargetTitle.insert(title, target);
905
906
907
908
917
918
919
920
921void Tree::addKeywordsToTargetMaps(
Node *node) {
925 for (Atom *i : std::as_const(node->doc().keywords())) {
926 QString ref = refForAtom(i);
927 QString title = i->string();
928 if (!ref.isEmpty() && !title.isEmpty()) {
929 auto *target =
new TargetRec(ref, nextSection(i) ? TargetRec::ContentsKeyword : TargetRec::Keyword, node, 1);
930 m_nodesByTargetRef.insert(Utilities::asAsciiPrintable(title), target);
931 m_nodesByTargetTitle.insert(title, target);
932 if (!target->isEmpty())
933 i->append(target->m_ref);
939
940
941
942
943
944void Tree::populateTocSectionTargetMap(
Node *node) {
948 QStack<Atom *> tocLevels;
949 QSet<QString> anchors;
953 for (Atom *atom: std::as_const(node->doc().tableOfContents())) {
954 while (!tocLevels.isEmpty() && tocLevels.top()->string().toInt() >= atom->string().toInt())
957 tocLevels.push(atom);
959 QString ref = refForAtom(atom);
960 const QString &title = Text::sectionHeading(atom).toString();
961 if (ref.isEmpty() || title.isEmpty())
964 if (anchors.contains(ref)) {
965 QStringList refParts;
966 for (
const auto tocLevel : tocLevels)
967 refParts << refForAtom(tocLevel);
969 refParts << QString::number(index);
970 ref = refParts.join(QLatin1Char(
'-'));
974 if (atom->next(Atom::SectionHeadingLeft))
975 atom->next()->append(ref);
978 const QString &key = Utilities::asAsciiPrintable(title);
979 auto *target =
new TargetRec(ref, TargetRec::Contents, node, 3);
980 m_nodesByTargetRef.insert(key, target);
981 m_nodesByTargetTitle.insert(title, target);
986
987
988
989
990
991void Tree::addToPageNodeByTitleMap(
Node *node) {
995 auto *pageNode =
static_cast<
PageNode *>(node);
996 QString key = pageNode->title();
1000 if (key.contains(QChar(
' ')))
1001 key = Utilities::asAsciiPrintable(key);
1002 const QList<PageNode *> nodes = m_pageNodesByTitle.values(key);
1004 bool alreadyThere =
std::any_of(nodes.cbegin(), nodes.cend(), [&](
const auto &knownNode) {
1005 return knownNode->isExternalPage() && knownNode->name() == pageNode->name();
1009 m_pageNodesByTitle.insert(key, pageNode);
1013
1014
1015
1016const TargetRec *
Tree::findUnambiguousTarget(
const QString &target, Genus genus)
const
1018 auto findBestCandidate = [&](
const TargetMap &tgtMap,
const QString &key) {
1020 auto [it, end] = tgtMap.equal_range(key);
1023 if ((genus == Genus::DontCare) || (hasCommonGenusType(genus, candidate
->genus()))) {
1032 TargetRec *bestTarget = findBestCandidate(m_nodesByTargetTitle, target);
1034 bestTarget = findBestCandidate(m_nodesByTargetRef, Utilities::asAsciiPrintable(target));
1040
1041
1042const PageNode *
Tree::findPageNodeByTitle(
const QString &title)
const
1044 PageNodeMultiMap::const_iterator it;
1045 if (title.contains(QChar(
' ')))
1046 it = m_pageNodesByTitle.constFind(Utilities::asAsciiPrintable(title));
1048 it = m_pageNodesByTitle.constFind(title);
1049 if (it != m_pageNodesByTitle.constEnd()) {
1051
1052
1053
1054
1055 PageNodeMultiMap::const_iterator j = it;
1057 if (j != m_pageNodesByTitle.constEnd() && j.key() == it.key()) {
1058 while (j != m_pageNodesByTitle.constEnd()) {
1059 if (j.key() == it.key() && j.value()->url().isEmpty()) {
1064 if (j != m_pageNodesByTitle.cend()) {
1065 it.value()->location().warning(
"This page title exists in more than one file: "
1067 j.value()->location().warning(
"[It also exists here]");
1076
1077
1078
1079
1080
1081
1091 if (atom->count() == 2)
1092 return atom->string(1);
1097 if (
const auto *section = nextSection(atom))
1098 return refForAtom(section);
1099 return Utilities::asAsciiPrintable(atom->string());
1106
1107
1108
1109
1112
1113
1114
1115
1118
1119
1120
1121
1124
1125
1126
1135 return &m_qmlModules;
1143
1144
1145
1146
1147
1150 CNMap *map = getCollectionMap(type);
1152 auto it = map->constFind(name);
1153 if (it != map->cend())
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1175 CNMap *m = getCollectionMap(type);
1178 auto it = m->constFind(name);
1179 if (it != m->cend())
1183 m->insert(name, cn);
1188
1189
1190
1191
1192
1193
1194
1197
1198
1199
1200
1201
1202
1203
1206
1207
1208
1209
1210
1211
1212
1215
1216
1217
1218
1219
1220
1223
1224
1225
1226
1227
1228
1231
1232
1233
1234
1235
1236
1239
1240
1241
1242
1243
1244
1245
1246
1252 node->appendGroupName(name);
1258
1259
1260
1261
1262
1263
1268 node->setPhysicalModuleName(name);
1273
1274
1275
1276
1277
1281 QStringList dotSplit;
1282 QStringList blankSplit = name.split(QLatin1Char(
' '));
1283 qmid.append(blankSplit[0]);
1284 if (blankSplit.size() > 1) {
1285 qmid.append(blankSplit[0] + blankSplit[1]);
1286 dotSplit = blankSplit[1].split(QLatin1Char(
'.'));
1287 qmid.append(blankSplit[0] + dotSplit[0]);
1295 for (
int i = 0; i < qmid.size(); ++i) {
1296 QString key = qmid[i] +
"::" + node->name();
1297 insertQmlType(key, n);
1300 insertQmlType(node->name(), n);
1306
1307
1308
1309
1312 m_qmlTypeMap.insert(key, n);
1316
1317
1318
1319
1320
1323 auto values = m_qmlTypeMap.values(name);
1324 if (values.isEmpty())
1328 if (!relative || values.size() == 1)
1329 return values.first();
1333 const auto *relativeQmlType =
static_cast<
const QmlTypeNode *>(relative);
1336 for (
auto *candidate : values) {
1337 if (candidate->logicalModule() == relativeModule)
1343 return values.first();
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1359 const Node *relative, Genus genus)
const
1361 if (path.size() == 3 && !path[0].isEmpty()
1362 && ((genus == Genus::QML) || (genus == Genus::DontCare))) {
1363 QmlTypeNode *qcn = lookupQmlType(QString(path[0] +
"::" + path[1]), relative);
1364 if (qcn ==
nullptr) {
1365 QStringList p(path[1]);
1366 Node *n = findNodeByNameAndType(p, &Node::isQmlType);
1374 if (relative ==
nullptr)
1376 else if (genus != Genus::DontCare) {
1377 if (!(hasCommonGenusType(genus, relative
->genus())))
1382 Node *node =
const_cast<
Node *>(relative);
1385 for (i = 0; i < path.size(); ++i) {
1390 Node *next =
nullptr;
1391 if (i == path.size() - 1)
1394 next = aggregate->findChildNode(path.at(i), genus);
1398 for (
auto *base : bases) {
1399 if (i == path.size() - 1)
1400 next = base->findFunctionChild(path.at(i), parameters);
1402 next = base->findChildNode(path.at(i), genus);
1404 if (next !=
nullptr)
1422 while (FN
->isPrivate() && !FN->overridesThis().isEmpty()) {
1423 QStringList path = FN->overridesThis().split(
"::");
1424 FN = m_qdb->findFunctionNode(path, parameters, relative, genus);
1438
1439
1440
1441
1444 if (parent ==
nullptr)
1447 for (Node *n : children) {
1448 if (n !=
nullptr && n->isFunction() && n->hasTag(tag))
1449 return static_cast<FunctionNode *>(n);
1451 for (Node *n : children) {
1452 if (n !=
nullptr && n->isAggregate()) {
1453 n = findFunctionNodeForTag(tag,
static_cast<Aggregate *>(n));
1455 return static_cast<FunctionNode *>(n);
1462
1463
1464
1467 if (parent ==
nullptr)
1470 for (Node *n : children) {
1471 if (n !=
nullptr && (n->isMacro() || n->isFunction()) && n->name() == t)
1472 return static_cast<FunctionNode *>(n);
1474 for (Node *n : children) {
1475 if (n !=
nullptr && n->isAggregate()) {
1476 FunctionNode *fn = findMacroNode(t,
static_cast<Aggregate *>(n));
1485
1486
1487
1490 arg.remove(QChar(
'('));
1491 arg.remove(QChar(
')'));
1492 QString t = arg.simplified();
1493 QStringList sl = t.split(QChar(
' '));
1496 for (
const QString &s : sl) {
1497 if (!m_dontDocumentMap.contains(s))
1498 m_dontDocumentMap.insert(s,
nullptr);
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1517 for (
auto it = m_dontDocumentMap.begin(); it != m_dontDocumentMap.end(); ++it) {
1518 Aggregate *node = findAggregate(it.key());
1519 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.
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...
QmlTypeNode * qmlBaseNode() const override
If this Aggregate is a QmlTypeNode, this function returns a pointer to the QmlTypeNode that is its ba...
CollectionNode * logicalModule() const override
If this is a QmlTypeNode, a pointer to its QML module is returned, which is a pointer to a Collection...
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.
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...
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.
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