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
classnode.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 "classnode.h"
5
6#include "functionnode.h"
7#include "propertynode.h"
8#include "qdocdatabase.h"
9#include "qmltypenode.h"
10
12
13/*!
14 \class ClassNode
15 \brief The ClassNode represents a C++ class.
16
17 It is also used to represent a C++ struct or union. There are some
18 actual uses for structs, but I don't think any unions have been
19 documented yet.
20 */
21
22/*!
23 Adds the base class \a node to this class's list of base
24 classes. The base class has the specified \a access. This
25 is a resolved base class.
26 */
27void ClassNode::addResolvedBaseClass(Access access, ClassNode *node)
28{
29 m_bases.append(RelatedClass(access, node));
30 node->m_derived.append(RelatedClass(access, this));
31}
32
33/*!
34 Adds the derived class \a node to this class's list of derived
35 classes. The derived class inherits this class with \a access.
36 */
37void ClassNode::addDerivedClass(Access access, ClassNode *node)
38{
39 m_derived.append(RelatedClass(access, node));
40}
41
42/*!
43 Add an unresolved base class to this class node's list of
44 base classes. The unresolved base class will be resolved
45 before the generate phase of qdoc. In an unresolved base
46 class, the pointer to the base class node is 0.
47 */
48void ClassNode::addUnresolvedBaseClass(Access access, const QStringList &path)
49{
50 m_bases.append(RelatedClass(access, path));
51}
52
53/*!
54 Search the child list to find the property node with the
55 specified \a name.
56 */
58{
59 Node *n = findNonfunctionChild(name, &Node::isProperty);
60
61 if (n)
62 return static_cast<PropertyNode *>(n);
63
64 PropertyNode *pn = nullptr;
65
66 const QList<RelatedClass> &bases = baseClasses();
67 if (!bases.isEmpty()) {
68 for (const RelatedClass &base : bases) {
69 ClassNode *cn = base.m_node;
70 if (cn) {
71 pn = cn->findPropertyNode(name);
72 if (pn)
73 break;
74 }
75 }
76 }
77 const QList<RelatedClass> &ignoredBases = ignoredBaseClasses();
78 if (!ignoredBases.isEmpty()) {
79 for (const RelatedClass &base : ignoredBases) {
80 ClassNode *cn = base.m_node;
81 if (cn) {
82 pn = cn->findPropertyNode(name);
83 if (pn)
84 break;
85 }
86 }
87 }
88
89 return pn;
90}
91
92/*!
93 \a fn is an overriding function in this class or in a class
94 derived from this class. Find the node for the function that
95 \a fn overrides in this class's children or in one of this
96 class's base classes. Return a pointer to the overridden
97 function or return 0.
98
99 This should be revised because clang provides the path to the
100 overridden function. mws 15/12/2018
101 */
103{
104 for (auto &bc : m_bases) {
105 ClassNode *cn = bc.m_node;
106 if (cn == nullptr) {
107 cn = QDocDatabase::qdocDB()->findClassNode(bc.m_path);
108 bc.m_node = cn;
109 }
110 if (cn != nullptr) {
111 FunctionNode *result = cn->findFunctionChild(fn);
112 if (result != nullptr && !result->isInternal() && !result->isNonvirtual()
113 && result->hasDoc())
114 return result;
115 result = cn->findOverriddenFunction(fn);
116 if (result != nullptr && !result->isNonvirtual())
117 return result;
118 }
119 }
120 return nullptr;
121}
122
123/*!
124 \a fn is an overriding function in this class or in a class
125 derived from this class. Find the node for the property that
126 \a fn overrides in this class's children or in one of this
127 class's base classes. Return a pointer to the overridden
128 property or return 0.
129 */
131{
132 for (auto &baseClass : m_bases) {
133 ClassNode *cn = baseClass.m_node;
134 if (cn == nullptr) {
135 cn = QDocDatabase::qdocDB()->findClassNode(baseClass.m_path);
136 baseClass.m_node = cn;
137 }
138 if (cn != nullptr) {
139 const NodeList &children = cn->childNodes();
140 for (const auto &child : children) {
141 if (child->isProperty()) {
142 auto *pn = static_cast<PropertyNode *>(child);
143 if (pn->name() == fn->name() || pn->hasAccessFunction(fn->name())) {
144 if (pn->hasDoc())
145 return pn;
146 }
147 }
148 }
149 PropertyNode *result = cn->findOverriddenProperty(fn);
150 if (result != nullptr)
151 return result;
152 }
153 }
154 return nullptr;
155}
156
157/*!
158 Returns true if the class or struct represented by this class
159 node must be documented. If this function returns true, then
160 qdoc must find a qdoc comment for this class. If it returns
161 false, then the class need not be documented.
162 */
164{
165 if (!hasDoc() || isPrivate() || isInternal() || isDontDocument())
166 return false;
167 if (declLocation().fileName().endsWith(QLatin1String("_p.h")) && !hasDoc())
168 return false;
169
170 return true;
171}
172
173/*!
174 A base class of this class node was private or internal.
175 That node's list of \a bases is traversed in this function.
176 Each of its public base classes is promoted to be a base
177 class of this node for documentation purposes. For each
178 private or internal class node in \a bases, this function
179 is called recursively with the list of base classes from
180 that private or internal class node.
181 */
182void ClassNode::promotePublicBases(const QList<RelatedClass> &bases)
183{
184 if (!bases.isEmpty()) {
185 for (qsizetype i = bases.size() - 1; i >= 0; --i) {
186 ClassNode *bc = bases.at(i).m_node;
187 if (bc == nullptr)
188 bc = QDocDatabase::qdocDB()->findClassNode(bases.at(i).m_path);
189 if (bc != nullptr) {
190 if (bc->isPrivate() || bc->isInternal())
191 promotePublicBases(bc->baseClasses());
192 else
193 m_bases.append(bases.at(i));
194 }
195 }
196 }
197}
198
199/*!
200 Remove private and internal bases classes from this class's list
201 of base classes. When a base class is removed from the list, add
202 its base classes to this class's list of base classes.
203 */
205{
206 int i;
207 i = 0;
208 QSet<ClassNode *> found;
209
210 // Remove private and duplicate base classes.
211 while (i < m_bases.size()) {
212 ClassNode *bc = m_bases.at(i).m_node;
213 if (bc == nullptr)
214 bc = QDocDatabase::qdocDB()->findClassNode(m_bases.at(i).m_path);
215 if (bc != nullptr
216 && (bc->isPrivate() || bc->isInternal() || bc->isDontDocument()
217 || found.contains(bc))) {
218 RelatedClass rc = m_bases.at(i);
219 m_bases.removeAt(i);
220 m_ignoredBases.append(rc);
221 promotePublicBases(bc->baseClasses());
222 } else {
223 ++i;
224 }
225 found.insert(bc);
226 }
227
228 i = 0;
229 while (i < m_derived.size()) {
230 ClassNode *dc = m_derived.at(i).m_node;
231 if (dc != nullptr && (dc->isPrivate() || dc->isInternal() || dc->isDontDocument())) {
232 m_derived.removeAt(i);
233 const QList<RelatedClass> &dd = dc->derivedClasses();
234 for (qsizetype j = dd.size() - 1; j >= 0; --j)
235 m_derived.insert(i, dd.at(j));
236 } else {
237 ++i;
238 }
239 }
240}
241
242/*!
243 */
245{
246 for (const auto &baseClass : std::as_const(baseClasses())) {
247 ClassNode *cn = baseClass.m_node;
248 if (cn) {
249 Node *n = cn->findNonfunctionChild(pn->name(), &Node::isProperty);
250 if (n) {
251 auto *baseProperty = static_cast<PropertyNode *>(n);
252 cn->resolvePropertyOverriddenFromPtrs(baseProperty);
253 pn->setOverriddenFrom(baseProperty);
254 } else
255 cn->resolvePropertyOverriddenFromPtrs(pn);
256 }
257 }
258}
259
260QT_END_NAMESPACE
The ClassNode represents a C++ class.
Definition classnode.h:21
PropertyNode * findPropertyNode(const QString &name)
Search the child list to find the property node with the specified name.
Definition classnode.cpp:57
void addResolvedBaseClass(Access access, ClassNode *node)
Adds the base class node to this class's list of base classes.
Definition classnode.cpp:27
PropertyNode * findOverriddenProperty(const FunctionNode *fn)
fn is an overriding function in this class or in a class derived from this class.
FunctionNode * findOverriddenFunction(const FunctionNode *fn)
fn is an overriding function in this class or in a class derived from this class.
bool docMustBeGenerated() const override
Returns true if the class or struct represented by this class node must be documented.
void removePrivateAndInternalBases()
Remove private and internal bases classes from this class's list of base classes.
void resolvePropertyOverriddenFromPtrs(PropertyNode *pn)
void addDerivedClass(Access access, ClassNode *node)
Adds the derived class node to this class's list of derived classes.
Definition classnode.cpp:37
void addUnresolvedBaseClass(Access access, const QStringList &path)
Add an unresolved base class to this class node's list of base classes.
Definition classnode.cpp:48
This node is used to represent any kind of function being documented.
bool isDontDocument() const
Returns true if this node's status is DontDocument.
Definition node.h:131
bool isPrivate() const
Returns true if this node's access is Private.
Definition node.h:146
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
const Location & declLocation() const
Returns the Location where this node's declaration was seen.
Definition node.h:265
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
LinkType
An unsigned char value that probably should be moved out of the Node base class.
Definition node.h:112
This class describes one instance of using the Q_PROPERTY macro.
This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a...
static QDocDatabase * qdocDB()
Creates the singleton.
Combined button and popup list for selecting options.
A struct for indicating that a ClassNode is related in some way to another ClassNode.
RelatedClass(Access access, ClassNode *node)
This is the constructor used when the related class has been resolved.