Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qmlpropertynode.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5
6#include "classnode.h"
7#include "enumnode.h"
8#include "genustypes.h"
9#include "propertynode.h"
10#include "qdocdatabase.h"
11#include "utilities.h"
12
13#include <utility>
14
15
17
18using namespace Qt::StringLiterals;
19
20/*!
21 Constructor for the QML property node.
22 */
23QmlPropertyNode::QmlPropertyNode(Aggregate *parent, const QString &name, QString type,
24 bool attached)
25 : Node(NodeType::QmlProperty, parent, name),
27 m_attached(attached)
28{
29 if (m_type == "alias")
30 m_isAlias = true;
31 if (name.startsWith("__"))
33 // Set the default prefix for enumerators
34 m_nativeEnum.setPrefix(parent->name());
35}
36
37/*!
38 Sets the data type of this property to \a dataType,
39 preserving the list property modifier if one is set
40 already.
41*/
42void QmlPropertyNode::setDataType(const QString &dataType)
43{
44 m_type = dataType;
45 // Re-apply list modifier if needed
46 if (auto is_list = m_isList; is_list == FlagValueTrue) {
47 m_isList = FlagValueDefault;
48 setIsList(true);
49 }
50}
51
52/*!
53 \fn bool QmlPropertyNode::isReadOnly() const
54
55 Returns \c true if this QML property node is marked as a
56 read-only property.
57*/
58
59/*!
60 Marks this property as a list if \a isList is \c true.
61 The \c m_type member of a list property is wrapped with
62 \c {list<>}.
63*/
64void QmlPropertyNode::setIsList(bool isList)
65{
66 if (m_isList != FlagValueDefault)
67 return;
68
69 if ((m_isList = toFlagValue(isList)))
70 m_type = "list<%1>"_L1.arg(m_type);
71}
72
73/*!
74 Returns \c true if this QML property or attached property is
75 read-only. If the read-only status is not set explicitly
76 using the \\readonly command, QDoc attempts to resolve it
77 from the associated C++ class instantiated by the QML type
78 that this property belongs to.
79
80 \note Depending on how the QML type is implemented, this
81 information may not be available to QDoc. If so, add a debug
82 line but do not treat it as a warning.
83 */
85{
86 if (m_readOnly != FlagValueDefault)
87 return fromFlagValue(m_readOnly, false);
88
89 // Find the parent QML type node
90 auto *parent{this->parent()};
91 while (parent && !(parent->isQmlType()))
92 parent = parent->parent();
93
94 bool readonly{false};
95 if (auto qcn = static_cast<QmlTypeNode *>(parent); qcn && qcn->classNode()) {
96 if (auto propertyNode = findCorrespondingCppProperty(); propertyNode)
97 readonly = !propertyNode->isWritable();
98 else
99 qCDebug(lcQdoc).nospace()
100 << qPrintable(defLocation().toString())
101 << ": Automatic resolution of QML property attributes failed for "
102 << name()
103 << " (Q_PROPERTY not found in the C++ class hierarchy known to QDoc. "
104 << "Likely, the type is replaced with a private implementation.)";
105 }
106 markReadOnly(readonly);
107 return readonly;
108}
109
110/*!
111 Returns \c true if this QML property is marked with \required or the
112 corresponding C++ property uses the REQUIRED keyword.
113*/
115{
116 if (m_required != FlagValueDefault)
117 return fromFlagValue(m_required, false);
118
119 PropertyNode *pn = findCorrespondingCppProperty();
120 return pn != nullptr && pn->isRequired();
121}
122
123/*!
124 Returns a pointer this QML property's corresponding C++
125 property, if it has one.
126 */
127PropertyNode *QmlPropertyNode::findCorrespondingCppProperty()
128{
129 PropertyNode *pn;
130 Node *n = parent();
131 while (n && !(n->isQmlType()))
132 n = n->parent();
133 if (n) {
134 auto *qcn = static_cast<QmlTypeNode *>(n);
135 ClassNode *cn = qcn->classNode();
136 if (cn) {
137 /*
138 If there is a dot in the property name, first
139 find the C++ property corresponding to the QML
140 property group.
141 */
142 QStringList dotSplit = name().split(QChar('.'));
143 pn = cn->findPropertyNode(dotSplit[0]);
144 if (pn) {
145 /*
146 Now find the C++ property corresponding to
147 the QML property in the QML property group,
148 <group>.<property>.
149 */
150 if (dotSplit.size() > 1) {
151 QStringList path(extractClassName(pn->qualifiedDataType()));
152 Node *nn = QDocDatabase::qdocDB()->findClassNode(path);
153 if (nn) {
154 auto *cn = static_cast<ClassNode *>(nn);
155 PropertyNode *pn2 = cn->findPropertyNode(dotSplit[1]);
156 /*
157 If found, return the C++ property
158 corresponding to the QML property.
159 Otherwise, return the C++ property
160 corresponding to the QML property
161 group.
162 */
163 return (pn2 ? pn2 : pn);
164 }
165 } else
166 return pn;
167 }
168 }
169 }
170 return nullptr;
171}
172
173// Only define a mapping between C++ and QML value types with different names.
174QSet<QString> QmlPropertyNode::cppQmlValueTypes = {
175 "float",
176 "QColor",
177 "QDateTime",
178 "QFont",
179 "QMatrix4x4",
180 "QPoint",
181 "QPointF",
182 "QQuaternion",
183 "qreal",
184 "QRect",
185 "QRectF",
186 "QSize",
187 "QSizeF",
188 "QString",
189 "QUrl",
190 "QVector2D",
191 "QVector3D",
192 "QVector4D",
193 "unsigned int",
194};
195
196QRegularExpression QmlPropertyNode::qmlBasicList("^list<([^>]+)>$");
197QRegularExpression QmlPropertyNode::cppBasicList("^(Q[A-Za-z0-9]+)List$");
198
199/*!
200 Validates a QML property type for the property, returning true if the type
201 is a QML type or QML list type, returning false if the type is a Qt value
202 type or Qt list type.
203
204 Specifically, if the type name matches a known value or object type in
205 qdoc's database, true is returned immediately.
206
207 If the type name matches the syntax for a non-nested QML list of types,
208 true is returned if the item type of the list is valid; otherwise false is
209 returned.
210
211 If the type name is a C or C++ type with a corresponding QML type, or if it
212 matches the syntax of a Qt list type, such as QStringList, false is
213 returned.
214
215 If none of the above applied, the type name is assumed to be valid and true
216 is returned.
217*/
218bool QmlPropertyNode::validateDataType(const QString &type) const
219{
220 QString qmlType = type;
221 if (qmlType.isNull())
222 qmlType = dataType();
223
224 if (QDocDatabase::qdocDB()->getQmlValueTypes().contains(qmlType) ||
225 QDocDatabase::qdocDB()->findQmlType(qmlType))
226 return true;
227
228 auto match = qmlBasicList.match(qmlType);
229 if (match.hasMatch())
230 return validateDataType(match.captured(1));
231
232 if (cppQmlValueTypes.contains(qmlType) ||
233 cppBasicList.match(qmlType).hasMatch())
234 return false;
235
236 return true;
237}
238
239QT_END_NAMESPACE
The ClassNode represents a C++ class.
Definition classnode.h:21
This class describes one instance of using the Q_PROPERTY macro.
bool isRequired() const
bool isWritable() const
This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a...
static QDocDatabase * qdocDB()
Creates the singleton.
NodeMultiMap & getQmlValueTypes()
Returns a reference to the map of QML basic types.
void markReadOnly(bool flag) override
If this node is a QmlPropertyNode, then the property's read-only flag is set to flag.
bool isRequired()
Returns true if this QML property is marked with \required or the corresponding C++ property uses the...
void setIsList(bool isList)
Marks this property as a list if isList is true.
void setDataType(const QString &dataType) override
Sets the data type of this property to dataType, preserving the list property modifier if one is set ...
QmlPropertyNode(Aggregate *parent, const QString &name, QString type, bool attached)
Constructor for the QML property node.
bool isReadOnly()
Returns true if this QML property or attached property is read-only.
bool validateDataType(const QString &type=QString()) const
Validates a QML property type for the property, returning true if the type is a QML type or QML list ...
NodeType
Definition genustypes.h:150
The Node class is the base class for all the nodes in QDoc's parse tree.
bool isQmlType() const
Returns true if the node type is QmlType or QmlValueType.
Definition node.h:128
Aggregate * parent() const
Returns the node's parent pointer.
Definition node.h:215
static bool fromFlagValue(FlagValue fv, bool defaultValue)
Converts the enum fv back to a boolean value.
Definition node.cpp:701
@ FlagValueDefault
Definition node.h:82
@ FlagValueTrue
Definition node.h:82
void setStatus(Status t)
Sets the node's status to t.
Definition node.cpp:510
@ Internal
Definition node.h:61