diff options
Diffstat (limited to 'src/qdoc/qdoc/src/qdoc/qmlpropertynode.cpp')
-rw-r--r-- | src/qdoc/qdoc/src/qdoc/qmlpropertynode.cpp | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/qdoc/qdoc/src/qdoc/qmlpropertynode.cpp b/src/qdoc/qdoc/src/qdoc/qmlpropertynode.cpp new file mode 100644 index 000000000..335b7d870 --- /dev/null +++ b/src/qdoc/qdoc/src/qdoc/qmlpropertynode.cpp @@ -0,0 +1,175 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "qmlpropertynode.h" + +#include "classnode.h" +#include "propertynode.h" +#include "enumnode.h" + +#include <utility> +#include "qdocdatabase.h" +#include "utilities.h" + +QT_BEGIN_NAMESPACE + +/*! + Constructor for the QML property node. + */ +QmlPropertyNode::QmlPropertyNode(Aggregate *parent, const QString &name, QString type, + bool attached) + : Node(QmlProperty, parent, name), + m_type(std::move(type)), + m_attached(attached) +{ + if (m_type == "alias") + m_isAlias = true; + if (name.startsWith("__")) + setStatus(Internal); +} + +/*! + \fn bool QmlPropertyNode::isReadOnly() const + + Returns \c true if this QML property node is marked as a + read-only property. +*/ + +/*! + \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 + from the associated C++ class instantiated by the QML type + that this property belongs to. + + \note Depending on how the QML type is implemented, this + information may not be available to QDoc. If so, add a debug + line but do not treat it as a warning. + */ +bool QmlPropertyNode::isReadOnly() +{ + if (m_readOnly != FlagValueDefault) + return fromFlagValue(m_readOnly, false); + + // Find the parent QML type node + auto *parent{this->parent()}; + while (parent && !(parent->isQmlType())) + parent = parent->parent(); + + bool readonly{false}; + if (auto qcn = static_cast<QmlTypeNode *>(parent); qcn && qcn->classNode()) { + if (auto propertyNode = findCorrespondingCppProperty(); propertyNode) + readonly = !propertyNode->isWritable(); + else + qCDebug(lcQdoc).nospace() + << qPrintable(defLocation().toString()) + << ": Automatic resolution of QML property attributes failed for " + << name() + << " (Q_PROPERTY not found in the C++ class hierarchy known to QDoc. " + << "Likely, the type is replaced with a private implementation.)"; + } + markReadOnly(readonly); + return readonly; +} + +/*! + Returns \c true if this QML property is marked with \required or the + corresponding C++ property uses the REQUIRED keyword. +*/ +bool QmlPropertyNode::isRequired() +{ + if (m_required != FlagValueDefault) + return fromFlagValue(m_required, false); + + PropertyNode *pn = findCorrespondingCppProperty(); + return pn != nullptr && pn->isRequired(); +} + +/*! + Returns a pointer this QML property's corresponding C++ + property, if it has one. + */ +PropertyNode *QmlPropertyNode::findCorrespondingCppProperty() +{ + PropertyNode *pn; + Node *n = parent(); + while (n && !(n->isQmlType())) + n = n->parent(); + if (n) { + auto *qcn = static_cast<QmlTypeNode *>(n); + ClassNode *cn = qcn->classNode(); + if (cn) { + /* + If there is a dot in the property name, first + find the C++ property corresponding to the QML + property group. + */ + QStringList dotSplit = name().split(QChar('.')); + pn = cn->findPropertyNode(dotSplit[0]); + if (pn) { + /* + Now find the C++ property corresponding to + the QML property in the QML property group, + <group>.<property>. + */ + if (dotSplit.size() > 1) { + QStringList path(extractClassName(pn->qualifiedDataType())); + Node *nn = QDocDatabase::qdocDB()->findClassNode(path); + if (nn) { + auto *cn = static_cast<ClassNode *>(nn); + PropertyNode *pn2 = cn->findPropertyNode(dotSplit[1]); + /* + If found, return the C++ property + corresponding to the QML property. + Otherwise, return the C++ property + corresponding to the QML property + group. + */ + return (pn2 ? pn2 : pn); + } + } else + return pn; + } + } + } + return nullptr; +} + +QT_END_NAMESPACE |