Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmlmetatype.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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 "qqmlmetatype_p.h"
5
6#include <private/qqmlextensionplugin_p.h>
7#include <private/qqmlmetatypedata_p.h>
8#include <private/qqmlpropertycachecreator_p.h>
9#include <private/qqmltype_p_p.h>
10#include <private/qqmltypeloader_p.h>
11#include <private/qqmltypemodule_p.h>
12#include <private/qqmlvaluetype_p.h>
13#include <private/qv4executablecompilationunit_p.h>
14
15#include <QtCore/qcoreapplication.h>
16#include <QtCore/qmutex.h>
17#include <QtCore/qloggingcategory.h>
18
19Q_DECLARE_LOGGING_CATEGORY(DBG_DISK_CACHE)
20Q_LOGGING_CATEGORY(lcTypeRegistration, "qt.qml.typeregistration")
21
23
25{
26 friend class QQmlMetaTypeDataPtr;
27};
28
29Q_GLOBAL_STATIC(LockedData, metaTypeData)
30Q_GLOBAL_STATIC(QRecursiveMutex, metaTypeDataLock)
31
32struct ModuleUri : public QString
33{
34 ModuleUri(const QString &string) : QString(string) {}
35 ModuleUri(const std::unique_ptr<QQmlTypeModule> &module) : QString(module->module()) {}
36};
37
39{
40 Q_DISABLE_COPY_MOVE(QQmlMetaTypeDataPtr)
41public:
42 QQmlMetaTypeDataPtr() : locker(metaTypeDataLock()), data(metaTypeData()) {}
44
47 operator QQmlMetaTypeData *() { return data; }
48
49 const QQmlMetaTypeData &operator*() const { return *data; }
50 const QQmlMetaTypeData *operator->() const { return data; }
51 operator const QQmlMetaTypeData *() const { return data; }
52
53 bool isValid() const { return data != nullptr; }
54
55private:
57 LockedData *data = nullptr;
58};
59
62{
64 d->extraData.interfaceTypeData = type.iid;
65 d->typeId = type.typeId;
66 d->listId = type.listId;
67 d->module = QString::fromUtf8(type.uri);
68 d->version = type.version;
69 data->registerType(d);
70 return d;
71}
72
75{
77 data->registerType(d);
78
79 d->setName(QString::fromUtf8(type.uri), elementName);
80 d->version = type.version;
81
82 if (type.qObjectApi) {
83 d->baseMetaObject = type.instanceMetaObject;
84 d->typeId = type.typeId;
85 d->revision = type.revision;
86 }
87
88 d->extraData.singletonTypeData->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo;
89 d->extraData.singletonTypeData->singletonInstanceInfo->scriptCallback = type.scriptApi;
90 d->extraData.singletonTypeData->singletonInstanceInfo->qobjectCallback = type.qObjectApi;
91 d->extraData.singletonTypeData->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
92 d->extraData.singletonTypeData->singletonInstanceInfo->instanceMetaObject
93 = type.qObjectApi ? type.instanceMetaObject : nullptr;
94 d->extraData.singletonTypeData->extFunc = type.extensionObjectCreate;
95 d->extraData.singletonTypeData->extMetaObject = type.extensionMetaObject;
96
97 return d;
98}
99
102{
104 data->registerType(d);
105 d->setName(QString::fromUtf8(type.uri), elementName);
106
107 d->version = type.version;
108 d->revision = type.revision;
109 d->typeId = type.typeId;
110 d->listId = type.listId;
111 d->extraData.cppTypeData->allocationSize = type.objectSize;
112 d->extraData.cppTypeData->userdata = type.userdata;
113 d->extraData.cppTypeData->newFunc = type.create;
114 d->extraData.cppTypeData->noCreationReason = type.noCreationReason;
115 d->extraData.cppTypeData->createValueTypeFunc = type.createValueType;
116 d->baseMetaObject = type.metaObject;
117 d->extraData.cppTypeData->attachedPropertiesFunc = type.attachedPropertiesFunction;
118 d->extraData.cppTypeData->attachedPropertiesType = type.attachedPropertiesMetaObject;
119 d->extraData.cppTypeData->parserStatusCast = type.parserStatusCast;
120 d->extraData.cppTypeData->propertyValueSourceCast = type.valueSourceCast;
121 d->extraData.cppTypeData->propertyValueInterceptorCast = type.valueInterceptorCast;
122 d->extraData.cppTypeData->finalizerCast = type.has(QQmlPrivate::RegisterType::FinalizerCast)
123 ? type.finalizerCast
124 : -1;
125 d->extraData.cppTypeData->extFunc = type.extensionObjectCreate;
126 d->extraData.cppTypeData->customParser = reinterpret_cast<QQmlCustomParser *>(type.customParser);
127 d->extraData.cppTypeData->registerEnumClassesUnscoped = true;
128 d->extraData.cppTypeData->registerEnumsFromRelatedTypes = true;
129 d->extraData.cppTypeData->constructValueType = type.has(QQmlPrivate::RegisterType::CreationMethod)
131 d->extraData.cppTypeData->populateValueType = type.has(QQmlPrivate::RegisterType::CreationMethod)
133
134 if (type.extensionMetaObject)
135 d->extraData.cppTypeData->extMetaObject = type.extensionMetaObject;
136
137 // Check if the user wants only scoped enum classes
138 if (d->baseMetaObject) {
139 auto indexOfUnscoped = d->baseMetaObject->indexOfClassInfo("RegisterEnumClassesUnscoped");
140 if (indexOfUnscoped != -1
141 && qstrcmp(d->baseMetaObject->classInfo(indexOfUnscoped).value(), "false") == 0) {
142 d->extraData.cppTypeData->registerEnumClassesUnscoped = false;
143 }
144
145 auto indexOfRelated = d->baseMetaObject->indexOfClassInfo("RegisterEnumsFromRelatedTypes");
146 if (indexOfRelated != -1
147 && qstrcmp(d->baseMetaObject->classInfo(indexOfRelated).value(), "false") == 0) {
148 d->extraData.cppTypeData->registerEnumsFromRelatedTypes = false;
149 }
150 }
151
152 return d;
153}
154
156{
157 QByteArray ptr = className + '*';
158 QByteArray lst = "QQmlListProperty<" + className + '>';
159
160 QMetaType ptr_type(new QQmlMetaTypeInterface(ptr));
161 QMetaType lst_type(new QQmlListMetaTypeInterface(lst, ptr_type.iface()));
162
163 // Retrieve the IDs once, so that the types are added to QMetaType's custom type registry.
164 ptr_type.id();
165 lst_type.id();
166
167 priv->typeId = ptr_type;
168 priv->listId = lst_type;
169}
170
173{
175 data->registerType(d);
176 d->setName(QString::fromUtf8(type.uri), elementName);
177 d->version = type.version;
178
180 d->extraData.compositeTypeData = normalized;
183 return d;
184}
185
188{
190 data->registerType(d);
191 d->setName(QString::fromUtf8(type.uri), elementName);
192
193 d->version = type.version;
194
196 d->extraData.singletonTypeData->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo;
197 d->extraData.singletonTypeData->singletonInstanceInfo->url = normalized;
198 d->extraData.singletonTypeData->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
201 return d;
202}
203
205 const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd,
207{
208 // Set classname
209 builder.setClassName(mo->className());
210
211 // Clone Q_CLASSINFO
212 for (int ii = mo->classInfoOffset(); ii < mo->classInfoCount(); ++ii) {
213 QMetaClassInfo info = mo->classInfo(ii);
214
215 int otherIndex = ignoreEnd->indexOfClassInfo(info.name());
216 if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
217 // Skip
218 } else {
219 builder.addClassInfo(info.name(), info.value());
220 }
221 }
222
224 // Clone Q_METHODS - do this first to avoid duplicating the notify signals.
225 for (int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) {
226 QMetaMethod method = mo->method(ii);
227
228 // More complex - need to search name
229 QByteArray name = method.name();
230
231 bool found = false;
232
233 for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount();
234 !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount(); ++ii) {
235
236 QMetaMethod other = ignoreEnd->method(ii);
237
238 found = name == other.name();
239 }
240
242 if (found) // SKIP
244 }
245
246 // Clone Q_PROPERTY
247 for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) {
248 QMetaProperty property = mo->property(ii);
249
250 int otherIndex = ignoreEnd->indexOfProperty(property.name());
251 if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) {
252 builder.addProperty(QByteArray("__qml_ignore__") + property.name(),
253 QByteArray("void"));
254 // Skip
255 } else {
256 builder.addProperty(property);
257 }
258 }
259 }
260
261 // Clone enums registered with the metatype system
262 for (int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) {
263 QMetaEnum enumerator = mo->enumerator(ii);
264
265 int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name());
266 if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) {
267 // Skip
268 } else {
269 builder.addEnumerator(enumerator);
270 }
271 }
272}
273
274void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, void (*registerFunction)())
275{
277 if (data->moduleTypeRegistrationFunctions.contains(uri))
278 qFatal("Cannot add multiple registrations for %s", qPrintable(uri));
279 else
280 data->moduleTypeRegistrationFunctions.insert(uri, registerFunction);
281}
282
284{
286
287 if (!data.isValid())
288 return; // shutdown/deletion race. Not a problem.
289
290 if (!data->moduleTypeRegistrationFunctions.contains(uri))
291 qFatal("Cannot remove multiple registrations for %s", qPrintable(uri));
292 else
293 data->moduleTypeRegistrationFunctions.remove(uri);
294}
295
297{
299 return data->registerModuleTypes(uri);
300}
301
303{
304 //Only cleans global static, assumed no running engine
306
307 data->uriToModule.clear();
308 data->types.clear();
309 data->idToType.clear();
310 data->nameToType.clear();
311 data->urlToType.clear();
312 data->typePropertyCaches.clear();
313 data->urlToNonFileImportType.clear();
314 data->metaObjectToType.clear();
315 data->undeletableTypes.clear();
316 data->propertyCaches.clear();
317 data->inlineComponentTypes.clear();
318
319 // Avoid deletion recursion (via QQmlTypePrivate dtor) by moving them out of the way first.
320 QQmlMetaTypeData::CompositeTypes emptyComposites;
321 emptyComposites.swap(data->compositeTypes);
322}
323
325{
327 const QQmlType type = data->types.value(typeIndex);
328 const QQmlTypePrivate *priv = type.priv();
329 data->nameToType.insert(name, priv);
330}
331
333{
334 if (function.structVersion > 1)
335 qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
336
338
339 data->parentFunctions.append(function.function);
340
341 return data->parentFunctions.size() - 1;
342}
343
345{
347 data->parentFunctions.removeOne(function);
348}
349
351{
352 if (type.structVersion > 1)
353 qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
354
357 Q_ASSERT(priv);
358
359
360 data->idToType.insert(priv->typeId.id(), priv);
361 data->idToType.insert(priv->listId.id(), priv);
362
363 data->interfaces.insert(type.typeId.id());
364
365 return QQmlType(priv);
366}
367
369{
371 if (typeType == QQmlType::CppType)
372 typeStr = QStringLiteral("element");
373 else if (typeType == QQmlType::SingletonType)
374 typeStr = QStringLiteral("singleton type");
375 else if (typeType == QQmlType::CompositeSingletonType)
376 typeStr = QStringLiteral("composite singleton type");
377 else if (typeType == QQmlType::SequentialContainerType)
378 typeStr = QStringLiteral("sequential container type");
379 else
380 typeStr = QStringLiteral("type");
381 return typeStr;
382}
383
384// NOTE: caller must hold a QMutexLocker on "data"
386 QQmlType::RegistrationType typeType, QQmlMetaTypeData *data, const char *uri,
387 const QString &typeName, QTypeRevision version, QMetaType::TypeFlags flags)
388{
389 if (!typeName.isEmpty()) {
390 if (typeName.at(0).isLower() && (flags & QMetaType::PointerToQObject)) {
391 QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\"; type names must begin with an uppercase letter"));
392 data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType), typeName));
393 return false;
394 }
395
396 if (typeName.at(0).isUpper()
398 qCWarning(lcTypeRegistration).noquote()
400 "qmlRegisterType",
401 "Invalid QML %1 name \"%2\"; "
402 "value type names should begin with a lowercase letter")
404 }
405
406 // There can also be types that aren't even gadgets, and there can be types for namespaces.
407 // We cannot check those, but namespaces should be uppercase.
408
409 int typeNameLen = typeName.size();
410 for (int ii = 0; ii < typeNameLen; ++ii) {
411 if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == u'_')) {
412 QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\""));
413 data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType), typeName));
414 return false;
415 }
416 }
417 }
418
419 if (uri && !typeName.isEmpty()) {
420 QString nameSpace = QString::fromUtf8(uri);
421 QQmlTypeModule *qqtm = data->findTypeModule(nameSpace, version);
422 if (qqtm && qqtm->lockLevel() != QQmlTypeModule::LockLevel::Open) {
424 "qmlRegisterType",
425 "Cannot install %1 '%2' into protected module '%3' version '%4'"));
426 data->recordTypeRegFailure(failure
427 .arg(registrationTypeString(typeType), typeName, nameSpace)
428 .arg(version.majorVersion()));
429 return false;
430 }
431 }
432
433 return true;
434}
435
436// NOTE: caller must hold a QMutexLocker on "data"
438 const QHashedString &uri, QTypeRevision version, QQmlMetaTypeData *data)
439{
440 if (QQmlTypeModule *module = data->findTypeModule(uri, version))
441 return module;
442 return data->addTypeModule(std::make_unique<QQmlTypeModule>(uri, version.majorVersion()));
443}
444
445// NOTE: caller must hold a QMutexLocker on "data"
447{
448 Q_ASSERT(type);
449
450 if (!type->elementName.isEmpty())
451 data->nameToType.insert(type->elementName, type);
452
453 if (type->baseMetaObject)
454 data->metaObjectToType.insert(type->baseMetaObject, type);
455
456 if (type->regType == QQmlType::SequentialContainerType) {
457 if (type->listId.isValid())
458 data->idToType.insert(type->listId.id(), type);
459 } else {
460 if (type->typeId.isValid())
461 data->idToType.insert(type->typeId.id(), type);
462
463 if (type->listId.flags().testFlag(QMetaType::IsQmlList))
464 data->idToType.insert(type->listId.id(), type);
465 }
466
467 if (!type->module.isEmpty()) {
468 const QHashedString &mod = type->module;
469
470 QQmlTypeModule *module = getTypeModule(mod, type->version, data);
471 Q_ASSERT(module);
472 module->add(type);
473 }
474}
475
477{
478 if (type.structVersion > int(QQmlPrivate::RegisterType::CurrentVersion))
479 qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
480
482
483 QString elementName = QString::fromUtf8(type.elementName);
484 if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.version,
485 QMetaType(type.typeId).flags())) {
486 return QQmlType();
487 }
488
489 QQmlTypePrivate *priv = createQQmlType(data, elementName, type);
491
492 return QQmlType(priv);
493}
494
496{
497 if (type.structVersion > 1)
498 qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
499
501
504 QMetaType(type.typeId).flags())) {
505 return QQmlType();
506 }
507
509
511
512 return QQmlType(priv);
513}
514
516{
517 if (type.structVersion > 1)
518 qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
519
520 // Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
522
524 bool fileImport = false;
525 if (*(type.uri) == '\0')
526 fileImport = true;
527 if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? nullptr : type.uri,
528 typeName, type.version, {})) {
529 return QQmlType();
530 }
531
534
535 QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
537
538 return QQmlType(priv);
539}
540
542{
543 if (type.structVersion > 1)
544 qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
545
546 // Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
548
550 bool fileImport = false;
551 if (*(type.uri) == '\0')
552 fileImport = true;
553 if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName,
554 type.version, {})) {
555 return QQmlType();
556 }
557
560
561 QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
563
564 return QQmlType(priv);
565}
566
568{
569 Q_DISABLE_COPY_MOVE(QQmlMetaTypeRegistrationFailureRecorder)
570public:
572 : data(data)
573 {
574 data->setTypeRegistrationFailures(failures);
575 }
576
578 {
579 data->setTypeRegistrationFailures(nullptr);
580 }
581
583};
584
585
587 QQmlMetaTypeData *data, const QUrl &url, const QHashedStringRef &qualifiedType,
589{
590 const int dot = qualifiedType.indexOf(QLatin1Char('.'));
591 const QString typeName = dot < 0
592 ? qualifiedType.toString()
593 : QString(qualifiedType.constData() + dot + 1, qualifiedType.length() - dot - 1);
594
595 QStringList failures;
596 QQmlMetaTypeRegistrationFailureRecorder failureRecorder(data, &failures);
597
598 // Register the type. Note that the URI parameters here are empty; for
599 // file type imports, we do not place them in a URI as we don't
600 // necessarily have a good and unique one (picture a library import,
601 // which may be found in multiple plugin locations on disk), but there
602 // are other reasons for this too.
603 //
604 // By not putting them in a URI, we prevent the types from being
605 // registered on a QQmlTypeModule; this is important, as once types are
606 // placed on there, they cannot be easily removed, meaning if the
607 // developer subsequently loads a different import (meaning different
608 // types) with the same URI (using, say, a different plugin path), it is
609 // very undesirable that we continue to associate the types from the
610 // "old" URI with that new module.
611 //
612 // Not having URIs also means that the types cannot be found by name
613 // etc, the only way to look them up is through QQmlImports -- for
614 // better or worse.
618 if (checkRegistration(registrationType, data, nullptr, typeName, version, {})) {
619
620 // TODO: Ideally we should defer most of this work using some lazy/atomic mechanism
621 // that creates the details on first use. We must not observably modify
622 // QQmlTypePrivate after it has been created since it is supposed to be immutable
623 // and shared across threads.
624
625 auto *priv = new QQmlTypePrivate(registrationType);
627
628 priv->setName(QString(), typeName);
629 priv->version = version;
630
632 priv->extraData.singletonTypeData->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo;
633 priv->extraData.singletonTypeData->singletonInstanceInfo->url = url;
634 priv->extraData.singletonTypeData->singletonInstanceInfo->typeName = typeName;
635 } else {
636 priv->extraData.compositeTypeData = url;
637 }
638
639 data->registerType(priv);
641 return QQmlType(priv);
642 }
643
644 // This means that the type couldn't be found by URL, but could not be
645 // registered either, meaning we most likely were passed some kind of bad
646 // data.
647 if (errors) {
649 error.setDescription(failures.join(u'\n'));
650 errors->prepend(error);
651 } else {
652 qWarning("%s", failures.join(u'\n').toLatin1().constData());
653 }
654 return QQmlType();
655}
656
658 const QUrl &url, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
660{
663
664 bool urlExists = true;
665 auto found = data->urlToType.find(normalized);
666 if (found == data->urlToType.end()) {
667 found = data->urlToNonFileImportType.find(normalized);
668 if (found == data->urlToNonFileImportType.end())
669 urlExists = false;
670 }
671
672 if (urlExists) {
673 const auto composite = data->compositeTypes.constFind(found.value()->typeId.iface());
674 if (composite == data->compositeTypes.constEnd() || composite.value() == compilationUnit)
675 return QQmlType(*found);
676 }
677
680
681 if (!urlExists && type.isValid())
682 data->urlToType.insert(normalized, type.priv());
683
684 return type;
685}
686
688{
690 priv->setName(QString(), url.fragment());
691
692 priv->extraData.inlineComponentTypeData = url;
693
696
698 const QQmlType result(priv);
699 priv->release();
700
701 data->inlineComponentTypes.insert(url, result);
702
703 return result;
704}
705
707 const QUrl &url, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit)
708{
710
711 // If there is an "unclaimed" inline component type, we can "claim" it now. Otherwise
712 // we have to create a new one.
713 const auto it = data->inlineComponentTypes.constFind(url);
714 if (it != data->inlineComponentTypes.constEnd()) {
715 const auto jt = data->compositeTypes.constFind(it->typeId().iface());
716 if (jt == data->compositeTypes.constEnd() || *jt == compilationUnit)
717 return *it;
718 }
719
721}
722
724{
725 // This may be called from delayed dtors on shutdown when the data is already gone.
727 if (data.isValid()) {
728 if (QQmlValueType *vt = data->metaTypeToValueType.take(metaType.id()))
729 delete vt;
730 if (QQmlValueType *vt = data->metaTypeToValueType.take(listMetaType.id()))
731 delete vt;
732
733 auto it = data->compositeTypes.constFind(metaType.iface());
734 if (it != data->compositeTypes.constEnd())
735 data->compositeTypes.erase(it);
736 }
737
739 QMetaType::unregisterMetaType(listMetaType);
740 delete static_cast<const QQmlMetaTypeInterface *>(metaType.iface());
741 delete static_cast<const QQmlListMetaTypeInterface *>(listMetaType.iface());
742}
743
745 const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration)
746{
747 if (hookRegistration.structVersion > 1)
748 qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
749
751 data->lookupCachedQmlUnit << hookRegistration.lookupCachedQmlUnit;
752 return 0;
753}
754
757{
758 if (container.structVersion > 1)
759 qFatal("qmlRegisterSequenceContainer(): Cannot mix incompatible QML versions.");
760
762
764 container.version, {})) {
765 return QQmlType();
766 }
767
769
770 data->registerType(priv);
771 priv->setName(QString::fromUtf8(container.uri), QString());
772 priv->version = container.version;
773 priv->revision = container.revision;
774 priv->typeId = container.metaSequence.valueMetaType();
775 priv->listId = container.typeId;
776 priv->extraData.sequentialContainerTypeData = container.metaSequence;
777
779
780 return QQmlType(priv);
781}
782
784{
785 unregisterType(id);
786}
787
789 bool weakProtectAllVersions)
790{
792 if (version.hasMajorVersion()) {
793 if (QQmlTypeModule *module = data->findTypeModule(uri, version)) {
794 if (!weakProtectAllVersions) {
795 module->setLockLevel(QQmlTypeModule::LockLevel::Strong);
796 return true;
797 }
798 } else {
799 return false;
800 }
801 }
802
803 const auto range = std::equal_range(
804 data->uriToModule.begin(), data->uriToModule.end(), uri,
805 std::less<ModuleUri>());
806
807 for (auto it = range.first; it != range.second; ++it)
808 (*it)->setLockLevel(QQmlTypeModule::LockLevel::Weak);
809
810 return range.first != range.second;
811}
812
814 const QQmlDirParser::Import &import)
815{
817
818 data->moduleImports.insert(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import);
819}
820
822 const QQmlDirParser::Import &import)
823{
825 data->moduleImports.remove(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import);
826}
827
829 const QString &uri, QTypeRevision version)
830{
833
834 const auto unrevisioned = data->moduleImports.equal_range(
836 for (auto it = unrevisioned.second; it != unrevisioned.first;)
837 result.append(*(--it));
838
839 if (version.hasMajorVersion()) {
840 const auto revisioned = data->moduleImports.equal_range(
841 QQmlMetaTypeData::VersionedUri(uri, version));
842 for (auto it = revisioned.second; it != revisioned.first;)
843 result.append(*(--it));
844 return result;
845 }
846
847 // Use latest module available with that URI.
848 const auto begin = data->moduleImports.begin();
849 auto it = unrevisioned.first;
850 if (it == begin)
851 return result;
852
853 const QQmlMetaTypeData::VersionedUri latestVersion = (--it).key();
854 if (latestVersion.uri != uri)
855 return result;
856
857 do {
858 result += *it;
859 } while (it != begin && (--it).key() == latestVersion);
860
861 return result;
862}
863
864void QQmlMetaType::registerModule(const char *uri, QTypeRevision version)
865{
867
868 QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
869 Q_ASSERT(module);
870
871 if (version.hasMinorVersion())
872 module->addMinorVersion(version.minorVersion());
873}
874
875int QQmlMetaType::typeId(const char *uri, QTypeRevision version, const char *qmlName)
876{
878
879 QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
880 if (!module)
881 return -1;
882
883 QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), version);
884 if (!type.isValid())
885 return -1;
886
887 return type.index();
888}
889
891{
893 data->undeletableTypes.insert(dtype);
894}
895
897 QTypeRevision version)
898{
899 // Has any type previously been installed to this namespace?
900 QHashedString nameSpace(uri);
901 for (const QQmlType &type : data->types) {
902 if (type.module() == nameSpace && type.version().majorVersion() == version.majorVersion())
903 return true;
904 }
905
906 return false;
907}
908
910 QObject *instance, const QString &basePath, const QString &uri,
911 const QString &typeNamespace, QTypeRevision version, QList<QQmlError> *errors)
912{
913 if (!typeNamespace.isEmpty() && typeNamespace != uri) {
914 // This is an 'identified' module
915 // The namespace for type registrations must match the URI for locating the module
916 if (errors) {
918 error.setDescription(
919 QStringLiteral("Module namespace '%1' does not match import URI '%2'")
920 .arg(typeNamespace, uri));
921 errors->prepend(error);
922 }
924 }
925
926 QStringList failures;
928 {
929 QQmlMetaTypeRegistrationFailureRecorder failureRecorder(data, &failures);
930 if (!typeNamespace.isEmpty()) {
931 // This is an 'identified' module
932 if (namespaceContainsRegistrations(data, typeNamespace, version)) {
933 // Other modules have already installed to this namespace
934 if (errors) {
936 error.setDescription(QStringLiteral("Namespace '%1' has already been used "
937 "for type registration")
938 .arg(typeNamespace));
939 errors->prepend(error);
940 }
942 }
943 } else {
944 // This is not an identified module - provide a warning
945 qWarning().nospace() << qPrintable(
946 QStringLiteral("Module '%1' does not contain a module identifier directive - "
947 "it cannot be protected from external registrations.").arg(uri));
948 }
949
950 if (instance && !qobject_cast<QQmlEngineExtensionInterface *>(instance)) {
951 QQmlTypesExtensionInterface *iface = qobject_cast<QQmlTypesExtensionInterface *>(instance);
952 if (!iface) {
953 if (errors) {
955 // Also does not implement QQmlTypesExtensionInterface, but we want to discourage that.
956 error.setDescription(QStringLiteral("Module loaded for URI '%1' does not implement "
957 "QQmlEngineExtensionInterface").arg(typeNamespace));
958 errors->prepend(error);
959 }
961 }
962
963#if QT_DEPRECATED_SINCE(6, 3)
964 if (auto *plugin = qobject_cast<QQmlExtensionPlugin *>(instance)) {
965 // basepath should point to the directory of the module, not the plugin file itself:
966 QQmlExtensionPluginPrivate::get(plugin)->baseUrl
968 }
969#else
970 Q_UNUSED(basePath)
971#endif
972
973 const QByteArray bytes = uri.toUtf8();
974 const char *moduleId = bytes.constData();
975 iface->registerTypes(moduleId);
976 }
977
978 if (failures.isEmpty() && !data->registerModuleTypes(uri))
980
981 if (!failures.isEmpty()) {
982 if (errors) {
983 for (const QString &failure : std::as_const(failures)) {
985 error.setDescription(failure);
986 errors->prepend(error);
987 }
988 }
990 }
991 }
992
994}
995
996/*
997 \internal
998
999 Fetches the QQmlType instance registered for \a urlString, creating a
1000 registration for it if it is not already registered, using the associated
1001 \a typeName, \a isCompositeSingleton, \a majorVersion and \a minorVersion
1002 details.
1003
1004 Errors (if there are any) are placed into \a errors, if it is nonzero.
1005 Otherwise errors are printed as warnings.
1006*/
1008 const QHashedStringRef &qualifiedType,
1010 QTypeRevision version)
1011{
1012 // ### unfortunate (costly) conversion
1013 const QUrl url = QQmlTypeLoader::normalize(QUrl(urlString));
1014
1016 {
1017 QQmlType ret(data->urlToType.value(url));
1018 if (ret.isValid() && ret.sourceUrl() == url)
1019 return ret;
1020 }
1021 {
1022 QQmlType ret(data->urlToNonFileImportType.value(url));
1023 if (ret.isValid() && ret.sourceUrl() == url)
1024 return ret;
1025 }
1026
1028 data, url, qualifiedType, mode, errors, version);
1029 data->urlToType.insert(url, type.priv());
1030 return type;
1031}
1032
1033/*
1034 Returns the latest version of \a uri installed, or an in valid QTypeRevision().
1035*/
1037{
1039 auto upper = std::upper_bound(data->uriToModule.begin(), data->uriToModule.end(), uri,
1040 std::less<ModuleUri>());
1041 if (upper == data->uriToModule.begin())
1042 return QTypeRevision();
1043
1044 const auto module = (--upper)->get();
1045 return (module->module() == uri)
1046 ? QTypeRevision::fromVersion(module->majorVersion(), module->maximumMinorVersion())
1047 : QTypeRevision();
1048}
1049
1050/*
1051 Returns true if a module \a uri of this version is installed and locked;
1052*/
1054{
1056
1057 if (QQmlTypeModule* qqtm = data->findTypeModule(uri, version))
1058 return qqtm->lockLevel() == QQmlTypeModule::LockLevel::Strong;
1059 return false;
1060}
1061
1062/*
1063 Returns the best matching registered version for the given \a module. If \a version is
1064 the does not have a major version, returns the latest registered version. Otherwise
1065 chooses the same major version and checks if the minor version is within the range
1066 of registered minor versions. If so, retuens the original version, otherwise returns
1067 an invalid version. If \a version does not have a minor version, chooses the latest one.
1068*/
1070{
1071 if (!version.hasMajorVersion())
1072 return latestModuleVersion(module);
1073
1075
1076 // first, check Types
1077 if (QQmlTypeModule *tm = data->findTypeModule(module, version)) {
1078 if (!version.hasMinorVersion())
1079 return QTypeRevision::fromVersion(version.majorVersion(), tm->maximumMinorVersion());
1080
1081 if (tm->minimumMinorVersion() <= version.minorVersion()
1082 && tm->maximumMinorVersion() >= version.minorVersion()) {
1083 return version;
1084 }
1085 }
1086
1087 return QTypeRevision();
1088}
1089
1091{
1093
1094 if (version.hasMajorVersion())
1095 return data->findTypeModule(uri, version);
1096
1097 auto range = std::equal_range(data->uriToModule.begin(), data->uriToModule.end(),
1098 uri, std::less<ModuleUri>());
1099
1100 return range.first == range.second ? nullptr : (--range.second)->get();
1101}
1102
1104{
1106 return data->parentFunctions;
1107}
1108
1110{
1111 if (!v.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
1112 if (ok) *ok = false;
1113 return nullptr;
1114 }
1115
1116 if (ok) *ok = true;
1117
1118 return *(QObject *const *)v.constData();
1119}
1120
1121/*
1122 Returns the item type for a list of type \a id.
1123 */
1125{
1126 if (isList(metaType)) {
1127 const auto iface = metaType.iface();
1128 if (iface && iface->metaObjectFn == &dynamicQmlListMarker)
1129 return QMetaType(static_cast<const QQmlListMetaTypeInterface *>(iface)->valueType);
1130 } else if (metaType.flags() & QMetaType::PointerToQObject) {
1131 return QMetaType();
1132 }
1133
1135 Q_ASSERT(data);
1136 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1137
1138 if (type && type->listId == metaType)
1139 return type->typeId;
1140 else
1141 return QMetaType {};
1142}
1143
1145 const QMetaObject *mo)
1146{
1148
1149 QQmlType type(data->metaObjectToType.value(mo));
1150 return type.attachedPropertiesFunction(engine);
1151}
1152
1154{
1155 int idx = metaObject->indexOfClassInfo("DefaultProperty");
1156 if (-1 == idx)
1157 return QMetaProperty();
1158
1159 QMetaClassInfo info = metaObject->classInfo(idx);
1160 if (!info.value())
1161 return QMetaProperty();
1162
1163 idx = metaObject->indexOfProperty(info.value());
1164 if (-1 == idx)
1165 return QMetaProperty();
1166
1167 return metaObject->property(idx);
1168}
1169
1171{
1172 if (!obj)
1173 return QMetaProperty();
1174
1175 const QMetaObject *metaObject = obj->metaObject();
1177}
1178
1180{
1181 int idx = metaObject->indexOfClassInfo("DefaultMethod");
1182 if (-1 == idx)
1183 return QMetaMethod();
1184
1185 QMetaClassInfo info = metaObject->classInfo(idx);
1186 if (!info.value())
1187 return QMetaMethod();
1188
1189 idx = metaObject->indexOfMethod(info.value());
1190 if (-1 == idx)
1191 return QMetaMethod();
1192
1193 return metaObject->method(idx);
1194}
1195
1197{
1198 if (!obj)
1199 return QMetaMethod();
1200
1201 const QMetaObject *metaObject = obj->metaObject();
1202 return defaultMethod(metaObject);
1203}
1204
1209{
1211 return data->interfaces.contains(type.id());
1212}
1213
1215{
1217 const QQmlType type(data->idToType.value(metaType.id()));
1218 return (type.isInterface() && type.typeId() == metaType) ? type.interfaceIId() : nullptr;
1219}
1220
1222{
1223 if (type.flags().testFlag(QMetaType::IsQmlList))
1224 return true;
1225 else
1226 return false;
1227}
1228
1234{
1235 int slash = qualifiedName.indexOf(QLatin1Char('/'));
1236 if (slash <= 0)
1237 return QQmlType();
1238
1239 QHashedStringRef module(qualifiedName.constData(), slash);
1240 QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.size() - slash - 1);
1241
1242 return qmlType(name, module, version);
1243}
1244
1254 QTypeRevision version)
1255{
1257
1258 const QHashedString key(QString::fromRawData(name.constData(), name.length()), name.hash());
1260 while (it != data->nameToType.cend() && it.key() == name) {
1261 QQmlType t(*it);
1262 if (module.isEmpty() || t.availableInVersion(module, version))
1263 return t;
1264 ++it;
1265 }
1266
1267 return QQmlType();
1268}
1269
1275{
1277 return QQmlType(data->metaObjectToType.value(metaObject));
1278}
1279
1286 QTypeRevision version)
1287{
1289
1290 const auto range = data->metaObjectToType.equal_range(metaObject);
1291 for (auto it = range.first; it != range.second; ++it) {
1292 QQmlType t(*it);
1293 if (module.isEmpty() || t.availableInVersion(module, version))
1294 return t;
1295 }
1296
1297 return QQmlType();
1298}
1299
1305{
1307 QQmlType type = data->types.value(qmlTypeId);
1308 if (type.isValid())
1309 return type;
1310 return QQmlType();
1311}
1312
1318{
1320 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1321 return (type && type->typeId == metaType) ? QQmlType(type) : QQmlType();
1322}
1323
1325{
1327 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1328 return (type && type->listId == metaType) ? QQmlType(type) : QQmlType();
1329}
1330
1337QQmlType QQmlMetaType::qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports /* = false */)
1338{
1339 const QUrl url = QQmlTypeLoader::normalize(unNormalizedUrl);
1341
1342 QQmlType type(data->urlToType.value(url));
1343 if (!type.isValid() && includeNonFileImports)
1344 type = QQmlType(data->urlToNonFileImportType.value(url));
1345
1346 if (type.sourceUrl() == url)
1347 return type;
1348 else
1349 return QQmlType();
1350}
1351
1353{
1355 const auto it = data->inlineComponentTypes.constFind(url);
1356 if (it != data->inlineComponentTypes.constEnd())
1357 return *it;
1358
1360}
1361
1362
1370{
1371 if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted)
1373 return QQmlMetaType::propertyCache(obj->metaObject(), version);
1374}
1375
1377 const QMetaObject *metaObject, QTypeRevision version)
1378{
1379 QQmlMetaTypeDataPtr data; // not const: the cache is created on demand
1380 return data->propertyCache(metaObject, version);
1381}
1382
1384 const QQmlType &type, QTypeRevision version)
1385{
1386 QQmlMetaTypeDataPtr data; // not const: the cache is created on demand
1387 return data->propertyCache(type, version);
1388}
1389
1396{
1398 if (auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1399 return QQmlMetaObject(composite);
1400
1401 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1402 return (type && type->typeId == metaType) ? type->baseMetaObject : nullptr;
1403}
1404
1411{
1413 if (auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1414 return QQmlMetaObject(composite);
1415
1416 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1417 return (type && type->typeId == metaType)
1419 : nullptr;
1420}
1421
1428{
1430 if (auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1431 return composite;
1432
1433 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1434 if (type && type->typeId == metaType) {
1435 if (const QMetaObject *mo = QQmlType(type).metaObject())
1436 return data->propertyCache(mo, type->version);
1437 }
1438
1440}
1441
1450{
1452 if (auto composite = QQmlMetaType::findPropertyCacheInCompositeTypes(metaType))
1453 return composite;
1454
1455 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1456 return (type && type->typeId == metaType)
1457 ? data->propertyCache(type->baseMetaObject, QTypeRevision())
1459}
1460
1468 QMetaType metaType, QTypeRevision version)
1469{
1471 if (auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1472 return composite;
1473
1474 const QQmlTypePrivate *typePriv = data->idToType.value(metaType.id());
1475 if (!typePriv || typePriv->typeId != metaType)
1477
1478 const QQmlType type(typePriv);
1479 if (type.containsRevisionedAttributes()) {
1480 // It can only have (revisioned) properties or methods if it has a metaobject
1481 Q_ASSERT(type.metaObject());
1482 return data->propertyCache(type, version);
1483 }
1484
1485 if (const QMetaObject *metaObject = type.metaObject())
1486 return data->propertyCache(metaObject, version);
1487
1489}
1490
1492{
1494 const QQmlType type = data->types.value(typeIndex);
1495 if (const QQmlTypePrivate *d = type.priv()) {
1496 if (d->regType == QQmlType::CompositeType || d->regType == QQmlType::CompositeSingletonType)
1497 removeFromInlineComponents(data->inlineComponentTypes, d);
1498 removeQQmlTypePrivate(data->idToType, d);
1499 removeQQmlTypePrivate(data->nameToType, d);
1500 removeQQmlTypePrivate(data->urlToType, d);
1501 removeQQmlTypePrivate(data->urlToNonFileImportType, d);
1502 removeQQmlTypePrivate(data->metaObjectToType, d);
1503 for (auto & module : data->uriToModule)
1504 module->remove(d);
1505 data->clearPropertyCachesForVersion(typeIndex);
1506 data->types[typeIndex] = QQmlType();
1507 data->undeletableTypes.remove(type);
1508 }
1509}
1510
1512{
1513 Q_ASSERT(type);
1514
1516 data->metaObjectToType.insert(metaobject, type);
1517}
1518
1520{
1521 for (auto it = data->inlineComponentTypes.begin(), end = data->inlineComponentTypes.end();
1522 it != end; ++it) {
1523 if (!QQmlMetaType::equalBaseUrls(it.key(), d->sourceUrl()))
1524 continue;
1525
1526 const QQmlTypePrivate *icPriv = it->priv();
1527 if (icPriv && icPriv->count() > 1)
1528 return true;
1529 }
1530 return false;
1531}
1532
1534{
1536
1537 // in case this is being called during program exit, `data` might be destructed already
1538 if (!data.isValid())
1539 return;
1540
1541 bool deletedAtLeastOneType;
1542 do {
1543 deletedAtLeastOneType = false;
1545 while (it != data->types.end()) {
1546 const QQmlTypePrivate *d = (*it).priv();
1547 if (d && d->count() == 1 && !hasActiveInlineComponents(data, d)) {
1548 deletedAtLeastOneType = true;
1549
1550 if (d->regType == QQmlType::CompositeType
1551 || d->regType == QQmlType::CompositeSingletonType) {
1552 removeFromInlineComponents(data->inlineComponentTypes, d);
1553 }
1554 removeQQmlTypePrivate(data->idToType, d);
1555 removeQQmlTypePrivate(data->nameToType, d);
1556 removeQQmlTypePrivate(data->urlToType, d);
1557 removeQQmlTypePrivate(data->urlToNonFileImportType, d);
1558 removeQQmlTypePrivate(data->metaObjectToType, d);
1559
1560 for (auto &module : data->uriToModule)
1561 module->remove(d);
1562
1563 data->clearPropertyCachesForVersion(d->index);
1564 *it = QQmlType();
1565 } else {
1566 ++it;
1567 }
1568 }
1569 } while (deletedAtLeastOneType);
1570
1571 bool deletedAtLeastOneCache;
1572 do {
1573 deletedAtLeastOneCache = false;
1574 auto it = data->propertyCaches.begin();
1575 while (it != data->propertyCaches.end()) {
1576 if ((*it)->count() == 1) {
1577 it = data->propertyCaches.erase(it);
1578 deletedAtLeastOneCache = true;
1579 } else {
1580 ++it;
1581 }
1582 }
1583 } while (deletedAtLeastOneCache);
1584}
1585
1590{
1592
1594 names.reserve(data->nameToType.size());
1596 while (it != data->nameToType.cend()) {
1597 QQmlType t(*it);
1598 names += t.qmlTypeName();
1599 ++it;
1600 }
1601
1602 return names;
1603}
1604
1609{
1611
1613 for (const QQmlTypePrivate *t : data->nameToType)
1614 types.append(QQmlType(t));
1615
1616 return types;
1617}
1618
1623{
1625 return data->types;
1626}
1627
1632{
1634
1635 QList<QQmlType> retn;
1636 for (const auto t : std::as_const(data->nameToType)) {
1637 QQmlType type(t);
1638 if (type.isSingleton())
1639 retn.append(type);
1640 }
1641 return retn;
1642}
1643
1645{
1646 quint32 numTypedFunctions = 0;
1648 function; ++function) {
1649 if (function->functionPtr)
1650 ++numTypedFunctions;
1651 else
1652 return false;
1653 }
1654 return numTypedFunctions == unit->qmlData->functionTableSize;
1655}
1656
1659{
1662
1663 for (const auto lookup : std::as_const(data->lookupCachedQmlUnit)) {
1664 if (const QQmlPrivate::CachedQmlUnit *unit = lookup(uri)) {
1665 QString error;
1667 qCDebug(DBG_DISK_CACHE) << "Error loading pre-compiled file " << uri << ":" << error;
1668 if (status)
1670 return nullptr;
1671 }
1672
1673 if (mode == RequireFullyTyped && !isFullyTyped(unit)) {
1674 qCDebug(DBG_DISK_CACHE)
1675 << "Error loading pre-compiled file " << uri
1676 << ": compilation unit contains functions not compiled to native code.";
1677 if (status)
1679 return nullptr;
1680 }
1681
1682 if (status)
1684 return unit;
1685 }
1686 }
1687
1688 if (status)
1690
1691 return nullptr;
1692}
1693
1695{
1697 data->lookupCachedQmlUnit.prepend(handler);
1698}
1699
1701{
1703 data->lookupCachedQmlUnit.removeAll(handler);
1704}
1705
1710{
1712
1713 if (!object)
1714 return typeName;
1715
1716 QQmlType type = QQmlMetaType::qmlType(object->metaObject());
1717 if (type.isValid()) {
1718 typeName = type.qmlTypeName();
1719 const int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
1720 if (lastSlash != -1)
1721 typeName = typeName.mid(lastSlash + 1);
1722 }
1723
1724 if (typeName.isEmpty()) {
1725 typeName = QString::fromUtf8(object->metaObject()->className());
1726 int marker = typeName.indexOf(QLatin1String("_QMLTYPE_"));
1727 if (marker != -1)
1728 typeName = typeName.left(marker);
1729
1730 marker = typeName.indexOf(QLatin1String("_QML_"));
1731 if (marker != -1) {
1734 if (type.isValid()) {
1735 QString qmlTypeName = type.qmlTypeName();
1736 const int lastSlash = qmlTypeName.lastIndexOf(QLatin1Char('/'));
1737 if (lastSlash != -1)
1738 qmlTypeName = qmlTypeName.mid(lastSlash + 1);
1739 if (!qmlTypeName.isEmpty())
1741 }
1742 }
1743 }
1744
1745 return typeName;
1746}
1747
1749 const QMetaObject *baseMetaObject,
1750 QMetaObject *lastMetaObject)
1751{
1753 mo = mo->d.superdata;
1754
1755 if (!mo)
1756 return metaObjects;
1757
1758 auto createProxyMetaObject = [&](QQmlTypePrivate *This,
1759 const QMetaObject *superdataBaseMetaObject,
1760 const QMetaObject *extMetaObject,
1761 QObject *(*extFunc)(QObject *)) {
1762 if (!extMetaObject)
1763 return;
1764
1765 QMetaObjectBuilder builder;
1766 clone(builder, extMetaObject, superdataBaseMetaObject, baseMetaObject,
1768 QMetaObject *mmo = builder.toMetaObject();
1769 mmo->d.superdata = baseMetaObject;
1770 if (!metaObjects.isEmpty())
1771 metaObjects.constLast().metaObject->d.superdata = mmo;
1772 else if (lastMetaObject)
1773 lastMetaObject->d.superdata = mmo;
1774 QQmlProxyMetaObject::ProxyData data = { mmo, extFunc, 0, 0 };
1775 metaObjects << data;
1776 registerMetaObjectForType(mmo, This);
1777 };
1778
1779 for (const QQmlMetaTypeDataPtr data; mo; mo = mo->d.superdata) {
1780 // TODO: There can in fact be multiple QQmlTypePrivate* for a single QMetaObject*.
1781 // This algorithm only accounts for the most recently inserted one. That's pretty
1782 // random. However, the availability of types depends on what documents you have
1783 // loaded before. Just adding all possible extensions would also be pretty random.
1784 // The right way to do this would be to take the relations between the QML modules
1785 // into account. For this we would need proper module dependency information.
1786 if (QQmlTypePrivate *t = data->metaObjectToType.value(mo)) {
1787 if (t->regType == QQmlType::CppType) {
1788 createProxyMetaObject(
1789 t, t->baseMetaObject, t->extraData.cppTypeData->extMetaObject,
1790 t->extraData.cppTypeData->extFunc);
1791 } else if (t->regType == QQmlType::SingletonType) {
1792 createProxyMetaObject(
1793 t, t->baseMetaObject, t->extraData.singletonTypeData->extMetaObject,
1794 t->extraData.singletonTypeData->extFunc);
1795 }
1796 }
1797 };
1798
1799 return metaObjects;
1800}
1801
1802static bool isInternalType(int idx)
1803{
1804 // Qt internal types
1805 switch (idx) {
1807 case QMetaType::QStringList:
1808 case QMetaType::QObjectStar:
1809 case QMetaType::VoidStar:
1810 case QMetaType::Nullptr:
1812 case QMetaType::QLocale:
1813 case QMetaType::QImage: // scarce type, keep as QVariant
1814 case QMetaType::QPixmap: // scarce type, keep as QVariant
1815 return true;
1816 default:
1817 return false;
1818 }
1819}
1820
1822{
1823 if (!type.isValid() || isInternalType(type.id()))
1824 return false;
1825
1826 return valueType(type) != nullptr;
1827}
1828
1830{
1831 switch (metaType.id()) {
1832 case QMetaType::QPoint:
1833 return &QQmlPointValueType::staticMetaObject;
1834 case QMetaType::QPointF:
1835 return &QQmlPointFValueType::staticMetaObject;
1836 case QMetaType::QSize:
1837 return &QQmlSizeValueType::staticMetaObject;
1838 case QMetaType::QSizeF:
1839 return &QQmlSizeFValueType::staticMetaObject;
1840 case QMetaType::QRect:
1841 return &QQmlRectValueType::staticMetaObject;
1842 case QMetaType::QRectF:
1843 return &QQmlRectFValueType::staticMetaObject;
1844#if QT_CONFIG(easingcurve)
1845 case QMetaType::QEasingCurve:
1846 return &QQmlEasingValueType::staticMetaObject;
1847#endif
1848 default:
1849 break;
1850 }
1851
1852 // It doesn't have to be a gadget for a QML type to exist, but we don't want to
1853 // call QObject pointers value types. Explicitly registered types also override
1854 // the implicit use of gadgets.
1855 if (!(metaType.flags() & QMetaType::PointerToQObject)) {
1857 return mo;
1858 }
1859
1860 // If it _is_ a gadget, we can just use it.
1861 if (metaType.flags() & QMetaType::IsGadget)
1862 return metaType.metaObject();
1863
1864 return nullptr;
1865}
1866
1868{
1870
1871 const auto it = data->metaTypeToValueType.constFind(type.id());
1872 if (it != data->metaTypeToValueType.constEnd())
1873 return *it;
1874
1876 return *data->metaTypeToValueType.insert(type.id(), new QQmlValueType(type, mo));
1877 return *data->metaTypeToValueType.insert(type.id(), nullptr);
1878}
1879
1881{
1883 return data->findPropertyCacheInCompositeTypes(t);
1884}
1885
1888{
1890
1891 auto doInsert = [&data, &compilationUnit](const QtPrivate::QMetaTypeInterface *iface) {
1892 Q_ASSERT(iface);
1893 const auto it = data->compositeTypes.constFind(iface);
1894 Q_ASSERT(it == data->compositeTypes.constEnd() || *it == compilationUnit);
1895 data->compositeTypes.insert(iface, compilationUnit);
1896 };
1897
1898 doInsert(compilationUnit->qmlType.typeId().iface());
1899 for (auto &&inlineData: compilationUnit->inlineComponentData)
1900 doInsert(inlineData.qmlType.typeId().iface());
1901}
1902
1905{
1907
1908 auto doRemove = [&](const QtPrivate::QMetaTypeInterface *iface) {
1909 if (!iface)
1910 return;
1911
1912 const auto it = data->compositeTypes.constFind(iface);
1913 if (it != data->compositeTypes.constEnd() && *it == compilationUnit)
1914 data->compositeTypes.erase(it);
1915 };
1916
1917 doRemove(compilationUnit->qmlType.typeId().iface());
1918 for (auto &&inlineData: compilationUnit->inlineComponentData)
1919 doRemove(inlineData.qmlType.typeId().iface());
1920}
1921
1924{
1926
1927 int result = 0;
1928 auto doCheck = [&](const QtPrivate::QMetaTypeInterface *iface) {
1929 if (!iface)
1930 return;
1931
1932 const auto it = data->compositeTypes.constFind(iface);
1933 if (it != data->compositeTypes.constEnd() && *it == compilationUnit)
1934 ++result;
1935 };
1936
1937 doCheck(compilationUnit->qmlType.typeId().iface());
1938 for (auto &&inlineData: compilationUnit->inlineComponentData)
1939 doCheck(inlineData.qmlType.typeId().iface());
1940
1941 return result;
1942}
1943
1946{
1948 return data->compositeTypes.value(type.iface());
1949}
1950
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
\inmodule QtCore\reentrant
Definition qdatetime.h:257
void swap(QHash &other) noexcept
Definition qhash.h:898
int indexOf(const QChar &, int from=0) const
QString toString() const
const QChar * constData() const
bool isEmpty() const
Definition qlist.h:74
bool isEmpty() const noexcept
Definition qlist.h:390
const T & constLast() const noexcept
Definition qlist.h:633
void prepend(rvalue_ref t)
Definition qlist.h:456
void append(parameter_type t)
Definition qlist.h:441
\inmodule QtCore
\inmodule QtCore
const char * name() const
Returns the name of the type (without the scope).
void setAccess(QMetaMethod::Access value)
Sets the access specification of this method (private, protected, or public) to value.
\inmodule QtCore
Definition qmetaobject.h:18
QMetaEnumBuilder addEnumerator(const QByteArray &name)
Adds a new enumerator to this class with the specified name.
QMetaObject * toMetaObject() const
Converts this meta object builder into a concrete QMetaObject.
int addClassInfo(const QByteArray &name, const QByteArray &value)
Adds name and value as an item of class information to this class.
QMetaMethodBuilder addMethod(const QByteArray &signature)
Adds a new public method to this class with the specified signature.
QMetaPropertyBuilder addProperty(const QByteArray &name, const QByteArray &type, int notifierId=-1)
Adds a new readable/writable property to this class with the specified name and type.
void setClassName(const QByteArray &name)
Sets the name of the class being constructed by this meta object builder.
\inmodule QtCore
QMetaType valueMetaType() const
Returns the meta type for values stored in the container.
\inmodule QtCore
Definition qmetatype.h:320
constexpr TypeFlags flags() const
Definition qmetatype.h:2628
const QtPrivate::QMetaTypeInterface * iface() const
Definition qmetatype.h:750
static QMetaType fromName(QByteArrayView name)
Returns a QMetaType matching typeName.
int id(int=0) const
Definition qmetatype.h:454
@ PointerToQObject
Definition qmetatype.h:385
@ PointerToGadget
Definition qmetatype.h:392
constexpr const QMetaObject * metaObject() const
Definition qmetatype.h:2633
static void unregisterMetaType(QMetaType type)
friend class QVariant
Definition qmetatype.h:775
\inmodule QtCore
Definition qmutex.h:317
static QObjectPrivate * get(QObject *o)
Definition qobject_p.h:153
\inmodule QtCore
Definition qobject.h:90
The QQmlCustomParser class allows you to add new arbitrary types to QML.
The QQmlError class encapsulates a QML error.
Definition qqmlerror.h:18
static QUrl urlFromLocalFileOrQrcOrUrl(const QString &)
QQmlMetaTypeData & operator*()
~QQmlMetaTypeDataPtr()=default
QQmlMetaTypeData * operator->()
const QQmlMetaTypeData * operator->() const
const QQmlMetaTypeData & operator*() const
QQmlMetaTypeRegistrationFailureRecorder(QQmlMetaTypeData *data, QStringList *failures)
static QQmlType qmlTypeById(int qmlTypeId)
Returns the type (if any) that corresponds to qmlTypeId.
static QQmlType registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type)
static QQmlType registerSequentialContainer(const QQmlPrivate::RegisterSequentialContainer &sequenceRegistration)
static QString prettyTypeName(const QObject *object)
Returns the pretty QML type name (e.g.
static void unregisterType(int type)
static void qmlRemoveModuleRegistration(const QString &uri)
static QMetaType listValueType(QMetaType type)
static void registerUndeletableType(const QQmlType &dtype)
static QQmlPropertyCache::ConstPtr rawPropertyCacheForType(QMetaType metaType)
static bool equalBaseUrls(const QUrl &aUrl, const QUrl &bUrl)
static void unregisterAutoParentFunction(const QQmlPrivate::AutoParentFunction &function)
static int countInternalCompositeTypeSelfReferences(const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit)
static bool protectModule(const QString &uri, QTypeRevision version, bool weakProtectAllVersions=false)
static bool isStronglyLockedModule(const QString &uri, QTypeRevision version)
static QQmlType qmlListType(QMetaType metaType)
static void registerInternalCompositeType(const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit)
static void removeCachedUnitLookupFunction(QQmlPrivate::QmlUnitCacheLookupFunction handler)
static void prependCachedUnitLookupFunction(QQmlPrivate::QmlUnitCacheLookupFunction handler)
static void registerModule(const char *uri, QTypeRevision version)
static bool isList(QMetaType type)
static QQmlType registerInterface(const QQmlPrivate::RegisterInterface &type)
static int typeId(const char *uri, QTypeRevision version, const char *qmlName)
static const char * interfaceIId(QMetaType type)
static QQmlType registerType(const QQmlPrivate::RegisterType &type)
static QList< QQmlProxyMetaObject::ProxyData > proxyData(const QMetaObject *mo, const QMetaObject *baseMetaObject, QMetaObject *lastMetaObject)
static const QMetaObject * metaObjectForValueType(QMetaType type)
static QQmlMetaObject metaObjectForType(QMetaType metaType)
static QQmlPropertyCache::ConstPtr findPropertyCacheInCompositeTypes(QMetaType t)
static QQmlType inlineComponentTypeForUrl(const QUrl &url)
static QList< QQmlPrivate::AutoParentFunction > parentFunctions()
static QTypeRevision matchingModuleVersion(const QString &module, QTypeRevision version)
static void registerModuleImport(const QString &uri, QTypeRevision version, const QQmlDirParser::Import &import)
static QList< QQmlDirParser::Import > moduleImports(const QString &uri, QTypeRevision version)
static QQmlAttachedPropertiesFunc attachedPropertiesFunc(QQmlEnginePrivate *, const QMetaObject *)
static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd, ClonePolicy policy)
static QObject * toQObject(const QVariant &, bool *ok=nullptr)
static void registerTypeAlias(int typeId, const QString &name)
static QQmlType registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
static void qmlInsertModuleRegistration(const QString &uri, void(*registerFunction)())
static int registerAutoParentFunction(const QQmlPrivate::RegisterAutoParent &autoparent)
static QList< QQmlType > qmlSingletonTypes()
Returns the list of registered QML singleton types.
static QTypeRevision latestModuleVersion(const QString &uri)
static QQmlTypeModule * typeModule(const QString &uri, QTypeRevision version)
static void clearTypeRegistrations()
static bool qmlRegisterModuleTypes(const QString &uri)
static bool isInterface(QMetaType type)
See qmlRegisterInterface() for information about when this will return true.
static QQmlMetaObject rawMetaObjectForType(QMetaType metaType)
static QQmlValueType * valueType(QMetaType metaType)
static QMetaProperty defaultProperty(const QMetaObject *)
static void removeFromInlineComponents(InlineComponentContainer &container, const QQmlTypePrivate *reference)
static QQmlType typeForUrl(const QString &urlString, const QHashedStringRef &typeName, CompositeTypeLookupMode mode, QList< QQmlError > *errors, QTypeRevision version=QTypeRevision())
static const QQmlPrivate::CachedQmlUnit * findCachedCompilationUnit(const QUrl &uri, CacheMode mode, CachedUnitLookupError *status)
static QQmlPropertyCache::ConstPtr propertyCache(QObject *object, QTypeRevision version=QTypeRevision())
Returns a QQmlPropertyCache for obj if one is available.
static QQmlType registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version)
Returns the type (if any) of URI-qualified named qualifiedName and version specified by version_major...
static QList< QQmlType > qmlTypes()
Returns the list of registered QML types.
static QList< QString > qmlTypeNames()
Returns the list of registered QML type names.
static void registerMetaObjectForType(const QMetaObject *metaobject, QQmlTypePrivate *type)
static void freeUnusedTypesAndCaches()
static void unregisterSequentialContainer(int id)
static QQmlType findCompositeType(const QUrl &url, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, CompositeTypeLookupMode mode=NonSingleton)
static bool isValueType(QMetaType type)
static QQmlType findInlineComponentType(const QUrl &url, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit)
static void removeQQmlTypePrivate(QQmlTypeContainer &container, const QQmlTypePrivate *reference)
static int registerUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration)
static QList< QQmlType > qmlAllTypes()
Returns the list of all registered types.
static RegistrationResult registerPluginTypes(QObject *instance, const QString &basePath, const QString &uri, const QString &typeNamespace, QTypeRevision version, QList< QQmlError > *errors)
static void unregisterInternalCompositeType(QMetaType metaType, QMetaType listMetaType)
static QMetaMethod defaultMethod(const QMetaObject *)
static void unregisterModuleImport(const QString &uri, QTypeRevision version, const QQmlDirParser::Import &import)
static QQmlRefPointer< QV4::ExecutableCompilationUnit > obtainExecutableCompilationUnit(QMetaType type)
static QQmlPropertyCache::ConstPtr propertyCacheForType(QMetaType metaType)
int count() const
static QUrl normalize(const QUrl &unNormalizedUrl)
LockLevel lockLevel() const
QQmlType type(const QHashedStringRef &name, QTypeRevision version) const
void addMinorVersion(quint8 minorVersion)
void add(QQmlTypePrivate *)
const QMetaObject * baseMetaObject
@ InlineComponentType
Definition qqmltype_p.h:156
@ SingletonType
Definition qqmltype_p.h:152
@ SequentialContainerType
Definition qqmltype_p.h:157
@ CompositeType
Definition qqmltype_p.h:154
@ CompositeSingletonType
Definition qqmltype_p.h:155
@ InterfaceType
Definition qqmltype_p.h:153
int index() const
Definition qqmltype.cpp:734
const QMetaObject * metaObject() const
Definition qqmltype.cpp:658
\inmodule QtCore
Definition qmutex.h:313
iterator begin()
Definition qset.h:136
iterator end()
Definition qset.h:140
const_iterator cend() const noexcept
Definition qset.h:142
const_iterator constEnd() const noexcept
Definition qset.h:143
iterator erase(const_iterator i)
Definition qset.h:145
const_iterator constFind(const T &value) const
Definition qset.h:161
const_iterator cbegin() const noexcept
Definition qset.h:138
iterator insert(const T &value)
Definition qset.h:155
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:76
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition qstring.h:1101
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8606
static QString fromRawData(const QChar *, qsizetype size)
Constructs a QString that uses the first size Unicode characters in the array unicode.
Definition qstring.cpp:9242
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4420
QByteArray toUtf8() const &
Definition qstring.h:563
\inmodule QtCore
static constexpr QTypeRevision fromVersion(Major majorVersion, Minor minorVersion)
Produces a QTypeRevision from the given majorVersion and minorVersion, both of which need to be a val...
constexpr bool hasMinorVersion() const
Returns true if the minor version is known, otherwise false.
constexpr bool hasMajorVersion() const
Returns true if the major version is known, otherwise false.
constexpr quint8 minorVersion() const
Returns the minor version encoded in the revision.
constexpr quint8 majorVersion() const
Returns the major version encoded in the revision.
\inmodule QtCore
Definition qurl.h:94
QString fragment(ComponentFormattingOptions options=PrettyDecoded) const
Returns the fragment of the URL.
Definition qurl.cpp:2679
static bool verifyHeader(const CompiledData::Unit *unit, QDateTime expectedSourceTimeStamp, QString *errorString)
\inmodule QtCore
Definition qvariant.h:64
QSet< QString >::iterator it
auto mo
[7]
const CachedQmlUnit *(* QmlUnitCacheLookupFunction)(const QUrl &url)
AutoParentResult(* AutoParentFunction)(QObject *object, QObject *parent)
Combined button and popup list for selecting options.
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
static QDBusError::ErrorType get(const char *name)
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:162
#define qFatal
Definition qlogging.h:164
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
return ret
static ControlElement< T > * ptr(QWidget *widget)
static const QMetaObjectPrivate * priv(const uint *data)
const char * typeName
GLsizei const GLfloat * v
[13]
GLenum mode
const GLfloat * m
GLuint64 key
GLuint GLuint end
GLsizei GLenum GLenum * types
GLuint object
[3]
GLsizei range
GLenum type
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
const GLchar * marker
GLuint name
GLhandleARB obj
[2]
GLuint GLuint * names
GLdouble GLdouble t
Definition qopenglext.h:243
GLint GLenum GLboolean normalized
Definition qopenglext.h:752
GLuint64EXT * result
[6]
GLsizei const GLchar *const * string
[0]
Definition qopenglext.h:694
static qreal dot(const QPointF &a, const QPointF &b)
int qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
Definition qqml.cpp:337
static void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data)
static bool namespaceContainsRegistrations(const QQmlMetaTypeData *data, const QString &uri, QTypeRevision version)
static bool isFullyTyped(const QQmlPrivate::CachedQmlUnit *unit)
static void addQQmlMetaTypeInterfaces(QQmlTypePrivate *priv, const QByteArray &className)
static bool hasActiveInlineComponents(const QQmlMetaTypeData *data, const QQmlTypePrivate *d)
static bool isInternalType(int idx)
static QQmlTypePrivate * createQQmlType(QQmlMetaTypeData *data, const QQmlPrivate::RegisterInterface &type)
static QQmlType createTypeForUrl(QQmlMetaTypeData *data, const QUrl &url, const QHashedStringRef &qualifiedType, QQmlMetaType::CompositeTypeLookupMode mode, QList< QQmlError > *errors, QTypeRevision version)
static bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data, const char *uri, const QString &typeName, QTypeRevision version, QMetaType::TypeFlags flags)
static QQmlTypeModule * getTypeModule(const QHashedString &uri, QTypeRevision version, QQmlMetaTypeData *data)
static QQmlType doRegisterInlineComponentType(QQmlMetaTypeData *data, const QUrl &url)
static QString registrationTypeString(QQmlType::RegistrationType typeType)
const QMetaObject * dynamicQmlListMarker(const QtPrivate::QMetaTypeInterface *)
QQmlPrivate::QQmlAttachedPropertiesFunc< QObject > QQmlAttachedPropertiesFunc
Definition qqmlprivate.h:62
static const char * qmlTypeName(const QObject *object)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
static QLatin1StringView typeStr(QShaderDescription::VariableType t)
SSL_CTX int(*) void arg)
#define qPrintable(string)
Definition qstring.h:1391
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
#define Q_UNUSED(x)
unsigned int quint32
Definition qtypes.h:45
const char property[13]
Definition qwizard.cpp:101
const char className[16]
[1]
Definition qwizard.cpp:100
QFileInfo info(fileName)
[8]
QUrl url("example.com")
[constructor-url-reference]
obj metaObject() -> className()
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
QStringList files
[8]
QSizePolicy policy
QJSEngine engine
[0]
ModuleUri(const std::unique_ptr< QQmlTypeModule > &module)
ModuleUri(const QString &string)
\inmodule QtCore \reentrant
Definition qchar.h:17
SuperData superdata
\inmodule QtCore
int propertyCount() const
Returns the number of properties in this class, including the number of properties provided by each b...
int indexOfClassInfo(const char *name) const
Finds class information item name and returns its index; otherwise returns -1.
int indexOfEnumerator(const char *name) const
Finds enumerator name and returns its index; otherwise returns -1.
int enumeratorOffset() const
Returns the enumerator offset for this class; i.e.
int methodCount() const
Returns the number of methods in this class, including the number of methods provided by each base cl...
int classInfoCount() const
Returns the number of items of class information in this class.
int indexOfProperty(const char *name) const
Finds property name and returns its index; otherwise returns -1.
int methodOffset() const
Returns the method offset for this class; i.e.
struct QMetaObject::Data d
QMetaMethod method(int index) const
Returns the meta-data for the method with the given index.
int propertyOffset() const
Returns the property offset for this class; i.e.
int enumeratorCount() const
Returns the number of enumerators in this class.
int classInfoOffset() const
Returns the class information offset for this class; i.e.
const AOTCompiledFunction * aotCompiledFunctions
const QV4::CompiledData::Unit * qmlData
QmlUnitCacheLookupFunction lookupCachedQmlUnit
static QByteArray createClassNameTypeByUrl(const QUrl &url)
static QByteArray createClassNameForInlineComponent(const QUrl &baseUrl, const QString &name)