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) in the global scope to the
223 aggregate specified in 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 Q_ASSERT(name().isEmpty()); // Must be called on the root namespace
231 auto *database = QDocDatabase::qdocDB();
232
233 for (auto *node : m_children) {
234 if (node->isRelatedNonmember() || node->isAggregate())
235 continue;
236 if (node->genus() != Node::CPP)
237 continue;
238
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 }
252}
253
254/*!
255 Sorts the lists of overloads in the function map and assigns overload
256 numbers.
257
258 For sorting, active functions take precedence over internal ones, as well
259 as ones marked as \\overload - the latter ones typically do not contain
260 full documentation, so selecting them as the \e primary function
261 would cause unnecessary warnings to be generated.
262
263 Otherwise, the order is set as determined by FunctionNode::compare().
264 */
266{
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(),
270 [](const FunctionNode *f1, const FunctionNode *f2) -> bool {
271 if (f1->isInternal() != f2->isInternal())
272 return f2->isInternal();
274 return f2->isOverload();
275 // Prioritize documented over undocumented
276 if (f1->hasDoc() != f2->hasDoc())
277 return f1->hasDoc();
278 return (compare(f1, f2) < 0);
279 });
280 // Set overload numbers
281 signed short n{0};
282 for (auto *fn : (*map_it))
283 fn->setOverloadNumber(n++);
284 }
285 }
286
287 for (auto *node : std::as_const(m_children)) {
288 if (node->isAggregate())
289 static_cast<Aggregate *>(node)->normalizeOverloads();
290 }
291}
292
293/*!
294 Returns a const reference to the list of child nodes of this
295 aggregate that are not function nodes. Duplicate nodes are
296 removed from the list.
297 */
299{
300 m_nonfunctionList = m_nonfunctionMap.values();
301 std::sort(m_nonfunctionList.begin(), m_nonfunctionList.end(), Node::nodeNameLessThan);
302 m_nonfunctionList.erase(std::unique(m_nonfunctionList.begin(), m_nonfunctionList.end()),
303 m_nonfunctionList.end());
304 return m_nonfunctionList;
305}
306
307/*! \fn bool Aggregate::isAggregate() const
308 Returns \c true because this node is an instance of Aggregate,
309 which means it can have children.
310 */
311
312/*!
313 Finds the enum type node that has \a enumValue as one of
314 its enum values and returns a pointer to it. Returns 0 if
315 no enum type node is found that has \a enumValue as one
316 of its values.
317 */
318const EnumNode *Aggregate::findEnumNodeForValue(const QString &enumValue) const
319{
320 for (const auto *node : m_enumChildren) {
321 const auto *en = static_cast<const EnumNode *>(node);
322 if (en->hasItem(enumValue))
323 return en;
324 }
325 return nullptr;
326}
327
328/*!
329 Adds the \a child to this node's child map using \a title
330 as the key. The \a child is not added to the child list
331 again, because it is presumed to already be there. We just
332 want to be able to find the child by its \a title.
333 */
334void Aggregate::addChildByTitle(Node *child, const QString &title)
335{
336 m_nonfunctionMap.insert(title, child);
337}
338
339/*!
340 Adds the \a child to this node's child list and sets the child's
341 parent pointer to this Aggregate. It then mounts the child with
342 mountChild().
343
344 The \a child is then added to this Aggregate's searchable maps
345 and lists.
346
347 \note This function does not test the child's parent pointer
348 for null before changing it. If the child's parent pointer
349 is not null, then it is being reparented. The child becomes
350 a child of this Aggregate, but it also remains a child of
351 the Aggregate that is it's old parent. But the child will
352 only have one parent, and it will be this Aggregate. The is
353 because of the \c relates command.
354
355 \sa mountChild(), dismountChild()
356 */
358{
359 m_children.append(child);
360 child->setParent(this);
361 child->setUrl(QString());
363
364 if (child->isFunction()) {
365 m_functionMap[child->name()].emplace_back(static_cast<FunctionNode *>(child));
366 } else if (!child->name().isEmpty()) {
367 m_nonfunctionMap.insert(child->name(), child);
368 if (child->isEnumType())
369 m_enumChildren.append(child);
370 }
371}
372
373/*!
374 This Aggregate becomes the adoptive parent of \a child. The
375 \a child knows this Aggregate as its parent, but its former
376 parent continues to have pointers to the child in its child
377 list and in its searchable data structures. But the child is
378 also added to the child list and searchable data structures
379 of this Aggregate.
380 */
382{
383 if (child->parent() != this) {
384 m_children.append(child);
385 child->setParent(this);
386 if (child->isFunction()) {
387 m_functionMap[child->name()].emplace_back(static_cast<FunctionNode *>(child));
388 } else if (!child->name().isEmpty()) {
389 m_nonfunctionMap.insert(child->name(), child);
390 if (child->isEnumType())
391 m_enumChildren.append(child);
392 }
393 if (child->isSharedCommentNode()) {
394 auto *scn = static_cast<SharedCommentNode *>(child);
395 for (Node *n : scn->collective())
396 adoptChild(n);
397 }
398 }
399}
400
401/*!
402 If this node has a child that is a QML property named \a n, return a
403 pointer to that child. Otherwise, return \nullptr.
404 */
405QmlPropertyNode *Aggregate::hasQmlProperty(const QString &n) const
406{
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);
412 }
413 }
414 return nullptr;
415}
416
417/*!
418 If this node has a child that is a QML property named \a n and that
419 also matches \a attached, return a pointer to that child.
420 */
421QmlPropertyNode *Aggregate::hasQmlProperty(const QString &n, bool attached) const
422{
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);
428 }
429 }
430 return nullptr;
431}
432
433/*!
434 Returns \c true if this aggregate has multiple function
435 overloads matching the name of \a fn.
436
437 \note Assumes \a fn is a member of this aggregate.
438*/
439bool Aggregate::hasOverloads(const FunctionNode *fn) const
440{
441 auto it = m_functionMap.find(fn->name());
442 return !(it == m_functionMap.end()) && (it.value().size() > 1);
443}
444
445/*
446 When deciding whether to include a function in the function
447 index, if the function is marked private, don't include it.
448 If the function is marked obsolete, don't include it. If the
449 function is marked internal, don't include it. Or if the
450 function is a destructor or any kind of constructor, don't
451 include it. Otherwise include it.
452 */
453static bool keep(FunctionNode *fn)
454{
456 return false;
457 return true;
458}
459
460/*!
461 Insert all functions declared in this aggregate into the
462 \a functionIndex. Call the function recursively for each
463 child that is an aggregate.
464
465 Only include functions that are in the public API and
466 that are not constructors or destructors.
467 */
469{
470 for (auto functions : m_functionMap) {
471 std::for_each(functions.begin(), functions.end(),
472 [&functionIndex](FunctionNode *fn) {
473 if (keep(fn))
474 functionIndex[fn->name()].insert(fn->parent()->fullDocumentName(), fn);
475 }
476 );
477 }
478
479 for (Node *node : std::as_const(m_children)) {
480 if (node->isAggregate() && !node->isPrivate() && !node->isDontDocument())
481 static_cast<Aggregate *>(node)->findAllFunctions(functionIndex);
482 }
483}
484
485/*!
486 For each child of this node, if the child is a namespace node,
487 insert the child into the \a namespaces multimap. If the child
488 is an aggregate, call this function recursively for that child.
489
490 When the function called with the root node of a tree, it finds
491 all the namespace nodes in that tree and inserts them into the
492 \a namespaces multimap.
493
494 The root node of a tree is a namespace, but it has no name, so
495 it is not inserted into the map. So, if this function is called
496 for each tree in the qdoc database, it finds all the namespace
497 nodes in the database.
498 */
500{
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);
506 }
507 }
508}
509
510/*!
511 Returns true if this aggregate contains at least one child
512 that is marked obsolete. Otherwise returns false.
513 */
515{
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())
520 return true;
521 }
522 return false;
523}
524
525/*!
526 Finds all the obsolete C++ classes and QML types in this
527 aggregate and all the C++ classes and QML types with obsolete
528 members, and inserts them into maps used elsewhere for
529 generating documentation.
530 */
532{
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(),
548 node);
549 } else if (node->isAggregate()) {
550 static_cast<Aggregate *>(node)->findAllObsoleteThings();
551 }
552 }
553 }
554}
555
556/*!
557 Finds all the C++ classes, QML types, QML basic types, and examples
558 in this aggregate and inserts them into appropriate maps for later
559 use in generating documentation.
560 */
562{
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);
571 // also add to the QML basic type map
572 if (node->isQmlBasicType())
573 QDocDatabase::qmlBasicTypes().insert(name, node);
574 } else if (node->isExample()) {
575 // use the module index title as key for the example map
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();
581 }
582 }
583 }
584}
585
586/*!
587 Find all the attribution pages in this node and insert them
588 into \a attributions.
589 */
591{
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);
598 }
599 }
600}
601
602/*!
603 Finds all the nodes in this node where a \e{since} command appeared
604 in the qdoc comment and sorts them into maps according to the kind
605 of node.
606
607 This function is used for generating the "New Classes... in x.y"
608 section on the \e{What's New in Qt x.y} page.
609 */
611{
612 for (auto *node : std::as_const(m_children)) {
613 if (node->isRelatedNonmember() && node->parent() != this)
614 continue;
615 QString sinceString = node->since();
616 // Insert a new entry into each map for each new since string found.
617 if (node->isInAPI() && !sinceString.isEmpty()) {
618 // operator[] will insert a default-constructed value into the
619 // map if key is not found, which is what we want here.
620 auto &nsmap = QDocDatabase::newSinceMaps()[sinceString];
621 auto &ncmap = QDocDatabase::newClassMaps()[sinceString];
622 auto &nqcmap = QDocDatabase::newQmlTypeMaps()[sinceString];
623
624 if (node->isFunction()) {
625 // Insert functions into the general since map.
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()) {
630 // Insert classes into the since and class maps.
631 QString name = node->qualifyWithParentName();
632 nsmap.insert(name, node);
633 ncmap.insert(name, node);
634 } else if (node->isQmlType()) {
635 // Insert QML elements into the since and element maps.
636 QString name = node->qualifyWithParentName();
637 nsmap.insert(name, node);
638 nqcmap.insert(name, node);
639 } else if (node->isQmlProperty()) {
640 // Insert QML properties into the since map.
641 nsmap.insert(node->name(), node);
642 } else {
643 // Insert external documents into the general since map.
644 QString name = node->qualifyWithParentName();
645 nsmap.insert(name, node);
646 }
647 }
648 // Enum values - a special case as EnumItem is not a Node subclass
649 if (node->isInAPI() && node->isEnumType()) {
650 for (const auto &val : static_cast<EnumNode *>(node)->items()) {
651 sinceString = val.since();
652 if (sinceString.isEmpty())
653 continue;
654 // Insert to enum value map
655 QDocDatabase::newEnumValueMaps()[sinceString].insert(
656 node->name() + "::" + val.name(), node);
657 // Ugly hack: Insert into general map with an empty key -
658 // we need something in there to mark the corresponding
659 // section populated. See Sections class constructor.
660 QDocDatabase::newSinceMaps()[sinceString].replace(QString(), node);
661 }
662 }
663
664 // Recursively find child nodes with since commands.
665 if (node->isAggregate())
666 static_cast<Aggregate *>(node)->findAllSince();
667 }
668}
669
670/*!
671 Resolves the inheritance information for all QML type children
672 of this aggregate.
673*/
675{
676 NodeMap previousSearches;
677 for (auto *child : std::as_const(m_children)) {
678 if (!child->isQmlType())
679 continue;
680 static_cast<QmlTypeNode *>(child)->resolveInheritance(previousSearches);
681 }
682}
683
684/*!
685 Returns a word representing the kind of Aggregate this node is.
686 Currently only works for class, struct, and union, but it can
687 easily be extended. If \a cap is true, the word is capitalised.
688 */
689QString Aggregate::typeWord(bool cap) const
690{
691 if (cap) {
692 switch (nodeType()) {
693 case Node::Class:
694 return QLatin1String("Class");
695 case Node::Struct:
696 return QLatin1String("Struct");
697 case Node::Union:
698 return QLatin1String("Union");
699 default:
700 break;
701 }
702 } else {
703 switch (nodeType()) {
704 case Node::Class:
705 return QLatin1String("class");
706 case Node::Struct:
707 return QLatin1String("struct");
708 case Node::Union:
709 return QLatin1String("union");
710 default:
711 break;
712 }
713 }
714 return QString();
715}
716
717/*! \fn int Aggregate::count() const
718 Returns the number of children in the child list.
719 */
720
721/*! \fn const NodeList &Aggregate::childNodes() const
722 Returns a const reference to the child list.
723 */
724
725/*! \fn NodeList::ConstIterator Aggregate::constBegin() const
726 Returns a const iterator pointing at the beginning of the child list.
727 */
728
729/*! \fn NodeList::ConstIterator Aggregate::constEnd() const
730 Returns a const iterator pointing at the end of the child list.
731 */
732
733/*! \fn QmlTypeNode *Aggregate::qmlBaseNode() const
734 If this Aggregate is a QmlTypeNode, this function returns a pointer to
735 the QmlTypeNode that is its base type. Otherwise it returns \c nullptr.
736 A QmlTypeNode doesn't always have a base type, so even when this Aggregate
737 is aQmlTypeNode, the pointer returned can be \c nullptr.
738 */
739
740/*! \fn FunctionMap &Aggregate::functionMap()
741 Returns a reference to this Aggregate's function map, which
742 is a map of all the children of this Aggregate that are
743 FunctionNodes.
744 */
745
746/*! \fn void Aggregate::appendToRelatedByProxy(const NodeList &t)
747 Appends the list of node pointers to the list of elements that are
748 related to this Aggregate but are documented in a different module.
749
750 \sa relatedByProxy()
751 */
752
753/*! \fn NodeList &Aggregate::relatedByProxy()
754 Returns a reference to a list of node pointers where each element
755 points to a node in an index file for some other module, such that
756 whatever the node represents was documented in that other module,
757 but it is related to this Aggregate, so when the documentation for
758 this Aggregate is written, it will contain links to elements in the
759 other module.
760 */
761
762QT_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
@ Struct
Definition node.h:58
@ Union
Definition node.h:59
@ QmlProperty
Definition node.h:74
@ Class
Definition node.h:57
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