From aa20eefca427123e591ff05af452b3c0c4805589 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 25 May 2022 21:59:06 +0200 Subject: qdoc: Automatically resolve read-only attribute for QML properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QDoc had code for automatically resolving the writability of a QML property for properties that have an associated C++ property declaration. However, this code path was never executed as it was behind a conditional statement that always resolved to false. Enable the automatic resolution - note that in Qt, many QML types are nowadays implemented so that the C++ type is exposed to QML via a private class that modify/extend the public type listed in the documentation using the \instantiates command. Relations of these private implementations to QML types are not possible for QDoc to resolve; therefore this feature does not produce reliable results for all existing properties. To address this, turn the previous documentation warnings into a debug message; these can be used to find the properties for which auto-resolution fails; the \readonly command can be then inserted manually as needed, or the public \instantiates C++ type declaration can be amended with a QDOC_PROPERTY() macro. Fixes: QTBUG-103828 Change-Id: I41ff613650668aef336394582ccc6f2b860fe8e1 Reviewed-by: Topi Reiniƶ (cherry picked from commit 4be3d11129af9e26cd52b4a0b0c55c97f9a7b896) Reviewed-by: Qt Cherry-pick Bot --- src/qdoc/qmlpropertynode.cpp | 48 +++++++++------------- src/qdoc/qmltypenode.h | 2 - .../properties-docbook/testqdoc-testderived.xml | 12 ++++++ .../expected_output/properties/qml-thetype.html | 43 +++++++++++++++++++ .../expected_output/properties/testcpp.index | 4 ++ .../properties/testqdoc-testderived.html | 2 +- .../testdata/testcpp/properties.qdoc | 11 +++++ .../qdoc/generatedoutput/tst_generatedoutput.cpp | 1 + 8 files changed, 92 insertions(+), 31 deletions(-) create mode 100644 tests/auto/qdoc/generatedoutput/expected_output/properties/qml-thetype.html diff --git a/src/qdoc/qmlpropertynode.cpp b/src/qdoc/qmlpropertynode.cpp index 681b878b3..39e35512b 100644 --- a/src/qdoc/qmlpropertynode.cpp +++ b/src/qdoc/qmlpropertynode.cpp @@ -33,6 +33,7 @@ #include #include "qdocdatabase.h" +#include "utilities.h" QT_BEGIN_NAMESPACE @@ -53,15 +54,14 @@ QmlPropertyNode::QmlPropertyNode(Aggregate *parent, const QString &name, QString /*! Returns \c true if a QML property or attached property is - not read-only. The algorithm for figuring this out is long - amd tedious and almost certainly will break. It currently - doesn't work for the qmlproperty: + not 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. - \code - bool PropertyChanges::explicit, - \endcode - - ...because the tokenizer gets confused on \e{explicit}. + \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::isWritable() { @@ -69,26 +69,18 @@ bool QmlPropertyNode::isWritable() return !fromFlagValue(readOnly_, false); QmlTypeNode *qcn = qmlTypeNode(); - if (qcn) { - if (qcn->cppClassRequired()) { - if (qcn->classNode()) { - PropertyNode *pn = findCorrespondingCppProperty(); - if (pn) - return pn->isWritable(); - else - defLocation().warning( - QStringLiteral( - "No Q_PROPERTY for QML property %1::%2::%3 " - "in C++ class documented as QML type: " - "(property not found in the C++ class or its base classes)") - .arg(logicalModuleName(), qmlTypeName(), name())); - } else - defLocation().warning(QStringLiteral("No Q_PROPERTY for QML property %1::%2::%3 " - "in C++ class documented as QML type: " - "(C++ class not specified or not found).") - .arg(logicalModuleName(), qmlTypeName(), name())); - } - } + if (qcn && qcn->classNode()) { + PropertyNode *pn = findCorrespondingCppProperty(); + if (pn) + return pn->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.)"; +} return true; } diff --git a/src/qdoc/qmltypenode.h b/src/qdoc/qmltypenode.h index 612564dc4..60d34e35e 100644 --- a/src/qdoc/qmltypenode.h +++ b/src/qdoc/qmltypenode.h @@ -73,7 +73,6 @@ public: void setQmlBaseName(const QString &name) { m_qmlBaseName = name; } [[nodiscard]] QmlTypeNode *qmlBaseNode() const override { return m_qmlBaseNode; } void resolveInheritance(NodeMap &previousSearches); - [[nodiscard]] bool cppClassRequired() const { return m_classNodeRequired; } static void addInheritedBy(const Node *base, Node *sub); static void subclasses(const Node *base, NodeList &subs); static void terminate(); @@ -84,7 +83,6 @@ public: private: bool m_abstract { false }; - bool m_classNodeRequired { false }; bool m_wrapper { false }; ClassNode *m_classNode { nullptr }; QString m_qmlBaseName {}; diff --git a/tests/auto/qdoc/generatedoutput/expected_output/properties-docbook/testqdoc-testderived.xml b/tests/auto/qdoc/generatedoutput/expected_output/properties-docbook/testqdoc-testderived.xml index 260426726..22b176815 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/properties-docbook/testqdoc-testderived.xml +++ b/tests/auto/qdoc/generatedoutput/expected_output/properties-docbook/testqdoc-testderived.xml @@ -30,6 +30,18 @@ +Inherited By + + + + + +Instantiated By + +qml-thetype.xml + + + Inherits TestQDoc::Test diff --git a/tests/auto/qdoc/generatedoutput/expected_output/properties/qml-thetype.html b/tests/auto/qdoc/generatedoutput/expected_output/properties/qml-thetype.html new file mode 100644 index 000000000..f518fe2bb --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/expected_output/properties/qml-thetype.html @@ -0,0 +1,43 @@ + + + + + + TheType QML Type | TestCPP + + +
  • TheType
  • + +

    TheType QML Type

    +
    +
    Instantiates: TestDerived
    +

    Properties

    + + +

    Detailed Description

    + +

    Property Documentation

    + +
    +
    + + +

    +[read-only] name : string

    +

    Read-only status of this property is resolved from Q_PROPERTY.

    +
    +
    + + diff --git a/tests/auto/qdoc/generatedoutput/expected_output/properties/testcpp.index b/tests/auto/qdoc/generatedoutput/expected_output/properties/testcpp.index index 4a6de7b7d..8b1afc762 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/properties/testcpp.index +++ b/tests/auto/qdoc/generatedoutput/expected_output/properties/testcpp.index @@ -103,10 +103,14 @@ + + + + diff --git a/tests/auto/qdoc/generatedoutput/expected_output/properties/testqdoc-testderived.html b/tests/auto/qdoc/generatedoutput/expected_output/properties/testqdoc-testderived.html index 52997f234..689465a13 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/properties/testqdoc-testderived.html +++ b/tests/auto/qdoc/generatedoutput/expected_output/properties/testqdoc-testderived.html @@ -30,7 +30,7 @@
    Header: #include <TestDerived>
    CMake: find_package(Qt6 REQUIRED COMPONENTS QDocTest)
    -target_link_libraries(mytarget PRIVATE Qt6::QDocTest)
    qmake: QT += testcpp
    Inherits: TestQDoc::Test
    +target_link_libraries(mytarget PRIVATE Qt6::QDocTest) qmake: QT += testcpp Instantiated By: TheType Inherits: TestQDoc::Test
    • List of all members, including inherited members
    • Deprecated members
    • diff --git a/tests/auto/qdoc/generatedoutput/testdata/testcpp/properties.qdoc b/tests/auto/qdoc/generatedoutput/testdata/testcpp/properties.qdoc index 0ef6f4ea7..b097c03f5 100644 --- a/tests/auto/qdoc/generatedoutput/testdata/testcpp/properties.qdoc +++ b/tests/auto/qdoc/generatedoutput/testdata/testcpp/properties.qdoc @@ -56,6 +56,17 @@ \brief Something invokable. */ +/*! + \qmltype TheType + \instantiates TestQDoc::TestDerived + \inqmlmodule TheModule +*/ + +/*! + \qmlproperty string TheType::name + \brief Read-only status of this property is resolved from Q_PROPERTY. +*/ + /*! //! avoid link warnings for auto-generated links to QProperty \externalpage https://wiki.qt.io/QProperty diff --git a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp index c53c10acc..5fa03f486 100644 --- a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp +++ b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp @@ -529,6 +529,7 @@ void tst_generatedOutput::properties() testAndCompare("testdata/configs/properties.qdocconf", "properties/testqdoc-testderived.html " "properties/testqdoc-testderived-members.html " + "properties/qml-thetype.html " "properties/testcpp.index " "properties-docbook/testqdoc-testderived.xml", m_extraParams.toLatin1().data()); -- cgit v1.2.3