summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTopi Reinio <topi.reinio@qt.io>2022-05-25 21:59:06 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-06-13 09:52:47 +0000
commitaa20eefca427123e591ff05af452b3c0c4805589 (patch)
treec0039111574911426808e9606907eec36f682272
parent7b52506eb739536867655692cc247fa9ac45cef7 (diff)
qdoc: Automatically resolve read-only attribute for QML properties
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ƶ <topi.reinio@qt.io> (cherry picked from commit 4be3d11129af9e26cd52b4a0b0c55c97f9a7b896) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/qdoc/qmlpropertynode.cpp48
-rw-r--r--src/qdoc/qmltypenode.h2
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/properties-docbook/testqdoc-testderived.xml12
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/properties/qml-thetype.html43
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/properties/testcpp.index4
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/properties/testqdoc-testderived.html2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/testcpp/properties.qdoc11
-rw-r--r--tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp1
8 files changed, 92 insertions, 31 deletions
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 <utility>
#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 @@
</db:listitem>
</db:varlistentry>
<db:varlistentry>
+<db:term>Inherited By</db:term>
+<db:listitem>
+<db:para/>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
+<db:term>Instantiated By</db:term>
+<db:listitem>
+<db:para>qml-thetype.xml</db:para>
+</db:listitem>
+</db:varlistentry>
+<db:varlistentry>
<db:term>Inherits</db:term>
<db:listitem>
<db:para><db:link xlink:href="testqdoc-test.xml" xlink:role="class">TestQDoc::Test</db:link></db:para>
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 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- properties.qdoc -->
+ <title>TheType QML Type | TestCPP</title>
+</head>
+<body>
+<li>TheType</li>
+<div class="sidebar">
+<div class="toc">
+<h3 id="toc">Contents</h3>
+<ul>
+<li class="level1"><a href="#properties">Properties</a></li>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">TheType QML Type</h1>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Instantiates:</td><td class="memItemRight bottomAlign"> <a href="testqdoc-testderived.html">TestDerived</a></td></tr></table></div><ul>
+<li><a href="qml-thetype-members.html">List of all members, including inherited members</a></li>
+</ul>
+<h2 id="properties">Properties</h2>
+<ul>
+<li class="fn"><b><a href="qml-thetype.html#name-prop">name</a></b> : string</li>
+</ul>
+<!-- $$$TheType-description -->
+<h2 id="details">Detailed Description</h2>
+<!-- @@@TheType -->
+<h2>Property Documentation</h2>
+<!-- $$$name -->
+<div class="qmlitem"><div class="qmlproto">
+<div class="table"><table class="qmlname">
+<tr valign="top" class="odd" id="name-prop">
+<td class="tblQmlPropNode"><p>
+<span class="qmlextra">[read-only] </span><span class="name">name</span> : <span class="type">string</span></p></td></tr>
+</table></div></div>
+<div class="qmldoc"><p>Read-only status of this property is resolved from Q_PROPERTY.</p>
+</div></div><!-- @@@name -->
+<br/>
+</body>
+</html>
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 @@
</property>
</class>
</namespace>
+ <qmlclass name="TheType" qml-module-name="TheType" href="qml-thetype.html" status="active" access="public" location="properties.qdoc" documented="true" title="TheType" fulltitle="TheType" subtitle="">
+ <qmlproperty name="name" fullname="TheType::name" href="qml-thetype.html#name-prop" status="active" access="public" location="properties.qdoc" documented="true" type="string" attached="false" writable="false" brief="Read-only status of this property is resolved from Q_PROPERTY"/>
+ </qmlclass>
<group name="testgroup" href="testgroup.html" status="internal" seen="false" title=""/>
<module name="TestCPP" href="testcpp-module.html" status="active" documented="true" seen="true" title="QDoc Test C++ Classes" brief="A test module page">
<contents name="linking-to-function-like-things" title="Linking to function-like things" level="1"/>
<contents name="section" title="section()" level="2"/>
</module>
+ <qmlmodule name="TheModule" qml-module-name="TheModule" href="themodule-qmlmodule.html" status="internal" seen="false" title=""/>
</namespace>
</INDEX>
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 @@
<div class="table"><table class="alignedsummary">
<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;TestDerived&gt;</span>
</td></tr><tr><td class="memItemLeft rightAlign topAlign"> CMake:</td><td class="memItemRight bottomAlign"> find_package(Qt6 REQUIRED COMPONENTS QDocTest) <br/>
-target_link_libraries(mytarget PRIVATE Qt6::QDocTest)</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr><tr><td class="memItemLeft rightAlign topAlign"> Inherits:</td><td class="memItemRight bottomAlign"> <a href="testqdoc-test.html">TestQDoc::Test</a></td></tr></table></div>
+target_link_libraries(mytarget PRIVATE Qt6::QDocTest)</td></tr><tr><td class="memItemLeft rightAlign topAlign"> qmake:</td><td class="memItemRight bottomAlign"> QT += testcpp</td></tr><tr><td class="memItemLeft rightAlign topAlign"> Instantiated By:</td><td class="memItemRight bottomAlign"> <a href="qml-thetype.html">TheType</a></td></tr><tr><td class="memItemLeft rightAlign topAlign"> Inherits:</td><td class="memItemRight bottomAlign"> <a href="testqdoc-test.html">TestQDoc::Test</a></td></tr></table></div>
<ul>
<li><a href="testqdoc-testderived-members.html">List of all members, including inherited members</a></li>
<li><a href="testqdoc-testderived-obsolete.html">Deprecated members</a></li>
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
@@ -57,6 +57,17 @@
*/
/*!
+ \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
\title 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());