diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qdoc/.prev_CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/qdoc/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/qdoc/clangcodeparser.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/codemarker.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/cppcodemarker.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/cppcodeparser.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/docbookgenerator.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/docbookgenerator.h | 2 | ||||
-rw-r--r-- | src/qdoc/functionnode.cpp | 613 | ||||
-rw-r--r-- | src/qdoc/functionnode.h | 212 | ||||
-rw-r--r-- | src/qdoc/generator.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/generator.h | 1 | ||||
-rw-r--r-- | src/qdoc/helpprojectwriter.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/htmlgenerator.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/node.cpp | 584 | ||||
-rw-r--r-- | src/qdoc/node.h | 170 | ||||
-rw-r--r-- | src/qdoc/propertynode.h | 1 | ||||
-rw-r--r-- | src/qdoc/qdoc.pro | 2 | ||||
-rw-r--r-- | src/qdoc/qdocdatabase.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/qdocdatabase.h | 1 | ||||
-rw-r--r-- | src/qdoc/qdocindexfiles.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/qdocindexfiles.h | 1 | ||||
-rw-r--r-- | src/qdoc/qdoctagfiles.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/qmlvisitor.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/sections.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/tree.cpp | 1 | ||||
-rw-r--r-- | src/qdoc/tree.h | 1 | ||||
-rw-r--r-- | src/qdoc/xmlgenerator.cpp | 2 |
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 ¶meters() { return m_parameters; } + const Parameters ¶meters() 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 ¶meters() { return parameters_; } - const Parameters ¶meters() 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 |