24#include <QtCore/qobjectdefs.h>
25#include <QtCore/qset.h>
29QList<Section> Sections::s_stdSummarySections {
30 {
"Namespaces",
"namespace",
"namespaces",
"", Section::Summary },
31 {
"Classes",
"class",
"classes",
"", Section::Summary },
32 {
"Types",
"type",
"types",
"", Section::Summary },
33 {
"Variables",
"variable",
"variables",
"", Section::Summary },
34 {
"Static Variables",
"static variable",
"static variables",
"", Section::Summary },
35 {
"Functions",
"function",
"functions",
"", Section::Summary },
36 {
"Macros",
"macro",
"macros",
"", Section::Summary },
39QList<Section>
Sections::s_stdDetailsSections {
43 {
"Variable Documentation",
"variable",
"variables",
"vars",
Section::Details },
44 {
"Static Variables",
"static variable",
"static variables", QString(),
Section::Details },
45 {
"Function Documentation",
"function",
"functions",
"func",
Section::Details },
49QList<Section>
Sections::s_stdCppClassSummarySections {
52 {
"Public Functions",
"public function",
"public functions",
"",
Section::Summary },
55 {
"Public Variables",
"public variable",
"public variables",
"",
Section::Summary },
56 {
"Static Public Members",
"static public member",
"static public members",
"",
Section::Summary },
57 {
"Protected Types",
"protected type",
"protected types",
"",
Section::Summary },
58 {
"Protected Functions",
"protected function",
"protected functions",
"",
Section::Summary },
59 {
"Protected Slots",
"protected slot",
"protected slots",
"",
Section::Summary },
60 {
"Protected Variables",
"protected type",
"protected variables",
"",
Section::Summary },
61 {
"Static Protected Members",
"static protected member",
"static protected members",
"",
Section::Summary },
63 {
"Private Functions",
"private function",
"private functions",
"",
Section::Summary },
65 {
"Private Variables",
"private variable",
"private variables",
"",
Section::Summary },
66 {
"Static Private Members",
"static private member",
"static private members",
"",
Section::Summary },
67 {
"Related Non-Members",
"related non-member",
"related non-members",
"",
Section::Summary },
71QList<Section>
Sections::s_stdCppClassDetailsSections {
72 {
"Member Type Documentation",
"member",
"members",
"types",
Section::Details },
74 {
"Member Function Documentation",
"member",
"members",
"func",
Section::Details },
75 {
"Member Variable Documentation",
"member",
"members",
"vars",
Section::Details },
76 {
"Related Non-Members",
"member",
"members",
"relnonmem",
Section::Details },
80QList<Section>
Sections::s_stdQmlTypeSummarySections {
83 {
"Attached Properties",
"attached property",
"attached properties",
"",
Section::Summary },
85 {
"Signal Handlers",
"signal handler",
"signal handlers",
"",
Section::Summary },
86 {
"Attached Signals",
"attached signal",
"attached signals",
"",
Section::Summary },
88 {
"Attached Methods",
"attached method",
"attached methods",
"",
Section::Summary },
91QList<Section>
Sections::s_stdQmlTypeDetailsSections {
92 {
"Enumeration Documentation",
"member",
"members",
"qmlenum",
Section::Details },
93 {
"Property Documentation",
"member",
"members",
"qmlprop",
Section::Details },
94 {
"Attached Property Documentation",
"member",
"members",
"qmlattprop",
Section::Details },
96 {
"Signal Handler Documentation",
"signal handler",
"signal handlers",
"qmlsighan",
Section::Details },
97 {
"Attached Signal Documentation",
"signal",
"signals",
"qmlattsig",
Section::Details },
98 {
"Method Documentation",
"member",
"members",
"qmlmeth",
Section::Details },
99 {
"Attached Method Documentation",
"member",
"members",
"qmlattmeth",
Section::Details },
102QList<Section>
Sections::s_sinceSections {
125
126
127
130
131
132
139
140
141
142
143
146 m_reimplementedMemberMap.clear();
148 m_obsoleteMembers.clear();
149 m_reimplementedMembers.clear();
150 m_inheritedMembers.clear();
151 m_classNodesList.clear();
152 m_aggregate =
nullptr;
156
157
158
161 QString nodeName{node->name()};
164 for (qsizetype i = nodeName.size() - 1; i > 0; --i) {
165 if (nodeName.at(i).digitValue() == -1)
172 for (
int i = 0; i < 4 - numDigits; ++i)
173 nodeName.insert(nodeName.size() - numDigits - 1, QLatin1Char(
'0'));
177 return QLatin1Char(
'A') + nodeName;
180 const auto *fn =
static_cast<
const FunctionNode *>(node);
184 sortNo = QLatin1String(
"C");
185 else if (fn->isCCtor())
186 sortNo = QLatin1String(
"D");
187 else if (fn->isMCtor())
188 sortNo = QLatin1String(
"E");
189 else if (fn->isDtor())
190 sortNo = QLatin1String(
"F");
191 else if (nodeName.startsWith(QLatin1String(
"operator")) && nodeName.size() > 8
192 && !nodeName[8].isLetterOrNumber())
193 sortNo = QLatin1String(
"H");
195 sortNo = QLatin1String(
"G");
197 return sortNo + nodeName + QLatin1Char(
' ') + QString::number(fn->overloadNumber(), 36);
200 if (node->isFunction(Genus::QML))
201 return QLatin1Char(
'E') + nodeName + QLatin1Char(
' ') +
202 QString::number(
static_cast<
const FunctionNode*>(node)->overloadNumber(), 36);
205 return QLatin1Char(
'G') + nodeName;
207 return QLatin1Char(
'B') + nodeName;
211
212
213
216 bool irrelevant =
false;
217 bool inherited =
false;
226 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
232 auto *func =
static_cast<FunctionNode *>(node);
233 irrelevant = (inherited && (func->isSomeCtor() || func->isDtor()));
236 irrelevant = (inherited && m_style !=
AllMembers);
238 const auto *tdn =
static_cast<
const TypedefNode *>(node);
239 if (tdn->associatedEnum())
245 QString key = sortName(node);
247 m_obsoleteMembers.push_back(node);
250 m_members.push_back(node);
253 if (m_inheritedMembers.isEmpty()
254 || m_inheritedMembers.last().first != node->parent()) {
256 m_inheritedMembers.append(p);
258 m_inheritedMembers.last().second++;
265
266
267
268
269
270
271
274 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
279 const auto *fn =
static_cast<
const FunctionNode *>(node);
280 if (!fn->overridesThis().isEmpty()) {
281 if (fn->parent() == m_aggregate) {
282 QString key = sortName(fn);
283 if (!m_reimplementedMemberMap.contains(key)) {
284 m_reimplementedMemberMap.insert(key, node);
294
295
296
333 static auto node_less_than = [](
const Node* left,
const Node* right) {
337 if (left->isSharedCommentNode())
338 left =
static_cast<
const SharedCommentNode *>(left)->collective().first();
339 if (right->isSharedCommentNode())
340 right =
static_cast<
const SharedCommentNode *>(right)->collective().first();
341 return sortName(left) < sortName(right);
344 std::stable_sort(m_members.begin(), m_members.end(), node_less_than);
345 std::stable_sort(m_obsoleteMembers.begin(), m_obsoleteMembers.end(), node_less_than);
347 m_reimplementedMembers = m_reimplementedMemberMap.values().toVector();
349 for (
auto &cn : m_classNodesList) {
350 std::stable_sort(cn.second.begin(), cn.second.end(), node_less_than);
355
356
357
358
359
360
361
364
365
366
369 initAggregate(s_allMembers, m_aggregate);
374 initAggregate(s_stdCppClassSummarySections, m_aggregate);
375 initAggregate(s_stdCppClassDetailsSections, m_aggregate);
380 initAggregate(s_stdQmlTypeSummarySections, m_aggregate);
381 initAggregate(s_stdQmlTypeDetailsSections, m_aggregate);
388 initAggregate(s_stdSummarySections, m_aggregate);
389 initAggregate(s_stdDetailsSections, m_aggregate);
396
397
398
404 for (
auto it = nsmap.constBegin(); it != nsmap.constEnd(); ++it) {
405 Node *node = it.value();
407 case NodeType::QmlType:
408 sections[SinceQmlTypes].appendMember(node);
410 case NodeType::Namespace:
411 sections[SinceNamespaces].appendMember(node);
413 case NodeType::Class:
414 case NodeType::Struct:
415 case NodeType::Union:
416 sections[SinceClasses].appendMember(node);
422 if (!it.key().isEmpty())
423 sections[SinceEnumTypes].appendMember(node);
425 sections[SinceEnumValues].appendMember(node);
428 case NodeType::Typedef:
429 case NodeType::TypeAlias:
430 sections[SinceTypeAliases].appendMember(node);
433 const auto *fn =
static_cast<
const FunctionNode *>(node);
434 switch (fn->metaness()) {
435 case FunctionNode::QmlSignal:
436 sections[SinceQmlSignals].appendMember(node);
438 case FunctionNode::QmlSignalHandler:
439 sections[SinceQmlSignalHandlers].appendMember(node);
441 case FunctionNode::QmlMethod:
442 sections[SinceQmlMethods].appendMember(node);
446 sections[SinceMacros].appendMember(node);
448 Node *p = fn->parent();
451 sections[SinceMemberFunctions].appendMember(node);
453 if (p->name().isEmpty())
454 sections[SinceGlobalFunctions].appendMember(node);
456 sections[SinceNamespaceFunctions].appendMember(node);
458 sections[SinceGlobalFunctions].appendMember(node);
460 sections[SinceGlobalFunctions].appendMember(node);
466 case NodeType::Property:
467 sections[SinceProperties].appendMember(node);
469 case NodeType::SharedComment:
470 if (node->isPropertyGroup())
471 sections[SinceQmlProperties].appendMember(node);
473 case NodeType::Variable:
474 sections[SinceVariables].appendMember(node);
476 case NodeType::QmlProperty:
477 sections[SinceQmlProperties].appendMember(node);
479 case NodeType::QmlEnum:
480 sections[SinceQmlEnumTypes].appendMember(node);
489
490
491
492
493
517 m_aggregate =
nullptr;
524
525
528 for (Section §ion : v)
529 section.setAggregate(aggregate);
533
534
537 for (Section §ion : v)
542
543
546 for (Section §ion : v)
551
552
553
554
555
556
557
558
562 if (
auto *scn =
static_cast<SharedCommentNode *>(node); scn->collective().size())
563 return scn->collective().first();
569
570
575 case NodeType::Namespace:
576 v[StdNamespaces].insert(n);
578 case NodeType::Class:
579 case NodeType::Struct:
580 case NodeType::Union:
581 v[StdClasses].insert(n);
584 case NodeType::Typedef:
585 case NodeType::TypeAlias:
586 v[StdTypes].insert(n);
589 auto *func =
static_cast<FunctionNode *>(t);
591 v[StdMacros].insert(n);
593 v[StdFunctions].insert(n);
597 const auto *var =
static_cast<
const VariableNode *>(t);
598 if (!var->doc().isEmpty()) {
600 v[StdStaticVariables].insert(n);
602 v[StdVariables].insert(n);
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
630 bool documentAll =
true;
632 ns =
static_cast<
const NamespaceNode *>(m_aggregate);
636 for (
auto it = m_aggregate->constBegin(); it != m_aggregate->constEnd(); ++it) {
646 for (
const auto &node : relatedBy)
647 stdRefPageSwitch(stdSummarySections(), node);
650
651
652
653
656 for (
const auto &child : children) {
657 if (documentAll || child->hasDoc())
658 stdRefPageSwitch(stdSummarySections(), child);
667
668
669
670
674 static_cast<SharedCommentNode *>(n)->sort();
678 auto *fn =
static_cast<FunctionNode *>(n);
679 if (fn->isRelatedNonmember()) {
681 sv[Macros].insert(n);
683 sv[RelatedNonmembers].insert(n);
690 sv[PublicSlots].insert(fn);
691 else if (fn->isPrivate())
692 sv[PrivateSlots].insert(fn);
694 sv[ProtectedSlots].insert(fn);
695 }
else if (fn->isSignal()) {
696 if (fn->isPublic() && fn->isInAPI())
697 sv[Signals].insert(fn);
698 }
else if (fn->isPublic()) {
699 if (fn->isStatic() && fn->isInAPI())
700 sv[StaticPublicMembers].insert(fn);
701 else if (!sv[PublicFunctions].insertReimplementedMember(fn) && fn->isInAPI())
702 sv[PublicFunctions].insert(fn);
703 }
else if (fn->isPrivate()) {
705 sv[StaticPrivateMembers].insert(fn);
706 else if (!sv[PrivateFunctions].insertReimplementedMember(fn))
707 sv[PrivateFunctions].insert(fn);
710 sv[StaticProtectedMembers].insert(fn);
711 else if (!sv[ProtectedFunctions].insertReimplementedMember(fn))
712 sv[ProtectedFunctions].insert(fn);
717 sv[RelatedNonmembers].insert(n);
723 sv[StaticPublicMembers].insert(n);
724 else if (n->isPrivate())
725 sv[StaticPrivateMembers].insert(n);
727 sv[StaticProtectedMembers].insert(n);
730 sv[PublicVariables].insert(n);
731 else if (n->isProtected())
732 sv[ProtectedVariables].insert(n);
733 else if (n->isPrivate())
734 sv[PrivateVariables].insert(n);
739
740
741
742 if (n
->isTypedef() && (n->name() == QLatin1String(
"QtGadgetHelper")))
745 sv[Properties].insert(n);
746 else if (n->isPublic() && n->isInAPI())
747 sv[PublicTypes].insert(n);
748 else if (n->isPrivate())
749 sv[PrivateTypes].insert(n);
750 else if (n->isProtected())
751 sv[ProtectedTypes].insert(n);
755
756
757
758
766 auto *fn =
static_cast<FunctionNode *>(t);
767 if (fn->isRelatedNonmember()) {
769 dv[DetailsMacros].insert(n);
771 dv[DetailsRelatedNonmembers].insert(n);
776 if (!fn->hasAssociatedProperties() || !fn->doc().isEmpty())
777 dv[DetailsMemberFunctions].insert(n);
781 dv[DetailsRelatedNonmembers].insert(n);
785 if (t->name() != QLatin1String(
"QtGadgetHelper"))
786 dv[DetailsMemberTypes].insert(n);
790 dv[DetailsProperties].insert(n);
791 else if (t->isVariable() && !t->doc().isEmpty())
792 dv[DetailsMemberVariables].insert(n);
802 dv[QmlProperties].insert(n);
807 auto *pn =
static_cast<QmlPropertyNode *>(t);
808 if (pn->isAttached())
809 dv[QmlAttachedProperties].insert(n);
811 dv[QmlProperties].insert(n);
813 dv[QmlEnumTypes].insert(n);
815 auto *fn =
static_cast<FunctionNode *>(t);
816 if (fn->isQmlSignal()) {
817 if (fn->isAttached())
818 dv[QmlAttachedSignals].insert(n);
820 dv[QmlSignals].insert(n);
821 }
else if (fn->isQmlSignalHandler()) {
822 dv[QmlSignalHandlers].insert(n);
823 }
else if (fn->isQmlMethod()) {
824 if (fn->isAttached())
825 dv[QmlAttachedMethods].insert(n);
827 dv[QmlMethods].insert(n);
833
834
835
836
842 auto *pn =
static_cast<QmlPropertyNode *>(n);
843 if (pn->isAttached())
844 sv[QmlAttachedProperties].insert(pn);
846 sv[QmlProperties].insert(pn);
848 sv[QmlEnumTypes].insert(n);
850 auto *fn =
static_cast<FunctionNode *>(n);
851 if (fn->isQmlSignal()) {
852 if (fn->isAttached())
853 sv[QmlAttachedSignals].insert(fn);
855 sv[QmlSignals].insert(fn);
856 }
else if (fn->isQmlSignalHandler()) {
857 sv[QmlSignalHandlers].insert(fn);
858 }
else if (fn->isQmlMethod()) {
859 if (fn->isAttached())
860 sv[QmlAttachedMethods].insert(fn);
862 sv[QmlMethods].insert(fn);
865 auto *scn =
static_cast<SharedCommentNode *>(n);
866 if (scn->isPropertyGroup()) {
867 sv[QmlProperties].insert(scn);
869 for (
const auto &child : scn->collective())
870 distributeQmlNodeInSummaryVector(sv, child,
true);
877 const QList<RelatedClass> baseClasses = cn->baseClasses();
878 for (
const auto &cls : baseClasses) {
880 stack.prepend(cls.m_node);
885
886
887
894 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
896 for (
auto it = m_aggregate->constBegin(); it != m_aggregate->constEnd(); ++it) {
903 distributeNodeInSummaryVector(summarySections, n);
904 distributeNodeInDetailsVector(detailsSections, n);
908 for (
const auto &node : relatedBy)
909 distributeNodeInSummaryVector(summarySections, node);
912 QStack<ClassNode *> stack;
913 QSet<ClassNode *> visited;
914 auto *cn =
static_cast<ClassNode *>(m_aggregate);
916 pushBaseClasses(stack, cn);
917 while (!stack.isEmpty()) {
919 if (visited.contains(cur))
922 for (Node *n : cur->childNodes()) {
923 const NodeContext context = n->createContext();
924 if (InclusionFilter::isIncluded(policy, context) && !n->isProperty()
925 && !n->isRelatedNonmember() && !n->isSharedCommentNode()) {
926 allMembers.insert(n);
929 pushBaseClasses(stack, cur);
937
938
939
951 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
952 for (
const auto n : qtn->childNodes()) {
953 const NodeContext context = n->createContext();
954 if (!InclusionFilter::isIncluded(policy, context))
958 if (qtn != m_aggregate && qtn->isAbstract()) {
960 m_aggregate->findChildren(n->name(), candidates);
961 if (std::any_of(candidates.cbegin(), candidates.cend(), [&n](
const Node *c) {
962 if (c->nodeType() == n->nodeType()) {
963 if (!n->isFunction() ||
964 compare(
static_cast<
const FunctionNode *>(n),
965 static_cast<
const FunctionNode *>(c)) == 0)
974 if (!n->isSharedCommentNode() || n->isPropertyGroup()) {
975 allMembers.insert(n);
976 classNodes->second.push_back(n);
980 if (qtn == m_aggregate || qtn->isAbstract()) {
981 distributeQmlNodeInSummaryVector(summarySections, n);
982 distributeQmlNodeInDetailsVector(detailsSections, n);
986 qCDebug(lcQdoc,
"error: circular type definition: '%s' inherits itself",
987 qPrintable(qtn->name()));
999
1000
1001
1002
1003
1014 for (
const auto §ion : *sections) {
1015 if (!section.obsoleteMembers().isEmpty())
1016 summary_spv->append(§ion);
1024 for (
const auto &it : *sections) {
1025 if (!it.obsoleteMembers().isEmpty())
1026 details_spv->append(&it);
1028 return !summary_spv->isEmpty();
virtual QmlTypeNode * qmlBaseNode() const
If this Aggregate is a QmlTypeNode, this function returns a pointer to the QmlTypeNode that is its ba...
NodeList & relatedByProxy()
Returns a reference to a list of node pointers where each element points to a node in an index file f...
The ClassNode represents a C++ class.
static bool isReimplementedMemberVisible(const InclusionPolicy &policy, const NodeContext &context)
static bool isIncluded(const InclusionPolicy &policy, const NodeContext &context)
This class represents a C++ namespace.
const NodeList & includedChildren() const
Returns a const reference to the namespace node's list of included children, which contains pointers ...
A class for containing the elements of one documentation section.
void clear()
A Section is now an element in a static vector, so we don't have to repeatedly construct and destroy ...
void insert(Node *node)
Inserts the node into this section if it is appropriate for this section.
void reduce()
If this section is not empty, convert its maps to sequential structures for better traversal during d...
ClassNodesList & classNodesList()
bool insertReimplementedMember(Node *node)
Returns true if the node is a reimplemented member function of the current class.
~Section()
The destructor must delete the members of collections when the members are allocated on the heap.
A class for creating vectors of collections for documentation.
const SectionVector & stdCppClassDetailsSections() const
void buildStdCppClassRefPageSections()
Build the section vectors for a standard reference page, when the aggregate node is a C++.
Sections(Aggregate *aggregate)
This constructor builds the vectors of sections based on the type of the aggregate node.
SectionVector & stdCppClassSummarySections()
SectionVector & stdQmlTypeSummarySections()
~Sections()
The behavior of the destructor depends on the type of the Aggregate node that was passed to the const...
SectionVector & stdDetailsSections()
const SectionVector & stdQmlTypeDetailsSections() const
const SectionVector & stdCppClassSummarySections() const
const SectionVector & stdQmlTypeSummarySections() const
void buildStdRefPageSections()
Build the section vectors for a standard reference page, when the aggregate node is not a C++ class o...
void clear(SectionVector &v)
Reset each Section in vector v to its initialized state.
SectionVector & stdCppClassDetailsSections()
void reduce(SectionVector &v)
Linearize the maps in each Section in v.
const SectionVector & stdDetailsSections() const
void buildStdQmlTypeRefPageSections()
Build the section vectors for a standard reference page, when the aggregate node is a QML type.
SectionVector & stdQmlTypeDetailsSections()
SectionVector & sinceSections()
Sections(const NodeMultiMap &nsmap)
This constructor builds a vector of sections from the since node map, nsmap.
bool hasObsoleteMembers(SectionPtrVector *summary_spv, SectionPtrVector *details_spv) const
Returns true if any sections in this object contain obsolete members.
SectionVector & stdSummarySections()
const SectionVector & stdSummarySections() const
static Section & allMembersSection()
Combined button and popup list for selecting options.
QList< Node * > NodeVector
QString sortName(const Node *node)
Construct a name for the node that can be used for sorting a set of nodes into equivalence classes.
static Node * nodeToTestForDistribution(Node *node)
static void pushBaseClasses(QStack< ClassNode * > &stack, ClassNode *cn)
std::pair< const QmlTypeNode *, NodeVector > ClassNodes
QList< const Section * > SectionPtrVector
QList< Section > SectionVector
The Node class is the base class for all the nodes in QDoc's parse tree.
virtual bool isStatic() const
Returns true if the FunctionNode represents a static function.
bool isEnumType(Genus g) const
virtual bool isAbstract() const
Returns true if the ClassNode or QmlTypeNode is marked abstract.
bool isNamespace() const
Returns true if the node type is Namespace.
bool isTypedef() const
Returns true if the node type is Typedef.
bool isQmlType() const
Returns true if the node type is QmlType or QmlValueType.
bool isSharedCommentNode() const
Returns true if the node type is SharedComment.
NodeType nodeType() const override
Returns this node's type.
bool isEnumType() const
Returns true if the node type is Enum.
Aggregate * parent() const
Returns the node's parent pointer.
bool isVariable() const
Returns true if the node type is Variable.
virtual bool isDeprecated() const
Returns true if this node's status is Deprecated.
bool isFunction(Genus g=Genus::DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
virtual bool isInAPI() const
Returns true if this node is considered to be part of the API as per the InclusionPolicy retrieved fr...
bool isProperty() const
Returns true if the node type is Property.
NodeContext createContext() const
virtual bool isPropertyGroup() const
Returns true if the node is a SharedCommentNode for documenting multiple C++ properties or multiple Q...
bool isSharingComment() const
This function returns true if the node is sharing a comment with other nodes.
bool hasDoc() const
Returns true if this node is documented, or it represents a documented node read from the index ('had...
bool isRelatedNonmember() const
Returns true if this is a related nonmember of something.
virtual bool isClassNode() const
Returns true if this is an instance of ClassNode.
bool isQmlProperty() const
Returns true if the node type is QmlProperty.