Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmltypesclassdescription.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5
9
10#include <QtCore/qcborarray.h>
11#include <QtCore/qcbormap.h>
13
14using namespace Constants;
15using namespace Constants::MetatypesDotJson;
17using namespace QAnyStringViewUtils;
18
20 QList<QTypeRevision> &extraVersions)
21{
22 const QCborArray &items = component->value(key).toArray();
23 for (const QCborValue &item : items) {
24 const QCborMap obj = item.toMap();
25 const auto revision = obj.find(S_REVISION);
26 if (revision != obj.end()) {
27 const auto extraVersion = QTypeRevision::fromEncodedVersion(revision.value().toInteger());
28 if (!extraVersions.contains(extraVersion))
29 extraVersions.append(extraVersion);
30 }
31 }
32}
33
35 const QVector<QCborMap> &types, const QVector<QCborMap> &foreign,
36 const QAnyStringView &name, const QList<QAnyStringView> &namespaces)
37{
38 const auto compare = [](const QCborMap &type, const QAnyStringView &typeName) {
40 };
41
42 const auto tryFindType = [&](QAnyStringView qualifiedName) -> const QCborMap * {
43 for (const QVector<QCborMap> &t : {types, foreign}) {
44 const auto it = std::lower_bound(t.begin(), t.end(), qualifiedName, compare);
45 if (it != t.end() && toStringView(*it, S_QUALIFIED_CLASS_NAME) == qualifiedName)
46 return &(*it);
47 }
48
49 return nullptr;
50 };
51
52 if (startsWith(name, QLatin1String("::")))
53 return tryFindType(name.mid(2));
54
55 QString qualified;
56 for (int i = 0, end = namespaces.length(); i != end; ++i) {
57 for (int j = 0; j < end - i; ++j) {
58 namespaces[j].visit([&](auto data) { qualified.append(data); });
59 qualified.append(QLatin1String("::"));
60 }
61 name.visit([&](auto data) { qualified.append(data); });
62 if (const QCborMap *found = tryFindType(qualified))
63 return found;
64
65 qualified.truncate(0);
66 }
67
68 return tryFindType(name);
69}
70
71void QmlTypesClassDescription::collectSuperClasses(
72 const QCborMap *classDef, const QVector<QCborMap> &types,
73 const QVector<QCborMap> &foreign, CollectMode mode, QTypeRevision defaultRevision)
74{
76 const auto supers = classDef->value(S_SUPER_CLASSES).toArray();
77 for (const QCborValue &superValue : supers) {
78 const QCborMap superObject = superValue.toMap();
79 if (toStringView(superObject, S_ACCESS) == S_PUBLIC) {
80 const QAnyStringView superName = toStringView(superObject, S_NAME);
81
82 const CollectMode superMode = (mode == TopLevel) ? SuperClass : RelatedType;
83 if (const QCborMap *other = findType(types, foreign, superName, namespaces)) {
84 collect(other, types, foreign, superMode, defaultRevision);
85 if (mode == TopLevel && superClass.isEmpty())
87 }
88
89 // If we cannot locate a type for it, there is no point in recording the superClass
90 }
91 }
92}
93
94void QmlTypesClassDescription::collectInterfaces(const QCborMap *classDef)
95{
96 if (classDef->contains(S_INTERFACES)) {
97 const QCborArray array = classDef->value(S_INTERFACES).toArray();
98 for (const QCborValue &value : array) {
99 auto object = value.toArray()[0].toMap();
101 }
102 }
103}
104
106 const QCborMap *classDef, const QVector<QCborMap> &types,
107 const QVector<QCborMap> &foreign, QTypeRevision defaultRevision)
108{
109 file = toStringView(*classDef, S_INPUT_FILE);
110
111 resolvedClass = classDef;
113
114 if (classDef->value(S_OBJECT).toBool())
116 else if (classDef->value(S_GADGET).toBool())
118 else
120
121 const auto classInfos = classDef->value(S_CLASS_INFOS).toArray();
122 for (const QCborValue &classInfo : classInfos) {
123 const QCborMap obj = classInfo.toMap();
128 }
129
130 collectInterfaces(classDef);
131 collectSuperClasses(classDef, types, foreign, TopLevel, defaultRevision);
132}
133
135 const QCborMap *classDef, const QVector<QCborMap> &types,
136 const QVector<QCborMap> &foreign, CollectMode mode, QTypeRevision defaultRevision)
137{
138 if (file.isEmpty())
139 file = toStringView(*classDef, S_INPUT_FILE);
140
141 const auto classInfos = classDef->value(S_CLASS_INFOS).toArray();
142 const QAnyStringView classDefName = toStringView(*classDef, S_CLASS_NAME);
143 const QList<QAnyStringView> namespaces = MetaTypesJsonProcessor::namespaces(*classDef);
144
145 QAnyStringView foreignTypeName;
146 bool isConstructible = false;
147 for (const QCborValue &classInfo : classInfos) {
148 const QCborMap obj = classInfo.toMap();
151
152 if (name == S_DEFAULT_PROPERTY) {
155 } else if (name == S_PARENT_PROPERTY) {
158 } else if (name == S_ADDED_IN_VERSION) {
160 if (mode == TopLevel) {
161 addedInRevision = revision;
162 revisions.append(revision);
163 } else if (!elementName.isEmpty()) {
164 revisions.append(revision);
165 }
166 }
167
168 if (mode != TopLevel)
169 continue;
170
171 // These only apply to the original class
172 if (name == S_ELEMENT) {
173 if (value == S_AUTO)
174 elementName = classDefName;
175 else if (value != S_ANONYMOUS)
177 } else if (name == S_REMOVED_IN_VERSION) {
179 } else if (name == S_CREATABLE) {
181 } else if (name == S_CREATION_METHOD) {
183 isConstructible = isStructured || (value == S_CONSTRUCT);
184 } else if (name == S_ATTACHED) {
185 if (const QCborMap *attached = collectRelated(
186 value, types, foreign, defaultRevision, namespaces)) {
188 }
189 } else if (name == S_EXTENDED) {
190 if (const QCborMap *extension = collectRelated(
191 value, types, foreign, defaultRevision, namespaces)) {
193 }
194 } else if (name == S_EXTENSION_IS_NAMESPACE) {
195 if (value == S_TRUE)
197 } else if (name == S_SEQUENCE) {
198 if (const QCborMap *element = collectRelated(
199 value, types, foreign, defaultRevision, namespaces)) {
201 }
202 } else if (name == S_SINGLETON) {
203 if (value == S_TRUE)
204 isSingleton = true;
205 } else if (name == S_FOREIGN) {
206 foreignTypeName = value;
207 } else if (name == S_OMIT_FROM_QML_TYPES) {
208 if (value == S_TRUE)
209 omitFromQmlTypes = true;
210 } else if (name == S_HAS_CUSTOM_PARSER) {
211 if (value == S_TRUE)
212 hasCustomParser = true;
213 } else if (name == S_DEFERRED_PROPERTY_NAMES) {
214 deferredNames = split(value, ',');
215 } else if (name == S_IMMEDIATE_PROPERTY_NAMES) {
216 immediateNames = split(value, ',');
217 }
218 }
219
220 // If the local type is a namespace the result can only be a namespace,
221 // no matter what the foreign type is.
222 const bool isNamespace = classDef->value(S_NAMESPACE).toBool();
223
224 if (!foreignTypeName.isEmpty()) {
225 // We can re-use a type with own QML.* macros as target of QML.Foreign
226 if (const QCborMap *other = findType(foreign, types, foreignTypeName, namespaces)) {
227 classDef = other;
228
229 // Default properties are always local.
230 defaultProp = {};
231
232 // Foreign type can have a default property or an attached types
233 const auto classInfos = classDef->value(S_CLASS_INFOS).toArray();
234 for (const QCborValue &classInfo : classInfos) {
235 const QCborMap obj = classInfo.toMap();
236 const QAnyStringView foreignName = toStringView(obj, S_NAME);
237 const QAnyStringView foreignValue = toStringView(obj, S_VALUE);
238 if (defaultProp.isEmpty() && foreignName == S_DEFAULT_PROPERTY) {
239 defaultProp = foreignValue;
240 } else if (parentProp.isEmpty() && foreignName == S_PARENT_PROPERTY) {
241 parentProp = foreignValue;
242 } else if (foreignName == S_ATTACHED) {
243 if (const QCborMap *attached = collectRelated(
244 foreignValue, types, foreign, defaultRevision, namespaces)) {
246 }
247 } else if (foreignName == S_EXTENDED) {
248 if (const QCborMap *extension = collectRelated(
249 foreignValue, types, foreign, defaultRevision, namespaces)) {
251 }
252 } else if (foreignName == S_EXTENSION_IS_NAMESPACE) {
253 if (foreignValue == S_TRUE)
255 } else if (foreignName == S_SEQUENCE) {
256 if (const QCborMap *element = collectRelated(
257 foreignValue, types, foreign, defaultRevision, namespaces)) {
259 }
260 }
261 }
262 } else {
263 className = foreignTypeName;
264 classDef = nullptr;
265 }
266 }
267
268 if (classDef) {
269 if (mode == RelatedType || !elementName.isEmpty()) {
274 }
275
276 collectSuperClasses(classDef, types, foreign, mode, defaultRevision);
277 }
278
279 if (mode != TopLevel)
280 return;
281
282 if (classDef)
283 collectInterfaces(classDef);
284
285 if (!addedInRevision.isValid()) {
286 revisions.append(defaultRevision);
287 addedInRevision = defaultRevision;
288 } else if (addedInRevision < defaultRevision) {
289 revisions.append(defaultRevision);
290 }
291
292 std::sort(revisions.begin(), revisions.end());
293 const auto end = std::unique(revisions.begin(), revisions.end());
295
296 resolvedClass = classDef;
297 if (className.isEmpty() && classDef)
299
300 if (!sequenceValueType.isEmpty()) {
301 isCreatable = false;
303 } else if (isNamespace) {
304 isCreatable = false;
306 } else if (classDef && classDef->value(S_OBJECT).toBool()) {
308 } else {
309 isCreatable = isConstructible;
310
311 if (!classDef) {
313 // If no classDef, we generally assume it's a value type defined by the
314 // foreign/extended trick.
316 } else {
317 // Objects and namespaces always have metaobjects and therefore classDefs.
318 // However, we may not be able to resolve the metaobject at compile time. See
319 // the "Invisible" test case. In that case, we must not assume anything about
320 // access semantics.
321
322 qWarning() << "Warning: Refusing to generate non-lowercase name"
323 << elementName.toString() << "for unknown foreign type";
324 elementName = {};
325
326 // Make it completely inaccessible.
327 // We cannot get enums from anonymous types after all.
329 }
330 } else if (classDef->value(S_GADGET).toBool()) {
332 } else {
334 }
335 }
336}
337
339 QAnyStringView related, const QVector<QCborMap> &types, const QVector<QCborMap> &foreign,
340 QTypeRevision defaultRevision, const QList<QAnyStringView> &namespaces)
341{
342 if (const QCborMap *other = findType(types, foreign, related, namespaces)) {
343 collect(other, types, foreign, RelatedType, defaultRevision);
344 return other;
345 }
346 return nullptr;
347}
348
static QList< QAnyStringView > namespaces(const QCborMap &classDef)
\inmodule QtCore
QString toString() const
Returns a deep copy of this string view's data as a QString.
Definition qstring.h:1071
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
constexpr QChar front() const
Returns the first character in the string view.
Definition qstring.h:116
\inmodule QtCore\reentrant
Definition qcborarray.h:20
\inmodule QtCore\reentrant
Definition qcbormap.h:21
QCborValue value(qint64 key) const
Returns the QCborValue element in this map that corresponds to key key, if there is one.
Definition qcbormap.h:169
bool contains(qint64 key) const
Returns true if this map contains a key-value pair identified by key key.
Definition qcbormap.h:214
\inmodule QtCore\reentrant
Definition qcborvalue.h:50
QCborArray toArray() const
bool toBool(bool defaultValue=false) const
Returns the boolean value stored in this QCborValue, if it is of a boolean type.
Definition qcborvalue.h:192
constexpr bool isLower() const noexcept
Returns true if the character is a lowercase letter, for example category() is Letter_Lowercase.
Definition qchar.h:474
Definition qlist.h:74
iterator erase(const_iterator begin, const_iterator end)
Definition qlist.h:882
iterator end()
Definition qlist.h:609
qsizetype length() const noexcept
Definition qlist.h:388
iterator begin()
Definition qlist.h:608
void append(parameter_type t)
Definition qlist.h:441
const_iterator constEnd() const noexcept
Definition qlist.h:616
iterator end()
Definition qset.h:140
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
void truncate(qsizetype pos)
Truncates the string at the given position index.
Definition qstring.cpp:6159
QString & append(QChar c)
Definition qstring.cpp:3227
\inmodule QtCore
static constexpr QTypeRevision fromEncodedVersion(Integer value)
Produces a QTypeRevision from the given value.
constexpr bool isValid() const
Returns true if the major version or the minor version is known, otherwise false.
void extension()
[6]
Definition dialogs.cpp:230
QSet< QString >::iterator it
static constexpr QLatin1StringView S_REFERENCE
static constexpr QLatin1StringView S_VALUE
static constexpr QLatin1StringView S_NONE
static constexpr QLatin1StringView S_SEQUENCE
static constexpr QLatin1StringView S_ATTACHED
static constexpr QLatin1StringView S_FOREIGN
static constexpr QLatin1StringView S_SEQUENCE
static constexpr QLatin1StringView S_EXTENDED
static constexpr QLatin1StringView S_SINGLETON
static constexpr QLatin1StringView S_HAS_CUSTOM_PARSER
static constexpr QLatin1StringView S_EXTENSION_IS_NAMESPACE
static constexpr QLatin1StringView S_REMOVED_IN_VERSION
static constexpr QLatin1StringView S_ELEMENT
static constexpr QLatin1StringView S_CREATION_METHOD
static constexpr QLatin1StringView S_OMIT_FROM_QML_TYPES
static constexpr QLatin1StringView S_ADDED_IN_VERSION
static constexpr QLatin1StringView S_CREATABLE
static constexpr QLatin1StringView S_VALUE
static constexpr QLatin1StringView S_ANONYMOUS
static constexpr QLatin1StringView S_SIGNALS
static constexpr QLatin1StringView S_QUALIFIED_CLASS_NAME
static constexpr QLatin1StringView S_NAME
static constexpr QLatin1StringView S_SUPER_CLASSES
static constexpr QLatin1StringView S_DEFERRED_PROPERTY_NAMES
static constexpr QLatin1StringView S_INPUT_FILE
static constexpr QLatin1StringView S_STRUCTURED
static constexpr QLatin1StringView S_TRUE
static constexpr QLatin1StringView S_PARENT_PROPERTY
static constexpr QLatin1StringView S_ACCESS
static constexpr QLatin1StringView S_CLASS_NAME
static constexpr QLatin1StringView S_CLASS_INFOS
static constexpr QLatin1StringView S_REVISION
static constexpr QLatin1StringView S_PUBLIC
static constexpr QLatin1StringView S_SLOTS
static constexpr QLatin1StringView S_PROPERTIES
static constexpr QLatin1StringView S_DEFAULT_PROPERTY
static constexpr QLatin1StringView S_FALSE
static constexpr QLatin1StringView S_GADGET
static constexpr QLatin1StringView S_IMMEDIATE_PROPERTY_NAMES
static constexpr QLatin1StringView S_METHODS
static constexpr QLatin1StringView S_CONSTRUCT
static constexpr QLatin1StringView S_INTERFACES
static constexpr QLatin1StringView S_AUTO
static constexpr QLatin1StringView S_NAMESPACE
static constexpr QLatin1StringView S_OBJECT
bool startsWith(QAnyStringView whole, QAnyStringView part)
QAnyStringView toStringView(const QCborValue &value)
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:162
const char * typeName
GLenum mode
GLuint64 key
GLuint GLuint end
GLsizei GLenum GLenum * types
GLenum type
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
GLhandleARB obj
[2]
GLenum array
GLdouble GLdouble t
Definition qopenglext.h:243
static qreal component(const QPointF &point, unsigned int i)
static void collectExtraVersions(const QCborMap *component, QLatin1StringView key, QList< QTypeRevision > &extraVersions)
static void split(QT_FT_Vector *b)
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
static int compare(quint64 a, quint64 b)
static int toInt(const QChar &qc, int R)
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
QList< QTreeWidgetItem * > items
bool contains(const AT &t) const noexcept
Definition qlist.h:44
void collectLocalAnonymous(const QCborMap *classDef, const QVector< QCborMap > &types, const QVector< QCborMap > &foreign, QTypeRevision defaultRevision)
QList< QAnyStringView > implementsInterfaces
QList< QAnyStringView > immediateNames
void collect(const QCborMap *classDef, const QVector< QCborMap > &types, const QVector< QCborMap > &foreign, CollectMode mode, QTypeRevision defaultRevision)
const QCborMap * collectRelated(QAnyStringView related, const QVector< QCborMap > &types, const QVector< QCborMap > &foreign, QTypeRevision defaultRevision, const QList< QAnyStringView > &namespaces)
QList< QAnyStringView > deferredNames
static const QCborMap * findType(const QVector< QCborMap > &types, const QVector< QCborMap > &foreign, const QAnyStringView &name, const QList< QAnyStringView > &namespaces)