27using namespace Qt::StringLiterals;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
47
48
49
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
69
70
71
72
73
74
75
77 : m_camelCaseModuleName(camelCaseModuleName),
78 m_physicalModuleName(camelCaseModuleName.toLower()),
80 m_root(
nullptr, QString())
82 m_root.setPhysicalModuleName(m_physicalModuleName);
87
88
89
90
91
92
93
94
95
96
99 qDeleteAll(m_nodesByTargetRef);
100 m_nodesByTargetRef.clear();
101 m_nodesByTargetTitle.clear();
107
108
109
110
111
112Node *
Tree::findNodeForInclude(
const QStringList &path)
const
114 Node *n = findClassNode(path);
116 n = findNamespaceNode(path);
121
122
123
124
125
126
127
130 QStringList path = name.split(QLatin1String(
"::"));
131 return static_cast<Aggregate *>(findNodeRecursive(path, 0,
const_cast<NamespaceNode *>(root()),
132 &Node::isFirstClassAggregate));
136
137
138
139
140
143 if (start ==
nullptr)
145 return static_cast<ClassNode *>(findNodeRecursive(path, 0, start, &Node::isClassNode));
149
150
151
152
156 return static_cast<NamespaceNode *>(findNodeRecursive(path, 0, start, &Node::isNamespace));
160
161
162
163
164
165
166
167
168
169
170
173 Node *n = findNodeRecursive(path, 0, root(), &Node::isRelatableType);
174 return (((n !=
nullptr) && n->isAggregate()) ?
static_cast<Aggregate *>(n) :
nullptr);
178
179
180
184 m_unresolvedPropertyMap[property].insert(funcRole, funcName);
188
189
190
191
192
193
194
197 for (
auto it = n->constBegin(); it != n->constEnd(); ++it) {
198 if ((*it)->isClassNode()) {
199 auto *cn =
static_cast<
ClassNode *>(*it);
200 QList<RelatedClass> &bases = cn->baseClasses_mutable();
201 for (
auto &base : bases) {
202 if (base.m_node ==
nullptr) {
203 Node *n = m_qdb->findClassNode(base.m_path);
205
206
207
208
209
210
211
212
213
215 Aggregate *parent = cn->parent();
216 if (parent !=
nullptr)
218 if (parent->isNamespace() && !parent->name().isEmpty())
219 n = findClassNode(base.m_path, parent);
222 auto *bcn =
static_cast<ClassNode *>(n);
224 bcn->addDerivedClass(base.m_access, cn);
228 resolveBaseClasses(cn);
229 }
else if ((*it)->isNamespace()) {
236
239 for (
auto node = n->constBegin(); node != n->constEnd(); ++node) {
240 if ((*node)->isClassNode()) {
241 auto *cn =
static_cast<
ClassNode *>(*node);
242 for (
auto property = cn->constBegin(); property != cn->constEnd(); ++property) {
243 if ((*property)->isProperty())
244 cn->resolvePropertyOverriddenFromPtrs(
static_cast<
PropertyNode *>(*property));
246 resolvePropertyOverriddenFromPtrs(cn);
247 }
else if ((*node)->isNamespace()) {
248 resolvePropertyOverriddenFromPtrs(
static_cast<
NamespaceNode *>(*node));
254
255
256
257
258
261 for (
auto propEntry = m_unresolvedPropertyMap.constBegin();
262 propEntry != m_unresolvedPropertyMap.constEnd(); ++propEntry) {
271 for (
auto it = parent->constBegin(); it != parent->constEnd(); ++it) {
272 if ((*it)->isFunction()) {
274 if (function->access() == property
->access()
275 && (function->status() == property
->status() || function->doc().isEmpty())) {
276 if (function->name() == getterName) {
278 }
else if (function->name() == setterName) {
280 }
else if (function->name() == resetterName) {
282 }
else if (function->name() == notifierName) {
284 }
else if (function->name() == bindableName) {
292 for (
auto propEntry = m_unresolvedPropertyMap.constBegin();
293 propEntry != m_unresolvedPropertyMap.constEnd(); ++propEntry) {
300 m_unresolvedPropertyMap.clear();
304
305
306
307
308
309
310
311
312
313
314
315void Tree::validatePropertyDocumentation(
const Aggregate *aggregate)
const
317 const auto &config = Config::instance();
318 const InclusionPolicy policy = config.createInclusionPolicy();
319 validatePropertyDocumentation(aggregate, policy);
323
324
325
326
327
328
329void Tree::validatePropertyDocumentation(
const Aggregate *aggregate,
const InclusionPolicy &policy)
const
331 for (
auto it = aggregate->constBegin(); it != aggregate->constEnd(); ++it) {
337 node
->location().warning(u"Undocumented property '%1'"_s.arg(node->plainFullName()));
341 validatePropertyDocumentation(
static_cast<Aggregate *>(node), policy);
346
347
348
349
350void Tree::resolveCppToQmlLinks()
353 const NodeList &children = m_root.childNodes();
354 for (
auto *child : children) {
355 if (child->isQmlType()) {
356 auto *qcn =
static_cast<QmlTypeNode *>(child);
357 auto *cn =
const_cast<ClassNode *>(qcn->classNode());
359 cn->insertQmlNativeType(qcn);
365
366
367
368
369
370
371
372
375 for (
auto *child : aggregate.childNodes()) {
378 if (child->isEnumType())
379 resolveEnumValueSince(
static_cast<EnumNode&>(*child));
380 if (!child->isAggregate())
382 if (!child->since().isEmpty())
385 if (
const auto collectionNode = m_qdb->getModuleNode(child))
386 child->setSince(collectionNode->since());
388 resolveSince(
static_cast<Aggregate&>(*child));
393
394
395
396
397
398
399
400
403 const QStringList enumItems{en
.doc().enumItemNames()};
404 const Atom *atom = en
.doc().body().firstAtom();
410 if (
const auto &val = atom->string(); enumItems.contains(val)) {
418
419
420
421
422
423
424
425
428 if (rootNode ==
nullptr)
431 for (
auto node = rootNode->constBegin(); node != rootNode->constEnd(); ++node) {
432 if ((*node)->isClassNode())
434 else if ((*node)->isNamespace())
435 removePrivateAndInternalBases(
static_cast<
NamespaceNode *>(*node));
440
444 const auto &baseClasses = classNode->baseClasses();
445 for (
const auto &relatedClass : baseClasses) {
446 if (relatedClass.m_node !=
nullptr) {
447 result += relatedClass.m_node;
448 result += allBaseClasses(relatedClass.m_node);
455
456
457
458
459
460
463 return findNodeRecursive(path, 0, root(), isMatch);
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482Node *
Tree::findNodeRecursive(
const QStringList &path,
int pathIndex,
const Node *start,
483 bool (Node::*isMatch)()
const)
const
485 if (start ==
nullptr || path.isEmpty())
487 Node *node =
const_cast<
Node *>(start);
489 return ((pathIndex >= path.size()) ? node :
nullptr);
490 auto *current =
static_cast<Aggregate *>(node);
491 const NodeList &children = current->childNodes();
492 const QString &name = path.at(pathIndex);
493 for (
auto *node : children) {
496 if (node->name() == name) {
497 if (pathIndex + 1 >= path.size()) {
498 if ((node->*(isMatch))())
502 node = findNodeRecursive(path, pathIndex + 1, node, isMatch);
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527const Node *
Tree::findNodeForTarget(
const QStringList &path,
const QString &target,
528 const Node *start,
int flags, Genus genus,
531 const Node *node =
nullptr;
535 auto set_ref_from_target = [
this, &ref, &target](
const Node *n) ->
const Node* {
536 if (!target.isEmpty()) {
537 if (ref = getRef(target, n); ref.isEmpty())
543 if (genus == Genus::DontCare || genus == Genus::DOC) {
544 if (node = findPageNodeByTitle(path.at(0)); node) {
545 if (node = set_ref_from_target(node); node)
551
552
553
554
555
556 const bool prioritizeHierarchy = start &&
557 ((start
->isClassNode() && (genus == Genus::CPP || genus == Genus::DontCare)) ||
558 (start
->isQmlType() && (genus == Genus::QML || genus == Genus::DontCare)));
561 if (!prioritizeHierarchy) {
562 result = findUnambiguousTarget(path.join(QLatin1String(
"::")), genus, start);
565 if (node = set_ref_from_target(result
->m_node); node) {
578 const Node *current = start ? start : root();
580
581
582
583
584
586 if ((genus == Genus::QML || genus == Genus::DontCare)
587 && path.size() >= 2 && !path[0].isEmpty()) {
588 if (
auto *qcn = lookupQmlType(path.sliced(0, 2).join(QLatin1String(
"::")), start); qcn) {
591 if (path.size() == 2)
592 return set_ref_from_target(qcn);
599 if (
const Node *match = matchPathAndTarget(
600 path, path_idx, target, current, flags, genus, ref);
609 if (prioritizeHierarchy) {
610 result = findUnambiguousTarget(path.join(QLatin1String(
"::")), genus, start);
613 if (node = set_ref_from_target(result
->m_node); node) {
621 if (node && result) {
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650const Node *
Tree::matchPathAndTarget(
const QStringList &path,
int idx,
const QString &target,
651 const Node *node,
int flags, Genus genus,
652 QString &ref,
int duplicates)
const
655
656
657
658
659 if (idx == path.size()) {
660 if (!target.isEmpty()) {
661 ref = getRef(target, node);
686 QString name = path.at(idx);
689 static_cast<
const Aggregate *>(node)->findChildren(name, nodes);
690 for (
const auto *child : std::as_const(nodes)) {
691 if (genus != Genus::DontCare && !(hasCommonGenusType(genus, child->genus())))
693 const Node *t = matchPathAndTarget(path, idx + 1, target, child, flags, genus, ref, nodes.count() - 1);
694 if (t && !t->isPrivate() && !t->isInternal())
699 const auto *enumNode = node->isAggregate() ?
700 findEnumNode(
nullptr, node, path, idx) :
701 findEnumNode(node,
nullptr, path, idx);
705 if (((genus == Genus::CPP) || (genus == Genus::DontCare)) && node
->isClassNode()
707 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(node));
708 for (
const auto *base : bases) {
709 const Node *t = matchPathAndTarget(path, idx, target, base, flags, genus, ref);
710 if (t && !t->isPrivate() && !t->isInternal())
712 if (target.isEmpty() && (flags & SearchEnumValues)) {
713 if ((t = findEnumNode(base->findChildNode(path.at(idx), genus, flags), base, path, idx)))
718 if (((genus == Genus::QML) || (genus == Genus::DontCare)) && node
->isQmlType()
720 const QmlTypeNode *qtn =
static_cast<
const QmlTypeNode *>(node);
723 const Node *t = matchPathAndTarget(path, idx, target, qtn, flags, genus, ref);
732
733
734
735
736
737const Node *
Tree::findNode(
const QStringList &path,
const Node *start,
int flags,
740 const Node *current = start;
741 if (current ==
nullptr)
745 const Node *node = current;
750
751
752
753
754
755
756
757 if (((genus == Genus::QML) || (genus == Genus::DontCare)) && (path.size() >= 2)
758 && !path[0].isEmpty()) {
759 QmlTypeNode *qcn = lookupQmlType(QString(path[0] +
"::" + path[1]), start);
760 if (qcn !=
nullptr) {
762 if (path.size() == 2)
768 for (i = start_idx; i < path.size(); ++i) {
777 const Node *next =
static_cast<
const Aggregate *>(node)->findChildNode(path.at(i),
779 const Node *enumNode = (flags & SearchEnumValues) ?
780 findEnumNode(next, node, path, i) :
nullptr;
786 if (!next && ((genus == Genus::CPP) || (genus == Genus::DontCare))
788 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(node));
789 for (
const auto *base : bases) {
790 next = base->findChildNode(path.at(i), genus, tmpFlags);
791 if (flags & SearchEnumValues)
792 if ((enumNode = findEnumNode(next, base, path, i)))
798 if (!next && ((genus == Genus::QML) || (genus == Genus::DontCare))
800 const QmlTypeNode *qtn =
static_cast<
const QmlTypeNode *>(node);
803 next = qtn->findChildNode(path.at(i), genus, tmpFlags);
808 if ((node !=
nullptr) && i == path.size())
811 }
while (current !=
nullptr);
818
819
820
821
822
823
824
825const Node *
Tree::findEnumNode(
const Node *node,
const Node *aggregate,
const QStringList &path,
int offset)
const
829 const auto *en =
static_cast<
const EnumNode*>(node);
830 if (en->hasItem(path.last()))
835 return (!node && aggregate && offset == path.size() - 1) ?
836 static_cast<
const Aggregate *>(aggregate)->findEnumNodeForValue(path.last()) :
841
842
843
844
845
846QString
Tree::getRef(
const QString &target,
const Node *node)
const
848 auto it = m_nodesByTargetTitle.constFind(target);
849 if (it != m_nodesByTargetTitle.constEnd()) {
851 if (it.value()->m_node == node)
852 return it.value()->m_ref;
854 }
while (it != m_nodesByTargetTitle.constEnd() && it.key() == target);
856 QString key = TextUtils::asAsciiPrintable(target);
857 it = m_nodesByTargetRef.constFind(key);
858 if (it != m_nodesByTargetRef.constEnd()) {
860 if (it.value()->m_node == node)
861 return it.value()->m_ref;
863 }
while (it != m_nodesByTargetRef.constEnd() && it.key() == key);
869
870
871
872
873
875 Node *node,
int priority)
877 auto *target =
new TargetRec(name, type, node, priority);
878 m_nodesByTargetRef.insert(name, target);
879 m_nodesByTargetTitle.insert(title, target);
883
884
885
886
887
888
889
892 for (
auto *child : root->childNodes()) {
893 addToPageNodeByTitleMap(child);
894 populateTocSectionTargetMap(child);
895 addKeywordsToTargetMaps(child);
896 addTargetsToTargetMap(child);
898 if (child->isAggregate())
899 resolveTargets(
static_cast<Aggregate *>(child));
904
905
906
907
908void Tree::addTargetsToTargetMap(
Node *node) {
912 for (Atom *i : std::as_const(node->doc().targets())) {
913 const QString ref = refForAtom(i);
914 const QString title = i->string();
915 if (!ref.isEmpty() && !title.isEmpty()) {
916 QString key = TextUtils::asAsciiPrintable(title);
917 auto *target =
new TargetRec(std::move(ref), TargetRec::Target, node, 2);
918 m_nodesByTargetRef.insert(key, target);
919 m_nodesByTargetTitle.insert(title, target);
925
926
927
928
937
938
939
940
941void Tree::addKeywordsToTargetMaps(
Node *node) {
945 for (Atom *i : std::as_const(node->doc().keywords())) {
946 QString ref = refForAtom(i);
947 QString title = i->string();
948 if (!ref.isEmpty() && !title.isEmpty()) {
949 auto *target =
new TargetRec(ref, nextSection(i) ? TargetRec::ContentsKeyword : TargetRec::Keyword, node, 1);
950 m_nodesByTargetRef.insert(TextUtils::asAsciiPrintable(title), target);
951 m_nodesByTargetTitle.insert(title, target);
952 if (!target->isEmpty())
953 i->append(target->m_ref);
959
960
961
962
963
964void Tree::populateTocSectionTargetMap(
Node *node) {
968 QStack<Atom *> tocLevels;
969 QSet<QString> anchors;
973 for (Atom *atom: std::as_const(node->doc().tableOfContents())) {
974 while (!tocLevels.isEmpty() && tocLevels.top()->string().toInt() >= atom->string().toInt())
977 tocLevels.push(atom);
979 QString ref = refForAtom(atom);
980 const QString &title = Text::sectionHeading(atom).toString();
981 if (ref.isEmpty() || title.isEmpty())
984 if (anchors.contains(ref)) {
985 QStringList refParts;
986 for (
const auto tocLevel : tocLevels)
987 refParts << refForAtom(tocLevel);
989 refParts << QString::number(index);
990 ref = refParts.join(QLatin1Char(
'-'));
994 if (atom->next(Atom::SectionHeadingLeft))
995 atom->next()->append(ref);
998 const QString &key = TextUtils::asAsciiPrintable(title);
999 auto *target =
new TargetRec(ref, TargetRec::Contents, node, 3);
1000 m_nodesByTargetRef.insert(key, target);
1001 m_nodesByTargetTitle.insert(title, target);
1006
1007
1008
1009
1010
1011void Tree::addToPageNodeByTitleMap(
Node *node) {
1015 auto *pageNode =
static_cast<PageNode *>(node);
1016 QString key = pageNode->title();
1020 if (key.contains(QChar(
' ')))
1021 key = TextUtils::asAsciiPrintable(key);
1022 const QList<PageNode *> nodes = m_pageNodesByTitle.values(key);
1024 bool alreadyThere =
std::any_of(nodes.cbegin(), nodes.cend(), [&](
const auto &knownNode) {
1025 return knownNode->isExternalPage() && knownNode->name() == pageNode->name();
1029 m_pageNodesByTitle.insert(key, pageNode);
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049const TargetRec *
Tree::findUnambiguousTarget(
const QString &target, Genus genus,
const Node *start)
const
1052 auto closelyRelated = [](
const Node *n1,
const Node *n2) {
1055 return (n1 == n2) || (n1->parent() == n2) || (n1 == n2->parent());
1058 enum class TargetCategory { Keyword, Nearby, Other };
1060 auto rank = [&](
const TargetRec *candidate) {
1061 auto category = TargetCategory::Other;
1063 category = TargetCategory::Keyword;
1064 }
else if (closelyRelated(candidate
->m_node, start)) {
1065 category = TargetCategory::Nearby;
1068 return std::pair{category, candidate->m_priority};
1071 auto findBestCandidate = [&](
const TargetMap &tgtMap,
const QString &key) {
1073 auto [it, end] = tgtMap.equal_range(key);
1076 if ((genus == Genus::DontCare) || hasCommonGenusType(genus, candidate
->genus())) {
1077 if (!best || rank(candidate) < rank(best))
1085 TargetRec *bestTarget = findBestCandidate(m_nodesByTargetTitle, target);
1087 bestTarget = findBestCandidate(m_nodesByTargetRef, TextUtils::asAsciiPrintable(target));
1093
1094
1095const PageNode *
Tree::findPageNodeByTitle(
const QString &title)
const
1097 PageNodeMultiMap::const_iterator it;
1098 if (title.contains(QChar(
' ')))
1099 it = m_pageNodesByTitle.constFind(TextUtils::asAsciiPrintable(title));
1101 it = m_pageNodesByTitle.constFind(title);
1102 if (it != m_pageNodesByTitle.constEnd()) {
1104
1105
1106
1107
1108 PageNodeMultiMap::const_iterator j = it;
1110 if (j != m_pageNodesByTitle.constEnd() && j.key() == it.key()) {
1111 while (j != m_pageNodesByTitle.constEnd()) {
1112 if (j.key() == it.key() && j.value()->url().isEmpty()) {
1117 if (j != m_pageNodesByTitle.cend()) {
1118 it.value()->location().warning(
"This page title exists in more than one file: "
1120 j.value()->location().warning(
"[It also exists here]");
1129
1130
1131
1132
1133
1134
1144 if (atom->count() == 2)
1145 return atom->string(1);
1150 if (
const auto *section = nextSection(atom))
1151 return refForAtom(section);
1152 return TextUtils::asAsciiPrintable(atom->string());
1159
1160
1161
1162
1165
1166
1167
1168
1171
1172
1173
1174
1177
1178
1179
1188 return &m_qmlModules;
1198
1199
1200
1201
1202
1205 CNMap *map = getCollectionMap(type);
1207 auto it = map->constFind(name);
1208 if (it != map->cend())
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1230 CNMap *m = getCollectionMap(type);
1233 auto it = m->constFind(name);
1234 if (it != m->cend())
1238 m->insert(name, cn);
1243
1244
1245
1246
1247
1248
1249
1252
1253
1254
1255
1256
1257
1258
1261
1262
1263
1264
1265
1266
1267
1270
1271
1272
1273
1274
1275
1278
1279
1280
1281
1282
1283
1286
1287
1288
1289
1290
1291
1294
1295
1296
1297
1298
1299
1300
1301
1307 node->appendGroupName(name);
1313
1314
1315
1316
1317
1318
1323 node->setPhysicalModuleName(name);
1328
1329
1330
1331
1332
1336 QStringList dotSplit;
1337 QStringList blankSplit = name.split(QLatin1Char(
' '));
1338 qmid.append(blankSplit[0]);
1339 if (blankSplit.size() > 1) {
1340 qmid.append(blankSplit[0] + blankSplit[1]);
1341 dotSplit = blankSplit[1].split(QLatin1Char(
'.'));
1342 qmid.append(blankSplit[0] + dotSplit[0]);
1349 QmlTypeNode *n =
static_cast<QmlTypeNode *>(node);
1350 for (
int i = 0; i < qmid.size(); ++i) {
1351 QString key = qmid[i] +
"::" + node->name();
1352 insertQmlType(key, n);
1355 insertQmlType(node->name(), n);
1361
1362
1363
1364
1367 m_qmlTypeMap.insert(key, n);
1371
1372
1373
1374
1375
1378 auto values = m_qmlTypeMap.values(name);
1379 if (values.isEmpty())
1383 if (!relative || values.size() == 1)
1384 return values.first();
1388 const auto *relativeQmlType =
static_cast<
const QmlTypeNode *>(relative);
1389 const CollectionNode *relativeModule = relativeQmlType->logicalModule();
1391 for (
auto *candidate : values) {
1392 if (candidate->logicalModule() == relativeModule)
1398 return values.first();
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1414 const Node *relative, Genus genus)
const
1416 if (path.size() == 3 && !path[0].isEmpty()
1417 && ((genus == Genus::QML) || (genus == Genus::DontCare))) {
1418 QmlTypeNode *qcn = lookupQmlType(QString(path[0] +
"::" + path[1]), relative);
1419 if (qcn ==
nullptr) {
1420 QStringList p(path[1]);
1421 Node *n = findNodeByNameAndType(p, &Node::isQmlType);
1422 if ((n !=
nullptr) && n->isQmlType())
1423 qcn =
static_cast<QmlTypeNode *>(n);
1429 if (relative ==
nullptr)
1431 else if (genus != Genus::DontCare) {
1432 if (!(hasCommonGenusType(genus, relative
->genus())))
1437 Node *node =
const_cast<
Node *>(relative);
1440 for (i = 0; i < path.size(); ++i) {
1444 Aggregate *aggregate =
static_cast<Aggregate *>(node);
1445 Node *next =
nullptr;
1446 if (i == path.size() - 1)
1449 next = aggregate->findChildNode(path.at(i), genus);
1452 const ClassList bases = allBaseClasses(
static_cast<
const ClassNode *>(aggregate));
1453 for (
auto *base : bases) {
1454 if (i == path.size() - 1)
1455 next = base->findFunctionChild(path.at(i), parameters);
1457 next = base->findChildNode(path.at(i), genus);
1459 if (next !=
nullptr)
1475 const FunctionNode *fn =
static_cast<
const FunctionNode *>(node);
1477 while (FN
->isPrivate() && !FN->overridesThis().isEmpty()) {
1478 QStringList path = FN->overridesThis().split(
"::");
1479 FN = m_qdb->findFunctionNode(path, parameters, relative, genus);
1493
1494
1495
1496
1499 if (parent ==
nullptr)
1502 for (Node *n : children) {
1503 if (n !=
nullptr && n->isFunction() && n->hasTag(tag))
1504 return static_cast<FunctionNode *>(n);
1506 for (Node *n : children) {
1507 if (n !=
nullptr && n->isAggregate()) {
1508 n = findFunctionNodeForTag(tag,
static_cast<Aggregate *>(n));
1510 return static_cast<FunctionNode *>(n);
1517
1518
1519
1522 if (parent ==
nullptr)
1525 for (Node *n : children) {
1526 if (n !=
nullptr && (n->isMacro() || n->isFunction()) && n->name() == t)
1527 return static_cast<FunctionNode *>(n);
1529 for (Node *n : children) {
1530 if (n !=
nullptr && n->isAggregate()) {
1531 FunctionNode *fn = findMacroNode(t,
static_cast<Aggregate *>(n));
1540
1541
1542
1545 arg.remove(QChar(
'('));
1546 arg.remove(QChar(
')'));
1547 QString t = arg.simplified();
1548 QStringList sl = t.split(QChar(
' '));
1551 for (
const QString &s : sl) {
1552 if (!m_dontDocumentMap.contains(s))
1553 m_dontDocumentMap.insert(s,
nullptr);
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1572 for (
auto it = m_dontDocumentMap.begin(); it != m_dontDocumentMap.end(); ++it) {
1573 Aggregate *node = findAggregate(it.key());
1574 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