Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
aggregate.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "aggregate.h"
5
6#include "functionnode.h"
7#include "parameters.h"
8#include "typedefnode.h"
9#include "qdocdatabase.h"
11#include "qmltypenode.h"
13#include <vector>
14
15using namespace Qt::Literals::StringLiterals;
16
17QT_BEGIN_NAMESPACE
18
19/*!
20 \class Aggregate
21 */
22
23/*! \fn Aggregate::Aggregate(NodeType type, Aggregate *parent, const QString &name)
24 The constructor should never be called directly. It is only called
25 by the constructors of subclasses of Aggregate. Those constructors
26 pass the node \a type they want to create, the \a parent of the new
27 node, and its \a name.
28 */
29
30/*!
31 Recursively set all non-related members in the list of children to
32 \nullptr, after which each aggregate can safely delete all children
33 in their list. Aggregate's destructor calls this only on the root
34 namespace node.
35 */
36void Aggregate::dropNonRelatedMembers()
37{
38 for (auto &child : m_children) {
39 if (!child)
40 continue;
41 if (child->parent() != this)
42 child = nullptr;
43 else if (child->isAggregate())
44 static_cast<Aggregate*>(child)->dropNonRelatedMembers();
45 }
46}
47
48/*!
49 Destroys this Aggregate; deletes each child.
50 */
52{
53 // If this is the root, clear non-related children first
54 if (isNamespace() && name().isEmpty())
55 dropNonRelatedMembers();
56
57 m_enumChildren.clear();
58 m_nonfunctionMap.clear();
59 m_functionMap.clear();
60 qDeleteAll(m_children.begin(), m_children.end());
61 m_children.clear();
62}
63
64/*!
65 If \a genus is \c{Node::DontCare}, find the first node in
66 this node's child list that has the given \a name. If this
67 node is a QML type, be sure to also look in the children
68 of its property group nodes. Return the matching node or \c nullptr.
69
70 If \a genus is either \c{Node::CPP} or \c {Node::QML}, then
71 find all this node's children that have the given \a name,
72 and return the one that satisfies the \a genus requirement.
73 */
74Node *Aggregate::findChildNode(const QString &name, Node::Genus genus, int findFlags) const
75{
76 if (genus == Node::DontCare) {
77 Node *node = m_nonfunctionMap.value(name);
78 if (node)
79 return node;
80 } else {
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())
87 continue;
88 } else if (findFlags & IgnoreModules && node->isModule())
89 continue;
90 return node;
91 }
92 }
93 }
94 if (genus != Node::DontCare && !(genus & this->genus()))
95 return nullptr;
96
97 auto it = m_functionMap.find(name);
98 return it != m_functionMap.end() ? (*(*it).begin()) : nullptr;
99}
100
101/*!
102 Find all the child nodes of this node that are named
103 \a name and return them in \a nodes.
104 */
105void Aggregate::findChildren(const QString &name, NodeVector &nodes) const
106{
107 nodes.clear();
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);
113 while (it != end) {
114 nodes.emplace_back(*it);
115 ++it;
116 }
117}
118
119/*!
120 This function searches for a child node of this Aggregate,
121 such that the child node has the spacified \a name and the
122 function \a isMatch returns true for the node. The function
123 passed must be one of the isXxx() functions in class Node
124 that tests the node type.
125 */
126Node *Aggregate::findNonfunctionChild(const QString &name, bool (Node::*isMatch)() const)
127{
128 const NodeList &nodes = m_nonfunctionMap.values(name);
129 for (auto *node : nodes) {
130 if ((node->*(isMatch))())
131 return node;
132 }
133 return nullptr;
134}
135
136/*!
137 Find a function node that is a child of this node, such that
138 the function node has the specified \a name and \a parameters.
139 If \a parameters is empty but no matching function is found
140 that has no parameters, return the first non-internal primary
141 function or overload, whether it has parameters or not.
142
143 \sa normalizeOverloads()
144 */
145FunctionNode *Aggregate::findFunctionChild(const QString &name, const Parameters &parameters)
146{
147 auto map_it = m_functionMap.find(name);
148 if (map_it == m_functionMap.end())
149 return nullptr;
150
151 auto match_it = std::find_if((*map_it).begin(), (*map_it).end(),
152 [&parameters](const FunctionNode *fn) {
153 if (fn->isInternal())
154 return false;
155 if (parameters.count() != fn->parameters().count())
156 return false;
157 for (int i = 0; i < parameters.count(); ++i)
158 if (parameters.at(i).type() != fn->parameters().at(i).type())
159 return false;
160 return true;
161 });
162
163 if (match_it != (*map_it).end())
164 return *match_it;
165
166 // Assumes that overloads are already normalized; i.e, if there's
167 // an active function, it'll be found at the start of the list.
168 auto *fn = (*(*map_it).begin());
169 return (parameters.isEmpty() && !fn->isInternal()) ? fn : nullptr;
170}
171
172/*!
173 Returns the function node that is a child of this node, such
174 that the function described has the same name and signature
175 as the function described by the function node \a clone.
176
177 Returns \nullptr if no matching function was found.
178 */
180{
181 auto funcs_it = m_functionMap.find(clone->name());
182 if (funcs_it == m_functionMap.end())
183 return nullptr;
184
185 auto func_it = std::find_if((*funcs_it).begin(), (*funcs_it).end(),
186 [clone](const FunctionNode *fn) {
187 return compare(clone, fn) == 0;
188 });
189
190 return func_it != (*funcs_it).end() ? *func_it : nullptr;
191}
192
193/*!
194 Mark all child nodes that have no documentation as having
195 private access and internal status. qdoc will then ignore
196 them for documentation purposes.
197 */
199{
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())
205 continue;
206 } else if (child->isTypedef()) {
207 if (static_cast<TypedefNode *>(child)->hasAssociatedEnum())
208 continue;
209 }
210 child->setAccess(Access::Private);
211 child->setStatus(Node::Internal);
212 }
213 }
214 if (child->isAggregate()) {
215 static_cast<Aggregate *>(child)->markUndocumentedChildrenInternal();
216 }
217 }
218}
219
220/*!
221 Adopts each non-aggregate C++ node (function/macro, typedef, enum, variable,
222 or a shared comment node with genus Node::CPP) to the aggregate specified in
223 the node's documentation using the \\relates command.
224
225 If the target Aggregate is not found in the primary tree, creates a new
226 ProxyNode to use as the parent.
227*/
229{
230 auto *database = QDocDatabase::qdocDB();
231
232 for (auto *node : m_children) {
233 if (node->isRelatedNonmember())
234 continue;
235 if (node->genus() != Node::CPP)
236 continue;
237
238 if (!node->isAggregate()) {
239 const auto &relates_args = node->doc().metaCommandArgs("relates"_L1);
240 if (relates_args.isEmpty())
241 continue;
242
243 auto *aggregate = database->findRelatesNode(relates_args[0].first.split("::"_L1));
244 if (!aggregate)
245 aggregate = new ProxyNode(this, relates_args[0].first);
246 else if (node->parent() == aggregate)
247 continue;
248
249 aggregate->adoptChild(node);
250 node->setRelatedNonmember(true);
251 } else {
252 static_cast<Aggregate*>(node)->resolveRelates();
253 }
254 }
255}
256
257/*!
258 Sorts the lists of overloads in the function map and assigns overload
259 numbers.
260
261 For sorting, active functions take precedence over internal ones, as well
262 as ones marked as \\overload - the latter ones typically do not contain
263 full documentation, so selecting them as the \e primary function
264 would cause unnecessary warnings to be generated.
265
266 Otherwise, the order is set as determined by FunctionNode::compare().
267 */
269{
270 for (auto map_it = m_functionMap.begin(); map_it != m_functionMap.end(); ++map_it) {
271 if ((*map_it).size() > 1) {
272 std::sort((*map_it).begin(), (*map_it).end(),
273 [](const FunctionNode *f1, const FunctionNode *f2) -> bool {
274 if (f1->isInternal() != f2->isInternal())
275 return f2->isInternal();
277 return f2->isOverload();
278 // Prioritize documented over undocumented
279 if (f1->hasDoc() != f2->hasDoc())
280 return f1->hasDoc();
281 return (compare(f1, f2) < 0);
282 });
283 // Set overload numbers
284 signed short n{0};
285 for (auto *fn : (*map_it))
286 fn->setOverloadNumber(n++);
287 }
288 }
289
290 for (auto *node : std::as_const(m_children)) {
291 if (node->isAggregate())
292 static_cast<Aggregate *>(node)->normalizeOverloads();
293 }
294}
295
296/*!
297 Returns a const reference to the list of child nodes of this
298 aggregate that are not function nodes. Duplicate nodes are
299 removed from the list.
300 */
302{
303 m_nonfunctionList = m_nonfunctionMap.values();
304 std::sort(m_nonfunctionList.begin(), m_nonfunctionList.end(), Node::nodeNameLessThan);
305 m_nonfunctionList.erase(std::unique(m_nonfunctionList.begin(), m_nonfunctionList.end()),
306 m_nonfunctionList.end());
307 return m_nonfunctionList;
308}
309
310/*! \fn bool Aggregate::isAggregate() const
311 Returns \c true because this node is an instance of Aggregate,
312 which means it can have children.
313 */
314
315/*!
316 Finds the enum type node that has \a enumValue as one of
317 its enum values and returns a pointer to it. Returns 0 if
318 no enum type node is found that has \a enumValue as one
319 of its values.
320 */
321const EnumNode *Aggregate::findEnumNodeForValue(const QString &enumValue) const
322{
323 for (const auto *node : m_enumChildren) {
324 const auto *en = static_cast<const EnumNode *>(node);
325 if (en->hasItem(enumValue))
326 return en;
327 }
328 return nullptr;
329}
330
331/*!
332 Adds the \a child to this node's child map using \a title
333 as the key. The \a child is not added to the child list
334 again, because it is presumed to already be there. We just
335 want to be able to find the child by its \a title.
336 */
337void Aggregate::addChildByTitle(Node *child, const QString &title)
338{
339 m_nonfunctionMap.insert(title, child);
340}
341
342/*!
343 Adds the \a child to this node's child list and sets the child's
344 parent pointer to this Aggregate. It then mounts the child with
345 mountChild().
346
347 The \a child is then added to this Aggregate's searchable maps
348 and lists.
349
350 \note This function does not test the child's parent pointer
351 for null before changing it. If the child's parent pointer
352 is not null, then it is being reparented. The child becomes
353 a child of this Aggregate, but it also remains a child of
354 the Aggregate that is it's old parent. But the child will
355 only have one parent, and it will be this Aggregate. The is
356 because of the \c relates command.
357
358 \sa mountChild(), dismountChild()
359 */
361{
362 m_children.append(child);
363 child->setParent(this);
364 child->setUrl(QString());
366
367 if (child->isFunction()) {
368 m_functionMap[child->name()].emplace_back(static_cast<FunctionNode *>(child));
369 } else if (!child->name().isEmpty()) {
370 m_nonfunctionMap.insert(child->name(), child);
371 if (child->isEnumType())
372 m_enumChildren.append(child);
373 }
374}
375
376/*!
377 This Aggregate becomes the adoptive parent of \a child. The
378 \a child knows this Aggregate as its parent, but its former
379 parent continues to have pointers to the child in its child
380 list and in its searchable data structures. But the child is
381 also added to the child list and searchable data structures
382 of this Aggregate.
383 */
385{
386 if (child->parent() != this) {
387 m_children.append(child);
388 child->setParent(this);
389 if (child->isFunction()) {
390 m_functionMap[child->name()].emplace_back(static_cast<FunctionNode *>(child));
391 } else if (!child->name().isEmpty()) {
392 m_nonfunctionMap.insert(child->name(), child);
393 if (child->isEnumType())
394 m_enumChildren.append(child);
395 }
396 if (child->isSharedCommentNode()) {
397 auto *scn = static_cast<SharedCommentNode *>(child);
398 for (Node *n : scn->collective())
399 adoptChild(n);
400 }
401 }
402}
403
404/*!
405 If this node has a child that is a QML property named \a n, return a
406 pointer to that child. Otherwise, return \nullptr.
407 */
408QmlPropertyNode *Aggregate::hasQmlProperty(const QString &n) const
409{
411 for (auto *child : std::as_const(m_children)) {
412 if (child->nodeType() == goal) {
413 if (child->name() == n)
414 return static_cast<QmlPropertyNode *>(child);
415 }
416 }
417 return nullptr;
418}
419
420/*!
421 If this node has a child that is a QML property named \a n and that
422 also matches \a attached, return a pointer to that child.
423 */
424QmlPropertyNode *Aggregate::hasQmlProperty(const QString &n, bool attached) const
425{
427 for (auto *child : std::as_const(m_children)) {
428 if (child->nodeType() == goal) {
429 if (child->name() == n && child->isAttached() == attached)
430 return static_cast<QmlPropertyNode *>(child);
431 }
432 }
433 return nullptr;
434}
435
436/*!
437 Returns \c true if this aggregate has multiple function
438 overloads matching the name of \a fn.
439
440 \note Assumes \a fn is a member of this aggregate.
441*/
442bool Aggregate::hasOverloads(const FunctionNode *fn) const
443{
444 auto it = m_functionMap.find(fn->name());
445 return !(it == m_functionMap.end()) && (it.value().size() > 1);
446}
447
448/*
449 When deciding whether to include a function in the function
450 index, if the function is marked private, don't include it.
451 If the function is marked obsolete, don't include it. If the
452 function is marked internal, don't include it. Or if the
453 function is a destructor or any kind of constructor, don't
454 include it. Otherwise include it.
455 */
456static bool keep(FunctionNode *fn)
457{
459 return false;
460 return true;
461}
462
463/*!
464 Insert all functions declared in this aggregate into the
465 \a functionIndex. Call the function recursively for each
466 child that is an aggregate.
467
468 Only include functions that are in the public API and
469 that are not constructors or destructors.
470 */
472{
473 for (auto functions : m_functionMap) {
474 std::for_each(functions.begin(), functions.end(),
475 [&functionIndex](FunctionNode *fn) {
476 if (keep(fn))
477 functionIndex[fn->name()].insert(fn->parent()->fullDocumentName(), fn);
478 }
479 );
480 }
481
482 for (Node *node : std::as_const(m_children)) {
483 if (node->isAggregate() && !node->isPrivate() && !node->isDontDocument())
484 static_cast<Aggregate *>(node)->findAllFunctions(functionIndex);
485 }
486}
487
488/*!
489 For each child of this node, if the child is a namespace node,
490 insert the child into the \a namespaces multimap. If the child
491 is an aggregate, call this function recursively for that child.
492
493 When the function called with the root node of a tree, it finds
494 all the namespace nodes in that tree and inserts them into the
495 \a namespaces multimap.
496
497 The root node of a tree is a namespace, but it has no name, so
498 it is not inserted into the map. So, if this function is called
499 for each tree in the qdoc database, it finds all the namespace
500 nodes in the database.
501 */
503{
504 for (auto *node : std::as_const(m_children)) {
505 if (node->isAggregate() && !node->isPrivate()) {
506 if (node->isNamespace() && !node->name().isEmpty())
507 namespaces.insert(node->name(), node);
508 static_cast<Aggregate *>(node)->findAllNamespaces(namespaces);
509 }
510 }
511}
512
513/*!
514 Returns true if this aggregate contains at least one child
515 that is marked obsolete. Otherwise returns false.
516 */
518{
519 for (const auto *node : m_children)
520 if (!node->isPrivate() && node->isDeprecated()) {
521 if (node->isFunction() || node->isProperty() || node->isEnumType() || node->isTypedef()
522 || node->isTypeAlias() || node->isVariable() || node->isQmlProperty())
523 return true;
524 }
525 return false;
526}
527
528/*!
529 Finds all the obsolete C++ classes and QML types in this
530 aggregate and all the C++ classes and QML types with obsolete
531 members, and inserts them into maps used elsewhere for
532 generating documentation.
533 */
535{
536 for (auto *node : std::as_const(m_children)) {
537 if (!node->isPrivate()) {
538 if (node->isDeprecated()) {
539 if (node->isClassNode())
540 QDocDatabase::obsoleteClasses().insert(node->qualifyCppName(), node);
541 else if (node->isQmlType())
542 QDocDatabase::obsoleteQmlTypes().insert(node->qualifyQmlName(), node);
543 } else if (node->isClassNode()) {
544 auto *a = static_cast<Aggregate *>(node);
545 if (a->hasObsoleteMembers())
546 QDocDatabase::classesWithObsoleteMembers().insert(node->qualifyCppName(), node);
547 } else if (node->isQmlType()) {
548 auto *a = static_cast<Aggregate *>(node);
549 if (a->hasObsoleteMembers())
550 QDocDatabase::qmlTypesWithObsoleteMembers().insert(node->qualifyQmlName(),
551 node);
552 } else if (node->isAggregate()) {
553 static_cast<Aggregate *>(node)->findAllObsoleteThings();
554 }
555 }
556 }
557}
558
559/*!
560 Finds all the C++ classes, QML types, QML basic types, and examples
561 in this aggregate and inserts them into appropriate maps for later
562 use in generating documentation.
563 */
565{
566 for (auto *node : std::as_const(m_children)) {
567 if (!node->isPrivate() && !node->isInternal() && !node->isDontDocument()
568 && node->tree()->camelCaseModuleName() != QString("QDoc")) {
569 if (node->isClassNode()) {
570 QDocDatabase::cppClasses().insert(node->qualifyCppName().toLower(), node);
571 } else if (node->isQmlType()) {
572 QString name = node->name().toLower();
573 QDocDatabase::qmlTypes().insert(name, node);
574 // also add to the QML basic type map
575 if (node->isQmlBasicType())
576 QDocDatabase::qmlBasicTypes().insert(name, node);
577 } else if (node->isExample()) {
578 // use the module index title as key for the example map
579 QString title = node->tree()->indexTitle();
580 if (!QDocDatabase::examples().contains(title, node))
581 QDocDatabase::examples().insert(title, node);
582 } else if (node->isAggregate()) {
583 static_cast<Aggregate *>(node)->findAllClasses();
584 }
585 }
586 }
587}
588
589/*!
590 Find all the attribution pages in this node and insert them
591 into \a attributions.
592 */
594{
595 for (auto *node : std::as_const(m_children)) {
596 if (!node->isPrivate()) {
597 if (node->isPageNode() && static_cast<PageNode*>(node)->isAttribution())
598 attributions.insert(node->tree()->indexTitle(), node);
599 else if (node->isAggregate())
600 static_cast<Aggregate *>(node)->findAllAttributions(attributions);
601 }
602 }
603}
604
605/*!
606 Finds all the nodes in this node where a \e{since} command appeared
607 in the qdoc comment and sorts them into maps according to the kind
608 of node.
609
610 This function is used for generating the "New Classes... in x.y"
611 section on the \e{What's New in Qt x.y} page.
612 */
614{
615 for (auto *node : std::as_const(m_children)) {
616 if (node->isRelatedNonmember() && node->parent() != this)
617 continue;
618 QString sinceString = node->since();
619 // Insert a new entry into each map for each new since string found.
620 if (node->isInAPI() && !sinceString.isEmpty()) {
621 // operator[] will insert a default-constructed value into the
622 // map if key is not found, which is what we want here.
623 auto &nsmap = QDocDatabase::newSinceMaps()[sinceString];
624 auto &ncmap = QDocDatabase::newClassMaps()[sinceString];
625 auto &nqcmap = QDocDatabase::newQmlTypeMaps()[sinceString];
626
627 if (node->isFunction()) {
628 // Insert functions into the general since map.
629 auto *fn = static_cast<FunctionNode *>(node);
630 if (!fn->isDeprecated() && !fn->isSomeCtor() && !fn->isDtor())
631 nsmap.insert(fn->name(), fn);
632 } else if (node->isClassNode()) {
633 // Insert classes into the since and class maps.
634 QString name = node->qualifyWithParentName();
635 nsmap.insert(name, node);
636 ncmap.insert(name, node);
637 } else if (node->isQmlType()) {
638 // Insert QML elements into the since and element maps.
639 QString name = node->qualifyWithParentName();
640 nsmap.insert(name, node);
641 nqcmap.insert(name, node);
642 } else if (node->isQmlProperty()) {
643 // Insert QML properties into the since map.
644 nsmap.insert(node->name(), node);
645 } else {
646 // Insert external documents into the general since map.
647 QString name = node->qualifyWithParentName();
648 nsmap.insert(name, node);
649 }
650 }
651 // Enum values - a special case as EnumItem is not a Node subclass
652 if (node->isInAPI() && node->isEnumType()) {
653 for (const auto &val : static_cast<EnumNode *>(node)->items()) {
654 sinceString = val.since();
655 if (sinceString.isEmpty())
656 continue;
657 // Insert to enum value map
658 QDocDatabase::newEnumValueMaps()[sinceString].insert(
659 node->name() + "::" + val.name(), node);
660 // Ugly hack: Insert into general map with an empty key -
661 // we need something in there to mark the corresponding
662 // section populated. See Sections class constructor.
663 QDocDatabase::newSinceMaps()[sinceString].replace(QString(), node);
664 }
665 }
666
667 // Recursively find child nodes with since commands.
668 if (node->isAggregate())
669 static_cast<Aggregate *>(node)->findAllSince();
670 }
671}
672
673/*!
674 Resolves the inheritance information for all QML type children
675 of this aggregate.
676*/
678{
679 NodeMap previousSearches;
680 for (auto *child : std::as_const(m_children)) {
681 if (!child->isQmlType())
682 continue;
683 static_cast<QmlTypeNode *>(child)->resolveInheritance(previousSearches);
684 }
685}
686
687/*!
688 Returns a word representing the kind of Aggregate this node is.
689 Currently recognizes class, struct, union, and namespace.
690 If \a cap is true, the word is capitalised.
691 */
692QString Aggregate::typeWord(bool cap) const
693{
694 if (cap) {
695 switch (nodeType()) {
696 case Node::Class:
697 return "Class"_L1;
698 case Node::Struct:
699 return "Struct"_L1;
700 case Node::Union:
701 return "Union"_L1;
702 case Node::Namespace:
703 return "Namespace"_L1;
704 default:
705 break;
706 }
707 } else {
708 switch (nodeType()) {
709 case Node::Class:
710 return "class"_L1;
711 case Node::Struct:
712 return "struct"_L1;
713 case Node::Union:
714 return "union"_L1;
715 case Node::Namespace:
716 return "namespace"_L1;
717 default:
718 break;
719 }
720 }
721 return QString();
722}
723
724/*! \fn int Aggregate::count() const
725 Returns the number of children in the child list.
726 */
727
728/*! \fn const NodeList &Aggregate::childNodes() const
729 Returns a const reference to the child list.
730 */
731
732/*! \fn NodeList::ConstIterator Aggregate::constBegin() const
733 Returns a const iterator pointing at the beginning of the child list.
734 */
735
736/*! \fn NodeList::ConstIterator Aggregate::constEnd() const
737 Returns a const iterator pointing at the end of the child list.
738 */
739
740/*! \fn QmlTypeNode *Aggregate::qmlBaseNode() const
741 If this Aggregate is a QmlTypeNode, this function returns a pointer to
742 the QmlTypeNode that is its base type. Otherwise it returns \c nullptr.
743 A QmlTypeNode doesn't always have a base type, so even when this Aggregate
744 is aQmlTypeNode, the pointer returned can be \c nullptr.
745 */
746
747/*! \fn FunctionMap &Aggregate::functionMap()
748 Returns a reference to this Aggregate's function map, which
749 is a map of all the children of this Aggregate that are
750 FunctionNodes.
751 */
752
753/*! \fn void Aggregate::appendToRelatedByProxy(const NodeList &t)
754 Appends the list of node pointers to the list of elements that are
755 related to this Aggregate but are documented in a different module.
756
757 \sa relatedByProxy()
758 */
759
760/*! \fn NodeList &Aggregate::relatedByProxy()
761 Returns a reference to a list of node pointers where each element
762 points to a node in an index file for some other module, such that
763 whatever the node represents was documented in that other module,
764 but it is related to this Aggregate, so when the documentation for
765 this Aggregate is written, it will contain links to elements in the
766 other module.
767 */
768
769QT_END_NAMESPACE
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.
Definition aggregate.cpp:74
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.
Definition aggregate.cpp:51
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 &parameters)
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 ...
NodeList m_children
Definition aggregate.h:83
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
bool isDtor() const
bool isOverload() const
friend int compare(const FunctionNode *f1, const FunctionNode *f2)
Compares FunctionNode f1 with f2, assumed to have identical names.
bool isSomeCtor() const
bool isPrivate() const
Returns true if this node's access is Private.
Definition node.h:146
void setIndexNodeFlag(bool isIndexNode=true)
Sets a flag in this Node that indicates the node was created for something in an index file.
Definition node.h:214
NodeType
An unsigned char value that identifies an object as a particular subclass of Node.
Definition node.h:54
@ QmlProperty
Definition node.h:74
bool isFunction(Genus g=DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
Definition node.h:135
bool isSharedCommentNode() const
Returns true if the node type is SharedComment.
Definition node.h:158
virtual bool isInternal() const
Returns true if the node's status is Internal, or if its parent is a class with Internal status.
Definition node.cpp:849
bool isEnumType() const
Returns true if the node type is Enum.
Definition node.h:132
Aggregate * parent() const
Returns the node's parent pointer.
Definition node.h:244
NodeType nodeType() const
Returns this node's type.
Definition node.h:121
static bool nodeNameLessThan(const Node *first, const Node *second)
Returns true if the node n1 is less than node n2.
Definition node.cpp:57
Genus
An unsigned char value that specifies whether the Node represents a C++ element, a QML element,...
Definition node.h:81
@ DontCare
Definition node.h:82
Genus genus() const
Returns this node's Genus.
Definition node.h:124
bool hasDoc() const
Returns true if this node is documented, or it represents a documented node read from the index ('had...
Definition node.cpp:906
void setParent(Aggregate *n)
Sets the node's parent pointer to n.
Definition node.h:213
LinkType
An unsigned char value that probably should be moved out of the Node base class.
Definition node.h:112
bool isIndexNode() const
Returns true if this node was created from something in an index file.
Definition node.h:141
A class for parsing and managing a function parameter list.
Definition parameters.h:57
bool isEmpty() const
Definition parameters.h:70
const Parameter & at(int i) const
Definition parameters.h:74
int count() const
Definition parameters.h:72
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 * > NodeList
Definition node.h:41
QList< Node * > NodeVector
Definition node.h:43
QMap< QString, Node * > NodeMap
Definition node.h:44
QMap< QString, NodeMap > NodeMapMap
Definition node.h:45
QMultiMap< QString, Node * > NodeMultiMap
Definition node.h:46