summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qdoc/.prev_CMakeLists.txt1
-rw-r--r--src/qdoc/CMakeLists.txt1
-rw-r--r--src/qdoc/clangcodeparser.cpp1
-rw-r--r--src/qdoc/codemarker.cpp1
-rw-r--r--src/qdoc/cppcodemarker.cpp1
-rw-r--r--src/qdoc/cppcodeparser.cpp1
-rw-r--r--src/qdoc/docbookgenerator.cpp1
-rw-r--r--src/qdoc/docbookgenerator.h2
-rw-r--r--src/qdoc/functionnode.cpp613
-rw-r--r--src/qdoc/functionnode.h212
-rw-r--r--src/qdoc/generator.cpp1
-rw-r--r--src/qdoc/generator.h1
-rw-r--r--src/qdoc/helpprojectwriter.cpp1
-rw-r--r--src/qdoc/htmlgenerator.cpp1
-rw-r--r--src/qdoc/node.cpp584
-rw-r--r--src/qdoc/node.h170
-rw-r--r--src/qdoc/propertynode.h1
-rw-r--r--src/qdoc/qdoc.pro2
-rw-r--r--src/qdoc/qdocdatabase.cpp1
-rw-r--r--src/qdoc/qdocdatabase.h1
-rw-r--r--src/qdoc/qdocindexfiles.cpp1
-rw-r--r--src/qdoc/qdocindexfiles.h1
-rw-r--r--src/qdoc/qdoctagfiles.cpp1
-rw-r--r--src/qdoc/qmlvisitor.cpp1
-rw-r--r--src/qdoc/sections.cpp1
-rw-r--r--src/qdoc/tree.cpp1
-rw-r--r--src/qdoc/tree.h1
-rw-r--r--src/qdoc/xmlgenerator.cpp2
28 files changed, 854 insertions, 752 deletions
diff --git a/src/qdoc/.prev_CMakeLists.txt b/src/qdoc/.prev_CMakeLists.txt
index af132b39c..93e64355e 100644
--- a/src/qdoc/.prev_CMakeLists.txt
+++ b/src/qdoc/.prev_CMakeLists.txt
@@ -23,6 +23,7 @@ qt_add_tool(qdoc
docutilities.h
editdistance.cpp editdistance.h
enumitem.h
+ functionnode.cpp functionnode.h
generator.cpp generator.h
helpprojectwriter.cpp helpprojectwriter.h
htmlgenerator.cpp htmlgenerator.h
diff --git a/src/qdoc/CMakeLists.txt b/src/qdoc/CMakeLists.txt
index 461d3b022..814e19a34 100644
--- a/src/qdoc/CMakeLists.txt
+++ b/src/qdoc/CMakeLists.txt
@@ -24,6 +24,7 @@ qt_add_tool(qdoc
docutilities.h
editdistance.cpp editdistance.h
enumitem.h
+ functionnode.cpp functionnode.h
generator.cpp generator.h
helpprojectwriter.cpp helpprojectwriter.h
htmlgenerator.cpp htmlgenerator.h
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp
index 64c7d2be1..91607cbb9 100644
--- a/src/qdoc/clangcodeparser.cpp
+++ b/src/qdoc/clangcodeparser.cpp
@@ -45,6 +45,7 @@
#include "codechunk.h"
#include "config.h"
+#include "functionnode.h"
#include "loggingcategory.h"
#include "propertynode.h"
#include "qdocdatabase.h"
diff --git a/src/qdoc/codemarker.cpp b/src/qdoc/codemarker.cpp
index 992a7282f..9ab785f57 100644
--- a/src/qdoc/codemarker.cpp
+++ b/src/qdoc/codemarker.cpp
@@ -29,6 +29,7 @@
#include "codemarker.h"
#include "config.h"
+#include "functionnode.h"
#include "node.h"
#include "propertynode.h"
diff --git a/src/qdoc/cppcodemarker.cpp b/src/qdoc/cppcodemarker.cpp
index af2491fa9..9e504306c 100644
--- a/src/qdoc/cppcodemarker.cpp
+++ b/src/qdoc/cppcodemarker.cpp
@@ -32,6 +32,7 @@
#include "cppcodemarker.h"
+#include "functionnode.h"
#include "propertynode.h"
#include "text.h"
#include "tree.h"
diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp
index b69e9f743..bbe5ea572 100644
--- a/src/qdoc/cppcodeparser.cpp
+++ b/src/qdoc/cppcodeparser.cpp
@@ -29,6 +29,7 @@
#include "cppcodeparser.h"
#include "config.h"
+#include "functionnode.h"
#include "generator.h"
#include "loggingcategory.h"
#include "qdocdatabase.h"
diff --git a/src/qdoc/docbookgenerator.cpp b/src/qdoc/docbookgenerator.cpp
index 5e9b67b87..8410131f1 100644
--- a/src/qdoc/docbookgenerator.cpp
+++ b/src/qdoc/docbookgenerator.cpp
@@ -30,6 +30,7 @@
#include "codemarker.h"
#include "config.h"
+#include "functionnode.h"
#include "generator.h"
#include "node.h"
#include "propertynode.h"
diff --git a/src/qdoc/docbookgenerator.h b/src/qdoc/docbookgenerator.h
index d8f8a6e09..3d9b394cb 100644
--- a/src/qdoc/docbookgenerator.h
+++ b/src/qdoc/docbookgenerator.h
@@ -38,6 +38,8 @@
QT_BEGIN_NAMESPACE
+class FunctionNode;
+
class DocBookGenerator : public XmlGenerator
{
public:
diff --git a/src/qdoc/functionnode.cpp b/src/qdoc/functionnode.cpp
new file mode 100644
index 000000000..f0ce7239a
--- /dev/null
+++ b/src/qdoc/functionnode.cpp
@@ -0,0 +1,613 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "functionnode.h"
+
+#include "propertynode.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class FunctionNode
+
+ This node is used to represent any kind of function being
+ documented. It can represent a C++ class member function,
+ a C++ global function, a QML method, a javascript method,
+ or a macro, with or without parameters.
+
+ A C++ function can be a signal a slot, a constructor of any
+ kind, a destructor, a copy or move assignment operator, or
+ just a plain old member function or global function.
+
+ A QML or javascript method can be a plain old method, or a
+ signal or signal handler.
+
+ If the function is not an overload, its overload flag is
+ false. If it is an overload, its overload flag is true.
+ If it is not an overload but it has overloads, its next
+ overload pointer will point to an overload function. If it
+ is an overload function, its overload flag is true, and it
+ may or may not have a non-null next overload pointer.
+
+ So all the overloads of a function are in a linked list
+ using the next overload pointer. If a function has no
+ overloads, its overload flag is false and its overload
+ pointer is null.
+
+ The function node also has an overload number. If the
+ node's overload flag is set, this overload number is
+ positive; otherwise, the overload number is 0.
+ */
+
+/*!
+ Construct a function node for a C++ function. It's parent
+ is \a parent, and it's name is \a name.
+
+ \note The function node's overload flag is set to false, and
+ its overload number is set to 0. These data members are set
+ in normalizeOverloads(), when all the overloads are known.
+ */
+FunctionNode::FunctionNode(Aggregate *parent, const QString &name)
+ : Node(Function, parent, name),
+ m_const(false),
+ m_static(false),
+ m_reimpFlag(false),
+ m_attached(false),
+ m_overloadFlag(false),
+ m_isFinal(false),
+ m_isOverride(false),
+ m_isRef(false),
+ m_isRefRef(false),
+ m_isInvokable(false),
+ m_metaness(Plain),
+ m_virtualness(NonVirtual),
+ m_overloadNumber(0),
+ m_nextOverload(nullptr)
+{
+ // nothing
+}
+
+/*!
+ Construct a function node for a QML method or signal, specified
+ by ther Metaness value \a type. It's parent is \a parent, and
+ it's name is \a name. If \a attached is true, it is an attached
+ method or signal.
+
+ \note The function node's overload flag is set to false, and
+ its overload number is set to 0. These data members are set
+ in normalizeOverloads(), when all the overloads are known.
+ */
+FunctionNode::FunctionNode(Metaness kind, Aggregate *parent, const QString &name, bool attached)
+ : Node(Function, parent, name),
+ m_const(false),
+ m_static(false),
+ m_reimpFlag(false),
+ m_attached(attached),
+ m_overloadFlag(false),
+ m_isFinal(false),
+ m_isOverride(false),
+ m_isRef(false),
+ m_isRefRef(false),
+ m_isInvokable(false),
+ m_metaness(kind),
+ m_virtualness(NonVirtual),
+ m_overloadNumber(0),
+ m_nextOverload(nullptr)
+{
+ setGenus(getGenus(m_metaness));
+ if (!isCppNode() && name.startsWith("__"))
+ setStatus(Internal);
+}
+
+/*!
+ Clone this node on the heap and make the clone a child of
+ \a parent. Return the pointer to the clone.
+ */
+Node *FunctionNode::clone(Aggregate *parent)
+{
+ FunctionNode *fn = new FunctionNode(*this); // shallow copy
+ fn->setParent(nullptr);
+ fn->setNextOverload(nullptr);
+ parent->addChild(fn);
+ return fn;
+}
+
+/*!
+ Returns this function's virtualness value as a string
+ for use as an attribute value in index files.
+ */
+QString FunctionNode::virtualness() const
+{
+ switch (m_virtualness) {
+ case FunctionNode::NormalVirtual:
+ return QLatin1String("virtual");
+ case FunctionNode::PureVirtual:
+ return QLatin1String("pure");
+ case FunctionNode::NonVirtual:
+ default:
+ break;
+ }
+ return QLatin1String("non");
+}
+
+/*!
+ Sets the function node's virtualness value based on the value
+ of string \a value, which is the value of the function's \e{virtual}
+ attribute in an index file. If \a value is \e{pure}, and if the
+ parent() is a C++ class, set the parent's \e abstract flag to
+ \c {true}.
+ */
+void FunctionNode::setVirtualness(const QString &value)
+{
+ if (value == QLatin1String("non"))
+ m_virtualness = NonVirtual;
+ else if (value == QLatin1String("virtual"))
+ m_virtualness = NormalVirtual;
+ else if (value == QLatin1String("pure")) {
+ m_virtualness = PureVirtual;
+ if (parent() && parent()->isClassNode())
+ parent()->setAbstract(true);
+ }
+}
+
+static QMap<QString, FunctionNode::Metaness> metanessMap_;
+static void buildMetanessMap()
+{
+ metanessMap_["plain"] = FunctionNode::Plain;
+ metanessMap_["signal"] = FunctionNode::Signal;
+ metanessMap_["slot"] = FunctionNode::Slot;
+ metanessMap_["constructor"] = FunctionNode::Ctor;
+ metanessMap_["copy-constructor"] = FunctionNode::CCtor;
+ metanessMap_["move-constructor"] = FunctionNode::MCtor;
+ metanessMap_["destructor"] = FunctionNode::Dtor;
+ metanessMap_["macro"] = FunctionNode::MacroWithParams;
+ metanessMap_["macrowithparams"] = FunctionNode::MacroWithParams;
+ metanessMap_["macrowithoutparams"] = FunctionNode::MacroWithoutParams;
+ metanessMap_["copy-assign"] = FunctionNode::CAssign;
+ metanessMap_["move-assign"] = FunctionNode::MAssign;
+ metanessMap_["native"] = FunctionNode::Native;
+ metanessMap_["qmlsignal"] = FunctionNode::QmlSignal;
+ metanessMap_["qmlsignalhandler"] = FunctionNode::QmlSignalHandler;
+ metanessMap_["qmlmethod"] = FunctionNode::QmlMethod;
+ metanessMap_["jssignal"] = FunctionNode::JsSignal;
+ metanessMap_["jssignalhandler"] = FunctionNode::JsSignalHandler;
+ metanessMap_["jsmethos"] = FunctionNode::JsMethod;
+}
+
+static QMap<QString, FunctionNode::Metaness> topicMetanessMap_;
+static void buildTopicMetanessMap()
+{
+ topicMetanessMap_["fn"] = FunctionNode::Plain;
+ topicMetanessMap_["qmlsignal"] = FunctionNode::QmlSignal;
+ topicMetanessMap_["qmlattachedsignal"] = FunctionNode::QmlSignal;
+ topicMetanessMap_["qmlmethod"] = FunctionNode::QmlMethod;
+ topicMetanessMap_["qmlattachedmethod"] = FunctionNode::QmlMethod;
+ topicMetanessMap_["jssignal"] = FunctionNode::JsSignal;
+ topicMetanessMap_["jsattachedsignal"] = FunctionNode::JsSignal;
+ topicMetanessMap_["jsmethod"] = FunctionNode::JsMethod;
+ topicMetanessMap_["jsattachedmethod"] = FunctionNode::JsMethod;
+}
+
+/*!
+ Determines the Genus value for this FunctionNode given the
+ Metaness value \a metaness. Returns the Genus value. \a metaness must be
+ one of the values of Metaness. If not, Node::DontCare is
+ returned.
+ */
+Node::Genus FunctionNode::getGenus(FunctionNode::Metaness metaness)
+{
+ switch (metaness) {
+ case FunctionNode::Plain:
+ case FunctionNode::Signal:
+ case FunctionNode::Slot:
+ case FunctionNode::Ctor:
+ case FunctionNode::Dtor:
+ case FunctionNode::CCtor:
+ case FunctionNode::MCtor:
+ case FunctionNode::MacroWithParams:
+ case FunctionNode::MacroWithoutParams:
+ case FunctionNode::Native:
+ case FunctionNode::CAssign:
+ case FunctionNode::MAssign:
+ return Node::CPP;
+ case FunctionNode::QmlSignal:
+ case FunctionNode::QmlSignalHandler:
+ case FunctionNode::QmlMethod:
+ return Node::QML;
+ case FunctionNode::JsSignal:
+ case FunctionNode::JsSignalHandler:
+ case FunctionNode::JsMethod:
+ return Node::JS;
+ }
+ return Node::DontCare;
+}
+
+/*!
+ This static function converts the string \a value to an enum
+ value for the kind of function named by \a value.
+ */
+FunctionNode::Metaness FunctionNode::getMetaness(const QString &value)
+{
+ if (metanessMap_.isEmpty())
+ buildMetanessMap();
+ return metanessMap_[value];
+}
+
+/*!
+ This static function converts the topic string \a topic to an enum
+ value for the kind of function this FunctionNode represents.
+ */
+FunctionNode::Metaness FunctionNode::getMetanessFromTopic(const QString &topic)
+{
+ if (topicMetanessMap_.isEmpty())
+ buildTopicMetanessMap();
+ return topicMetanessMap_[topic];
+}
+
+/*!
+ Sets the function node's Metaness value based on the value
+ of string \a metaness, which is the value of the function's "meta"
+ attribute in an index file. Returns the Metaness value
+ */
+FunctionNode::Metaness FunctionNode::setMetaness(const QString &metaness)
+{
+ m_metaness = getMetaness(metaness);
+ return m_metaness;
+}
+
+/*!
+ If this function node's metaness is \a from, change the
+ metaness to \a to and return \c true. Otherwise return
+ false. This function is used to change Qml function node
+ metaness values to Javascript function node metaness,
+ values because these nodes are created as Qml function
+ nodes before it is discovered that what the function node
+ represents is not a Qml function but a javascript function.
+
+ Note that if the function returns true, which means the node
+ type was indeed changed, then the node's Genus is also changed
+ from QML to JS.
+
+ The function also works in the other direction, but there is
+ no use case for that.
+ */
+bool FunctionNode::changeMetaness(Metaness from, Metaness to)
+{
+ if (m_metaness == from) {
+ m_metaness = to;
+ switch (to) {
+ case QmlSignal:
+ case QmlSignalHandler:
+ case QmlMethod:
+ setGenus(Node::QML);
+ break;
+ case JsSignal:
+ case JsSignalHandler:
+ case JsMethod:
+ setGenus(Node::JS);
+ break;
+ default:
+ setGenus(Node::CPP);
+ break;
+ }
+ return true;
+ }
+ return false;
+}
+
+/*! \fn void FunctionNode::setOverloadNumber(unsigned char number)
+ Sets the function node's overload number to \a number. If \a number
+ is 0, the function node's overload flag is set to false. If
+ \a number is greater than 0, the overload flag is set to true.
+ */
+void FunctionNode::setOverloadNumber(signed short number)
+{
+ m_overloadNumber = number;
+ m_overloadFlag = (number > 0) ? true : false;
+}
+
+/*!
+ If this function's next overload pointer is null, set it to
+ \a functionNode. Otherwise continue down the overload list by calling
+ this function recursively for the next overload.
+
+ Although this function appends an overload function to the list of
+ overloads for this function's name, it does not set the function's
+ overload number or it's overload flag. If the function has the
+ \c{\\overload} in its qdoc comment, that will set the overload
+ flag. But qdoc treats the \c{\\overload} command as a hint that the
+ function should be documented as an overload. The hint is almost
+ always correct, but qdoc reserves the right to decide which function
+ should be the primary function and which functions are the overloads.
+ These decisions are made in Aggregate::normalizeOverloads().
+ */
+void FunctionNode::appendOverload(FunctionNode *functionNode)
+{
+ if (m_nextOverload == nullptr)
+ m_nextOverload = functionNode;
+ else
+ m_nextOverload->appendOverload(functionNode);
+}
+
+/*!
+ This function assumes that this FunctionNode is marked as an
+ overload function. It asks if the next overload is marked as
+ an overload. If not, then remove that FunctionNode from the
+ overload list and return it. Otherwise call this function
+ recursively for the next overload.
+ */
+FunctionNode *FunctionNode::findPrimaryFunction()
+{
+ if (m_nextOverload != nullptr) {
+ if (!m_nextOverload->isOverload()) {
+ FunctionNode *t = m_nextOverload;
+ m_nextOverload = t->nextOverload();
+ t->setNextOverload(nullptr);
+ return t;
+ }
+ return m_nextOverload->findPrimaryFunction();
+ }
+ return nullptr;
+}
+
+/*!
+ \fn void FunctionNode::setReimpFlag()
+
+ Sets the function node's reimp flag to \c true, which means
+ the \e {\\reimp} command was used in the qdoc comment. It is
+ supposed to mean that the function reimplements a virtual
+ function in a base class.
+ */
+
+/*!
+ Returns a string representing the kind of function this
+ Function node represents, which depends on the Metaness
+ value.
+ */
+QString FunctionNode::kindString() const
+{
+ switch (m_metaness) {
+ case FunctionNode::QmlSignal:
+ return "QML signal";
+ case FunctionNode::QmlSignalHandler:
+ return "QML signal handler";
+ case FunctionNode::QmlMethod:
+ return "QML method";
+ case FunctionNode::JsSignal:
+ return "JS signal";
+ case FunctionNode::JsSignalHandler:
+ return "JS signal handler";
+ case FunctionNode::JsMethod:
+ return "JS method";
+ default:
+ return "function";
+ }
+}
+
+/*!
+ Returns a string representing the Metaness enum value for
+ this function. It is used in index files.
+ */
+QString FunctionNode::metanessString() const
+{
+ switch (m_metaness) {
+ case FunctionNode::Plain:
+ return "plain";
+ case FunctionNode::Signal:
+ return "signal";
+ case FunctionNode::Slot:
+ return "slot";
+ case FunctionNode::Ctor:
+ return "constructor";
+ case FunctionNode::CCtor:
+ return "copy-constructor";
+ case FunctionNode::MCtor:
+ return "move-constructor";
+ case FunctionNode::Dtor:
+ return "destructor";
+ case FunctionNode::MacroWithParams:
+ return "macrowithparams";
+ case FunctionNode::MacroWithoutParams:
+ return "macrowithoutparams";
+ case FunctionNode::Native:
+ return "native";
+ case FunctionNode::CAssign:
+ return "copy-assign";
+ case FunctionNode::MAssign:
+ return "move-assign";
+ case FunctionNode::QmlSignal:
+ return "qmlsignal";
+ case FunctionNode::QmlSignalHandler:
+ return "qmlsignalhandler";
+ case FunctionNode::QmlMethod:
+ return "qmlmethod";
+ case FunctionNode::JsSignal:
+ return "jssignal";
+ case FunctionNode::JsSignalHandler:
+ return "jssignalhandler";
+ case FunctionNode::JsMethod:
+ return "jsmethod";
+ default:
+ return "plain";
+ }
+}
+
+/*!
+ Adds the "associated" property \a p to this function node.
+ The function might be the setter or getter for a property,
+ for example.
+ */
+void FunctionNode::addAssociatedProperty(PropertyNode *p)
+{
+ m_associatedProperties.append(p);
+}
+
+/*!
+ \reimp
+
+ Returns \c true if this is an access function for an obsolete property,
+ otherwise calls the base implementation of isObsolete().
+*/
+bool FunctionNode::isObsolete() const
+{
+ auto it = std::find_if_not(m_associatedProperties.begin(), m_associatedProperties.end(),
+ [](const Node *p) -> bool { return p->isObsolete(); });
+
+ if (!m_associatedProperties.isEmpty() && it == m_associatedProperties.end())
+ return true;
+
+ return Node::isObsolete();
+}
+
+/*! \fn unsigned char FunctionNode::overloadNumber() const
+ Returns the overload number for this function.
+ */
+
+/*!
+ Reconstructs and returns the function's signature. If \a values
+ is \c true, the default values of the parameters are included.
+ The return type is included unless \a noReturnType is \c true.
+ Function templates are prefixed with \c {template <parameter_list>}
+ if \a templateParams is \c true.
+ */
+QString FunctionNode::signature(bool values, bool noReturnType, bool templateParams) const
+{
+ QStringList elements;
+
+ if (templateParams)
+ elements << templateDecl();
+ if (!noReturnType)
+ elements << m_returnType;
+ elements.removeAll({});
+
+ if (!isMacroWithoutParams()) {
+ elements << name() + QLatin1Char('(') + m_parameters.signature(values) + QLatin1Char(')');
+ if (!isMacro()) {
+ if (isConst())
+ elements << QStringLiteral("const");
+ if (isRef())
+ elements << QStringLiteral("&");
+ else if (isRefRef())
+ elements << QStringLiteral("&&");
+ }
+ } else {
+ elements << name();
+ }
+ return elements.join(QLatin1Char(' '));
+}
+
+/*!
+ Print some information used for debugging qdoc. Only used when debugging.
+ */
+void FunctionNode::debug() const
+{
+ qDebug("QML METHOD %s m_returnType %s m_parentPath %s", qPrintable(name()),
+ qPrintable(m_returnType), qPrintable(m_parentPath.join(' ')));
+}
+
+/*!
+ Compares this FunctionNode to the FunctionNode pointed to
+ by \a functionNode. Returns true if they describe the same function.
+ */
+bool FunctionNode::compare(const FunctionNode *functionNode) const
+{
+ if (functionNode == nullptr)
+ return false;
+ if (metaness() != functionNode->metaness())
+ return false;
+ if (parent() != functionNode->parent())
+ return false;
+ if (m_returnType != functionNode->returnType())
+ return false;
+ if (isConst() != functionNode->isConst())
+ return false;
+ if (isAttached() != functionNode->isAttached())
+ return false;
+ const Parameters &p = functionNode->parameters();
+ if (m_parameters.count() != p.count())
+ return false;
+ if (!p.isEmpty()) {
+ for (int i = 0; i < p.count(); ++i) {
+ if (m_parameters.at(i).type() != p.at(i).type())
+ return false;
+ }
+ }
+ return true;
+}
+
+/*!
+ In some cases, it is ok for a public function to be not documented.
+ For example, the macro Q_OBJECT adds several functions to the API of
+ a class, but these functions are normally not meant to be documented.
+ So if a function node doesn't have documentation, then if its name is
+ in the list of functions that it is ok not to document, this function
+ returns true. Otherwise, it returns false.
+
+ These are the member function names added by macros. Usually they
+ are not documented, but they can be documented, so this test avoids
+ reporting an error if they are not documented.
+
+ But maybe we should generate a standard text for each of them?
+ */
+bool FunctionNode::isIgnored() const
+{
+ if (!hasDoc() && !hasSharedDoc()) {
+ if (name().startsWith(QLatin1String("qt_")) || name() == QLatin1String("metaObject")
+ || name() == QLatin1String("tr") || name() == QLatin1String("trUtf8")
+ || name() == QLatin1String("d_func")) {
+ return true;
+ }
+ QString s = signature(false, false);
+ if (s.contains(QLatin1String("enum_type")) && s.contains(QLatin1String("operator|")))
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Returns true if this function has overloads. Otherwise false.
+ First, if this function node's overload pointer is not nullptr,
+ return true. Next, if this function node's overload flag is true
+ return true. Finally, if this function's parent Aggregate has a
+ function by the same name as this one in its function map and
+ that function has overloads, return true. Otherwise return false.
+
+ There is a failsafe way to test it under any circumstances.
+ */
+bool FunctionNode::hasOverloads() const
+{
+ if (m_nextOverload != nullptr)
+ return true;
+ if (m_overloadFlag)
+ return true;
+ if (parent())
+ return parent()->hasOverloads(this);
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qdoc/functionnode.h b/src/qdoc/functionnode.h
new file mode 100644
index 000000000..b3518be27
--- /dev/null
+++ b/src/qdoc/functionnode.h
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FUNCTIONNODE_H
+#define FUNCTIONNODE_H
+
+#include "node.h"
+#include "parameters.h"
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+class FunctionNode : public Node
+{
+public:
+ enum Virtualness { NonVirtual, NormalVirtual, PureVirtual };
+
+ enum Metaness {
+ Plain,
+ Signal,
+ Slot,
+ Ctor,
+ Dtor,
+ CCtor, // copy constructor
+ MCtor, // move-copy constructor
+ MacroWithParams,
+ MacroWithoutParams,
+ Native,
+ CAssign, // copy-assignment operator
+ MAssign, // move-assignment operator
+ QmlSignal,
+ QmlSignalHandler,
+ QmlMethod,
+ JsSignal,
+ JsSignalHandler,
+ JsMethod
+ };
+
+ FunctionNode(Aggregate *parent, const QString &name); // C++ function (Plain)
+ FunctionNode(Metaness type, Aggregate *parent, const QString &name, bool attached = false);
+
+ Node *clone(Aggregate *parent) override;
+ Metaness metaness() const { return m_metaness; }
+ QString metanessString() const;
+ bool changeMetaness(Metaness from, Metaness to);
+ void setMetaness(Metaness metaness) { m_metaness = metaness; }
+ Metaness setMetaness(const QString &metaness);
+ QString kindString() const;
+ static Metaness getMetaness(const QString &value);
+ static Metaness getMetanessFromTopic(const QString &topic);
+ static Genus getGenus(Metaness metaness);
+
+ void setReturnType(const QString &type) { m_returnType = type; }
+ void setParentPath(const QStringList &path) { m_parentPath = path; }
+ void setVirtualness(const QString &value);
+ void setVirtualness(Virtualness virtualness) { m_virtualness = virtualness; }
+ void setVirtual() { m_virtualness = NormalVirtual; }
+ void setConst(bool b) { m_const = b; }
+ void setStatic(bool b) { m_static = b; }
+ void setReimpFlag() { m_reimpFlag = true; }
+ void setOverridesThis(const QString &path) { m_overridesThis = path; }
+
+ const QString &returnType() const { return m_returnType; }
+ QString virtualness() const;
+ bool isConst() const { return m_const; }
+ bool isStatic() const override { return m_static; }
+ bool isOverload() const { return m_overloadFlag; }
+ bool isMarkedReimp() const override { return m_reimpFlag; }
+ bool isSomeCtor() const { return isCtor() || isCCtor() || isMCtor(); }
+ bool isMacroWithParams() const { return (m_metaness == MacroWithParams); }
+ bool isMacroWithoutParams() const { return (m_metaness == MacroWithoutParams); }
+ bool isMacro() const override { return (isMacroWithParams() || isMacroWithoutParams()); }
+ bool isObsolete() const override;
+
+ bool isCppFunction() const { return m_metaness == Plain; } // Is this correct?
+ bool isSignal() const { return (m_metaness == Signal); }
+ bool isSlot() const { return (m_metaness == Slot); }
+ bool isCtor() const { return (m_metaness == Ctor); }
+ bool isDtor() const { return (m_metaness == Dtor); }
+ bool isCCtor() const { return (m_metaness == CCtor); }
+ bool isMCtor() const { return (m_metaness == MCtor); }
+ bool isCAssign() const { return (m_metaness == CAssign); }
+ bool isMAssign() const { return (m_metaness == MAssign); }
+
+ bool isJsMethod() const { return (m_metaness == JsMethod); }
+ bool isJsSignal() const { return (m_metaness == JsSignal); }
+ bool isJsSignalHandler() const { return (m_metaness == JsSignalHandler); }
+
+ bool isQmlMethod() const { return (m_metaness == QmlMethod); }
+ bool isQmlSignal() const { return (m_metaness == QmlSignal); }
+ bool isQmlSignalHandler() const { return (m_metaness == QmlSignalHandler); }
+
+ bool isSpecialMemberFunction() const
+ {
+ return (isDtor() || isCCtor() || isMCtor() || isCAssign() || isMAssign());
+ }
+ bool isNonvirtual() const { return (m_virtualness == NonVirtual); }
+ bool isVirtual() const { return (m_virtualness == NormalVirtual); }
+ bool isPureVirtual() const { return (m_virtualness == PureVirtual); }
+ bool returnsBool() const { return (m_returnType == QLatin1String("bool")); }
+
+ Parameters &parameters() { return m_parameters; }
+ const Parameters &parameters() const { return m_parameters; }
+ bool isPrivateSignal() const { return m_parameters.isPrivateSignal(); }
+ void setParameters(const QString &signature) { m_parameters.set(signature); }
+ QString signature(bool values, bool noReturnType, bool templateParams = false) const override;
+
+ const QString &overridesThis() const { return m_overridesThis; }
+ const NodeList &associatedProperties() const { return m_associatedProperties; }
+ const QStringList &parentPath() const { return m_parentPath; }
+ bool hasAssociatedProperties() const { return !m_associatedProperties.isEmpty(); }
+ bool hasOneAssociatedProperty() const { return (m_associatedProperties.size() == 1); }
+ Node *firstAssociatedProperty() const { return m_associatedProperties[0]; }
+
+ QString element() const override { return parent()->name(); }
+ bool isAttached() const override { return m_attached; }
+ bool isQtQuickNode() const override { return parent()->isQtQuickNode(); }
+ QString qmlTypeName() const override { return parent()->qmlTypeName(); }
+ QString logicalModuleName() const override { return parent()->logicalModuleName(); }
+ QString logicalModuleVersion() const override { return parent()->logicalModuleVersion(); }
+ QString logicalModuleIdentifier() const override { return parent()->logicalModuleIdentifier(); }
+
+ void debug() const;
+
+ void setFinal(bool b) { m_isFinal = b; }
+ bool isFinal() const { return m_isFinal; }
+
+ void setOverride(bool b) { m_isOverride = b; }
+ bool isOverride() const { return m_isOverride; }
+
+ void setRef(bool b) { m_isRef = b; }
+ bool isRef() const { return m_isRef; }
+
+ void setRefRef(bool b) { m_isRefRef = b; }
+ bool isRefRef() const { return m_isRefRef; }
+
+ void setInvokable(bool b) { m_isInvokable = b; }
+ bool isInvokable() const { return m_isInvokable; }
+
+ bool hasTag(const QString &tag) const override { return (m_tag == tag); }
+ void setTag(const QString &tag) { m_tag = tag; }
+ const QString &tag() const { return m_tag; }
+ bool compare(const FunctionNode *functionNode) const;
+ bool isIgnored() const;
+ bool hasOverloads() const;
+ void clearOverloadFlag() { m_overloadFlag = false; }
+ void setOverloadFlag() { m_overloadFlag = true; }
+ void setOverloadNumber(signed short number);
+ void appendOverload(FunctionNode *functionNode);
+ signed short overloadNumber() const { return m_overloadNumber; }
+ FunctionNode *nextOverload() { return m_nextOverload; }
+ void setNextOverload(FunctionNode *functionNode) { m_nextOverload = functionNode; }
+ FunctionNode *findPrimaryFunction();
+
+private:
+ void addAssociatedProperty(PropertyNode *property);
+
+ friend class Aggregate;
+ friend class PropertyNode;
+
+ bool m_const : 1;
+ bool m_static : 1;
+ bool m_reimpFlag : 1;
+ bool m_attached : 1;
+ bool m_overloadFlag : 1;
+ bool m_isFinal : 1;
+ bool m_isOverride : 1;
+ bool m_isRef : 1;
+ bool m_isRefRef : 1;
+ bool m_isInvokable : 1;
+ Metaness m_metaness {};
+ Virtualness m_virtualness {};
+ signed short m_overloadNumber {};
+ FunctionNode *m_nextOverload { nullptr };
+ QString m_returnType {};
+ QStringList m_parentPath {};
+ QString m_overridesThis {};
+ QString m_tag {};
+ NodeList m_associatedProperties {};
+ Parameters m_parameters {};
+};
+
+QT_END_NAMESPACE
+
+#endif // FUNCTIONNODE_H
diff --git a/src/qdoc/generator.cpp b/src/qdoc/generator.cpp
index 2a1084f75..31314511f 100644
--- a/src/qdoc/generator.cpp
+++ b/src/qdoc/generator.cpp
@@ -35,6 +35,7 @@
#include "config.h"
#include "doc.h"
#include "editdistance.h"
+#include "functionnode.h"
#include "loggingcategory.h"
#include "node.h"
#include "openedlist.h"
diff --git a/src/qdoc/generator.h b/src/qdoc/generator.h
index 355dce242..6f5e08427 100644
--- a/src/qdoc/generator.h
+++ b/src/qdoc/generator.h
@@ -43,6 +43,7 @@ typedef QMultiMap<QString, Node *> NodeMultiMap;
typedef QMap<Node *, NodeMultiMap> ParentMaps;
class CodeMarker;
+class FunctionNode;
class Location;
class Node;
class QDocDatabase;
diff --git a/src/qdoc/helpprojectwriter.cpp b/src/qdoc/helpprojectwriter.cpp
index 8e6698ae1..bc1889f8d 100644
--- a/src/qdoc/helpprojectwriter.cpp
+++ b/src/qdoc/helpprojectwriter.cpp
@@ -30,6 +30,7 @@
#include "atom.h"
#include "config.h"
+#include "functionnode.h"
#include "htmlgenerator.h"
#include "node.h"
#include "qdocdatabase.h"
diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp
index db4326b84..3f688c97d 100644
--- a/src/qdoc/htmlgenerator.cpp
+++ b/src/qdoc/htmlgenerator.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "codemarker.h"
#include "codeparser.h"
+#include "functionnode.h"
#include "helpprojectwriter.h"
#include "node.h"
#include "propertynode.h"
diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp
index c2fe42605..35ac5c365 100644
--- a/src/qdoc/node.cpp
+++ b/src/qdoc/node.cpp
@@ -31,6 +31,7 @@
#include "codemarker.h"
#include "config.h"
#include "cppcodeparser.h"
+#include "functionnode.h"
#include "generator.h"
#include "propertynode.h"
#include "qdocdatabase.h"
@@ -2324,7 +2325,7 @@ bool Aggregate::isSameSignature(const FunctionNode *f1, const FunctionNode *f2)
\not Adding a function increments the aggregate's function count,
which is the total number of function nodes in the function map,
including the overloads. The overloads are not inserted into the map
- but are in a linked list using the FunctionNode's nextOverload_
+ but are in a linked list using the FunctionNode's m_nextOverload
pointer.
\note The function's overload number and overload flag are set in
@@ -3767,587 +3768,6 @@ Node *TypeAliasNode::clone(Aggregate *parent)
return tan;
}
-/*!
- \class FunctionNode
-
- This node is used to represent any kind of function being
- documented. It can represent a C++ class member function,
- a C++ global function, a QML method, a javascript method,
- or a macro, with or without parameters.
-
- A C++ function can be a signal a slot, a constructor of any
- kind, a destructor, a copy or move assignment operator, or
- just a plain old member function or global function.
-
- A QML or javascript method can be a plain old method, or a
- signal or signal handler.
-
- If the function is not an overload, its overload flag is
- false. If it is an overload, its overload flag is true.
- If it is not an overload but it has overloads, its next
- overload pointer will point to an overload function. If it
- is an overload function, its overload flag is true, and it
- may or may not have a non-null next overload pointer.
-
- So all the overloads of a function are in a linked list
- using the next overload pointer. If a function has no
- overloads, its overload flag is false and its overload
- pointer is null.
-
- The function node also has an overload number. If the
- node's overload flag is set, this overload number is
- positive; otherwise, the overload number is 0.
- */
-
-/*!
- Construct a function node for a C++ function. It's parent
- is \a parent, and it's name is \a name.
-
- \note The function node's overload flag is set to false, and
- its overload number is set to 0. These data members are set
- in normalizeOverloads(), when all the overloads are known.
- */
-FunctionNode::FunctionNode(Aggregate *parent, const QString &name)
- : Node(Function, parent, name),
- const_(false),
- static_(false),
- reimpFlag_(false),
- attached_(false),
- overloadFlag_(false),
- isFinal_(false),
- isOverride_(false),
- isRef_(false),
- isRefRef_(false),
- isInvokable_(false),
- metaness_(Plain),
- virtualness_(NonVirtual),
- overloadNumber_(0),
- nextOverload_(nullptr)
-{
- // nothing
-}
-
-/*!
- Construct a function node for a QML method or signal, specified
- by ther Metaness value \a type. It's parent is \a parent, and
- it's name is \a name. If \a attached is true, it is an attached
- method or signal.
-
- \note The function node's overload flag is set to false, and
- its overload number is set to 0. These data members are set
- in normalizeOverloads(), when all the overloads are known.
- */
-FunctionNode::FunctionNode(Metaness kind, Aggregate *parent, const QString &name, bool attached)
- : Node(Function, parent, name),
- const_(false),
- static_(false),
- reimpFlag_(false),
- attached_(attached),
- overloadFlag_(false),
- isFinal_(false),
- isOverride_(false),
- isRef_(false),
- isRefRef_(false),
- isInvokable_(false),
- metaness_(kind),
- virtualness_(NonVirtual),
- overloadNumber_(0),
- nextOverload_(nullptr)
-{
- setGenus(getGenus(metaness_));
- if (!isCppNode() && name.startsWith("__"))
- setStatus(Internal);
-}
-
-/*!
- Clone this node on the heap and make the clone a child of
- \a parent. Return the pointer to the clone.
- */
-Node *FunctionNode::clone(Aggregate *parent)
-{
- FunctionNode *fn = new FunctionNode(*this); // shallow copy
- fn->setParent(nullptr);
- fn->setNextOverload(nullptr);
- parent->addChild(fn);
- return fn;
-}
-
-/*!
- Returns this function's virtualness value as a string
- for use as an attribute value in index files.
- */
-QString FunctionNode::virtualness() const
-{
- switch (virtualness_) {
- case FunctionNode::NormalVirtual:
- return QLatin1String("virtual");
- case FunctionNode::PureVirtual:
- return QLatin1String("pure");
- case FunctionNode::NonVirtual:
- default:
- break;
- }
- return QLatin1String("non");
-}
-
-/*!
- Sets the function node's virtualness value based on the value
- of string \a t, which is the value of the function's \e{virtual}
- attribute in an index file. If \a t is \e{pure}, and if the
- parent() is a C++ class, set the parent's \e abstract flag to
- \c {true}.
- */
-void FunctionNode::setVirtualness(const QString &t)
-{
- if (t == QLatin1String("non"))
- virtualness_ = NonVirtual;
- else if (t == QLatin1String("virtual"))
- virtualness_ = NormalVirtual;
- else if (t == QLatin1String("pure")) {
- virtualness_ = PureVirtual;
- if (parent() && parent()->isClassNode())
- parent()->setAbstract(true);
- }
-}
-
-static QMap<QString, FunctionNode::Metaness> metanessMap_;
-static void buildMetanessMap()
-{
- metanessMap_["plain"] = FunctionNode::Plain;
- metanessMap_["signal"] = FunctionNode::Signal;
- metanessMap_["slot"] = FunctionNode::Slot;
- metanessMap_["constructor"] = FunctionNode::Ctor;
- metanessMap_["copy-constructor"] = FunctionNode::CCtor;
- metanessMap_["move-constructor"] = FunctionNode::MCtor;
- metanessMap_["destructor"] = FunctionNode::Dtor;
- metanessMap_["macro"] = FunctionNode::MacroWithParams;
- metanessMap_["macrowithparams"] = FunctionNode::MacroWithParams;
- metanessMap_["macrowithoutparams"] = FunctionNode::MacroWithoutParams;
- metanessMap_["copy-assign"] = FunctionNode::CAssign;
- metanessMap_["move-assign"] = FunctionNode::MAssign;
- metanessMap_["native"] = FunctionNode::Native;
- metanessMap_["qmlsignal"] = FunctionNode::QmlSignal;
- metanessMap_["qmlsignalhandler"] = FunctionNode::QmlSignalHandler;
- metanessMap_["qmlmethod"] = FunctionNode::QmlMethod;
- metanessMap_["jssignal"] = FunctionNode::JsSignal;
- metanessMap_["jssignalhandler"] = FunctionNode::JsSignalHandler;
- metanessMap_["jsmethos"] = FunctionNode::JsMethod;
-}
-
-static QMap<QString, FunctionNode::Metaness> topicMetanessMap_;
-static void buildTopicMetanessMap()
-{
- topicMetanessMap_["fn"] = FunctionNode::Plain;
- topicMetanessMap_["qmlsignal"] = FunctionNode::QmlSignal;
- topicMetanessMap_["qmlattachedsignal"] = FunctionNode::QmlSignal;
- topicMetanessMap_["qmlmethod"] = FunctionNode::QmlMethod;
- topicMetanessMap_["qmlattachedmethod"] = FunctionNode::QmlMethod;
- topicMetanessMap_["jssignal"] = FunctionNode::JsSignal;
- topicMetanessMap_["jsattachedsignal"] = FunctionNode::JsSignal;
- topicMetanessMap_["jsmethod"] = FunctionNode::JsMethod;
- topicMetanessMap_["jsattachedmethod"] = FunctionNode::JsMethod;
-}
-
-/*!
- Determines the Genus value for this FunctionNode given the
- Metaness value \a t. Returns the Genus value. \a t must be
- one of the values of Metaness. If not, Node::DontCare is
- returned.
- */
-Node::Genus FunctionNode::getGenus(FunctionNode::Metaness t)
-{
- switch (t) {
- case FunctionNode::Plain:
- case FunctionNode::Signal:
- case FunctionNode::Slot:
- case FunctionNode::Ctor:
- case FunctionNode::Dtor:
- case FunctionNode::CCtor:
- case FunctionNode::MCtor:
- case FunctionNode::MacroWithParams:
- case FunctionNode::MacroWithoutParams:
- case FunctionNode::Native:
- case FunctionNode::CAssign:
- case FunctionNode::MAssign:
- return Node::CPP;
- case FunctionNode::QmlSignal:
- case FunctionNode::QmlSignalHandler:
- case FunctionNode::QmlMethod:
- return Node::QML;
- case FunctionNode::JsSignal:
- case FunctionNode::JsSignalHandler:
- case FunctionNode::JsMethod:
- return Node::JS;
- }
- return Node::DontCare;
-}
-
-/*!
- This static function converts the string \a t to an enum
- value for the kind of function named by \a t.
- */
-FunctionNode::Metaness FunctionNode::getMetaness(const QString &t)
-{
- if (metanessMap_.isEmpty())
- buildMetanessMap();
- return metanessMap_[t];
-}
-
-/*!
- This static function converts the topic string \a t to an enum
- value for the kind of function this FunctionNode represents.
- */
-FunctionNode::Metaness FunctionNode::getMetanessFromTopic(const QString &t)
-{
- if (topicMetanessMap_.isEmpty())
- buildTopicMetanessMap();
- return topicMetanessMap_[t];
-}
-
-/*!
- Sets the function node's Metaness value based on the value
- of string \a t, which is the value of the function's "meta"
- attribute in an index file. Returns the Metaness value
- */
-FunctionNode::Metaness FunctionNode::setMetaness(const QString &t)
-{
- metaness_ = getMetaness(t);
- return metaness_;
-}
-
-/*!
- If this function node's metaness is \a from, change the
- metaness to \a to and return \c true. Otherwise return
- false. This function is used to change Qml function node
- metaness values to Javascript function node metaness,
- values because these nodes are created as Qml function
- nodes before it is discovered that what the function node
- represents is not a Qml function but a javascript function.
-
- Note that if the function returns true, which means the node
- type was indeed changed, then the node's Genus is also changed
- from QML to JS.
-
- The function also works in the other direction, but there is
- no use case for that.
- */
-bool FunctionNode::changeMetaness(Metaness from, Metaness to)
-{
- if (metaness_ == from) {
- metaness_ = to;
- switch (to) {
- case QmlSignal:
- case QmlSignalHandler:
- case QmlMethod:
- setGenus(Node::QML);
- break;
- case JsSignal:
- case JsSignalHandler:
- case JsMethod:
- setGenus(Node::JS);
- break;
- default:
- setGenus(Node::CPP);
- break;
- }
- return true;
- }
- return false;
-}
-
-/*! \fn void FunctionNode::setOverloadNumber(unsigned char n)
- Sets the function node's overload number to \a n. If \a n
- is 0, the function node's overload flag is set to false. If
- \a n is greater than 0, the overload flag is set to true.
- */
-void FunctionNode::setOverloadNumber(signed short n)
-{
- overloadNumber_ = n;
- overloadFlag_ = (n > 0) ? true : false;
-}
-
-/*!
- If this function's next overload pointer is null, set it to
- \a fn. Otherwise continue down the overload list by calling
- this function recursively for the next overload.
-
- Although this function appends an overload function to the list of
- overloads for this function's name, it does not set the function's
- overload number or it's overload flag. If the function has the
- \c{\\overload} in its qdoc comment, that will set the overload
- flag. But qdoc treats the \c{\\overload} command as a hint that the
- function should be documented as an overload. The hint is almost
- always correct, but qdoc reserves the right to decide which function
- should be the primary function and which functions are the overloads.
- These decisions are made in Aggregate::normalizeOverloads().
- */
-void FunctionNode::appendOverload(FunctionNode *fn)
-{
- if (nextOverload_ == nullptr)
- nextOverload_ = fn;
- else
- nextOverload_->appendOverload(fn);
-}
-
-/*!
- This function assumes that this FunctionNode is marked as an
- overload function. It asks if the next overload is marked as
- an overload. If not, then remove that FunctionNode from the
- overload list and return it. Otherwise call this function
- recursively for the next overload.
- */
-FunctionNode *FunctionNode::findPrimaryFunction()
-{
- if (nextOverload_ != nullptr) {
- if (!nextOverload_->isOverload()) {
- FunctionNode *t = nextOverload_;
- nextOverload_ = t->nextOverload();
- t->setNextOverload(nullptr);
- return t;
- }
- return nextOverload_->findPrimaryFunction();
- }
- return nullptr;
-}
-
-/*!
- \fn void FunctionNode::setReimpFlag()
-
- Sets the function node's reimp flag to \c true, which means
- the \e {\\reimp} command was used in the qdoc comment. It is
- supposed to mean that the function reimplements a virtual
- function in a base class.
- */
-
-/*!
- Returns a string representing the kind of function this
- Function node represents, which depends on the Metaness
- value.
- */
-QString FunctionNode::kindString() const
-{
- switch (metaness_) {
- case FunctionNode::QmlSignal:
- return "QML signal";
- case FunctionNode::QmlSignalHandler:
- return "QML signal handler";
- case FunctionNode::QmlMethod:
- return "QML method";
- case FunctionNode::JsSignal:
- return "JS signal";
- case FunctionNode::JsSignalHandler:
- return "JS signal handler";
- case FunctionNode::JsMethod:
- return "JS method";
- default:
- return "function";
- }
-}
-
-/*!
- Returns a string representing the Metaness enum value for
- this function. It is used in index files.
- */
-QString FunctionNode::metanessString() const
-{
- switch (metaness_) {
- case FunctionNode::Plain:
- return "plain";
- case FunctionNode::Signal:
- return "signal";
- case FunctionNode::Slot:
- return "slot";
- case FunctionNode::Ctor:
- return "constructor";
- case FunctionNode::CCtor:
- return "copy-constructor";
- case FunctionNode::MCtor:
- return "move-constructor";
- case FunctionNode::Dtor:
- return "destructor";
- case FunctionNode::MacroWithParams:
- return "macrowithparams";
- case FunctionNode::MacroWithoutParams:
- return "macrowithoutparams";
- case FunctionNode::Native:
- return "native";
- case FunctionNode::CAssign:
- return "copy-assign";
- case FunctionNode::MAssign:
- return "move-assign";
- case FunctionNode::QmlSignal:
- return "qmlsignal";
- case FunctionNode::QmlSignalHandler:
- return "qmlsignalhandler";
- case FunctionNode::QmlMethod:
- return "qmlmethod";
- case FunctionNode::JsSignal:
- return "jssignal";
- case FunctionNode::JsSignalHandler:
- return "jssignalhandler";
- case FunctionNode::JsMethod:
- return "jsmethod";
- default:
- return "plain";
- }
-}
-
-/*!
- Adds the "associated" property \a p to this function node.
- The function might be the setter or getter for a property,
- for example.
- */
-void FunctionNode::addAssociatedProperty(PropertyNode *p)
-{
- associatedProperties_.append(p);
-}
-
-/*!
- \reimp
-
- Returns \c true if this is an access function for an obsolete property,
- otherwise calls the base implementation of isObsolete().
-*/
-bool FunctionNode::isObsolete() const
-{
- auto it = std::find_if_not(associatedProperties_.begin(),
- associatedProperties_.end(),
- [](const Node *p)->bool {
- return p->isObsolete();
- });
-
- if (!associatedProperties_.isEmpty() && it == associatedProperties_.end())
- return true;
-
- return Node::isObsolete();
-}
-
-/*! \fn unsigned char FunctionNode::overloadNumber() const
- Returns the overload number for this function.
- */
-
-/*!
- Reconstructs and returns the function's signature. If \a values
- is \c true, the default values of the parameters are included.
- The return type is included unless \a noReturnType is \c true.
- Function templates are prefixed with \c {template <parameter_list>}
- if \a templateParams is \c true.
- */
-QString FunctionNode::signature(bool values, bool noReturnType, bool templateParams) const
-{
- QStringList elements;
-
- if (templateParams)
- elements << templateDecl();
- if (!noReturnType)
- elements << returnType_;
- elements.removeAll({});
-
- if (!isMacroWithoutParams()) {
- elements << name() + QLatin1Char('(') + parameters_.signature(values) + QLatin1Char(')');
- if (!isMacro()) {
- if (isConst())
- elements << QStringLiteral("const");
- if (isRef())
- elements << QStringLiteral("&");
- else if (isRefRef())
- elements << QStringLiteral("&&");
- }
- } else {
- elements << name();
- }
- return elements.join(QLatin1Char(' '));
-}
-
-/*!
- Print some information used for debugging qdoc. Only used when debugging.
- */
-void FunctionNode::debug() const
-{
- qDebug("QML METHOD %s returnType_ %s parentPath_ %s", qPrintable(name()),
- qPrintable(returnType_), qPrintable(parentPath_.join(' ')));
-}
-
-/*!
- Compares this FunctionNode to the FunctionNode pointed to
- by \a fn. Returns true if they describe the same function.
- */
-bool FunctionNode::compare(const FunctionNode *fn) const
-{
- if (fn == nullptr)
- return false;
- if (metaness() != fn->metaness())
- return false;
- if (parent() != fn->parent())
- return false;
- if (returnType_ != fn->returnType())
- return false;
- if (isConst() != fn->isConst())
- return false;
- if (isAttached() != fn->isAttached())
- return false;
- const Parameters &p = fn->parameters();
- if (parameters_.count() != p.count())
- return false;
- if (!p.isEmpty()) {
- for (int i = 0; i < p.count(); ++i) {
- if (parameters_.at(i).type() != p.at(i).type())
- return false;
- }
- }
- return true;
-}
-
-/*!
- In some cases, it is ok for a public function to be not documented.
- For example, the macro Q_OBJECT adds several functions to the API of
- a class, but these functions are normally not meant to be documented.
- So if a function node doesn't have documentation, then if its name is
- in the list of functions that it is ok not to document, this function
- returns true. Otherwise, it returns false.
-
- These are the member function names added by macros. Usually they
- are not documented, but they can be documented, so this test avoids
- reporting an error if they are not documented.
-
- But maybe we should generate a standard text for each of them?
- */
-bool FunctionNode::isIgnored() const
-{
- if (!hasDoc() && !hasSharedDoc()) {
- if (name().startsWith(QLatin1String("qt_")) || name() == QLatin1String("metaObject")
- || name() == QLatin1String("tr") || name() == QLatin1String("trUtf8")
- || name() == QLatin1String("d_func")) {
- return true;
- }
- QString s = signature(false, false);
- if (s.contains(QLatin1String("enum_type")) && s.contains(QLatin1String("operator|")))
- return true;
- }
- return false;
-}
-
-/*!
- Returns true if this function has overloads. Otherwise false.
- First, if this function node's overload pointer is not nullptr,
- return true. Next, if this function node's overload flag is true
- return true. Finally, if this function's parent Aggregate has a
- function by the same name as this one in its function map and
- that function has overloads, return true. Otherwise return false.
-
- There is a failsafe way to test it under any circumstances.
- */
-bool FunctionNode::hasOverloads() const
-{
- if (nextOverload_ != nullptr)
- return true;
- if (overloadFlag_)
- return true;
- if (parent())
- return parent()->hasOverloads(this);
- return false;
-}
-
bool QmlTypeNode::qmlOnly = false;
QMultiMap<const Node *, Node *> QmlTypeNode::inheritedBy;
diff --git a/src/qdoc/node.h b/src/qdoc/node.h
index 5363c2212..0b77be322 100644
--- a/src/qdoc/node.h
+++ b/src/qdoc/node.h
@@ -958,176 +958,6 @@ private:
QVector<Node *> collective_;
};
-class FunctionNode : public Node
-{
-public:
- enum Virtualness { NonVirtual, NormalVirtual, PureVirtual };
-
- enum Metaness {
- Plain,
- Signal,
- Slot,
- Ctor,
- Dtor,
- CCtor, // copy constructor
- MCtor, // move-copy constructor
- MacroWithParams,
- MacroWithoutParams,
- Native,
- CAssign, // copy-assignment operator
- MAssign, // move-assignment operator
- QmlSignal,
- QmlSignalHandler,
- QmlMethod,
- JsSignal,
- JsSignalHandler,
- JsMethod
- };
-
- FunctionNode(Aggregate *parent, const QString &name); // C++ function (Plain)
- FunctionNode(Metaness type, Aggregate *parent, const QString &name, bool attached = false);
-
- Node *clone(Aggregate *parent) override;
- Metaness metaness() const { return metaness_; }
- QString metanessString() const;
- bool changeMetaness(Metaness from, Metaness to);
- void setMetaness(Metaness t) { metaness_ = t; }
- Metaness setMetaness(const QString &t);
- QString kindString() const;
- static Metaness getMetaness(const QString &t);
- static Metaness getMetanessFromTopic(const QString &t);
- static Genus getGenus(Metaness t);
-
- void setReturnType(const QString &t) { returnType_ = t; }
- void setParentPath(const QStringList &p) { parentPath_ = p; }
- void setVirtualness(const QString &t);
- void setVirtualness(Virtualness v) { virtualness_ = v; }
- void setVirtual() { virtualness_ = NormalVirtual; }
- void setConst(bool b) { const_ = b; }
- void setStatic(bool b) { static_ = b; }
- void setReimpFlag() { reimpFlag_ = true; }
- void setOverridesThis(const QString &path) { overridesThis_ = path; }
-
- const QString &returnType() const { return returnType_; }
- QString virtualness() const;
- bool isConst() const { return const_; }
- bool isStatic() const override { return static_; }
- bool isOverload() const { return overloadFlag_; }
- bool isMarkedReimp() const override { return reimpFlag_; }
- bool isSomeCtor() const { return isCtor() || isCCtor() || isMCtor(); }
- bool isMacroWithParams() const { return (metaness_ == MacroWithParams); }
- bool isMacroWithoutParams() const { return (metaness_ == MacroWithoutParams); }
- bool isMacro() const override { return (isMacroWithParams() || isMacroWithoutParams()); }
- bool isObsolete() const override;
-
- bool isCppFunction() const { return metaness_ == Plain; } // Is this correct?
- bool isSignal() const { return (metaness_ == Signal); }
- bool isSlot() const { return (metaness_ == Slot); }
- bool isCtor() const { return (metaness_ == Ctor); }
- bool isDtor() const { return (metaness_ == Dtor); }
- bool isCCtor() const { return (metaness_ == CCtor); }
- bool isMCtor() const { return (metaness_ == MCtor); }
- bool isCAssign() const { return (metaness_ == CAssign); }
- bool isMAssign() const { return (metaness_ == MAssign); }
-
- bool isJsMethod() const { return (metaness_ == JsMethod); }
- bool isJsSignal() const { return (metaness_ == JsSignal); }
- bool isJsSignalHandler() const { return (metaness_ == JsSignalHandler); }
-
- bool isQmlMethod() const { return (metaness_ == QmlMethod); }
- bool isQmlSignal() const { return (metaness_ == QmlSignal); }
- bool isQmlSignalHandler() const { return (metaness_ == QmlSignalHandler); }
-
- bool isSpecialMemberFunction() const
- {
- return (isDtor() || isCCtor() || isMCtor() || isCAssign() || isMAssign());
- }
- bool isNonvirtual() const { return (virtualness_ == NonVirtual); }
- bool isVirtual() const { return (virtualness_ == NormalVirtual); }
- bool isPureVirtual() const { return (virtualness_ == PureVirtual); }
- bool returnsBool() const { return (returnType_ == QLatin1String("bool")); }
-
- Parameters &parameters() { return parameters_; }
- const Parameters &parameters() const { return parameters_; }
- bool isPrivateSignal() const { return parameters_.isPrivateSignal(); }
- void setParameters(const QString &signature) { parameters_.set(signature); }
- QString signature(bool values, bool noReturnType, bool templateParams = false) const override;
-
- const QString &overridesThis() const { return overridesThis_; }
- const NodeList &associatedProperties() const { return associatedProperties_; }
- const QStringList &parentPath() const { return parentPath_; }
- bool hasAssociatedProperties() const { return !associatedProperties_.isEmpty(); }
- bool hasOneAssociatedProperty() const { return (associatedProperties_.size() == 1); }
- Node *firstAssociatedProperty() const { return associatedProperties_[0]; }
-
- QString element() const override { return parent()->name(); }
- bool isAttached() const override { return attached_; }
- bool isQtQuickNode() const override { return parent()->isQtQuickNode(); }
- QString qmlTypeName() const override { return parent()->qmlTypeName(); }
- QString logicalModuleName() const override { return parent()->logicalModuleName(); }
- QString logicalModuleVersion() const override { return parent()->logicalModuleVersion(); }
- QString logicalModuleIdentifier() const override { return parent()->logicalModuleIdentifier(); }
-
- void debug() const;
-
- void setFinal(bool b) { isFinal_ = b; }
- bool isFinal() const { return isFinal_; }
-
- void setOverride(bool b) { isOverride_ = b; }
- bool isOverride() const { return isOverride_; }
-
- void setRef(bool b) { isRef_ = b; }
- bool isRef() const { return isRef_; }
-
- void setRefRef(bool b) { isRefRef_ = b; }
- bool isRefRef() const { return isRefRef_; }
-
- void setInvokable(bool b) { isInvokable_ = b; }
- bool isInvokable() const { return isInvokable_; }
-
- bool hasTag(const QString &t) const override { return (tag_ == t); }
- void setTag(const QString &t) { tag_ = t; }
- const QString &tag() const { return tag_; }
- bool compare(const FunctionNode *fn) const;
- bool isIgnored() const;
- bool hasOverloads() const;
- void clearOverloadFlag() { overloadFlag_ = false; }
- void setOverloadFlag() { overloadFlag_ = true; }
- void setOverloadNumber(signed short n);
- void appendOverload(FunctionNode *fn);
- signed short overloadNumber() const { return overloadNumber_; }
- FunctionNode *nextOverload() { return nextOverload_; }
- void setNextOverload(FunctionNode *fn) { nextOverload_ = fn; }
- FunctionNode *findPrimaryFunction();
-
-private:
- void addAssociatedProperty(PropertyNode *property);
-
- friend class Aggregate;
- friend class PropertyNode;
-
- bool const_ : 1;
- bool static_ : 1;
- bool reimpFlag_ : 1;
- bool attached_ : 1;
- bool overloadFlag_ : 1;
- bool isFinal_ : 1;
- bool isOverride_ : 1;
- bool isRef_ : 1;
- bool isRefRef_ : 1;
- bool isInvokable_ : 1;
- Metaness metaness_;
- Virtualness virtualness_;
- signed short overloadNumber_;
- FunctionNode *nextOverload_;
- QString returnType_;
- QStringList parentPath_;
- QString overridesThis_;
- QString tag_;
- NodeList associatedProperties_;
- Parameters parameters_;
-};
-
class CollectionNode : public PageNode
{
public:
diff --git a/src/qdoc/propertynode.h b/src/qdoc/propertynode.h
index 735b3d498..3caf38dee 100644
--- a/src/qdoc/propertynode.h
+++ b/src/qdoc/propertynode.h
@@ -29,6 +29,7 @@
#ifndef PROPERTYNODE_H
#define PROPERTYNODE_H
+#include "functionnode.h"
#include "node.h"
#include <QtCore/qglobal.h>
diff --git a/src/qdoc/qdoc.pro b/src/qdoc/qdoc.pro
index 0b55fe6db..b7feaad39 100644
--- a/src/qdoc/qdoc.pro
+++ b/src/qdoc/qdoc.pro
@@ -46,6 +46,7 @@ HEADERS += atom.h \
docutilities.h \
editdistance.h \
enumitem.h \
+ functionnode.h \
generator.h \
helpprojectwriter.h \
htmlgenerator.h \
@@ -87,6 +88,7 @@ SOURCES += atom.cpp \
docparser.cpp \
docprivate.cpp \
editdistance.cpp \
+ functionnode.cpp \
generator.cpp \
helpprojectwriter.cpp \
htmlgenerator.cpp \
diff --git a/src/qdoc/qdocdatabase.cpp b/src/qdoc/qdocdatabase.cpp
index f19ee45c6..ceaa7e574 100644
--- a/src/qdoc/qdocdatabase.cpp
+++ b/src/qdoc/qdocdatabase.cpp
@@ -29,6 +29,7 @@
#include "qdocdatabase.h"
#include "atom.h"
+#include "functionnode.h"
#include "generator.h"
#include "qdocindexfiles.h"
#include "qdoctagfiles.h"
diff --git a/src/qdoc/qdocdatabase.h b/src/qdoc/qdocdatabase.h
index cabbc1a2e..52bd73a72 100644
--- a/src/qdoc/qdocdatabase.h
+++ b/src/qdoc/qdocdatabase.h
@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
typedef QMultiMap<Text, const Node *> TextToNodeMap;
class Atom;
+class FunctionNode;
class Generator;
class QDocDatabase;
diff --git a/src/qdoc/qdocindexfiles.cpp b/src/qdoc/qdocindexfiles.cpp
index 190def681..fef20b75d 100644
--- a/src/qdoc/qdocindexfiles.cpp
+++ b/src/qdoc/qdocindexfiles.cpp
@@ -30,6 +30,7 @@
#include "atom.h"
#include "config.h"
+#include "functionnode.h"
#include "generator.h"
#include "location.h"
#include "loggingcategory.h"
diff --git a/src/qdoc/qdocindexfiles.h b/src/qdoc/qdocindexfiles.h
index b37c132a4..41160f079 100644
--- a/src/qdoc/qdocindexfiles.h
+++ b/src/qdoc/qdocindexfiles.h
@@ -35,6 +35,7 @@
QT_BEGIN_NAMESPACE
class Atom;
+class FunctionNode;
class Generator;
class QStringList;
class QDocDatabase;
diff --git a/src/qdoc/qdoctagfiles.cpp b/src/qdoc/qdoctagfiles.cpp
index dfa51e03f..7ea8b91b8 100644
--- a/src/qdoc/qdoctagfiles.cpp
+++ b/src/qdoc/qdoctagfiles.cpp
@@ -28,6 +28,7 @@
#include "qdoctagfiles.h"
+#include "functionnode.h"
#include "htmlgenerator.h"
#include "location.h"
#include "node.h"
diff --git a/src/qdoc/qmlvisitor.cpp b/src/qdoc/qmlvisitor.cpp
index 104c4575d..9212818b0 100644
--- a/src/qdoc/qmlvisitor.cpp
+++ b/src/qdoc/qmlvisitor.cpp
@@ -30,6 +30,7 @@
#include "codechunk.h"
#include "codeparser.h"
+#include "functionnode.h"
#include "node.h"
#include "qdocdatabase.h"
#include "tokenizer.h"
diff --git a/src/qdoc/sections.cpp b/src/qdoc/sections.cpp
index 2bb8de7fd..1c945e17b 100644
--- a/src/qdoc/sections.cpp
+++ b/src/qdoc/sections.cpp
@@ -29,6 +29,7 @@
#include "sections.h"
#include "config.h"
+#include "functionnode.h"
#include "generator.h"
#include "loggingcategory.h"
#include "variablenode.h"
diff --git a/src/qdoc/tree.cpp b/src/qdoc/tree.cpp
index dcb3be7b8..7476f69cd 100644
--- a/src/qdoc/tree.cpp
+++ b/src/qdoc/tree.cpp
@@ -29,6 +29,7 @@
#include "tree.h"
#include "doc.h"
+#include "functionnode.h"
#include "htmlgenerator.h"
#include "location.h"
#include "node.h"
diff --git a/src/qdoc/tree.h b/src/qdoc/tree.h
index 6b377d424..6f95dbe2e 100644
--- a/src/qdoc/tree.h
+++ b/src/qdoc/tree.h
@@ -40,6 +40,7 @@
QT_BEGIN_NAMESPACE
+class FunctionNode;
class QStringList;
class QDocDatabase;
diff --git a/src/qdoc/xmlgenerator.cpp b/src/qdoc/xmlgenerator.cpp
index f5866d121..ae0080d74 100644
--- a/src/qdoc/xmlgenerator.cpp
+++ b/src/qdoc/xmlgenerator.cpp
@@ -27,6 +27,8 @@
****************************************************************************/
#include "xmlgenerator.h"
+
+#include "functionnode.h"
#include "qdocdatabase.h"
QT_BEGIN_NAMESPACE