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
functionnode.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 "functionnode.h"
5#include "propertynode.h"
6
7#include <string>
8
10
11/*!
12 \class FunctionNode
13
14 This node is used to represent any kind of function being
15 documented. It can represent a C++ class member function, a C++
16 global function, a QML method, or a macro, with or without
17 parameters.
18
19 A C++ function can be a signal, a slot, a constructor of any
20 kind, a destructor, a copy or move assignment operator, or
21 just a plain old member function or a global function.
22
23 A QML method can be a plain old method, or a
24 signal or signal handler.
25
26 If the function is an overload, its overload flag is
27 true.
28
29 The function node also has an overload number. If the
30 node's overload flag is set, this overload number is
31 positive; otherwise, the overload number is 0.
32 */
33
34/*!
35 Construct a function node for a C++ function. It's parent
36 is \a parent, and it's name is \a name.
37
38 \note The function node's overload flag is set to false, and
39 its overload number is set to 0. These data members are set
40 in normalizeOverloads(), when all the overloads are known.
41 */
42FunctionNode::FunctionNode(Aggregate *parent, const QString &name)
43 : Node(NodeType::Function, parent, name),
44 m_const(false),
45 m_implicitlyGenerated(false),
46 m_static(false),
47 m_reimpFlag(false),
48 m_attached(false),
49 m_overloadFlag(false),
50 m_primaryOverloadFlag(false),
51 m_isFinal(false),
52 m_isOverride(false),
53 m_isRef(false),
54 m_isRefRef(false),
55 m_isInvokable(false),
56 m_explicitlyDefaulted(false),
57 m_deleted(false),
58 m_hiddenFriend(false),
59 m_explicit{false},
60 m_constexpr{false},
61 m_metaness(Plain),
62 m_virtualness(NonVirtual),
63 m_overloadNumber(0)
64{
65 // nothing
66}
67
68/*!
69 Construct a function node for a QML method or signal, specified
70 by ther Metaness value \a type. It's parent is \a parent, and
71 it's name is \a name. If \a attached is true, it is an attached
72 method or signal.
73
74 \note The function node's overload flag is set to false, and
75 its overload number is set to 0. These data members are set
76 in normalizeOverloads(), when all the overloads are known.
77 */
78FunctionNode::FunctionNode(Metaness kind, Aggregate *parent, const QString &name, bool attached)
79 : Node(NodeType::Function, parent, name),
80 m_const(false),
81 m_implicitlyGenerated(false),
82 m_static(false),
83 m_reimpFlag(false),
84 m_attached(attached),
85 m_overloadFlag(false),
86 m_primaryOverloadFlag(false),
87 m_isFinal(false),
88 m_isOverride(false),
89 m_isRef(false),
90 m_isRefRef(false),
91 m_isInvokable(false),
92 m_explicitlyDefaulted(false),
93 m_deleted(false),
94 m_hiddenFriend(false),
95 m_explicit{false},
96 m_constexpr{false},
97 m_metaness(kind),
98 m_virtualness(NonVirtual),
99 m_overloadNumber(0)
100{
101 setGenus(getGenus(m_metaness));
102 if (!isCppNode() && name.startsWith("__"))
104}
105
106/*!
107 Clone this node on the heap and make the clone a child of
108 \a parent. Return the pointer to the clone.
109 */
110Node *FunctionNode::clone(Aggregate *parent)
111{
112 auto *fn = new FunctionNode(*this); // shallow copy
113 fn->setParent(nullptr);
114 parent->addChild(fn);
115 return fn;
116}
117
118/*!
119 Returns this function's virtualness value as a string
120 for use as an attribute value in index files.
121 */
123{
124 switch (m_virtualness) {
126 return QLatin1String("virtual");
128 return QLatin1String("pure");
130 default:
131 break;
132 }
133 return QLatin1String("non");
134}
135
136/*!
137 Sets the function node's virtualness value based on the value
138 of string \a value, which is the value of the function's \e{virtual}
139 attribute in an index file. If \a value is \e{pure}, and if the
140 parent() is a C++ class, set the parent's \e abstract flag to
141 \c {true}.
142 */
143void FunctionNode::setVirtualness(const QString &value)
144{
145 if (value == QLatin1String("pure")) {
146 m_virtualness = PureVirtual;
147 if (parent() && parent()->isClassNode())
148 parent()->setAbstract(true);
149 return;
150 }
151
152 m_virtualness = (value == QLatin1String("virtual")) ? NormalVirtual : NonVirtual;
153}
154
156static void buildMetanessMap()
157{
161 metanessMap_["constructor"] = FunctionNode::Ctor;
162 metanessMap_["copy-constructor"] = FunctionNode::CCtor;
163 metanessMap_["move-constructor"] = FunctionNode::MCtor;
164 metanessMap_["destructor"] = FunctionNode::Dtor;
166 metanessMap_["macrowithparams"] = FunctionNode::MacroWithParams;
167 metanessMap_["macrowithoutparams"] = FunctionNode::MacroWithoutParams;
168 metanessMap_["copy-assign"] = FunctionNode::CAssign;
169 metanessMap_["move-assign"] = FunctionNode::MAssign;
172 metanessMap_["qmlsignalhandler"] = FunctionNode::QmlSignalHandler;
174}
175
185
186/*!
187 Determines the Genus value for this FunctionNode given the
188 Metaness value \a metaness. Returns the Genus value. \a metaness must be
189 one of the values of Metaness. If not, Node::DontCare is
190 returned.
191 */
193{
194 switch (metaness) {
207 return Genus::CPP;
211 return Genus::QML;
212 }
213
214 return Genus::DontCare;
215}
216
217/*!
218 This static function converts the string \a value to an enum
219 value for the kind of function named by \a value.
220 */
221FunctionNode::Metaness FunctionNode::getMetaness(const QString &value)
222{
223 if (metanessMap_.isEmpty())
225 return metanessMap_[value];
226}
227
228/*!
229 This static function converts the topic string \a topic to an enum
230 value for the kind of function this FunctionNode represents.
231 */
232FunctionNode::Metaness FunctionNode::getMetanessFromTopic(const QString &topic)
233{
234 if (topicMetanessMap_.isEmpty())
236 return topicMetanessMap_[topic];
237}
238
239/*!
240 Extends the base implementation to test whether an associated enum
241 is in the API.
242*/
244{
245 if (Node::isInAPI())
246 return true;
247
248 for (auto *property : m_associatedProperties) {
249 if (property->isInAPI())
250 return true;
251 }
252
253 return false;
254}
255
256/*!
257 Sets the function node's overload number to \a number. If \a number
258 is 0, the function node's overload flag is set to false. If
259 \a number is greater than 0, the overload flag is set to true.
260 */
261void FunctionNode::setOverloadNumber(signed short number)
262{
263 m_overloadNumber = number;
264 m_overloadFlag = (number > 0);
265}
266
267/*!
268 \fn void FunctionNode::setReimpFlag()
269
270 Sets the function node's reimp flag to \c true, which means
271 the \e {\\reimp} command was used in the qdoc comment. It is
272 supposed to mean that the function reimplements a virtual
273 function in a base class.
274 */
275
276/*!
277 Returns a string representing the kind of function this
278 Function node represents, which depends on the Metaness
279 value.
280 */
282{
283 switch (m_metaness) {
285 return "QML signal";
287 return "QML signal handler";
289 return "QML method";
290 default:
291 return "function";
292 }
293}
294
295/*!
296 Returns a string representing the Metaness enum value for
297 this function. It is used in index files.
298 */
300{
301 switch (m_metaness) {
303 return "plain";
305 return "signal";
307 return "slot";
309 return "constructor";
311 return "copy-constructor";
313 return "move-constructor";
315 return "destructor";
317 return "macrowithparams";
319 return "macrowithoutparams";
321 return "native";
323 return "copy-assign";
325 return "move-assign";
327 return "qmlsignal";
329 return "qmlsignalhandler";
331 return "qmlmethod";
332 default:
333 return "plain";
334 }
335}
336
337/*!
338 Adds the "associated" property \a p to this function node.
339 The function might be the setter or getter for a property,
340 for example.
341 */
342void FunctionNode::addAssociatedProperty(PropertyNode *p)
343{
344 m_associatedProperties.append(p);
345}
346
347/*!
348 Returns the \e primary associated property, if this is an
349 access function for one or more properties.
350
351 An associated property is considered a primary if this
352 function's name starts with the property name. If there's
353 no such property, return the first one available as a
354 fallback.
355
356 If no associated properties exist, returns \nullptr.
357 */
359{
360 if (m_associatedProperties.isEmpty())
361 return nullptr;
362 if (m_associatedProperties.size() == 1)
363 return m_associatedProperties[0];
364
365 auto it = std::find_if(
366 m_associatedProperties.cbegin(), m_associatedProperties.cend(),
367 [this](const PropertyNode *p) {
368 return name().startsWith(p->name());
369 });
370
371 return it != m_associatedProperties.cend() ? *it : m_associatedProperties[0];
372}
373
374/*!
375 \reimp
376
377 Returns \c true if this is an access function for an obsolete property,
378 otherwise calls the base implementation of isDeprecated().
379*/
381{
383}
384
385/*! \fn unsigned char FunctionNode::overloadNumber() const
386 Returns the overload number for this function.
387 */
388
389/*!
390 Reconstructs and returns the function's signature.
391
392 Specific parts of the signature are included according to
393 flags in \a options:
394
395 \value Node::SignaturePlain
396 Plain signature
397 \value Node::SignatureDefaultValues
398 Include any default argument values
399 \value Node::SignatureReturnType
400 Include return type
401 \value Node::SignatureTemplateParams
402 Include \c {template <parameter_list>} if one exists
403 */
404QString FunctionNode::signature(Node::SignatureOptions options) const
405{
406 QStringList elements;
407
408 if (options & Node::SignatureTemplateParams && templateDecl())
409 elements << (*templateDecl()).to_qstring();
410 if (options & Node::SignatureReturnType)
411 elements << m_returnType.first;
412 elements.removeAll(QString());
413
414 if (!isMacroWithoutParams()) {
415 elements << name() + QLatin1Char('(')
416 + m_parameters.signature(options & Node::SignatureDefaultValues)
417 + QLatin1Char(')');
418 if (!isMacro()) {
419 if (isConst())
420 elements << QStringLiteral("const");
421 if (isRef())
422 elements << QStringLiteral("&");
423 else if (isRefRef())
424 elements << QStringLiteral("&&");
425 }
426 } else {
427 elements << name();
428 }
429 return elements.join(QLatin1Char(' '));
430}
431
432/*!
433 \fn int FunctionNode::compare(const FunctionNode *f1, const FunctionNode *f2)
434
435 Compares FunctionNode \a f1 with \a f2, assumed to have identical names.
436 Returns an integer less than, equal to, or greater than zero if f1 is
437 considered less than, equal to, or greater than f2.
438
439 The main purpose is to provide stable ordering for function overloads.
440 */
441[[nodiscard]] int compare(const FunctionNode *f1, const FunctionNode *f2)
442{
443 // Compare parameter count
444 int param_count{f1->parameters().count()};
445
446 if (int param_diff = param_count - f2->parameters().count(); param_diff != 0)
447 return param_diff;
448
449 // Constness
450 if (f1->isConst() != f2->isConst())
451 return f1->isConst() ? 1 : -1;
452
453 // Reference qualifiers
454 if (f1->isRef() != f2->isRef())
455 return f1->isRef() ? 1 : -1;
456 if (f1->isRefRef() != f2->isRefRef())
457 return f1->isRefRef() ? 1 : -1;
458
459 // Attachedness (applies to QML methods)
461 return f1->isAttached() ? 1 : -1;
462
463 // Parameter types
464 const Parameters &p1{f1->parameters()};
465 const Parameters &p2{f2->parameters()};
466 for (qsizetype i = 0; i < param_count; ++i) {
467 if (int type_comp = QString::compare(p1.at(i).type(), p2.at(i).type());
468 type_comp != 0) {
469 return type_comp;
470 }
471 }
472
473 // Template declarations
474 const auto &t1{f1->templateDecl()};
475 const auto &t2{f2->templateDecl()};
476 if (!t1 && !t2)
477 return 0;
478
479 if (t1 && t2)
480 return (*t1).to_std_string().compare((*t2).to_std_string());
481
482 return t1 ? 1 : -1;
483}
484
485/*!
486 In some cases, it is ok for a public function to be not documented.
487 For example, the macro Q_OBJECT adds several functions to the API of
488 a class, but these functions are normally not meant to be documented.
489 So if a function node doesn't have documentation, then if its name is
490 in the list of functions that it is ok not to document, this function
491 returns true. Otherwise, it returns false.
492
493 These are the member function names added by macros. Usually they
494 are not documented, but they can be documented, so this test avoids
495 reporting an error if they are not documented.
496
497 But maybe we should generate a standard text for each of them?
498 */
500{
501 if (!hasDoc()) {
502 if (name().startsWith(QLatin1String("qt_")) || name() == QLatin1String("metaObject")
503 || name() == QLatin1String("tr") || name() == QLatin1String("trUtf8")
504 || name() == QLatin1String("d_func")) {
505 return true;
506 }
507 QString s = signature(Node::SignatureReturnType);
508 if (s.contains(QLatin1String("enum_type")) && s.contains(QLatin1String("operator|")))
509 return true;
510 }
511 return false;
512}
513
514/*!
515 \fn bool FunctionNode::hasOverloads() const
516 Returns \c true if this function has overloads.
517 */
518
519/*!
520 \internal
521 \brief Returns the type of the function as a string.
522
523 The returned string is either the type as declared in the header, or `auto`
524 if that's the return type in the `\\fn` command for the function.
525 */
527{
528 if (m_returnType.second.has_value())
529 return m_returnType.second.value();
530 return m_returnType.first;
531}
532
533/*!
534 Returns the status of the function, taking the status of any associated
535 properties into account.
536*/
538{
539 auto it = std::find_if_not(m_associatedProperties.begin(), m_associatedProperties.end(),
540 [](const Node *p) -> bool { return p->isDeprecated(); });
541
542 if (!m_associatedProperties.isEmpty() && it == m_associatedProperties.end())
543 return Status::Deprecated;
544 else
545 return Node::status();
546}
547
548QT_END_NAMESPACE
This node is used to represent any kind of function being documented.
QString metanessString() const
Returns a string representing the Metaness enum value for this function.
QString kindString() const
Returns a string representing the kind of function this Function node represents, which depends on th...
FunctionNode(Metaness type, Aggregate *parent, const QString &name, bool attached=false)
Construct a function node for a QML method or signal, specified by ther Metaness value type.
const Parameters & parameters() const
bool isRef() const
bool isInAPI() const override
Extends the base implementation to test whether an associated enum is in the API.
bool isDeprecated() const override
\reimp
static Genus getGenus(Metaness metaness)
Determines the Genus value for this FunctionNode given the Metaness value metaness.
bool isConst() const
bool isRefRef() const
bool isAttached() const override
Returns true if the QML property or QML method node is marked as attached.
void setOverloadNumber(signed short number)
Sets the function node's overload number to number.
bool isIgnored() const
In some cases, it is ok for a public function to be not documented.
friend int compare(const FunctionNode *f1, const FunctionNode *f2)
Compares FunctionNode f1 with f2, assumed to have identical names.
QString returnTypeString() const
Returns the type of the function as a string.
virtual Status status() const override
Returns the status of the function, taking the status of any associated properties into account.
void setVirtualness(const QString &value)
Sets the function node's virtualness value based on the value of string value, which is the value of ...
const PropertyNode * primaryAssociatedProperty() const
Returns the primary associated property, if this is an access function for one or more properties.
QString virtualness() const
Returns this function's virtualness value as a string for use as an attribute value in index files.
This class describes one instance of using the Q_PROPERTY macro.
Status
Specifies the status of the QQmlIncubator.
static void buildTopicMetanessMap()
static void buildMetanessMap()
static QMap< QString, FunctionNode::Metaness > metanessMap_
static QMap< QString, FunctionNode::Metaness > topicMetanessMap_
NodeType
Definition genustypes.h:150
Combined button and popup list for selecting options.
@ Deprecated
Definition status.h:12
@ Internal
Definition status.h:15
The Node class is the base class for all the nodes in QDoc's parse tree.
void setGenus(Genus t)
Definition node.h:86
virtual Status status() const
Returns the node's status value.
Definition node.h:239
Aggregate * parent() const
Returns the node's parent pointer.
Definition node.h:208
virtual bool isDeprecated() const
Returns true if this node's status is Deprecated.
Definition node.h:134
const std::optional< RelaxedTemplateDeclaration > & templateDecl() const
Definition node.h:243
virtual bool isInAPI() const
Returns true if this node is considered to be part of the API as per the InclusionPolicy retrieved fr...
Definition node.cpp:917
bool hasDoc() const
Returns true if this node is documented, or it represents a documented node read from the index ('had...
Definition node.cpp:932
bool isCppNode() const
Returns true if this node's Genus value is CPP.
Definition node.h:91
void setStatus(Status t)
Sets the node's status to t.
Definition node.cpp:570
@ SignatureReturnType
Definition node.h:68
A class for parsing and managing a function parameter list.
Definition main.cpp:28
int count() const
Definition parameters.h:72