diff options
Diffstat (limited to 'src/qdoc/qdoc/src')
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/codeparser.h | 3 | ||||
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/cppcodemarker.cpp | 12 | ||||
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/cppcodeparser.cpp | 8 | ||||
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp | 12 | ||||
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/generator.cpp | 40 | ||||
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/generator.h | 1 | ||||
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/qmlpropertynode.cpp | 38 | ||||
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/qmlpropertynode.h | 4 | ||||
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/qmlvisitor.cpp | 10 | ||||
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/tree.h | 5 |
10 files changed, 127 insertions, 6 deletions
diff --git a/src/qdoc/qdoc/src/qdoc/codeparser.h b/src/qdoc/qdoc/src/qdoc/codeparser.h index 2b86df399..6357b3a21 100644 --- a/src/qdoc/qdoc/src/qdoc/codeparser.h +++ b/src/qdoc/qdoc/src/qdoc/codeparser.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE #define COMMAND_QMLVALUETYPE QLatin1String("qmlvaluetype") #define COMMAND_QMLCLASS QLatin1String("qmlclass") #define COMMAND_QMLDEFAULT QLatin1String("qmldefault") +#define COMMAND_QMLENUMERATORSFROM QLatin1String("qmlenumeratorsfrom") #define COMMAND_QMLINHERITS QLatin1String("inherits") #define COMMAND_QMLINSTANTIATES QLatin1String("instantiates") #define COMMAND_QMLMETHOD QLatin1String("qmlmethod") @@ -104,7 +105,7 @@ public: COMMAND_ABSTRACT, COMMAND_DEFAULT, COMMAND_DEPRECATED, COMMAND_INGROUP, COMMAND_INMODULE, COMMAND_INPUBLICGROUP, COMMAND_INQMLMODULE, COMMAND_INTERNAL, COMMAND_MODULESTATE, COMMAND_NOAUTOLIST, COMMAND_NONREENTRANT, COMMAND_OBSOLETE, - COMMAND_PRELIMINARY, COMMAND_QMLABSTRACT, COMMAND_QMLDEFAULT, COMMAND_QMLINHERITS, + COMMAND_PRELIMINARY, COMMAND_QMLABSTRACT, COMMAND_QMLDEFAULT, COMMAND_QMLENUMERATORSFROM, COMMAND_QMLINHERITS, COMMAND_QMLREADONLY, COMMAND_QMLREQUIRED, COMMAND_QTCMAKEPACKAGE, COMMAND_QTCMAKETARGETITEM, COMMAND_QTVARIABLE, COMMAND_REENTRANT, COMMAND_SINCE, COMMAND_STARTPAGE, COMMAND_SUBTITLE, COMMAND_THREADSAFE, COMMAND_TITLE, COMMAND_WRAPPER, COMMAND_ATTRIBUTION, diff --git a/src/qdoc/qdoc/src/qdoc/cppcodemarker.cpp b/src/qdoc/qdoc/src/qdoc/cppcodemarker.cpp index 97560a696..7fb26db0c 100644 --- a/src/qdoc/qdoc/src/qdoc/cppcodemarker.cpp +++ b/src/qdoc/qdoc/src/qdoc/cppcodemarker.cpp @@ -292,10 +292,18 @@ QString CppCodeMarker::markedUpName(const Node *node) QString CppCodeMarker::markedUpEnumValue(const QString &enumValue, const Node *relative) { - if (!relative->isEnumType()) + const auto *node = relative->parent(); + + if (relative->isQmlProperty()) { + const auto *qpn = static_cast<const QmlPropertyNode*>(relative); + if (qpn->enumNode() && !enumValue.startsWith("%1."_L1.arg(qpn->enumPrefix()))) + return "%1<@op>.</@op>%2"_L1.arg(qpn->enumPrefix(), enumValue); + } + + if (!relative->isEnumType()) { return enumValue; + } - const Node *node = relative->parent(); QStringList parts; while (!node->isHeader() && node->parent()) { parts.prepend(markedUpName(node)); diff --git a/src/qdoc/qdoc/src/qdoc/cppcodeparser.cpp b/src/qdoc/qdoc/src/qdoc/cppcodeparser.cpp index 371e403c8..14297c0fd 100644 --- a/src/qdoc/qdoc/src/qdoc/cppcodeparser.cpp +++ b/src/qdoc/qdoc/src/qdoc/cppcodeparser.cpp @@ -485,6 +485,14 @@ void CppCodeParser::processMetaCommand(const Doc &doc, const QString &command, } } else if (command == COMMAND_QMLDEFAULT) { node->markDefault(); + } else if (command == COMMAND_QMLENUMERATORSFROM) { + if (!node->isQmlProperty()) { + doc.location().warning("Ignored '\\%1', applies only to '\\%2'"_L1 + .arg(command, COMMAND_QMLPROPERTY)); + } else if (!static_cast<QmlPropertyNode*>(node)->setEnumNode(argPair.first, argPair.second)) { + doc.location().warning("Failed to find C++ enumeration '%2' passed to \\%1"_L1 + .arg(command, arg), "Use \\value commands instead"_L1); + } } else if (command == COMMAND_QMLREADONLY) { node->markReadOnly(true); } else if (command == COMMAND_QMLREQUIRED) { diff --git a/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp b/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp index 10bf00a36..9c8901cc6 100644 --- a/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp +++ b/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp @@ -2665,6 +2665,7 @@ void DocBookGenerator::generateBody(const Node *node) // Warning generation skipped with respect to Generator::generateBody. } + generateEnumValuesForQmlProperty(node, nullptr); generateRequiredLinks(node); } @@ -3883,13 +3884,22 @@ void DocBookGenerator::generateEnumValue(const QString &enumValue, const Node *r // From CppCodeMarker::markedUpEnumValue, simplifications from Generator::plainCode (removing // <@op>). With respect to CppCodeMarker::markedUpEnumValue, the order of generation of parents // must be reversed so that they are processed in the order + const auto *node = relative->parent(); + + if (relative->isQmlProperty()) { + const auto *qpn = static_cast<const QmlPropertyNode*>(relative); + if (qpn->enumNode() && !enumValue.startsWith("%1."_L1.arg(qpn->enumPrefix()))) { + m_writer->writeCharacters("%1.%2"_L1.arg(qpn->enumPrefix(), enumValue)); + return; + } + } + if (!relative->isEnumType()) { m_writer->writeCharacters(enumValue); return; } QList<const Node *> parents; - const Node *node = relative->parent(); while (!node->isHeader() && node->parent()) { parents.prepend(node); if (node->parent() == relative || node->parent()->name().isEmpty()) diff --git a/src/qdoc/qdoc/src/qdoc/generator.cpp b/src/qdoc/qdoc/src/qdoc/generator.cpp index e9b2d5076..fa30e93c8 100644 --- a/src/qdoc/qdoc/src/qdoc/generator.cpp +++ b/src/qdoc/qdoc/src/qdoc/generator.cpp @@ -20,6 +20,7 @@ #include "propertynode.h" #include "qdocdatabase.h" #include "qmltypenode.h" +#include "qmlpropertynode.h" #include "quoter.h" #include "sharedcommentnode.h" #include "tokenizer.h" @@ -792,6 +793,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } } } + generateEnumValuesForQmlProperty(node, marker); generateRequiredLinks(node, marker); } @@ -2030,6 +2032,44 @@ void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList) } } +void Generator::generateEnumValuesForQmlProperty(const Node *node, CodeMarker *marker) +{ + if (!node->isQmlProperty()) + return; + + const auto *qpn = static_cast<const QmlPropertyNode*>(node); + + if (!qpn->enumNode()) + return; + + auto findNext = + [](const Atom *atom, Atom::AtomType type, const QString &str) { + while (atom && (atom->type() != type || atom->string() != str)) + atom = atom->next(); + return atom; + }; + + // Retrieve atoms from C++ enum \value list + const auto body{qpn->enumNode()->doc().body()}; + const auto *start{body.firstAtom()}; + Text text; + + while ((start = findNext(start, Atom::ListLeft, ATOM_LIST_VALUE))) { + const auto end = findNext(start, Atom::ListRight, ATOM_LIST_VALUE); + // Skip subsequent ListLeft atoms, collating multiple lists into one + text << body.subText(text.isEmpty() ? start : start->next(), end); + start = end; + } + if (text.isEmpty()) + return; + + text << Atom(Atom::ListRight, ATOM_LIST_VALUE); + if (marker) + generateText(text, qpn, marker); + else + generateText(text, qpn); +} + void Generator::terminate() { for (const auto &generator : std::as_const(s_generators)) { diff --git a/src/qdoc/qdoc/src/qdoc/generator.h b/src/qdoc/qdoc/src/qdoc/generator.h index 46e11bafe..8f2b34039 100644 --- a/src/qdoc/qdoc/src/qdoc/generator.h +++ b/src/qdoc/qdoc/src/qdoc/generator.h @@ -108,6 +108,7 @@ protected: QMap<QString, QString> &formattingRightMap(); const Atom *generateAtomList(const Atom *atom, const Node *relative, CodeMarker *marker, bool generate, int &numGeneratedAtoms); + void generateEnumValuesForQmlProperty(const Node *node, CodeMarker *marker); void generateRequiredLinks(const Node *node, CodeMarker *marker); void generateLinkToExample(const ExampleNode *en, CodeMarker *marker, const QString &exampleUrl); diff --git a/src/qdoc/qdoc/src/qdoc/qmlpropertynode.cpp b/src/qdoc/qdoc/src/qdoc/qmlpropertynode.cpp index a8aaf1257..335b7d870 100644 --- a/src/qdoc/qdoc/src/qdoc/qmlpropertynode.cpp +++ b/src/qdoc/qdoc/src/qdoc/qmlpropertynode.cpp @@ -5,6 +5,7 @@ #include "classnode.h" #include "propertynode.h" +#include "enumnode.h" #include <utility> #include "qdocdatabase.h" @@ -35,6 +36,43 @@ QmlPropertyNode::QmlPropertyNode(Aggregate *parent, const QString &name, QString */ /*! + \fn const EnumNode *QmlPropertyNode::enumNode() const + + Returns the node representing the C++ enumeration associated + with this property, or \nullptr. +*/ + +/*! + Returns the prefix to use for documentated enumerators from + the associated C++ enum for this property. +*/ +const QString &QmlPropertyNode::enumPrefix() const +{ + return !m_enumNode.second.isEmpty() ? + m_enumNode.second : parent()->name(); +} + +/*! + Locates the node specified by \a path and sets it as the C++ enumeration + associated with this property. + + \a registeredQmlName is used as the prefix in the generated enum value + documentation. + + \note The target EnumNode is searched under the primary tree only. + + Returns \c true on success. +*/ +bool QmlPropertyNode::setEnumNode(const QString &path, const QString ®isteredQmlName) +{ + m_enumNode.first = static_cast<EnumNode*>( + QDocDatabase::qdocDB()->primaryTree()->findNodeByNameAndType(path.split("::"), &Node::isEnumType) + ); + m_enumNode.second = registeredQmlName; + return m_enumNode.first != nullptr; +} + +/*! Returns \c true if this QML property or attached property is read-only. If the read-only status is not set explicitly using the \\readonly command, QDoc attempts to resolve it diff --git a/src/qdoc/qdoc/src/qdoc/qmlpropertynode.h b/src/qdoc/qdoc/src/qdoc/qmlpropertynode.h index fec5ff89f..19d1c9485 100644 --- a/src/qdoc/qdoc/src/qdoc/qmlpropertynode.h +++ b/src/qdoc/qdoc/src/qdoc/qmlpropertynode.h @@ -21,6 +21,7 @@ public: void setStored(bool stored) { m_stored = toFlagValue(stored); } void setDefaultValue(const QString &value) { m_defaultValue = value; } void setRequired() { m_required = toFlagValue(true); } + bool setEnumNode(const QString &path, const QString ®isteredQmlName); [[nodiscard]] const QString &dataType() const { return m_type; } [[nodiscard]] const QString &defaultValue() const { return m_defaultValue; } @@ -46,6 +47,8 @@ public: return parent()->logicalModuleIdentifier(); } [[nodiscard]] QString element() const override { return parent()->name(); } + [[nodiscard]] const EnumNode *enumNode() const { return m_enumNode.first; } + [[nodiscard]] const QString &enumPrefix() const; void markDefault() override { m_isDefault = true; } void markReadOnly(bool flag) override { m_readOnly = toFlagValue(flag); } @@ -62,6 +65,7 @@ private: bool m_attached {}; FlagValue m_readOnly { FlagValueDefault }; FlagValue m_required { FlagValueDefault }; + std::pair<EnumNode *, QString> m_enumNode { nullptr, {} }; }; QT_END_NAMESPACE diff --git a/src/qdoc/qdoc/src/qdoc/qmlvisitor.cpp b/src/qdoc/qdoc/src/qdoc/qmlvisitor.cpp index 54f00f7b8..d6ecf1986 100644 --- a/src/qdoc/qdoc/src/qdoc/qmlvisitor.cpp +++ b/src/qdoc/qdoc/src/qdoc/qmlvisitor.cpp @@ -22,6 +22,8 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + /*! The constructor stores all the parameters in local data members. */ @@ -426,6 +428,14 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::SourceLocation, Node *node, Doc &d } } else if (command == COMMAND_QMLDEFAULT) { node->markDefault(); + } else if (command == COMMAND_QMLENUMERATORSFROM) { + if (!node->isQmlProperty()) { + doc.location().warning("Ignored '\\%1', applies only to '\\%2'"_L1 + .arg(command, COMMAND_QMLPROPERTY)); + } else if (!static_cast<QmlPropertyNode*>(node)->setEnumNode(args[0].first, args[0].second)) { + doc.location().warning("Failed to find C++ enumeration '%2' passed to \\%1"_L1 + .arg(command, args[0].first), "Use \\value commands instead"_L1); + } } else if (command == COMMAND_QMLREADONLY) { node->markReadOnly(1); } else if (command == COMMAND_QMLREQUIRED) { diff --git a/src/qdoc/qdoc/src/qdoc/tree.h b/src/qdoc/qdoc/src/qdoc/tree.h index 188746831..c7265b7b3 100644 --- a/src/qdoc/qdoc/src/qdoc/tree.h +++ b/src/qdoc/qdoc/src/qdoc/tree.h @@ -62,6 +62,9 @@ private: // Note the constructor and destructor are private. ~Tree(); public: // Of necessity, a few public functions remain. + [[nodiscard]] Node *findNodeByNameAndType(const QStringList &path, + bool (Node::*isMatch)() const) const; + [[nodiscard]] const QString &camelCaseModuleName() const { return m_camelCaseModuleName; } [[nodiscard]] const QString &physicalModuleName() const { return m_physicalModuleName; } [[nodiscard]] const QString &indexFileName() const { return m_indexFileName; } @@ -91,8 +94,6 @@ private: // The rest of the class is private. const Node *findNode(const QStringList &path, const Node *relative, int flags, Node::Genus genus) const; - [[nodiscard]] Node *findNodeByNameAndType(const QStringList &path, - bool (Node::*isMatch)() const) const; Aggregate *findRelatesNode(const QStringList &path); const Node *findEnumNode(const Node *node, const Node *aggregate, const QStringList &path, int offset) const; QString getRef(const QString &target, const Node *node) const; |