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(Function, parent, name),
44 m_const(false),
45 m_default(false),
46 m_static(false),
47 m_reimpFlag(false),
48 m_attached(false),
49 m_overloadFlag(false),
50 m_isFinal(false),
51 m_isOverride(false),
52 m_isRef(false),
53 m_isRefRef(false),
54 m_isInvokable(false),
55 m_explicit{false},
56 m_constexpr{false},
57 m_metaness(Plain),
58 m_virtualness(NonVirtual),
59 m_overloadNumber(0)
60{
61 // nothing
62}
63
64/*!
65 Construct a function node for a QML method or signal, specified
66 by ther Metaness value \a type. It's parent is \a parent, and
67 it's name is \a name. If \a attached is true, it is an attached
68 method or signal.
69
70 \note The function node's overload flag is set to false, and
71 its overload number is set to 0. These data members are set
72 in normalizeOverloads(), when all the overloads are known.
73 */
74FunctionNode::FunctionNode(Metaness kind, Aggregate *parent, const QString &name, bool attached)
75 : Node(Function, parent, name),
76 m_const(false),
77 m_default(false),
78 m_static(false),
79 m_reimpFlag(false),
80 m_attached(attached),
81 m_overloadFlag(false),
82 m_isFinal(false),
83 m_isOverride(false),
84 m_isRef(false),
85 m_isRefRef(false),
86 m_isInvokable(false),
87 m_explicit{false},
88 m_constexpr{false},
89 m_metaness(kind),
90 m_virtualness(NonVirtual),
91 m_overloadNumber(0)
92{
93 setGenus(getGenus(m_metaness));
94 if (!isCppNode() && name.startsWith("__"))
96}
97
98/*!
99 Clone this node on the heap and make the clone a child of
100 \a parent. Return the pointer to the clone.
101 */
102Node *FunctionNode::clone(Aggregate *parent)
103{
104 auto *fn = new FunctionNode(*this); // shallow copy
105 fn->setParent(nullptr);
106 parent->addChild(fn);
107 return fn;
108}
109
110/*!
111 Returns this function's virtualness value as a string
112 for use as an attribute value in index files.
113 */
115{
116 switch (m_virtualness) {
118 return QLatin1String("virtual");
120 return QLatin1String("pure");
122 default:
123 break;
124 }
125 return QLatin1String("non");
126}
127
128/*!
129 Sets the function node's virtualness value based on the value
130 of string \a value, which is the value of the function's \e{virtual}
131 attribute in an index file. If \a value is \e{pure}, and if the
132 parent() is a C++ class, set the parent's \e abstract flag to
133 \c {true}.
134 */
135void FunctionNode::setVirtualness(const QString &value)
136{
137 if (value == QLatin1String("pure")) {
138 m_virtualness = PureVirtual;
139 if (parent() && parent()->isClassNode())
140 parent()->setAbstract(true);
141 return;
142 }
143
144 m_virtualness = (value == QLatin1String("virtual")) ? NormalVirtual : NonVirtual;
145}
146
148static void buildMetanessMap()
149{
153 metanessMap_["constructor"] = FunctionNode::Ctor;
154 metanessMap_["copy-constructor"] = FunctionNode::CCtor;
155 metanessMap_["move-constructor"] = FunctionNode::MCtor;
156 metanessMap_["destructor"] = FunctionNode::Dtor;
158 metanessMap_["macrowithparams"] = FunctionNode::MacroWithParams;
159 metanessMap_["macrowithoutparams"] = FunctionNode::MacroWithoutParams;
160 metanessMap_["copy-assign"] = FunctionNode::CAssign;
161 metanessMap_["move-assign"] = FunctionNode::MAssign;
164 metanessMap_["qmlsignalhandler"] = FunctionNode::QmlSignalHandler;
166}
167
177
178/*!
179 Determines the Genus value for this FunctionNode given the
180 Metaness value \a metaness. Returns the Genus value. \a metaness must be
181 one of the values of Metaness. If not, Node::DontCare is
182 returned.
183 */
208
209/*!
210 This static function converts the string \a value to an enum
211 value for the kind of function named by \a value.
212 */
213FunctionNode::Metaness FunctionNode::getMetaness(const QString &value)
214{
215 if (metanessMap_.isEmpty())
217 return metanessMap_[value];
218}
219
220/*!
221 This static function converts the topic string \a topic to an enum
222 value for the kind of function this FunctionNode represents.
223 */
224FunctionNode::Metaness FunctionNode::getMetanessFromTopic(const QString &topic)
225{
226 if (topicMetanessMap_.isEmpty())
228 return topicMetanessMap_[topic];
229}
230
231/*!
232 Sets the function node's overload number to \a number. If \a number
233 is 0, the function node's overload flag is set to false. If
234 \a number is greater than 0, the overload flag is set to true.
235 */
236void FunctionNode::setOverloadNumber(signed short number)
237{
238 m_overloadNumber = number;
239 m_overloadFlag = (number > 0);
240}
241
242/*!
243 \fn void FunctionNode::setReimpFlag()
244
245 Sets the function node's reimp flag to \c true, which means
246 the \e {\\reimp} command was used in the qdoc comment. It is
247 supposed to mean that the function reimplements a virtual
248 function in a base class.
249 */
250
251/*!
252 Returns a string representing the kind of function this
253 Function node represents, which depends on the Metaness
254 value.
255 */
257{
258 switch (m_metaness) {
260 return "QML signal";
262 return "QML signal handler";
264 return "QML method";
265 default:
266 return "function";
267 }
268}
269
270/*!
271 Returns a string representing the Metaness enum value for
272 this function. It is used in index files.
273 */
275{
276 switch (m_metaness) {
278 return "plain";
280 return "signal";
282 return "slot";
284 return "constructor";
286 return "copy-constructor";
288 return "move-constructor";
290 return "destructor";
292 return "macrowithparams";
294 return "macrowithoutparams";
296 return "native";
298 return "copy-assign";
300 return "move-assign";
302 return "qmlsignal";
304 return "qmlsignalhandler";
306 return "qmlmethod";
307 default:
308 return "plain";
309 }
310}
311
312/*!
313 Adds the "associated" property \a p to this function node.
314 The function might be the setter or getter for a property,
315 for example.
316 */
317void FunctionNode::addAssociatedProperty(PropertyNode *p)
318{
319 m_associatedProperties.append(p);
320}
321
322/*!
323 Returns the \e primary associated property, if this is an
324 access function for one or more properties.
325
326 An associated property is considered a primary if this
327 function's name starts with the property name. If there's
328 no such property, return the first one available as a
329 fallback.
330
331 If no associated properties exist, returns \nullptr.
332 */
334{
335 if (m_associatedProperties.isEmpty())
336 return nullptr;
337 if (m_associatedProperties.size() == 1)
338 return m_associatedProperties[0];
339
340 auto it = std::find_if(
341 m_associatedProperties.cbegin(), m_associatedProperties.cend(),
342 [this](const PropertyNode *p) {
343 return name().startsWith(p->name());
344 });
345
346 return it != m_associatedProperties.cend() ? *it : m_associatedProperties[0];
347}
348
349/*!
350 \reimp
351
352 Returns \c true if this is an access function for an obsolete property,
353 otherwise calls the base implementation of isDeprecated().
354*/
356{
357 auto it = std::find_if_not(m_associatedProperties.begin(), m_associatedProperties.end(),
358 [](const Node *p) -> bool { return p->isDeprecated(); });
359
360 if (!m_associatedProperties.isEmpty() && it == m_associatedProperties.end())
361 return true;
362
363 return Node::isDeprecated();
364}
365
366/*! \fn unsigned char FunctionNode::overloadNumber() const
367 Returns the overload number for this function.
368 */
369
370/*!
371 Reconstructs and returns the function's signature.
372
373 Specific parts of the signature are included according to
374 flags in \a options:
375
376 \value Node::SignaturePlain
377 Plain signature
378 \value Node::SignatureDefaultValues
379 Include any default argument values
380 \value Node::SignatureReturnType
381 Include return type
382 \value Node::SignatureTemplateParams
383 Include \c {template <parameter_list>} if one exists
384 */
385QString FunctionNode::signature(Node::SignatureOptions options) const
386{
387 QStringList elements;
388
389 if (options & Node::SignatureTemplateParams && templateDecl())
390 elements << (*templateDecl()).to_qstring();
391 if (options & Node::SignatureReturnType)
392 elements << m_returnType.first;
393 elements.removeAll(QString());
394
395 if (!isMacroWithoutParams()) {
396 elements << name() + QLatin1Char('(')
397 + m_parameters.signature(options & Node::SignatureDefaultValues)
398 + QLatin1Char(')');
399 if (!isMacro()) {
400 if (isConst())
401 elements << QStringLiteral("const");
402 if (isRef())
403 elements << QStringLiteral("&");
404 else if (isRefRef())
405 elements << QStringLiteral("&&");
406 }
407 } else {
408 elements << name();
409 }
410 return elements.join(QLatin1Char(' '));
411}
412
413/*!
414 \fn int FunctionNode::compare(const FunctionNode *f1, const FunctionNode *f2)
415
416 Compares FunctionNode \a f1 with \a f2, assumed to have identical names.
417 Returns an integer less than, equal to, or greater than zero if f1 is
418 considered less than, equal to, or greater than f2.
419
420 The main purpose is to provide stable ordering for function overloads.
421 */
422[[nodiscard]] int compare(const FunctionNode *f1, const FunctionNode *f2)
423{
424 // Compare parameter count
425 int param_count{f1->parameters().count()};
426
427 if (int param_diff = param_count - f2->parameters().count(); param_diff != 0)
428 return param_diff;
429
430 // Constness
431 if (f1->isConst() != f2->isConst())
432 return f1->isConst() ? 1 : -1;
433
434 // Reference qualifiers
435 if (f1->isRef() != f2->isRef())
436 return f1->isRef() ? 1 : -1;
437 if (f1->isRefRef() != f2->isRefRef())
438 return f1->isRefRef() ? 1 : -1;
439
440 // Attachedness (applies to QML methods)
442 return f1->isAttached() ? 1 : -1;
443
444 // Parameter types
445 const Parameters &p1{f1->parameters()};
446 const Parameters &p2{f2->parameters()};
447 for (qsizetype i = 0; i < param_count; ++i) {
448 if (int type_comp = QString::compare(p1.at(i).type(), p2.at(i).type());
449 type_comp != 0) {
450 return type_comp;
451 }
452 }
453
454 // Template declarations
455 const auto t1{f1->templateDecl()};
456 const auto t2{f2->templateDecl()};
457 if (!t1 && !t2)
458 return 0;
459
460 if (t1 && t2)
461 return (*t1).to_std_string().compare((*t2).to_std_string());
462
463 return t1 ? 1 : -1;
464}
465
466/*!
467 In some cases, it is ok for a public function to be not documented.
468 For example, the macro Q_OBJECT adds several functions to the API of
469 a class, but these functions are normally not meant to be documented.
470 So if a function node doesn't have documentation, then if its name is
471 in the list of functions that it is ok not to document, this function
472 returns true. Otherwise, it returns false.
473
474 These are the member function names added by macros. Usually they
475 are not documented, but they can be documented, so this test avoids
476 reporting an error if they are not documented.
477
478 But maybe we should generate a standard text for each of them?
479 */
481{
482 if (!hasDoc()) {
483 if (name().startsWith(QLatin1String("qt_")) || name() == QLatin1String("metaObject")
484 || name() == QLatin1String("tr") || name() == QLatin1String("trUtf8")
485 || name() == QLatin1String("d_func")) {
486 return true;
487 }
488 QString s = signature(Node::SignatureReturnType);
489 if (s.contains(QLatin1String("enum_type")) && s.contains(QLatin1String("operator|")))
490 return true;
491 }
492 return false;
493}
494
495/*!
496 \fn bool FunctionNode::hasOverloads() const
497 Returns \c true if this function has overloads.
498 */
499
500/*!
501 \internal
502 \brief Returns the type of the function as a string.
503
504 The returned string is either the type as declared in the header, or `auto`
505 if that's the return type in the `\\fn` command for the function.
506 */
508{
509 if (m_returnType.second.has_value())
510 return m_returnType.second.value();
511 return m_returnType.first;
512}
513QT_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 isDeprecated() const override
\reimp
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.
static Genus getGenus(Metaness metaness)
Determines the Genus value for this FunctionNode given the Metaness value metaness.
QString returnTypeString() const
Returns the type of the function as a string.
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.
void setGenus(Genus t)
Definition node.h:125
@ Function
Definition node.h:65
Aggregate * parent() const
Returns the node's parent pointer.
Definition node.h:244
virtual bool isDeprecated() const
Returns true if this node's status is Deprecated.
Definition node.h:168
const std::optional< RelaxedTemplateDeclaration > & templateDecl() const
Definition node.h:282
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
@ CPP
Definition node.h:83
@ QML
Definition node.h:84
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
bool isCppNode() const
Returns true if this node's Genus value is CPP.
Definition node.h:130
void setStatus(Status t)
Sets the node's status to t.
Definition node.cpp:560
@ Internal
Definition node.h:93
A class for parsing and managing a function parameter list.
Definition parameters.h:57
int count() const
Definition parameters.h:72
This class describes one instance of using the Q_PROPERTY macro.
static void buildTopicMetanessMap()
static void buildMetanessMap()
static QMap< QString, FunctionNode::Metaness > metanessMap_
static QMap< QString, FunctionNode::Metaness > topicMetanessMap_
Combined button and popup list for selecting options.