15using namespace Qt::Literals::StringLiterals;
20
21
24
25
26
27
28
31
32
33
34
35
38 for (
auto &child : m_children) {
41 if (child->parent() !=
this)
43 else if (child->isAggregate())
44 static_cast<Aggregate*>(child)->dropNonRelatedMembers();
49
50
54 if (isNamespace() && name().isEmpty())
55 dropNonRelatedMembers();
57 m_enumChildren.clear();
58 m_nonfunctionMap.clear();
59 m_functionMap.clear();
65
66
67
68
69
70
71
72
73
77 Node *node = m_nonfunctionMap.value(name);
81 const NodeList &nodes = m_nonfunctionMap.values(name);
82 for (
auto *node : nodes) {
83 if (genus & node->genus()) {
84 if (findFlags & TypesOnly) {
85 if (!node->isTypedef() && !node->isClassNode()
86 && !node->isQmlType() && !node->isEnumType())
88 }
else if (findFlags & IgnoreModules && node->isModule())
97 auto it = m_functionMap.find(name);
98 return it != m_functionMap.end() ? (*(*it).begin()) :
nullptr;
102
103
104
108 const auto &functions = m_functionMap.value(name);
109 nodes.reserve(functions.size() + m_nonfunctionMap.count(name));
110 for (
auto f : functions)
111 nodes.emplace_back(f);
112 auto [it, end] = m_nonfunctionMap.equal_range(name);
114 nodes.emplace_back(*it);
120
121
122
123
124
125
128 const NodeList &nodes = m_nonfunctionMap.values(name);
129 for (
auto *node : nodes) {
130 if ((node->*(isMatch))())
137
138
139
140
141
142
143
144
147 auto map_it = m_functionMap.find(name);
148 if (map_it == m_functionMap.end())
151 auto match_it =
std::find_if((*map_it).begin(), (*map_it).end(),
157 for (
int i = 0; i < parameters
.count(); ++i)
163 if (match_it != (*map_it).end())
168 auto *fn = (*(*map_it).begin());
169 return (parameters
.isEmpty() && !fn->isInternal()) ? fn :
nullptr;
173
174
175
176
177
178
181 auto funcs_it = m_functionMap.find(clone->name());
182 if (funcs_it == m_functionMap.end())
185 auto func_it =
std::find_if((*funcs_it).begin(), (*funcs_it).end(),
190 return func_it != (*funcs_it).end() ? *func_it :
nullptr;
194
195
196
197
200 for (
auto *child : std::as_const(m_children)) {
201 if (!child->hasDoc() && !child->isDontDocument()) {
202 if (!child->docMustBeGenerated()) {
203 if (child->isFunction()) {
204 if (
static_cast<FunctionNode *>(child)->hasAssociatedProperties())
206 }
else if (child->isTypedef()) {
207 if (
static_cast<TypedefNode *>(child)->hasAssociatedEnum())
210 child->setAccess(Access::Private);
211 child->setStatus(Node::Internal);
214 if (child->isAggregate()) {
215 static_cast<Aggregate *>(child)->markUndocumentedChildrenInternal();
221
222
223
224
225
226
227
230 Q_ASSERT(name().isEmpty());
233 for (
auto *node : m_children) {
234 if (node->isRelatedNonmember() || node->isAggregate())
236 if (node->genus() != Node::CPP)
239 const auto &relates_args = node->doc().metaCommandArgs(
"relates"_L1);
240 if (relates_args.isEmpty())
243 auto *aggregate = database->findRelatesNode(relates_args[0].first.split(
"::"_L1));
245 aggregate =
new ProxyNode(
this, relates_args[0].first);
246 else if (node->parent() == aggregate)
249 aggregate->adoptChild(node);
250 node->setRelatedNonmember(
true);
255
256
257
258
259
260
261
262
263
264
267 for (
auto map_it = m_functionMap.begin(); map_it != m_functionMap.end(); ++map_it) {
268 if ((*map_it).size() > 1) {
269 std::sort((*map_it).begin(), (*map_it).end(),
282 for (
auto *fn : (*map_it))
283 fn->setOverloadNumber(n++);
287 for (
auto *node : std::as_const(m_children)) {
288 if (node->isAggregate())
289 static_cast<Aggregate *>(node)->normalizeOverloads();
294
295
296
297
300 m_nonfunctionList = m_nonfunctionMap.values();
302 m_nonfunctionList.erase(
std::unique(m_nonfunctionList.begin(), m_nonfunctionList.end()),
303 m_nonfunctionList.end());
304 return m_nonfunctionList;
308
309
310
313
314
315
316
317
320 for (
const auto *node : m_enumChildren) {
321 const auto *en =
static_cast<
const EnumNode *>(node);
322 if (en->hasItem(enumValue))
329
330
331
332
333
336 m_nonfunctionMap.insert(title, child);
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
361 child->setUrl(QString());
365 m_functionMap[child->name()].emplace_back(
static_cast<FunctionNode *>(child));
366 }
else if (!child->name().isEmpty()) {
367 m_nonfunctionMap.insert(child->name(), child);
369 m_enumChildren.append(child);
374
375
376
377
378
379
380
387 m_functionMap[child->name()].emplace_back(
static_cast<FunctionNode *>(child));
388 }
else if (!child->name().isEmpty()) {
389 m_nonfunctionMap.insert(child->name(), child);
391 m_enumChildren.append(child);
395 for (Node *n : scn->collective())
402
403
404
408 for (
auto *child : std::as_const(m_children)) {
409 if (child->nodeType() == goal) {
410 if (child->name() == n)
411 return static_cast<QmlPropertyNode *>(child);
418
419
420
424 for (
auto *child : std::as_const(m_children)) {
425 if (child->nodeType() == goal) {
426 if (child->name() == n && child->isAttached() == attached)
427 return static_cast<QmlPropertyNode *>(child);
434
435
436
437
438
441 auto it = m_functionMap.find(fn->name());
442 return !(it == m_functionMap.end()) && (it.value().size() > 1);
446
447
448
449
450
451
452
461
462
463
464
465
466
467
470 for (
auto functions : m_functionMap) {
471 std::for_each(functions.begin(), functions.end(),
472 [&functionIndex](FunctionNode *fn) {
474 functionIndex[fn->name()].insert(fn->parent()->fullDocumentName(), fn);
479 for (Node *node : std::as_const(m_children)) {
480 if (node->isAggregate() && !node->isPrivate() && !node->isDontDocument())
481 static_cast<Aggregate *>(node)->findAllFunctions(functionIndex);
486
487
488
489
490
491
492
493
494
495
496
497
498
501 for (
auto *node : std::as_const(m_children)) {
502 if (node->isAggregate() && !node->isPrivate()) {
503 if (node->isNamespace() && !node->name().isEmpty())
504 namespaces.insert(node->name(), node);
505 static_cast<Aggregate *>(node)->findAllNamespaces(namespaces);
511
512
513
516 for (
const auto *node : m_children)
517 if (!node->isPrivate() && node->isDeprecated()) {
518 if (node->isFunction() || node->isProperty() || node->isEnumType() || node->isTypedef()
519 || node->isTypeAlias() || node->isVariable() || node->isQmlProperty())
526
527
528
529
530
533 for (
auto *node : std::as_const(m_children)) {
534 if (!node->isPrivate()) {
535 if (node->isDeprecated()) {
536 if (node->isClassNode())
537 QDocDatabase::obsoleteClasses().insert(node->qualifyCppName(), node);
538 else if (node->isQmlType())
539 QDocDatabase::obsoleteQmlTypes().insert(node->qualifyQmlName(), node);
540 }
else if (node->isClassNode()) {
541 auto *a =
static_cast<Aggregate *>(node);
542 if (a->hasObsoleteMembers())
543 QDocDatabase::classesWithObsoleteMembers().insert(node->qualifyCppName(), node);
544 }
else if (node->isQmlType()) {
545 auto *a =
static_cast<Aggregate *>(node);
546 if (a->hasObsoleteMembers())
547 QDocDatabase::qmlTypesWithObsoleteMembers().insert(node->qualifyQmlName(),
549 }
else if (node->isAggregate()) {
550 static_cast<Aggregate *>(node)->findAllObsoleteThings();
557
558
559
560
563 for (
auto *node : std::as_const(m_children)) {
564 if (!node->isPrivate() && !node->isInternal() && !node->isDontDocument()
565 && node->tree()->camelCaseModuleName() != QString(
"QDoc")) {
566 if (node->isClassNode()) {
567 QDocDatabase::cppClasses().insert(node->qualifyCppName().toLower(), node);
568 }
else if (node->isQmlType()) {
569 QString name = node->name().toLower();
570 QDocDatabase::qmlTypes().insert(name, node);
572 if (node->isQmlBasicType())
573 QDocDatabase::qmlBasicTypes().insert(name, node);
574 }
else if (node->isExample()) {
576 QString title = node->tree()->indexTitle();
577 if (!QDocDatabase::examples().contains(title, node))
578 QDocDatabase::examples().insert(title, node);
579 }
else if (node->isAggregate()) {
580 static_cast<Aggregate *>(node)->findAllClasses();
587
588
589
592 for (
auto *node : std::as_const(m_children)) {
593 if (!node->isPrivate()) {
594 if (node->isPageNode() &&
static_cast<PageNode*>(node)->isAttribution())
595 attributions.insert(node->tree()->indexTitle(), node);
596 else if (node->isAggregate())
597 static_cast<Aggregate *>(node)->findAllAttributions(attributions);
603
604
605
606
607
608
609
612 for (
auto *node : std::as_const(m_children)) {
613 if (node->isRelatedNonmember() && node->parent() !=
this)
615 QString sinceString = node->since();
617 if (node->isInAPI() && !sinceString.isEmpty()) {
620 auto &nsmap = QDocDatabase::newSinceMaps()[sinceString];
621 auto &ncmap = QDocDatabase::newClassMaps()[sinceString];
622 auto &nqcmap = QDocDatabase::newQmlTypeMaps()[sinceString];
624 if (node->isFunction()) {
626 auto *fn =
static_cast<FunctionNode *>(node);
627 if (!fn->isDeprecated() && !fn->isSomeCtor() && !fn->isDtor())
628 nsmap.insert(fn->name(), fn);
629 }
else if (node->isClassNode()) {
631 QString name = node->qualifyWithParentName();
632 nsmap.insert(name, node);
633 ncmap.insert(name, node);
634 }
else if (node->isQmlType()) {
636 QString name = node->qualifyWithParentName();
637 nsmap.insert(name, node);
638 nqcmap.insert(name, node);
639 }
else if (node->isQmlProperty()) {
641 nsmap.insert(node->name(), node);
644 QString name = node->qualifyWithParentName();
645 nsmap.insert(name, node);
649 if (node->isInAPI() && node->isEnumType()) {
650 for (
const auto &val :
static_cast<EnumNode *>(node)->items()) {
651 sinceString = val.since();
652 if (sinceString.isEmpty())
655 QDocDatabase::newEnumValueMaps()[sinceString].insert(
656 node->name() +
"::" + val.name(), node);
660 QDocDatabase::newSinceMaps()[sinceString].replace(QString(), node);
665 if (node->isAggregate())
666 static_cast<Aggregate *>(node)->findAllSince();
671
672
673
677 for (
auto *child : std::as_const(m_children)) {
678 if (!child->isQmlType())
680 static_cast<QmlTypeNode *>(child)->resolveInheritance(previousSearches);
685
686
687
688
694 return QLatin1String(
"Class");
696 return QLatin1String(
"Struct");
698 return QLatin1String(
"Union");
705 return QLatin1String(
"class");
707 return QLatin1String(
"struct");
709 return QLatin1String(
"union");
718
719
722
723
726
727
730
731
734
735
736
737
738
741
742
743
744
747
748
749
750
751
754
755
756
757
758
759
760
static bool keep(FunctionNode *fn)
void resolveRelates()
Adopts each non-aggregate C++ node (function/macro, typedef, enum, variable, or a shared comment node...
void adoptChild(Node *child)
This Aggregate becomes the adoptive parent of child.
QString typeWord(bool cap) const
Returns a word representing the kind of Aggregate this node is.
void resolveQmlInheritance()
Resolves the inheritance information for all QML type children of this aggregate.
void addChildByTitle(Node *child, const QString &title)
Adds the child to this node's child map using title as the key.
QmlPropertyNode * hasQmlProperty(const QString &) const
If this node has a child that is a QML property named n, return a pointer to that child.
bool hasOverloads(const FunctionNode *fn) const
Returns true if this aggregate has multiple function overloads matching the name of fn.
Node * findChildNode(const QString &name, Node::Genus genus, int findFlags=0) const
If genus is {Node::DontCare}, find the first node in this node's child list that has the given name.
void findAllObsoleteThings()
Finds all the obsolete C++ classes and QML types in this aggregate and all the C++ classes and QML ty...
~Aggregate() override
Destroys this Aggregate; deletes each child.
void findChildren(const QString &name, NodeVector &nodes) const
Find all the child nodes of this node that are named name and return them in nodes.
bool hasObsoleteMembers() const
Returns true if this aggregate contains at least one child that is marked obsolete.
FunctionNode * findFunctionChild(const QString &name, const Parameters ¶meters)
Find a function node that is a child of this node, such that the function node has the specified name...
void findAllSince()
Finds all the nodes in this node where a {since} command appeared in the qdoc comment and sorts them ...
void normalizeOverloads()
Sorts the lists of overloads in the function map and assigns overload numbers.
Node * findNonfunctionChild(const QString &name, bool(Node::*)() const)
This function searches for a child node of this Aggregate, such that the child node has the spacified...
void findAllFunctions(NodeMapMap &functionIndex)
Insert all functions declared in this aggregate into the functionIndex.
void findAllNamespaces(NodeMultiMap &namespaces)
For each child of this node, if the child is a namespace node, insert the child into the namespaces m...
void markUndocumentedChildrenInternal()
Mark all child nodes that have no documentation as having private access and internal status.
void addChild(Node *child)
Adds the child to this node's child list and sets the child's parent pointer to this Aggregate.
FunctionNode * findFunctionChild(const FunctionNode *clone)
Returns the function node that is a child of this node, such that the function described has the same...
QmlPropertyNode * hasQmlProperty(const QString &, bool attached) const
If this node has a child that is a QML property named n and that also matches attached,...
const NodeList & nonfunctionList()
Returns a const reference to the list of child nodes of this aggregate that are not function nodes.
void findAllClasses()
Finds all the C++ classes, QML types, QML basic types, and examples in this aggregate and inserts the...
void findAllAttributions(NodeMultiMap &attributions)
Find all the attribution pages in this node and insert them into attributions.
const EnumNode * findEnumNodeForValue(const QString &enumValue) const
Finds the enum type node that has enumValue as one of its enum values and returns a pointer to it.
This node is used to represent any kind of function being documented.
const Parameters & parameters() const
bool isDeprecated() const override
\reimp
friend int compare(const FunctionNode *f1, const FunctionNode *f2)
Compares FunctionNode f1 with f2, assumed to have identical names.
bool isPrivate() const
Returns true if this node's access is Private.
void setIndexNodeFlag(bool isIndexNode=true)
Sets a flag in this Node that indicates the node was created for something in an index file.
NodeType
An unsigned char value that identifies an object as a particular subclass of Node.
bool isFunction(Genus g=DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
bool isSharedCommentNode() const
Returns true if the node type is SharedComment.
virtual bool isInternal() const
Returns true if the node's status is Internal, or if its parent is a class with Internal status.
bool isEnumType() const
Returns true if the node type is Enum.
Aggregate * parent() const
Returns the node's parent pointer.
NodeType nodeType() const
Returns this node's type.
static bool nodeNameLessThan(const Node *first, const Node *second)
Returns true if the node n1 is less than node n2.
Genus
An unsigned char value that specifies whether the Node represents a C++ element, a QML element,...
Genus genus() const
Returns this node's Genus.
bool hasDoc() const
Returns true if this node is documented, or it represents a documented node read from the index ('had...
void setParent(Aggregate *n)
Sets the node's parent pointer to n.
LinkType
An unsigned char value that probably should be moved out of the Node base class.
bool isIndexNode() const
Returns true if this node was created from something in an index file.
A class for parsing and managing a function parameter list.
const Parameter & at(int i) const
This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a...
static QDocDatabase * qdocDB()
Creates the singleton.
QList< Node * > NodeVector
QMap< QString, Node * > NodeMap
QMap< QString, NodeMap > NodeMapMap
QMultiMap< QString, Node * > NodeMultiMap