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
qqmltype.cpp
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#include "qqmltype_p_p.h"
6
7#include <QtQml/qjsvalue.h>
8#include <QtQml/qqmlengine.h>
9#include <QtQml/qqmlcontext.h>
10#include <QtQml/qqmlcomponent.h>
11
12#include <private/qqmlcustomparser_p.h>
13#include <private/qqmldata_p.h>
14#include <private/qqmlmetatypedata_p.h>
15#include <private/qqmlpropertycache_p.h>
16#include <private/qqmltypedata_p.h>
17
19
20QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
21 : regType(type)
22{
23 switch (type) {
24 case QQmlType::CppType:
25 extraData.cppTypeData = new QQmlCppTypeData;
26 extraData.cppTypeData->allocationSize = 0;
27 extraData.cppTypeData->newFunc = nullptr;
28 extraData.cppTypeData->createValueTypeFunc = nullptr;
29 extraData.cppTypeData->parserStatusCast = -1;
30 extraData.cppTypeData->extFunc = nullptr;
31 extraData.cppTypeData->extMetaObject = nullptr;
32 extraData.cppTypeData->customParser = nullptr;
33 extraData.cppTypeData->attachedPropertiesFunc = nullptr;
34 extraData.cppTypeData->attachedPropertiesType = nullptr;
35 extraData.cppTypeData->propertyValueSourceCast = -1;
36 extraData.cppTypeData->propertyValueInterceptorCast = -1;
37 extraData.cppTypeData->finalizerCast = -1;
38 extraData.cppTypeData->registerEnumClassesUnscoped = true;
39 extraData.cppTypeData->registerEnumsFromRelatedTypes = true;
40 break;
41 case QQmlType::SingletonType:
42 case QQmlType::CompositeSingletonType:
43 extraData.singletonTypeData = new QQmlSingletonTypeData;
44 extraData.singletonTypeData->singletonInstanceInfo = nullptr;
45 extraData.singletonTypeData->extFunc = nullptr;
46 extraData.singletonTypeData->extMetaObject = nullptr;
47 break;
48 case QQmlType::InterfaceType:
49 extraData.interfaceTypeData = nullptr;
50 break;
51 case QQmlType::CompositeType:
52 new (&extraData.compositeTypeData) QUrl();
53 break;
54 case QQmlType::InlineComponentType:
55 new (&extraData.inlineComponentTypeData) QUrl();
56 break;
57 case QQmlType::SequentialContainerType:
58 new (&extraData.sequentialContainerTypeData) QMetaSequence();
59 break;
60 case QQmlType::JavaScriptType:
61 new (&extraData.javaScriptTypeData) QUrl();
62 break;
63 default: qFatal("QQmlTypePrivate Internal Error.");
64 }
65}
66
67QQmlTypePrivate::~QQmlTypePrivate()
68{
69 delete enums.fetchAndStoreAcquire(nullptr);
70 delete proxyMetaObjects.fetchAndStoreAcquire(nullptr);
71
72 switch (regType) {
73 case QQmlType::CppType:
74 delete extraData.cppTypeData->customParser;
75 delete extraData.cppTypeData;
76 break;
77 case QQmlType::SingletonType:
78 case QQmlType::CompositeSingletonType:
79 extraData.singletonTypeData->singletonInstanceInfo.reset();
80 delete extraData.singletonTypeData;
81 break;
82 case QQmlType::CompositeType:
83 extraData.compositeTypeData.~QUrl();
84 break;
85 case QQmlType::InlineComponentType:
86 extraData.inlineComponentTypeData.~QUrl();
87 break;
88 case QQmlType::SequentialContainerType:
89 extraData.sequentialContainerTypeData.~QMetaSequence();
90 break;
91 case QQmlType::JavaScriptType:
92 extraData.javaScriptTypeData.~QUrl();
93 break;
94 default: //Also InterfaceType, because it has no extra data
95 break;
96 }
97}
98
99QQmlType::QQmlType() = default;
100QQmlType::QQmlType(const QQmlType &) = default;
101QQmlType::QQmlType(QQmlType &&) = default;
102QQmlType &QQmlType::operator =(const QQmlType &other) = default;
103QQmlType &QQmlType::operator =(QQmlType &&other) = default;
104QQmlType::QQmlType(const QQmlTypePrivate *priv) : d(priv) {}
105QQmlType::~QQmlType() = default;
106
107QHashedString QQmlType::module() const
108{
109 if (!d)
110 return QHashedString();
111 return d->module;
112}
113
114QTypeRevision QQmlType::version() const
115{
116 if (!d)
117 return QTypeRevision();
118 return d->version;
119}
120
121bool QQmlType::availableInVersion(QTypeRevision version) const
122{
123 if (!d)
124 return false;
125
126 if (!version.hasMajorVersion())
127 return true;
128
129 if (version.majorVersion() != d->version.majorVersion())
130 return false;
131
132 return !version.hasMinorVersion() || version.minorVersion() >= d->version.minorVersion();
133}
134
135bool QQmlType::availableInVersion(const QHashedStringRef &module, QTypeRevision version) const
136{
137 if (!d || module != d->module)
138 return false;
139
140 return availableInVersion(version);
141}
142
143QQmlType QQmlTypePrivate::resolveCompositeBaseType(QQmlTypeLoader *typeLoader) const
144{
145 Q_ASSERT(isComposite());
146 if (!typeLoader)
147 return QQmlType();
148 QQmlRefPointer<QQmlTypeData> td(typeLoader->getType(sourceUrl()));
149 if (td.isNull() || !td->isComplete())
150 return QQmlType();
151 QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit();
152 if (const auto cache = compilationUnit->rootPropertyCache())
153 return QQmlMetaType::qmlType(cache->firstCppMetaObject());
154 return QQmlType();
155}
156
157QQmlPropertyCache::ConstPtr QQmlTypePrivate::compositePropertyCache(
158 QQmlTypeLoader *typeLoader) const
159{
160 // similar logic to resolveCompositeBaseType
161 Q_ASSERT(isComposite());
162 if (!typeLoader)
163 return nullptr;
164 QQmlRefPointer<QQmlTypeData> td(typeLoader->getType(sourceUrl()));
165 if (td.isNull() || !td->isComplete())
166 return nullptr;
167 QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit();
168 return compilationUnit->rootPropertyCache();
169}
170
171static bool isPropertyRevisioned(const QMetaObject *mo, int index)
172{
173 return mo->property(index).revision();
174}
175
176const QQmlTypePrivate::ProxyMetaObjects *QQmlTypePrivate::init() const
177{
178 if (const ProxyMetaObjects *result = proxyMetaObjects.loadRelaxed())
179 return result;
180
181 ProxyMetaObjects *proxies = new ProxyMetaObjects;
182 auto finalize = [this, proxies]() -> const ProxyMetaObjects *{
183 const ProxyMetaObjects *concurrentModification;
184 if (proxyMetaObjects.testAndSetOrdered(nullptr, proxies, concurrentModification))
185 return proxies;
186
187 delete proxies;
188 return concurrentModification;
189 };
190
191 const QMetaObject *mo = baseMetaObject;
192 if (!mo) {
193 // version 0 singleton type without metaobject information
194 return finalize();
195 }
196
197 QList<QQmlProxyMetaObject::ProxyData> metaObjects;
198
199 auto setupExtendedMetaObject = [&](const QMetaObject *extMetaObject,
200 QObject *(*extFunc)(QObject *)) {
201 if (!extMetaObject)
202 return;
203
204 // XXX - very inefficient
205 QMetaObjectBuilder builder;
206 QQmlMetaType::clone(builder, extMetaObject, extMetaObject, extMetaObject,
207 extFunc ? QQmlMetaType::CloneAll : QQmlMetaType::CloneEnumsOnly);
208 QMetaObject *mmo = builder.toMetaObject();
209 mmo->d.superdata = mo;
210 QQmlProxyMetaObject::ProxyData data = { mmo, extFunc, 0, 0 };
211 metaObjects << data;
212 QQmlMetaType::registerMetaObjectForType(mmo, this);
213 };
214
215 if (regType == QQmlType::SingletonType)
216 setupExtendedMetaObject(extraData.singletonTypeData->extMetaObject, extraData.singletonTypeData->extFunc);
217 else if (regType == QQmlType::CppType)
218 setupExtendedMetaObject(extraData.cppTypeData->extMetaObject, extraData.cppTypeData->extFunc);
219
220 metaObjects.append(QQmlMetaType::proxyData(
221 mo, baseMetaObject, metaObjects.isEmpty() ? nullptr
222 : metaObjects.constLast().metaObject));
223
224 for (int ii = 0; ii < metaObjects.size(); ++ii) {
225 metaObjects[ii].propertyOffset =
226 metaObjects.at(ii).metaObject->propertyOffset();
227 metaObjects[ii].methodOffset =
228 metaObjects.at(ii).metaObject->methodOffset();
229 }
230
231 bool containsRevisionedAttributes = false;
232
233 // Check for revisioned details
234 {
235 const QMetaObject *mo = nullptr;
236 if (metaObjects.isEmpty())
237 mo = baseMetaObject;
238 else
239 mo = metaObjects.constFirst().metaObject;
240
241 for (int ii = 0; !containsRevisionedAttributes && ii < mo->propertyCount(); ++ii) {
242 if (isPropertyRevisioned(mo, ii))
243 containsRevisionedAttributes = true;
244 }
245
246 for (int ii = 0; !containsRevisionedAttributes && ii < mo->methodCount(); ++ii) {
247 if (mo->method(ii).revision() != 0)
248 containsRevisionedAttributes = true;
249 }
250 }
251
252 proxies->data = std::move(metaObjects);
253 proxies->containsRevisionedAttributes = containsRevisionedAttributes;
254
255 return finalize();
256}
257
258const QQmlTypePrivate::Enums *QQmlTypePrivate::initEnums(QQmlTypeLoader *typeLoader) const
259{
260 if (const Enums *result = enums.loadRelaxed())
261 return result;
262
263 QQmlPropertyCache::ConstPtr cache;
264 if (isComposite()) {
265 cache = compositePropertyCache(typeLoader);
266 if (!cache)
267 return nullptr; // Composite type not ready, yet.
268 }
269
270 Enums *newEnums = new Enums;
271
272 // beware: It could be a singleton type without metaobject
273
274 if (cache)
275 insertEnumsFromPropertyCache(newEnums, cache);
276
277 if (baseMetaObject) {
278 // init() can add to the metaObjects list. Therefore, check proxies->data only below
279 const ProxyMetaObjects *proxies = init();
280 insertEnums(
281 newEnums,
282 proxies->data.isEmpty() ? baseMetaObject : proxies->data.constFirst().metaObject);
283 }
284
285 const Enums *concurrentModification;
286 if (enums.testAndSetOrdered(nullptr, newEnums, concurrentModification))
287 return newEnums;
288
289 delete newEnums;
290 return concurrentModification;
291}
292
293void QQmlTypePrivate::insertEnums(Enums *enums, const QMetaObject *metaObject) const
294{
295 // Add any enum values defined by 'related' classes
296 if (regType != QQmlType::CppType || extraData.cppTypeData->registerEnumsFromRelatedTypes) {
297 if (const auto *related = metaObject->d.relatedMetaObjects) {
298 while (const QMetaObject *relatedMetaObject = *related) {
299 insertEnums(enums, relatedMetaObject);
300 ++related;
301 }
302 }
303 }
304
305 QSet<QString> localEnums;
306 const QMetaObject *localMetaObject = nullptr;
307
308 // ### TODO (QTBUG-123294): track this at instance creation time
309 auto shouldSingletonAlsoRegisterUnscoped = [&](){
310 Q_ASSERT(regType == QQmlType::SingletonType);
311 if (!baseMetaObject)
312 return true;
313 int idx = baseMetaObject->indexOfClassInfo("RegisterEnumClassesUnscoped");
314 if (idx == -1)
315 return true;
316 if (qstrcmp(baseMetaObject->classInfo(idx).value(), "false") == 0)
317 return false;
318 return true;
319 };
320
321 // Add any enum values defined by this class, overwriting any inherited values
322 for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
323 QMetaEnum me = metaObject->enumerator(ii);
324 const bool isScoped = me.isScoped();
325 QStringHash<int> *e = new QStringHash<int>();
326
327 // We allow enums in sub-classes to overwrite enums from base-classes, such as
328 // ListView.Center (from enum PositionMode) overwriting Item.Center (from enum TransformOrigin).
329 // This is acceptable because the _use_ of the enum from the QML side requires qualification
330 // anyway, i.e. ListView.Center vs. Item.Center.
331 // However if a class defines two enums with the same value, then that must produce a warning
332 // because it represents a valid conflict.
333 if (me.enclosingMetaObject() != localMetaObject) {
334 localEnums.clear();
335 localMetaObject = me.enclosingMetaObject();
336 }
337 const bool shouldRegisterUnscoped = !isScoped
338 || (regType == QQmlType::CppType && extraData.cppTypeData->registerEnumClassesUnscoped)
339 || (regType == QQmlType::SingletonType && shouldSingletonAlsoRegisterUnscoped())
340 ;
341
342 for (int jj = 0; jj < me.keyCount(); ++jj) {
343 const QString key = QString::fromUtf8(me.key(jj));
344 const int value = me.value(jj);
345 if (shouldRegisterUnscoped) {
346 if (localEnums.contains(key)) {
347 auto existingEntry = enums->enums.find(key);
348 if (existingEntry != enums->enums.end() && existingEntry.value() != value) {
349 qWarning("Previously registered enum will be overwritten due to name clash: %s.%s", metaObject->className(), key.toUtf8().constData());
350 createEnumConflictReport(metaObject, key);
351 }
352 } else {
353 localEnums.insert(key);
354 }
355 enums->enums.insert(key, value);
356 }
357 e->insert(key, value);
358 }
359
360 if (isScoped) {
361 enums->scopedEnumIndex.insert(QString::fromUtf8(me.name()), enums->scopedEnums.size());
362 enums->scopedEnums << e;
363 } else {
364 enums->unscopedEnumIndex.insert(QString::fromUtf8(me.name()), enums->unscopedEnums.size());
365 enums->unscopedEnums << e;
366 }
367 }
368}
369
370void QQmlTypePrivate::createListOfPossibleConflictingItems(const QMetaObject *metaObject, QList<EnumInfo> &enumInfoList, QStringList path) const
371{
372 path.append(QString::fromUtf8(metaObject->className()));
373
374 if (metaObject->d.relatedMetaObjects) {
375 const auto *related = metaObject->d.relatedMetaObjects;
376 if (related) {
377 while (*related)
378 createListOfPossibleConflictingItems(*related++, enumInfoList, path);
379 }
380 }
381
382 for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
383 const auto e = metaObject->enumerator(ii);
384
385 for (int jj = 0; jj < e.keyCount(); ++jj) {
386 const QString key = QString::fromUtf8(e.key(jj));
387
388 EnumInfo enumInfo;
389 enumInfo.metaObjectName = QString::fromUtf8(metaObject->className());
390 enumInfo.enumName = QString::fromUtf8(e.name());
391 enumInfo.enumKey = key;
392 enumInfo.scoped = e.isScoped();
393 enumInfo.path = path;
394 enumInfo.metaEnumScope = QString::fromUtf8(e.scope());
395 enumInfoList.append(enumInfo);
396 }
397 }
398}
399
400void QQmlTypePrivate::createEnumConflictReport(const QMetaObject *metaObject, const QString &conflictingKey) const
401{
402 QList<EnumInfo> enumInfoList;
403
404 if (baseMetaObject) // prefer baseMetaObject if available
405 metaObject = baseMetaObject;
406
407 if (!metaObject) { // If there is no metaObject at all return early
408 qWarning() << "No meta object information available. Skipping conflict analysis.";
409 return;
410 }
411
412 createListOfPossibleConflictingItems(metaObject, enumInfoList, QStringList());
413
414 qWarning().noquote() << QLatin1String("Possible conflicting items:");
415 // find items with conflicting key
416 for (const auto &i : std::as_const(enumInfoList)) {
417 if (i.enumKey == conflictingKey)
418 qWarning().noquote().nospace() << " " << i.metaObjectName << "." << i.enumName << "." << i.enumKey << " from scope "
419 << i.metaEnumScope << " injected by " << i.path.join(QLatin1String("->"));
420 }
421}
422
423void QQmlTypePrivate::insertEnumsFromPropertyCache(
424 Enums *enums, const QQmlPropertyCache::ConstPtr &cache) const
425{
426 const QMetaObject *cppMetaObject = cache->firstCppMetaObject();
427
428 for (const QQmlPropertyCache *currentCache = cache.data();
429 currentCache && currentCache->metaObject() != cppMetaObject;
430 currentCache = currentCache->parent().data()) {
431
432 int count = currentCache->qmlEnumCount();
433 for (int ii = 0; ii < count; ++ii) {
434 QStringHash<int> *scoped = new QStringHash<int>();
435 QQmlEnumData *enumData = currentCache->qmlEnum(ii);
436
437 for (int jj = 0; jj < enumData->values.size(); ++jj) {
438 const QQmlEnumValue &value = enumData->values.at(jj);
439 enums->enums.insert(value.namedValue, value.value);
440 scoped->insert(value.namedValue, value.value);
441 }
442 enums->scopedEnums << scoped;
443 enums->scopedEnumIndex.insert(enumData->name, enums->scopedEnums.size()-1);
444 }
445 }
446 insertEnums(enums, cppMetaObject);
447}
448
449void QQmlTypePrivate::setName(const QString &uri, const QString &element)
450{
451 module = uri;
452 elementName = element;
453 name = uri.isEmpty() ? element : (uri + QLatin1Char('/') + element);
454}
455
456QByteArray QQmlType::typeName() const
457{
458 if (d) {
459 if (d->regType == SingletonType || d->regType == CompositeSingletonType)
460 return d->extraData.singletonTypeData->singletonInstanceInfo->typeName;
461 else if (d->baseMetaObject)
462 return d->baseMetaObject->className();
463 }
464 return QByteArray();
465}
466
467QString QQmlType::elementName() const
468{
469 if (!d)
470 return QString();
471 return d->elementName;
472}
473
474QString QQmlType::qmlTypeName() const
475{
476 if (!d)
477 return QString();
478 return d->name;
479}
480
481/*!
482 \internal
483 Allocates and initializes an object if the type is creatable.
484 Returns a pointer to the object, or nullptr if the type was
485 not creatable.
486 */
487QObject *QQmlType::create() const
488{
489 void *unused;
490 return create(&unused, 0);
491}
492
493/*!
494 \internal
495 \brief Like create without arguments, but allocates some extra space after the object.
496 \param memory An out-only argument. *memory will point to the start of the additionally
497 allocated memory.
498 \param additionalMemory The amount of extra memory in bytes that shoudld be allocated.
499
500 \note This function is used to allocate the QQmlData next to the object in the
501 QQmlObjectCreator.
502
503 \overload
504 */
505QObject *QQmlType::create(void **memory, size_t additionalMemory) const
506{
507 if (!d || !isCreatable())
508 return nullptr;
509
510 QObject *rv = (QObject *)operator new(d->extraData.cppTypeData->allocationSize + additionalMemory);
511 d->extraData.cppTypeData->newFunc(rv, d->extraData.cppTypeData->userdata);
512
513 createProxy(rv);
514 *memory = ((char *)rv) + d->extraData.cppTypeData->allocationSize;
515 return rv;
516}
517
518/*!
519 \internal
520 Like create, but also allocates memory behind the object, constructs a QQmlData there
521 and lets the objects declarativeData point to the newly created QQmlData.
522 */
523QObject *QQmlType::createWithQQmlData() const
524{
525 void *ddataMemory = nullptr;
526 auto instance = create(&ddataMemory, sizeof(QQmlData));
527 if (!instance)
528 return nullptr;
529 QObjectPrivate* p = QObjectPrivate::get(instance);
530 Q_ASSERT(!p->isDeletingChildren);
531 if (!p->declarativeData)
532 p->declarativeData = new (ddataMemory) QQmlData(QQmlData::DoesNotOwnMemory);
533 return instance;
534}
535
536QQmlType::SingletonInstanceInfo::ConstPtr QQmlType::singletonInstanceInfo() const
537{
538 if (!d)
539 return {};
540 if (d->regType != SingletonType && d->regType != CompositeSingletonType)
541 return {};
542 return d->extraData.singletonTypeData->singletonInstanceInfo;
543}
544
545QQmlCustomParser *QQmlType::customParser() const
546{
547 if (!d)
548 return nullptr;
549 if (d->regType != CppType)
550 return nullptr;
551 return d->extraData.cppTypeData->customParser;
552}
553
554QQmlType::CreateValueTypeFunc QQmlType::createValueTypeFunction() const
555{
556 if (!d || d->regType != CppType)
557 return nullptr;
558 return d->extraData.cppTypeData->createValueTypeFunc;
559}
560
561bool QQmlType::canConstructValueType() const
562{
563 if (!d || d->regType != CppType)
564 return false;
565 return d->extraData.cppTypeData->constructValueType;
566}
567
568bool QQmlType::canPopulateValueType() const
569{
570 if (!d || d->regType != CppType)
571 return false;
572 return d->extraData.cppTypeData->populateValueType;
573}
574
575QQmlType::CreateFunc QQmlType::createFunction() const
576{
577 if (!d || d->regType != CppType)
578 return nullptr;
579 return d->extraData.cppTypeData->newFunc;
580}
581
582QString QQmlType::noCreationReason() const
583{
584 if (!d || d->regType != CppType)
585 return QString();
586 return d->extraData.cppTypeData->noCreationReason;
587}
588
589bool QQmlType::isCreatable() const
590{
591 return d && d->regType == CppType && d->extraData.cppTypeData->newFunc;
592}
593
594QQmlType::ExtensionFunc QQmlType::extensionFunction() const
595{
596 if (!d)
597 return nullptr;
598
599 switch (d->regType) {
600 case CppType:
601 return d->extraData.cppTypeData->extFunc;
602 case SingletonType:
603 return d->extraData.singletonTypeData->extFunc;
604 default:
605 return nullptr;
606 }
607}
608
609const QMetaObject *QQmlType::extensionMetaObject() const
610{
611 if (!d)
612 return nullptr;
613
614 switch (d->regType) {
615 case CppType:
616 return d->extraData.cppTypeData->extMetaObject;
617 case SingletonType:
618 return d->extraData.singletonTypeData->extMetaObject;
619 default:
620 return nullptr;
621 }
622}
623
624bool QQmlType::isExtendedType() const
625{
626 return d && !d->init()->data.isEmpty();
627}
628
629bool QQmlType::isSingleton() const
630{
631 return d && (d->regType == SingletonType || d->regType == CompositeSingletonType);
632}
633
634bool QQmlType::isInterface() const
635{
636 return d && d->regType == InterfaceType;
637}
638
639bool QQmlType::isComposite() const
640{
641 return d && d->isComposite();
642}
643
644bool QQmlType::isCompositeSingleton() const
645{
646 // if the outer type is a composite singleton, d->regType will indicate that even for
647 // the inline component type
648 // however, inline components can -at least for now- never be singletons
649 // so we just do one additional check
650 return d && d->regType == CompositeSingletonType && !isInlineComponentType();
651}
652
653bool QQmlType::isQObjectSingleton() const
654{
655 return d && d->regType == SingletonType && d->extraData.singletonTypeData->singletonInstanceInfo->qobjectCallback;
656}
657
658bool QQmlType::isQJSValueSingleton() const
659{
660 return d && d->regType == SingletonType && d->extraData.singletonTypeData->singletonInstanceInfo->scriptCallback;
661}
662
663bool QQmlType::isSequentialContainer() const
664{
665 return d && d->regType == SequentialContainerType;
666}
667
668bool QQmlType::isValueType() const
669{
670 return d && d->isValueType();
671}
672
673QMetaType QQmlType::typeId() const
674{
675 return d ? d->typeId : QMetaType{};
676}
677
678QMetaType QQmlType::qListTypeId() const
679{
680 return d ? d->listId : QMetaType{};
681}
682
683QMetaSequence QQmlType::listMetaSequence() const
684{
685 return isSequentialContainer() ? d->extraData.sequentialContainerTypeData : QMetaSequence();
686}
687
688const QMetaObject *QQmlType::metaObject() const
689{
690 return d ? d->metaObject() : nullptr;
691}
692
693const QMetaObject *QQmlType::metaObjectForValueType() const
694{
695 Q_ASSERT(d);
696 return d->metaObjectForValueType();
697}
698
699const QMetaObject *QQmlType::baseMetaObject() const
700{
701 return d ? d->baseMetaObject : nullptr;
702}
703
704bool QQmlType::containsRevisionedAttributes() const
705{
706 return d && d->init()->containsRevisionedAttributes;
707}
708
709QTypeRevision QQmlType::metaObjectRevision() const
710{
711 return d ? d->revision : QTypeRevision();
712}
713
714QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlTypeLoader *typeLoader) const
715{
716 if (const QQmlTypePrivate *base = d ? d->attachedPropertiesBase(typeLoader) : nullptr)
717 return base->extraData.cppTypeData->attachedPropertiesFunc;
718 return nullptr;
719}
720
721const QMetaObject *QQmlType::attachedPropertiesType(QQmlTypeLoader *typeLoader) const
722{
723 if (const QQmlTypePrivate *base = d ? d->attachedPropertiesBase(typeLoader) : nullptr)
724 return base->extraData.cppTypeData->attachedPropertiesType;
725 return nullptr;
726}
727
728int QQmlType::parserStatusCast() const
729{
730 if (!d || d->regType != CppType)
731 return -1;
732 return d->extraData.cppTypeData->parserStatusCast;
733}
734
735int QQmlType::propertyValueSourceCast() const
736{
737 if (!d || d->regType != CppType)
738 return -1;
739 return d->extraData.cppTypeData->propertyValueSourceCast;
740}
741
742int QQmlType::propertyValueInterceptorCast() const
743{
744 if (!d || d->regType != CppType)
745 return -1;
746 return d->extraData.cppTypeData->propertyValueInterceptorCast;
747}
748
749int QQmlType::finalizerCast() const
750{
751 if (!d || d->regType != CppType)
752 return -1;
753 return d->extraData.cppTypeData->finalizerCast;
754}
755
756const char *QQmlType::interfaceIId() const
757{
758 if (!d || d->regType != InterfaceType)
759 return nullptr;
760 return d->extraData.interfaceTypeData;
761}
762
763int QQmlType::index() const
764{
765 return d ? d->index : -1;
766}
767
768bool QQmlType::isInlineComponentType() const {
769 return d ? d->regType == QQmlType::InlineComponentType : false;
770}
771
772QUrl QQmlType::sourceUrl() const
773{
774 return d ? d->sourceUrl() : QUrl();
775}
776
777int QQmlType::enumValue(QQmlTypeLoader *typeLoader, const QHashedStringRef &name, bool *ok) const
778{
779 return QQmlTypePrivate::enumValue(d, typeLoader, name, ok);
780}
781
782int QQmlType::enumValue(QQmlTypeLoader *typeLoader, const QHashedCStringRef &name, bool *ok) const
783{
784 return QQmlTypePrivate::enumValue(d, typeLoader, name, ok);
785}
786
787int QQmlType::enumValue(QQmlTypeLoader *typeLoader, const QV4::String *name, bool *ok) const
788{
789 return QQmlTypePrivate::enumValue(d, typeLoader, name, ok);
790}
791
792int QQmlType::scopedEnumIndex(QQmlTypeLoader *typeLoader, const QV4::String *name, bool *ok) const
793{
794 return QQmlTypePrivate::enumIndex<QQmlTypePrivate::Enums::Scoped>(
795 d, typeLoader, name, ok);
796}
797
798int QQmlType::scopedEnumIndex(QQmlTypeLoader *typeLoader, const QString &name, bool *ok) const
799{
800 return QQmlTypePrivate::enumIndex<QQmlTypePrivate::Enums::Scoped>(
801 d, typeLoader, name, ok);
802}
803
804int QQmlType::unscopedEnumIndex(QQmlTypeLoader *typeLoader, const QV4::String *name, bool *ok) const
805{
806 return QQmlTypePrivate::enumIndex<QQmlTypePrivate::Enums::Unscoped>(
807 d, typeLoader, name, ok);
808}
809
810int QQmlType::unscopedEnumIndex(QQmlTypeLoader *typeLoader, const QString &name, bool *ok) const
811{
812 return QQmlTypePrivate::enumIndex<QQmlTypePrivate::Enums::Unscoped>(
813 d, typeLoader, name, ok);
814}
815
816int QQmlType::scopedEnumValue(QQmlTypeLoader *typeLoader, int index, const QV4::String *name, bool *ok) const
817{
818 return QQmlTypePrivate::enumValue<QQmlTypePrivate::Enums::Scoped>(
819 d, typeLoader, index, name, ok);
820}
821
822int QQmlType::scopedEnumValue(QQmlTypeLoader *typeLoader, int index, const QString &name, bool *ok) const
823{
824 return QQmlTypePrivate::enumValue<QQmlTypePrivate::Enums::Scoped>(
825 d, typeLoader, index, name, ok);
826}
827
828int QQmlType::scopedEnumValue(QQmlTypeLoader *typeLoader, const QHashedStringRef &scopedEnumName, const QHashedStringRef &name, bool *ok) const
829{
830 return QQmlTypePrivate::enumValue<QQmlTypePrivate::Enums::Scoped>(
831 d, typeLoader, scopedEnumName, name, ok);
832}
833
834int QQmlType::unscopedEnumValue(QQmlTypeLoader *typeLoader, int index, const QV4::String *name, bool *ok) const
835{
836 return QQmlTypePrivate::enumValue<QQmlTypePrivate::Enums::Unscoped>(
837 d, typeLoader, index, name, ok);
838}
839
840int QQmlType::unscopedEnumValue(QQmlTypeLoader *typeLoader, int index, const QString &name, bool *ok) const
841{
842 return QQmlTypePrivate::enumValue<QQmlTypePrivate::Enums::Unscoped>(
843 d, typeLoader, index, name, ok);
844}
845
846int QQmlType::unscopedEnumValue(QQmlTypeLoader *typeLoader, const QHashedStringRef &scopedEnumName, const QHashedStringRef &name, bool *ok) const
847{
848 return QQmlTypePrivate::enumValue<QQmlTypePrivate::Enums::Unscoped>(
849 d, typeLoader, scopedEnumName, name, ok);
850}
851
852QString QQmlType::scopedEnumKey(QQmlTypeLoader *typeLoader, int index, int value, bool *ok) const
853{
854 return QQmlTypePrivate::enumKey<QQmlTypePrivate::Enums::Scoped>(
855 d, typeLoader, index, value, ok);
856}
857
858QStringList QQmlType::scopedEnumKeys(QQmlTypeLoader *typeLoader, int index, int value, bool *ok) const
859{
860 return QQmlTypePrivate::enumKeys<QQmlTypePrivate::Enums::Scoped>(
861 d, typeLoader, index, value, ok);
862}
863
864QString QQmlType::unscopedEnumKey(QQmlTypeLoader *typeLoader, int index, int value, bool *ok) const
865{
866 return QQmlTypePrivate::enumKey<QQmlTypePrivate::Enums::Unscoped>(
867 d, typeLoader, index, value, ok);
868}
869
870QStringList QQmlType::unscopedEnumKeys(QQmlTypeLoader *typeLoader, int index, int value,
871 bool *ok) const
872{
873 return QQmlTypePrivate::enumKeys<QQmlTypePrivate::Enums::Unscoped>(
874 d, typeLoader, index, value, ok);
875}
876
877
878void QQmlType::refHandle(const QQmlTypePrivate *priv)
879{
880 if (priv)
881 priv->addref();
882}
883
884void QQmlType::derefHandle(const QQmlTypePrivate *priv)
885{
886 if (priv)
887 priv->release();
888}
889
890int QQmlType::refCount(const QQmlTypePrivate *priv)
891{
892 if (priv)
893 return priv->count();
894 return -1;
895}
896
897void QQmlType::createProxy(QObject *instance) const
898{
899 const QQmlTypePrivate::ProxyMetaObjects *proxies = d->init();
900 if (!proxies->data.isEmpty())
901 (void)new QQmlProxyMetaObject(instance, &proxies->data);
902}
903
904QT_END_NAMESPACE
Combined button and popup list for selecting options.
static bool isPropertyRevisioned(const QMetaObject *mo, int index)
Definition qqmltype.cpp:171