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