Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qqmltype_p_p.h
Go to the documentation of this file.
1
// Copyright (C) 2019 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant
4
5
#
ifndef
QQMLTYPE_P_P_H
6
#
define
QQMLTYPE_P_P_H
7
8
//
9
// W A R N I N G
10
// -------------
11
//
12
// This file is not part of the Qt API. It exists purely as an
13
// implementation detail. This header file may change from version to
14
// version without notice, or even be removed.
15
//
16
// We mean it.
17
//
18
19
#
include
<
private
/
qqmlengine_p
.
h
>
20
#
include
<
private
/
qqmlmetatype_p
.
h
>
21
#
include
<
private
/
qqmlpropertycache_p
.
h
>
22
#
include
<
private
/
qqmlproxymetaobject_p
.
h
>
23
#
include
<
private
/
qqmlrefcount_p
.
h
>
24
#
include
<
private
/
qqmltype_p
.
h
>
25
#
include
<
private
/
qqmltypeloader_p
.
h
>
26
#
include
<
private
/
qstringhash_p
.
h
>
27
#
include
<
private
/
qv4engine_p
.
h
>
28
#
include
<
private
/
qv4executablecompilationunit_p
.
h
>
29
#
include
<
private
/
qv4resolvedtypereference_p
.
h
>
30
31
#
include
<
QAtomicInteger
>
32
#
include
<
QtCore
/
qtyperevision
.
h
>
33
34
QT_BEGIN_NAMESPACE
35
36
class
QQmlTypePrivate final :
public
QQmlRefCounted<QQmlTypePrivate>
37
{
38
Q_DISABLE_COPY_MOVE(QQmlTypePrivate)
39
public
:
40
struct
ProxyMetaObjects
41
{
42
~ProxyMetaObjects()
43
{
44
for
(
const
QQmlProxyMetaObject::ProxyData &metaObject : std::as_const(data))
45
free(metaObject.metaObject);
46
}
47
48
QList<QQmlProxyMetaObject::ProxyData> data;
49
bool
containsRevisionedAttributes =
false
;
50
};
51
52
struct
Enums
53
{
54
enum
Scoping { Scoped, Unscoped };
55
~Enums()
56
{
57
qDeleteAll(scopedEnums);
58
qDeleteAll(unscopedEnums);
59
}
60
61
QStringHash<
int
> enums;
62
QStringHash<
int
> scopedEnumIndex;
// maps from enum name to index in scopedEnums
63
QStringHash<
int
> unscopedEnumIndex;
// maps from enum name to index in unscopedEnums
64
QList<QStringHash<
int
> *> scopedEnums;
65
QList<QStringHash<
int
> *> unscopedEnums;
66
};
67
68
QQmlTypePrivate(QQmlType::RegistrationType type);
69
70
const
ProxyMetaObjects *init()
const
;
71
72
QUrl sourceUrl()
const
73
{
74
switch
(regType) {
75
case
QQmlType::CompositeType:
76
return
extraData.compositeTypeData;
77
case
QQmlType::CompositeSingletonType:
78
return
extraData.singletonTypeData->singletonInstanceInfo->url;
79
case
QQmlType::InlineComponentType:
80
return
extraData.inlineComponentTypeData;
81
case
QQmlType::JavaScriptType:
82
return
extraData.javaScriptTypeData;
83
default
:
84
return
QUrl();
85
}
86
}
87
88
const
QQmlTypePrivate *attachedPropertiesBase(QQmlTypeLoader *typeLoader)
const
89
{
90
for
(
const
QQmlTypePrivate *d =
this
; d;
91
d = d->resolveCompositeBaseType(typeLoader).d.data()) {
92
if
(d->regType == QQmlType::CppType)
93
return
d->extraData.cppTypeData->attachedPropertiesType ? d :
nullptr
;
94
95
if
(d->regType != QQmlType::CompositeType)
96
return
nullptr
;
97
}
98
return
nullptr
;
99
}
100
101
bool
isComposite()
const
102
{
103
switch
(regType) {
104
case
QQmlType::CompositeType:
105
case
QQmlType::CompositeSingletonType:
106
case
QQmlType::InlineComponentType:
107
return
true
;
108
default
:
109
break
;
110
}
111
112
return
false
;
113
}
114
115
bool
isValueType()
const
116
{
117
return
regType == QQmlType::CppType && !(typeId.flags() & QMetaType::PointerToQObject);
118
}
119
120
QQmlType resolveCompositeBaseType(QQmlTypeLoader *typeLoader)
const
;
121
QQmlPropertyCache::ConstPtr compositePropertyCache(QQmlTypeLoader *typeLoader)
const
;
122
123
struct
QQmlCppTypeData
124
{
125
int
allocationSize;
126
void
(*newFunc)(
void
*,
void
*);
127
void
*userdata =
nullptr
;
128
QString noCreationReason;
129
QVariant (*createValueTypeFunc)(
const
QJSValue &);
130
int
parserStatusCast;
131
QObject *(*extFunc)(QObject *);
132
const
QMetaObject *extMetaObject;
133
QQmlCustomParser *customParser;
134
QQmlAttachedPropertiesFunc attachedPropertiesFunc;
135
const
QMetaObject *attachedPropertiesType;
136
int
propertyValueSourceCast;
137
int
propertyValueInterceptorCast;
138
int
finalizerCast;
139
bool
registerEnumClassesUnscoped;
140
bool
registerEnumsFromRelatedTypes;
141
bool
constructValueType;
142
bool
populateValueType;
143
};
144
145
struct
QQmlSingletonTypeData
146
{
147
QQmlType::SingletonInstanceInfo::ConstPtr singletonInstanceInfo;
148
QObject *(*extFunc)(QObject *);
149
const
QMetaObject *extMetaObject;
150
};
151
152
int
index = -1;
153
154
union
extraData {
155
extraData() {}
// QQmlTypePrivate() does the actual construction.
156
~extraData() {}
// ~QQmlTypePrivate() does the actual destruction.
157
158
QQmlCppTypeData *cppTypeData;
159
QQmlSingletonTypeData *singletonTypeData;
160
QUrl compositeTypeData;
161
QUrl javaScriptTypeData;
162
QUrl inlineComponentTypeData;
163
QMetaSequence sequentialContainerTypeData;
164
const
char
*interfaceTypeData;
165
} extraData;
166
static_assert
(
sizeof
(extraData) ==
sizeof
(
void
*));
167
168
QHashedString module;
169
QString name;
170
QString elementName;
171
QMetaType typeId;
172
QMetaType listId;
173
QQmlType::RegistrationType regType;
174
QTypeRevision version;
175
QTypeRevision revision = QTypeRevision::zero();
176
const
QMetaObject *baseMetaObject =
nullptr
;
177
178
void
setName(
const
QString &uri,
const
QString &element);
179
180
template
<
typename
String>
181
static
int
enumValue(
182
const
QQmlRefPointer<
const
QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
183
const
String &name,
bool
*ok)
184
{
185
const
auto
*rv = doGetEnumOp<
const
int
*>(
186
d, typeLoader, [&](
const
QQmlTypePrivate::Enums *enums) {
187
return
enums->enums.value(name);
188
}, [](
const
int
*p) {
return
!!p; }, ok);
189
return
rv ? *rv : -1;
190
}
191
192
template
<Enums::Scoping scoping,
typename
String>
193
static
int
enumIndex(
194
const
QQmlRefPointer<
const
QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
195
const
String &name,
bool
*ok)
196
{
197
const
auto
*rv = doGetEnumOp<
const
int
*> (
198
d, typeLoader, [&](
const
QQmlTypePrivate::Enums *enums) {
199
if
constexpr
(scoping == Enums::Scoped)
200
return
enums->scopedEnumIndex.value(name);
201
else
202
return
enums->unscopedEnumIndex.value(name);
203
}, [](
const
int
*p) {
return
!!p; }, ok);
204
return
rv ? *rv : -1;
205
}
206
207
template
<Enums::Scoping scoping,
typename
String>
208
static
int
enumValue(
209
const
QQmlRefPointer<
const
QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
int
index,
210
const
String &name,
bool
*ok)
211
{
212
const
auto
*rv = doGetEnumOp<
const
int
*>(
213
d, typeLoader, [&](
const
QQmlTypePrivate::Enums *enums) {
214
if
constexpr
(scoping == Enums::Scoped) {
215
Q_ASSERT(index > -1 && index < enums->scopedEnums.size());
216
return
enums->scopedEnums.at(index)->value(name);
217
}
else
{
218
Q_ASSERT(index > -1 && index < enums->unscopedEnums.size());
219
return
enums->unscopedEnums.at(index)->value(name);
220
}
221
}, [](
const
int
*p) {
return
!!p; }, ok);
222
return
rv ? *rv : -1;
223
}
224
225
template
<Enums::Scoping scoping,
typename
String1,
typename
String2>
226
static
int
enumValue(
227
const
QQmlRefPointer<
const
QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
228
const
String1 &scopedEnumName,
const
String2 &name,
bool
*ok)
229
{
230
const
auto
*rv = doGetEnumOp<
const
int
*>(
231
d, typeLoader, [&](
const
QQmlTypePrivate::Enums *enums) {
232
const
QStringHash<
int
> *enumIndex;
233
const
QList<QStringHash<
int
> *> *_enums;
234
if
constexpr
(scoping == Enums::Scoped) {
235
enumIndex = &enums->scopedEnumIndex;
236
_enums = &enums->scopedEnums;
237
}
else
{
238
enumIndex = &enums->unscopedEnumIndex;
239
_enums = &enums->unscopedEnums;
240
}
241
242
const
int
*rv = enumIndex->value(scopedEnumName);
243
if
(!rv)
244
return
static_cast
<
int
*>(
nullptr
);
245
246
const
int
index = *rv;
247
Q_ASSERT(index > -1 && index < _enums->size());
248
return
_enums->at(index)->value(name);
249
}, [](
const
int
*p) {
return
!!p; }, ok);
250
return
rv ? *rv : -1;
251
}
252
253
template
<Enums::Scoping scoping>
254
static
QString enumKey(
255
const
QQmlRefPointer<
const
QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
256
int
index,
int
value,
bool
*ok)
257
{
258
return
doGetEnumOp<QString>(d, typeLoader, [&](
const
QQmlTypePrivate::Enums *enums) {
259
const
QList<QStringHash<
int
> *> *_enums;
260
if
constexpr
(scoping == Enums::Scoped)
261
_enums = &enums->scopedEnums;
262
else
263
_enums = &enums->unscopedEnums;
264
265
Q_ASSERT(index > -1 && index < _enums->size());
266
const
auto
hash = _enums->at(index);
267
for
(
auto
it = hash->constBegin(), end = hash->constEnd(); it != end; ++it) {
268
if
(it.value() == value)
269
return
QString(it.key());
270
}
271
return
QString();
272
}, [](
const
QString &s) {
return
!s.isEmpty(); }, ok);
273
}
274
275
template
<Enums::Scoping scoping>
276
static
QStringList enumKeys(
277
const
QQmlRefPointer<
const
QQmlTypePrivate> &d, QQmlTypeLoader *typeLoader,
278
int
index,
int
value,
bool
*ok)
279
{
280
return
doGetEnumOp<QStringList>(d, typeLoader, [&](
const
QQmlTypePrivate::Enums *enums) {
281
const
QList<QStringHash<
int
> *> *_enums;
282
if
constexpr
(scoping == Enums::Scoped)
283
_enums = &enums->scopedEnums;
284
else
285
_enums = &enums->unscopedEnums;
286
287
Q_ASSERT(index > -1 && index < _enums->size());
288
QStringList keys;
289
const
auto
hash = _enums->at(index);
290
for
(
auto
it = hash->constBegin(), end = hash->constEnd(); it != end; ++it) {
291
if
(it.value() == value)
292
keys.append(QString(it.key()));
293
}
294
std::reverse(keys.begin(), keys.end());
295
return
keys;
296
}, [](
const
QStringList &l) {
return
!l.empty(); }, ok);
297
}
298
299
const
QMetaObject *metaObject()
const
300
{
301
if
(isValueType())
302
return
metaObjectForValueType();
303
304
const
QQmlTypePrivate::ProxyMetaObjects *proxies = init();
305
return
proxies->data.isEmpty()
306
? baseMetaObject
307
: proxies->data.constFirst().metaObject;
308
}
309
310
const
QMetaObject *metaObjectForValueType()
const
311
{
312
Q_ASSERT(isValueType());
313
314
// Prefer the extension meta object, if any.
315
// Extensions allow registration of non-gadget value types.
316
if
(
const
QMetaObject *extensionMetaObject = extraData.cppTypeData->extMetaObject) {
317
// This may be a namespace even if the original metaType isn't.
318
// You can do such things with QML_FOREIGN declarations.
319
if
(extensionMetaObject->metaType().flags() & QMetaType::IsGadget)
320
return
extensionMetaObject;
321
}
322
323
if
(baseMetaObject) {
324
// This may be a namespace even if the original metaType isn't.
325
// You can do such things with QML_FOREIGN declarations.
326
if
(baseMetaObject->metaType().flags() & QMetaType::IsGadget)
327
return
baseMetaObject;
328
}
329
330
return
nullptr
;
331
}
332
333
static
QQmlType visibleQmlTypeByName(
334
const
QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit,
335
const
QString &elementName, QQmlTypeLoader *typeLoader)
336
{
337
// Invalid speculative inline component types are either rejected at creation time
338
// (if the base type is already registered) or pruned when the base type registers.
339
return
unit->typeNameCache->query<QQmlImport::AllowRecursion>(
340
elementName, typeLoader).type;
341
}
342
343
// Tries the base unit's resolvedTypes first. If successful, that is cheap
344
// because it's just a hash. Otherwise falls back to typeNameCache.
345
// typeNameCache is slower because it will do a generic type search on all imports.
346
// This can involve iterating all the types of an import or querying QQmlMetaType for
347
// further details.
348
// TODO: Not all referenced types are pre-resolved when loading. That should be fixed.
349
// In particular, types only used in function signatures are not resolved.
350
static
QQmlType visibleQmlTypeByName(
351
const
QV4::ExecutableCompilationUnit *unit,
int
elementNameId,
352
QQmlTypeLoader *typeLoader =
nullptr
)
353
{
354
const
auto
&base = unit->baseCompilationUnit();
355
const
auto
it = base->resolvedTypes.constFind(elementNameId);
356
if
(it == base->resolvedTypes.constEnd()) {
357
return
visibleQmlTypeByName(
358
base, base->stringAt(elementNameId),
359
typeLoader ? typeLoader : unit->engine->typeLoader());
360
}
361
362
return
(*it)->type();
363
}
364
365
private
:
366
mutable
QAtomicPointer<
const
ProxyMetaObjects> proxyMetaObjects;
367
mutable
QAtomicPointer<
const
Enums> enums;
368
369
~QQmlTypePrivate();
370
friend
class
QQmlRefCounted<QQmlTypePrivate>;
371
372
struct
EnumInfo {
373
QStringList path;
374
QString metaObjectName;
375
QString enumName;
376
QString enumKey;
377
QString metaEnumScope;
378
bool
scoped;
379
};
380
381
template
<
typename
Ret,
typename
Op,
typename
Check>
382
static
Ret doGetEnumOp(
const
QQmlRefPointer<
const
QQmlTypePrivate> &d,
383
QQmlTypeLoader *typeLoader, Op &&op, Check &&check,
bool
*ok)
384
{
385
Q_ASSERT(ok);
386
if
(d) {
387
if
(
const
QQmlTypePrivate::Enums *enums = d->initEnums(typeLoader)) {
388
if
(Ret rv = op(enums); check(rv)) {
389
*ok =
true
;
390
return
rv;
391
}
392
}
393
}
394
395
*ok =
false
;
396
return
Ret();
397
}
398
399
const
Enums *initEnums(QQmlTypeLoader *typeLoader)
const
;
400
void
insertEnums(Enums *enums,
const
QMetaObject *metaObject)
const
;
401
void
insertEnumsFromPropertyCache(Enums *enums,
const
QQmlPropertyCache::ConstPtr &cache)
const
;
402
403
void
createListOfPossibleConflictingItems(
const
QMetaObject *metaObject, QList<EnumInfo> &enumInfoList, QStringList path)
const
;
404
void
createEnumConflictReport(
const
QMetaObject *metaObject,
const
QString &conflictingKey)
const
;
405
};
406
407
QT_END_NAMESPACE
408
409
#
endif
// QQMLTYPE_P_P_H
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
isPropertyRevisioned
static bool isPropertyRevisioned(const QMetaObject *mo, int index)
Definition
qqmltype.cpp:171
qtdeclarative
src
qml
qml
qqmltype_p_p.h
Generated on
for Qt by
1.18.0