7#include <private/qqmlextensionplugin_p.h>
8#include <private/qqmlmetatypedata_p.h>
9#include <private/qqmlpropertycachecreator_p.h>
10#include <private/qqmlscriptblob_p.h>
11#include <private/qqmlscriptdata_p.h>
12#include <private/qqmltype_p_p.h>
13#include <private/qqmltypemodule_p.h>
14#include <private/qqmlvaluetype_p.h>
16#include <QtCore/qcoreapplication.h>
17#include <QtCore/qmutex.h>
18#include <QtCore/qloggingcategory.h>
25
26
27
28
30struct LockedData :
private QQmlMetaTypeData
32 friend class QQmlMetaTypeDataPtr;
35Q_GLOBAL_STATIC(LockedData, metaTypeData)
36Q_GLOBAL_STATIC(QRecursiveMutex, metaTypeDataLock)
38struct ModuleUri :
public QString
40 ModuleUri(
const QString &string) : QString(string) {}
41 ModuleUri(
const std::unique_ptr<QQmlTypeModule> &module) : QString(module->module()) {}
63 LockedData *data =
nullptr;
67 const QQmlPrivate::RegisterInterface &type)
69 auto *d =
new QQmlTypePrivate(QQmlType::InterfaceType);
70 d->extraData.interfaceTypeData = type.iid;
71 d->typeId = type.typeId;
72 d->listId = type.listId;
73 d->module = QString::fromUtf8(type.uri);
74 d->version = type.version;
75 data->registerType(d);
80 QQmlMetaTypeData *data,
const QString &elementName,
81 const QQmlPrivate::RegisterSingletonType &type,
82 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
84 auto *d =
new QQmlTypePrivate(QQmlType::SingletonType);
85 data->registerType(d);
87 d->setName(QString::fromUtf8(type.uri), elementName);
88 d->version = type.version;
90 if (type.qObjectApi) {
91 d->baseMetaObject = type.instanceMetaObject;
92 d->typeId = type.typeId;
93 d->revision = type.revision;
96 d->extraData.singletonTypeData->singletonInstanceInfo = siinfo;
97 d->extraData.singletonTypeData->extFunc = type.extensionObjectCreate;
98 d->extraData.singletonTypeData->extMetaObject = type.extensionMetaObject;
104 const QQmlPrivate::RegisterType &type)
106 QQmlTypePrivate *d =
new QQmlTypePrivate(QQmlType::CppType);
107 data->registerType(d);
108 d->setName(QString::fromUtf8(type.uri), elementName);
110 d->version = type.version;
111 d->revision = type.revision;
112 d->typeId = type.typeId;
113 d->listId = type.listId;
114 d->extraData.cppTypeData->allocationSize = type.objectSize;
115 d->extraData.cppTypeData->userdata = type.userdata;
116 d->extraData.cppTypeData->newFunc = type.create;
117 d->extraData.cppTypeData->noCreationReason = type.noCreationReason;
118 d->extraData.cppTypeData->createValueTypeFunc = type.createValueType;
119 d->baseMetaObject = type.metaObject;
120 d->extraData.cppTypeData->attachedPropertiesFunc = type.attachedPropertiesFunction;
121 d->extraData.cppTypeData->attachedPropertiesType = type.attachedPropertiesMetaObject;
122 d->extraData.cppTypeData->parserStatusCast = type.parserStatusCast;
123 d->extraData.cppTypeData->propertyValueSourceCast = type.valueSourceCast;
124 d->extraData.cppTypeData->propertyValueInterceptorCast = type.valueInterceptorCast;
125 d->extraData.cppTypeData->finalizerCast = type.has(QQmlPrivate::RegisterType::FinalizerCast)
128 d->extraData.cppTypeData->extFunc = type.extensionObjectCreate;
129 d->extraData.cppTypeData->customParser =
reinterpret_cast<QQmlCustomParser *>(type.customParser);
130 d->extraData.cppTypeData->registerEnumClassesUnscoped =
true;
131 d->extraData.cppTypeData->registerEnumsFromRelatedTypes =
true;
132 d->extraData.cppTypeData->constructValueType = type.has(QQmlPrivate::RegisterType::CreationMethod)
133 && type.creationMethod != QQmlPrivate::ValueTypeCreationMethod::None;
134 d->extraData.cppTypeData->populateValueType = type.has(QQmlPrivate::RegisterType::CreationMethod)
135 && type.creationMethod == QQmlPrivate::ValueTypeCreationMethod::Structured;
137 if (type.extensionMetaObject)
138 d->extraData.cppTypeData->extMetaObject = type.extensionMetaObject;
141 if (d->baseMetaObject) {
142 auto indexOfUnscoped = d->baseMetaObject->indexOfClassInfo(
"RegisterEnumClassesUnscoped");
143 if (indexOfUnscoped != -1
144 && qstrcmp(d->baseMetaObject->classInfo(indexOfUnscoped).value(),
"false") == 0) {
145 d->extraData.cppTypeData->registerEnumClassesUnscoped =
false;
148 auto indexOfRelated = d->baseMetaObject->indexOfClassInfo(
"RegisterEnumsFromRelatedTypes");
149 if (indexOfRelated != -1
150 && qstrcmp(d->baseMetaObject->classInfo(indexOfRelated).value(),
"false") == 0) {
151 d->extraData.cppTypeData->registerEnumsFromRelatedTypes =
false;
159 QQmlMetaTypeData *data,
const QUrl &url, QQmlTypePrivate *priv,
const QByteArray &className)
161 Q_ASSERT(!className.isEmpty());
162 QByteArray ptr = className +
'*';
163 QByteArray lst =
"QQmlListProperty<" + className +
'>';
165 QQmlMetaTypeData::CompositeMetaTypes &types = data->compositeMetaTypes[url];
167 Q_ASSERT(types.listType);
169 QMetaType::unregisterMetaType(QMetaType(types.type));
170 QMetaType::unregisterMetaType(QMetaType(types.listType));
172 types.type->name = std::move(ptr);
173 types.type->QMetaTypeInterface::name = types.type->name.constData();
174 types.listType->name = std::move(lst);
175 types.listType->QMetaTypeInterface::name = types.listType->name.constData();
177 types.type =
new QQmlMetaTypeInterface(std::move(ptr));
178 types.listType =
new QQmlListMetaTypeInterface(std::move(lst), types.type);
181 QMetaType ptr_type(types.type);
182 QMetaType lst_type(types.listType);
188 priv->typeId = ptr_type;
189 priv->listId = lst_type;
193 const QQmlPrivate::RegisterCompositeType &type)
195 auto *d =
new QQmlTypePrivate(QQmlType::CompositeType);
196 data->registerType(d);
197 d->setName(QString::fromUtf8(type.uri), elementName);
198 d->version = type.version;
200 const QUrl normalized = QQmlMetaType::normalizedUrl(type.url);
201 d->extraData.compositeTypeData = normalized;
202 addQQmlMetaTypeInterfaces(
203 data, normalized, d, QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(normalized));
208 QQmlMetaTypeData *data,
const QString &elementName,
209 const QQmlPrivate::RegisterCompositeSingletonType &type,
210 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
212 auto *d =
new QQmlTypePrivate(QQmlType::CompositeSingletonType);
213 data->registerType(d);
214 d->setName(QString::fromUtf8(type.uri), elementName);
216 d->version = type.version;
218 d->extraData.singletonTypeData->singletonInstanceInfo = siinfo;
219 const QUrl &url = siinfo->url;
220 addQQmlMetaTypeInterfaces(
221 data, url, d, QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(url));
225void QQmlMetaType::clone(QMetaObjectBuilder &builder,
const QMetaObject *mo,
226 const QMetaObject *ignoreStart,
const QMetaObject *ignoreEnd,
227 QQmlMetaType::ClonePolicy policy)
230 builder.setClassName(mo->className());
233 for (
int ii = mo->classInfoOffset(); ii < mo->classInfoCount(); ++ii) {
234 QMetaClassInfo info = mo->classInfo(ii);
236 int otherIndex = ignoreEnd->indexOfClassInfo(info.name());
237 if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
240 builder.addClassInfo(info.name(), info.value());
244 if (policy != QQmlMetaType::CloneEnumsOnly) {
246 for (
int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) {
247 QMetaMethod method = mo->method(ii);
250 QByteArray name = method.name();
254 for (
int ii = ignoreStart->methodOffset() + ignoreStart->methodCount();
255 !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount(); ++ii) {
257 QMetaMethod other = ignoreEnd->method(ii);
259 found = name == other.name();
262 QMetaMethodBuilder m = builder.addMethod(method);
264 m.setAccess(QMetaMethod::Private);
268 for (
int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) {
269 QMetaProperty property = mo->property(ii);
271 int otherIndex = ignoreEnd->indexOfProperty(property.name());
272 if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) {
273 builder.addProperty(QByteArray(
"__qml_ignore__") + property.name(),
277 builder.addProperty(property);
283 for (
int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) {
284 QMetaEnum enumerator = mo->enumerator(ii);
286 int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name());
287 if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) {
290 builder.addEnumerator(enumerator);
295void QQmlMetaType::qmlInsertModuleRegistration(
const QString &uri,
void (*registerFunction)())
297 QQmlMetaTypeDataPtr data;
298 if (data->moduleTypeRegistrationFunctions.contains(uri))
299 qFatal(
"Cannot add multiple registrations for %s", qPrintable(uri));
301 data->moduleTypeRegistrationFunctions.insert(uri, registerFunction);
304void QQmlMetaType::qmlRemoveModuleRegistration(
const QString &uri)
306 QQmlMetaTypeDataPtr data;
311 if (!data->moduleTypeRegistrationFunctions.remove(uri))
312 qFatal(
"Cannot remove multiple registrations for %s", qPrintable(uri));
315bool QQmlMetaType::qmlRegisterModuleTypes(
const QString &uri)
317 QQmlMetaTypeDataPtr data;
318 return data->registerModuleTypes(uri);
321void QQmlMetaType::clearTypeRegistrations()
324 QQmlMetaTypeDataPtr data;
326 data->uriToModule.clear();
328 data->idToType.clear();
329 data->nameToType.clear();
330 data->urlToType.clear();
331 data->speculativeInlineComponentTypes.clear();
332 data->metaObjectToType.clear();
333 data->undeletableTypes.clear();
334 data->propertyCaches.clear();
336 qDeleteAll(data->metaTypeToValueType);
337 data->metaTypeToValueType.clear();
339 data->moduleImports.clear();
341 data->clearCompositeTypes();
343 qDeleteAll(data->metaTypeToValueType);
344 data->metaTypeToValueType.clear();
346 data->clearCompositeMetaTypes();
349void QQmlMetaType::registerTypeAlias(
int typeIndex,
const QString &name)
351 QQmlMetaTypeDataPtr data;
352 const QQmlType type = data->types.value(typeIndex).type;
353 const QQmlTypePrivate *priv = type.priv();
354 data->nameToType.insert(name, priv);
357int QQmlMetaType::registerAutoParentFunction(
const QQmlPrivate::RegisterAutoParent &function)
359 if (function.structVersion > 1)
360 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
362 QQmlMetaTypeDataPtr data;
364 data->parentFunctions.append(function.function);
366 return data->parentFunctions.size() - 1;
369void QQmlMetaType::unregisterAutoParentFunction(
const QQmlPrivate::AutoParentFunction &function)
371 QQmlMetaTypeDataPtr data;
372 data->parentFunctions.removeOne(function);
375QQmlType QQmlMetaType::registerInterface(
const QQmlPrivate::RegisterInterface &type)
377 if (type.structVersion > 1)
378 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
380 QQmlMetaTypeDataPtr data;
381 QQmlTypePrivate *priv = createQQmlType(data, type);
385 data->idToType.insert(priv->typeId.id(), priv);
386 data->idToType.insert(priv->listId.id(), priv);
388 return QQmlType(priv);
394 if (typeType == QQmlType::CppType)
395 typeStr = QStringLiteral(
"element");
396 else if (typeType == QQmlType::SingletonType)
397 typeStr = QStringLiteral(
"singleton type");
398 else if (typeType == QQmlType::CompositeSingletonType)
399 typeStr = QStringLiteral(
"composite singleton type");
400 else if (typeType == QQmlType::SequentialContainerType)
401 typeStr = QStringLiteral(
"sequential container type");
403 typeStr = QStringLiteral(
"type");
409 QQmlType::RegistrationType typeType, QQmlMetaTypeData *data,
const char *uri,
410 const QString &typeName, QTypeRevision version, QMetaType::TypeFlags flags)
412 if (!typeName.isEmpty()) {
413 if (typeName.at(0).isLower() && (flags & QMetaType::PointerToQObject)) {
414 QString failure(QCoreApplication::translate(
"qmlRegisterType",
"Invalid QML %1 name \"%2\"; type names must begin with an uppercase letter"));
415 data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType), typeName));
419 if (typeName.at(0).isUpper()
420 && (flags & (QMetaType::IsGadget | QMetaType::PointerToGadget))) {
421 qCWarning(lcTypeRegistration).noquote()
422 << QCoreApplication::translate(
424 "Invalid QML %1 name \"%2\"; "
425 "value type names should begin with a lowercase letter")
426 .arg(registrationTypeString(typeType), typeName);
432 int typeNameLen = typeName.size();
433 for (
int ii = 0; ii < typeNameLen; ++ii) {
434 if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == u'_')) {
435 QString failure(QCoreApplication::translate(
"qmlRegisterType",
"Invalid QML %1 name \"%2\""));
436 data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType), typeName));
442 if (uri && !typeName.isEmpty()) {
443 QString nameSpace = QString::fromUtf8(uri);
445 if (qqtm && qqtm->lockLevel() != QQmlTypeModule::LockLevel::Open) {
446 QString failure(QCoreApplication::translate(
448 "Cannot install %1 '%2' into protected module '%3' version '%4'"));
449 data->recordTypeRegFailure(failure
450 .arg(registrationTypeString(typeType), typeName, nameSpace)
451 .arg(version.majorVersion()));
461 const QHashedString &uri, QTypeRevision version, QQmlMetaTypeData *data)
465 return data->addTypeModule(std::make_unique<QQmlTypeModule>(uri, version.majorVersion()));
473 if (!type->elementName.isEmpty())
474 data->nameToType.insert(type->elementName, type);
476 if (type->baseMetaObject)
477 data->metaObjectToType.insert(type->baseMetaObject, type);
479 if (type->regType == QQmlType::SequentialContainerType) {
480 if (type->listId.isValid())
481 data->idToType.insert(type->listId.id(), type);
483 if (type->typeId.isValid())
484 data->idToType.insert(type->typeId.id(), type);
486 if (type->listId.flags().testFlag(QMetaType::IsQmlList))
487 data->idToType.insert(type->listId.id(), type);
490 if (!type->module.isEmpty()) {
491 const QHashedString &mod = type->module;
499QQmlType QQmlMetaType::registerType(
const QQmlPrivate::RegisterType &type)
501 if (type.structVersion >
int(QQmlPrivate::RegisterType::CurrentVersion))
502 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
504 QQmlMetaTypeDataPtr data;
506 QString elementName = QString::fromUtf8(type.elementName);
507 if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.version,
508 QMetaType(type.typeId).flags())) {
512 QQmlTypePrivate *priv = createQQmlType(data, elementName, type);
513 addTypeToData(priv, data);
515 return QQmlType(priv);
518QQmlType QQmlMetaType::registerSingletonType(
519 const QQmlPrivate::RegisterSingletonType &type,
520 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
522 if (type.structVersion > 1)
523 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
525 QQmlMetaTypeDataPtr data;
527 QString typeName = QString::fromUtf8(type.typeName);
528 if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.version,
529 QMetaType(type.typeId).flags())) {
533 QQmlTypePrivate *priv = createQQmlType(data, typeName, type, siinfo);
535 addTypeToData(priv, data);
537 return QQmlType(priv);
540QQmlType QQmlMetaType::registerCompositeSingletonType(
541 const QQmlPrivate::RegisterCompositeSingletonType &type,
542 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
544 if (type.structVersion > 1)
545 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
548 QQmlMetaTypeDataPtr data;
550 QString typeName = QString::fromUtf8(type.typeName);
551 if (!checkRegistration(
552 QQmlType::CompositeSingletonType, data, type.uri, typeName, type.version, {})) {
556 QQmlTypePrivate *priv = createQQmlType(data, typeName, type, siinfo);
557 addTypeToData(priv, data);
559 data->urlToType.insert(siinfo->url, priv);
561 return QQmlType(priv);
564QQmlType QQmlMetaType::registerCompositeType(
const QQmlPrivate::RegisterCompositeType &type)
566 if (type.structVersion > 1)
567 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
570 QQmlMetaTypeDataPtr data;
572 QString typeName = QString::fromUtf8(type.typeName);
573 if (!checkRegistration(QQmlType::CompositeType, data, type.uri, typeName, type.version, {}))
576 QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
577 addTypeToData(priv, data);
579 data->urlToType.insert(QQmlMetaType::normalizedUrl(type.url), priv);
581 return QQmlType(priv);
604 QQmlMetaTypeData *data,
const QUrl &url,
const QHashedStringRef &qualifiedType,
605 QQmlMetaType::CompositeTypeLookupMode mode, QList<QQmlError> *errors, QTypeRevision version)
607 const int dot = qualifiedType.indexOf(QLatin1Char(
'.'));
608 const QString typeName = dot < 0
609 ? qualifiedType.toString()
610 : QString(qualifiedType.constData() + dot + 1, qualifiedType.length() - dot - 1);
612 QStringList failures;
632 QQmlType::RegistrationType registrationType;
634 case QQmlMetaType::Singleton:
635 registrationType = QQmlType::CompositeSingletonType;
637 case QQmlMetaType::NonSingleton:
638 registrationType = QQmlType::CompositeType;
640 case QQmlMetaType::JavaScript:
641 registrationType = QQmlType::JavaScriptType;
644 Q_UNREACHABLE_RETURN(QQmlType());
647 if (checkRegistration(registrationType, data,
nullptr, typeName, version, {})) {
654 auto *priv =
new QQmlTypePrivate(registrationType);
655 addQQmlMetaTypeInterfaces(
656 data, url, priv, QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(url));
658 priv->setName(QString(), typeName);
659 priv->version = version;
662 case QQmlMetaType::Singleton: {
663 QQmlType::SingletonInstanceInfo::Ptr siinfo = QQmlType::SingletonInstanceInfo::create();
665 siinfo->typeName = typeName.toUtf8();
666 priv->extraData.singletonTypeData->singletonInstanceInfo =
667 QQmlType::SingletonInstanceInfo::ConstPtr(
668 siinfo.take(), QQmlType::SingletonInstanceInfo::ConstPtr::Adopt);
671 case QQmlMetaType::NonSingleton: {
672 priv->extraData.compositeTypeData = url;
675 case QQmlMetaType::JavaScript: {
676 priv->extraData.javaScriptTypeData = url;
681 data->registerType(priv);
682 addTypeToData(priv, data);
683 return QQmlType(priv);
691 error.setDescription(failures.join(u'\n'));
692 errors->prepend(error);
694 qWarning(
"%s", failures.join(u'\n').toLatin1().constData());
699QQmlType QQmlMetaType::findCompositeType(
700 const QUrl &url,
const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit,
701 CompositeTypeLookupMode mode)
703 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
704 QQmlMetaTypeDataPtr data;
706 bool urlExists =
true;
707 auto found = data->urlToType.constFind(normalized);
708 if (found == data->urlToType.cend())
712 if (compilationUnit.isNull())
713 return QQmlType(*found);
714 const auto [begin, end]
715 = std::as_const(data->compositeTypes).equal_range(found.value()->typeId.iface());
717 return QQmlType(*found);
718 for (
auto it = begin; it != end; ++it) {
719 if (it.value() == compilationUnit)
720 return QQmlType(*found);
724 const QQmlType type = createTypeForUrl(
725 data, normalized, QHashedStringRef(), mode,
nullptr, QTypeRevision());
727 if (!urlExists && type.isValid())
728 data->urlToType.insert(normalized, type.priv());
735 QQmlTypePrivate *priv =
new QQmlTypePrivate(QQmlType::InlineComponentType);
736 priv->setName(QString(), url.fragment());
738 priv->extraData.inlineComponentTypeData = url;
739 data->registerType(priv);
741 addQQmlMetaTypeInterfaces(
742 data, url, priv, QQmlPropertyCacheCreatorBase::createClassNameForInlineComponent(url));
743 data->urlToType.insert(url, priv);
745 data->idToType.insert(priv->typeId.id(), priv);
746 data->idToType.insert(priv->listId.id(), priv);
748 return QQmlType(priv);
751QQmlType QQmlMetaType::findOrCreateFactualInlineComponentType(
752 const QUrl &url,
const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
754 QQmlMetaTypeDataPtr data;
758 const auto it = data->urlToType.constFind(url);
759 if (it == data->urlToType.constEnd())
760 return doRegisterInlineComponentType(data, url);
762 const auto [begin, end]
763 = std::as_const(data->compositeTypes).equal_range((*it)->typeId.iface());
765 data->speculativeInlineComponentTypes.remove(url);
766 return QQmlType(*it);
769 for (
auto jt = begin; jt != end; ++jt) {
770 if (*jt != compilationUnit)
773 data->speculativeInlineComponentTypes.remove(url);
774 return QQmlType(*it);
777 return doRegisterInlineComponentType(data, url);
780int QQmlMetaType::registerUnitCacheHook(
781 const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration)
783 if (hookRegistration.structVersion > 1)
784 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
786 QQmlMetaTypeDataPtr data;
787 data->lookupCachedQmlUnit << hookRegistration.lookupCachedQmlUnit;
791QQmlType QQmlMetaType::registerSequentialContainer(
792 const QQmlPrivate::RegisterSequentialContainer &container)
794 if (container.structVersion > 1)
795 qFatal(
"qmlRegisterSequenceContainer(): Cannot mix incompatible QML versions.");
797 QQmlMetaTypeDataPtr data;
799 if (!checkRegistration(QQmlType::SequentialContainerType, data, container.uri, QString(),
800 container.version, {})) {
804 QQmlTypePrivate *priv =
new QQmlTypePrivate(QQmlType::SequentialContainerType);
806 data->registerType(priv);
807 priv->setName(QString::fromUtf8(container.uri), QString());
808 priv->version = container.version;
809 priv->revision = container.revision;
810 priv->typeId = container.metaSequence.valueMetaType();
811 priv->listId = container.typeId;
812 priv->extraData.sequentialContainerTypeData = container.metaSequence;
814 addTypeToData(priv, data);
816 return QQmlType(priv);
819void QQmlMetaType::unregisterSequentialContainer(
int id)
824bool QQmlMetaType::protectModule(
const QString &uri, QTypeRevision version,
825 bool weakProtectAllVersions)
827 QQmlMetaTypeDataPtr data;
828 if (version.hasMajorVersion()) {
829 if (QQmlTypeModule *module = data->findTypeModule(uri, version)) {
830 if (!weakProtectAllVersions) {
831 module->setLockLevel(QQmlTypeModule::LockLevel::Strong);
839 const auto range = std::equal_range(
840 data->uriToModule.begin(), data->uriToModule.end(), uri,
841 std::less<ModuleUri>());
843 for (
auto it = range.first; it != range.second; ++it)
844 (*it)->setLockLevel(QQmlTypeModule::LockLevel::Weak);
846 return range.first != range.second;
849void QQmlMetaType::registerModuleImport(
const QString &uri, QTypeRevision moduleVersion,
850 const QQmlDirParser::Import &import)
852 QQmlMetaTypeDataPtr data;
854 data->moduleImports.insert(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import);
857void QQmlMetaType::unregisterModuleImport(
const QString &uri, QTypeRevision moduleVersion,
858 const QQmlDirParser::Import &import)
860 QQmlMetaTypeDataPtr data;
861 data->moduleImports.remove(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import);
864QList<QQmlDirParser::Import> QQmlMetaType::moduleImports(
865 const QString &uri, QTypeRevision version)
867 QQmlMetaTypeDataPtr data;
868 QList<QQmlDirParser::Import> result;
870 const auto unrevisioned = data->moduleImports.equal_range(
871 QQmlMetaTypeData::VersionedUri(uri, QTypeRevision()));
872 for (
auto it = unrevisioned.second; it != unrevisioned.first;)
873 result.append(*(--it));
875 if (version.hasMajorVersion()) {
876 const auto revisioned = data->moduleImports.equal_range(
877 QQmlMetaTypeData::VersionedUri(uri, version));
878 for (
auto it = revisioned.second; it != revisioned.first;)
879 result.append(*(--it));
884 const auto begin = data->moduleImports.begin();
885 auto it = unrevisioned.first;
889 const QQmlMetaTypeData::VersionedUri latestVersion = (--it).key();
890 if (latestVersion.uri != uri)
895 }
while (it != begin && (--it).key() == latestVersion);
900void QQmlMetaType::registerModule(
const char *uri, QTypeRevision version)
902 QQmlMetaTypeDataPtr data;
904 QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
907 if (version.hasMinorVersion())
908 module->addMinorVersion(version.minorVersion());
911int QQmlMetaType::typeId(
const char *uri, QTypeRevision version,
const char *qmlName)
913 QQmlMetaTypeDataPtr data;
915 QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
919 QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), version);
926void QQmlMetaType::registerUndeletableType(
const QQmlType &dtype)
928 QQmlMetaTypeDataPtr data;
929 data->undeletableTypes.insert(dtype);
933 QTypeRevision version)
936 QHashedString nameSpace(uri);
937 for (
const auto &typeAndCaches : std::as_const(data->types)) {
938 const QQmlType &type = typeAndCaches.type;
939 if (type.module() == nameSpace && type.version().majorVersion() == version.majorVersion())
946QQmlMetaType::RegistrationResult QQmlMetaType::registerPluginTypes(
947 QObject *instance,
const QString &basePath,
const QString &uri,
948 const QString &typeNamespace, QTypeRevision version, QList<QQmlError> *errors)
950 if (!typeNamespace.isEmpty() && typeNamespace != uri) {
955 error.setDescription(
956 QStringLiteral(
"Module namespace '%1' does not match import URI '%2'")
957 .arg(typeNamespace, uri));
958 errors->prepend(error);
960 return RegistrationResult::Failure;
963 QStringList failures;
964 QQmlMetaTypeDataPtr data;
966 QQmlMetaTypeRegistrationFailureRecorder failureRecorder(data, &failures);
967 if (!typeNamespace.isEmpty()) {
969 if (namespaceContainsRegistrations(data, typeNamespace, version)) {
973 error.setDescription(QStringLiteral(
"Namespace '%1' has already been used "
974 "for type registration")
975 .arg(typeNamespace));
976 errors->prepend(error);
978 return RegistrationResult::Failure;
982 qWarning().nospace() << qPrintable(
983 QStringLiteral(
"Module '%1' does not contain a module identifier directive - "
984 "it cannot be protected from external registrations.").arg(uri));
987 if (instance && !qobject_cast<QQmlEngineExtensionInterface *>(instance)) {
988 QQmlTypesExtensionInterface *iface = qobject_cast<QQmlTypesExtensionInterface *>(instance);
993 error.setDescription(QStringLiteral(
"Module loaded for URI '%1' does not implement "
994 "QQmlEngineExtensionInterface").arg(typeNamespace));
995 errors->prepend(error);
997 return RegistrationResult::Failure;
1000#if QT_DEPRECATED_SINCE(6
, 3
)
1001 if (
auto *plugin = qobject_cast<QQmlExtensionPlugin *>(instance)) {
1003 QQmlExtensionPluginPrivate::get(plugin)->baseUrl
1004 = QQmlImports::urlFromLocalFileOrQrcOrUrl(basePath);
1010 const QByteArray bytes = uri.toUtf8();
1011 const char *moduleId = bytes.constData();
1012 iface->registerTypes(moduleId);
1015 if (failures.isEmpty() && !data->registerModuleTypes(uri))
1016 return RegistrationResult::NoRegistrationFunction;
1018 if (!failures.isEmpty()) {
1020 for (
const QString &failure : std::as_const(failures)) {
1022 error.setDescription(failure);
1023 errors->prepend(error);
1026 return RegistrationResult::Failure;
1030 return RegistrationResult::Success;
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044QQmlType QQmlMetaType::typeForUrl(
1045 const QUrl &url,
const QHashedStringRef &qualifiedType, CompositeTypeLookupMode mode,
1046 QList<QQmlError> *errors, QTypeRevision version)
1049 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
1051 QQmlMetaTypeDataPtr data;
1053 QQmlType ret(data->urlToType.value(normalized));
1054 if (ret.isValid() && ret.sourceUrl() == normalized)
1058 const QQmlType type = createTypeForUrl(
1059 data, normalized, qualifiedType, mode, errors, version);
1060 data->urlToType.insert(normalized, type.priv());
1065
1066
1067QTypeRevision QQmlMetaType::latestModuleVersion(
const QString &uri)
1069 QQmlMetaTypeDataPtr data;
1070 auto upper = std::upper_bound(data->uriToModule.begin(), data->uriToModule.end(), uri,
1071 std::less<ModuleUri>());
1072 if (upper == data->uriToModule.begin())
1073 return QTypeRevision();
1075 const auto module = (--upper)->get();
1076 return (module->module() == uri)
1077 ? QTypeRevision::fromVersion(module->majorVersion(), module->maximumMinorVersion())
1082
1083
1084bool QQmlMetaType::isStronglyLockedModule(
const QString &uri, QTypeRevision version)
1086 QQmlMetaTypeDataPtr data;
1088 if (QQmlTypeModule* qqtm = data->findTypeModule(uri, version))
1089 return qqtm->lockLevel() == QQmlTypeModule::LockLevel::Strong;
1094
1095
1096
1097
1098
1099
1100QTypeRevision QQmlMetaType::matchingModuleVersion(
const QString &module, QTypeRevision version)
1102 if (!version.hasMajorVersion())
1103 return latestModuleVersion(module);
1105 QQmlMetaTypeDataPtr data;
1108 if (QQmlTypeModule *tm = data->findTypeModule(module, version)) {
1109 if (!version.hasMinorVersion())
1110 return QTypeRevision::fromVersion(version.majorVersion(), tm->maximumMinorVersion());
1112 if (tm->minimumMinorVersion() <= version.minorVersion()
1113 && tm->maximumMinorVersion() >= version.minorVersion()) {
1118 return QTypeRevision();
1121QQmlTypeModule *QQmlMetaType::typeModule(
const QString &uri, QTypeRevision version)
1123 QQmlMetaTypeDataPtr data;
1125 if (version.hasMajorVersion())
1126 return data->findTypeModule(uri, version);
1128 auto range = std::equal_range(data->uriToModule.begin(), data->uriToModule.end(),
1129 uri, std::less<ModuleUri>());
1131 return range.first == range.second ?
nullptr : (--range.second)->get();
1134QList<QQmlPrivate::AutoParentFunction> QQmlMetaType::parentFunctions()
1136 QQmlMetaTypeDataPtr data;
1137 return data->parentFunctions;
1140QObject *QQmlMetaType::toQObject(
const QVariant &v,
bool *ok)
1142 if (!v.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
1143 if (ok) *ok =
false;
1149 return *(QObject *
const *)v.constData();
1153
1154
1155QMetaType QQmlMetaType::listValueType(QMetaType metaType)
1157 if (isList(metaType)) {
1158 const auto iface = metaType.iface();
1159 if (iface && iface->metaObjectFn == &dynamicQmlListMarker)
1160 return QMetaType(
static_cast<
const QQmlListMetaTypeInterface *>(iface)->valueType);
1161 }
else if (metaType.flags() & QMetaType::PointerToQObject) {
1165 QQmlMetaTypeDataPtr data;
1167 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1169 if (type && type->listId == metaType)
1170 return type->typeId;
1172 return QMetaType {};
1175QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFunc(
1176 QQmlTypeLoader *typeLoader,
const QMetaObject *mo)
1178 QQmlMetaTypeDataPtr data;
1180 QQmlType type(data->metaObjectToType.value(mo));
1181 return type.attachedPropertiesFunction(typeLoader);
1184QMetaProperty QQmlMetaType::defaultProperty(
const QMetaObject *metaObject)
1186 int idx = metaObject->indexOfClassInfo(
"DefaultProperty");
1188 return QMetaProperty();
1190 QMetaClassInfo info = metaObject->classInfo(idx);
1192 return QMetaProperty();
1194 idx = metaObject->indexOfProperty(info.value());
1196 return QMetaProperty();
1198 return metaObject->property(idx);
1201QMetaProperty QQmlMetaType::defaultProperty(QObject *obj)
1204 return QMetaProperty();
1206 const QMetaObject *metaObject = obj->metaObject();
1207 return defaultProperty(metaObject);
1210QMetaMethod QQmlMetaType::defaultMethod(
const QMetaObject *metaObject)
1212 int idx = metaObject->indexOfClassInfo(
"DefaultMethod");
1214 return QMetaMethod();
1216 QMetaClassInfo info = metaObject->classInfo(idx);
1218 return QMetaMethod();
1220 idx = metaObject->indexOfMethod(info.value());
1222 return QMetaMethod();
1224 return metaObject->method(idx);
1227QMetaMethod QQmlMetaType::defaultMethod(QObject *obj)
1230 return QMetaMethod();
1232 const QMetaObject *metaObject = obj->metaObject();
1233 return defaultMethod(metaObject);
1237
1238
1239bool QQmlMetaType::isInterface(QMetaType metaType)
1241 const QQmlMetaTypeDataPtr data;
1242 return QQmlType(data->idToType.value(metaType.id())).isInterface();
1245const char *QQmlMetaType::interfaceIId(QMetaType metaType)
1247 const QQmlMetaTypeDataPtr data;
1248 const QQmlType type(data->idToType.value(metaType.id()));
1249 return (type.isInterface() && type.typeId() == metaType) ? type.interfaceIId() :
nullptr;
1252bool QQmlMetaType::isList(QMetaType type)
1254 if (type.flags().testFlag(QMetaType::IsQmlList))
1261
1262
1263
1264QQmlType QQmlMetaType::qmlType(
const QString &qualifiedName, QTypeRevision version)
1266 int slash = qualifiedName.indexOf(QLatin1Char(
'/'));
1270 QHashedStringRef module(qualifiedName.constData(), slash);
1271 QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.size() - slash - 1);
1273 return qmlType(name, module, version);
1277
1278
1279
1280
1281
1282
1283
1284QQmlType QQmlMetaType::qmlType(
const QHashedStringRef &name,
const QHashedStringRef &module,
1285 QTypeRevision version)
1287 const QQmlMetaTypeDataPtr data;
1289 const QHashedString key(QString::fromRawData(name.constData(), name.length()), name.hash());
1290 QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(key);
1291 while (it != data->nameToType.cend() && it.key() == name) {
1293 if (module.isEmpty() || t.availableInVersion(module, version))
1302
1303
1304
1305QQmlType QQmlMetaType::qmlType(
const QMetaObject *metaObject)
1307 const QQmlMetaTypeDataPtr data;
1308 return QQmlType(data->metaObjectToType.value(metaObject));
1312
1313
1314
1315
1316QQmlType QQmlMetaType::qmlType(
const QMetaObject *metaObject,
const QHashedStringRef &module,
1317 QTypeRevision version)
1319 const QQmlMetaTypeDataPtr data;
1321 const auto range = data->metaObjectToType.equal_range(metaObject);
1322 for (
auto it = range.first; it != range.second; ++it) {
1324 if (module.isEmpty() || t.availableInVersion(module, version))
1332
1333
1334
1335QQmlType QQmlMetaType::qmlTypeById(
int qmlTypeId)
1337 const QQmlMetaTypeDataPtr data;
1338 return data->types.value(qmlTypeId).type;
1342
1343
1344
1345
1346
1347
1348
1349
1350QQmlType QQmlMetaType::firstQmlTypeForAttachmentMetaObject(
const QMetaObject *attachmentMetaObject)
1352 const QQmlMetaTypeDataPtr data;
1353 if (
auto qmlTypePriv = data->metaObjectToType.value(attachmentMetaObject)) {
1355 if (qmlTypePriv->regType == QQmlType::CppType &&
1356 qmlTypePriv->extraData.cppTypeData->attachedPropertiesType == attachmentMetaObject)
1357 return QQmlType(qmlTypePriv);
1359 auto getAttachmentMetaObject = [](
const QQmlTypePrivate *priv) ->
const QMetaObject * {
1360 if (priv->regType != QQmlType::CppType)
1362 return priv->extraData.cppTypeData->attachedPropertiesType;
1364 auto it = std::find_if(data->metaObjectToType.constBegin(),
1365 data->metaObjectToType.constEnd(),
1366 [&](
const QQmlTypePrivate *type) {
return attachmentMetaObject == getAttachmentMetaObject(type); }
1368 if (it == data->metaObjectToType.constEnd())
1370 return QQmlType(*it);
1374
1375
1376
1377QQmlType QQmlMetaType::qmlType(QMetaType metaType)
1379 const QQmlMetaTypeDataPtr data;
1380 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1381 return (type && type->typeId == metaType) ? QQmlType(type) : QQmlType();
1384QQmlType QQmlMetaType::qmlListType(QMetaType metaType)
1386 const QQmlMetaTypeDataPtr data;
1387 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1388 return (type && type->listId == metaType) ? QQmlType(type) : QQmlType();
1392
1393
1394
1395
1396
1397QQmlType QQmlMetaType::qmlType(
const QUrl &unNormalizedUrl)
1399 const QUrl url = QQmlMetaType::normalizedUrl(unNormalizedUrl);
1400 const QQmlMetaTypeDataPtr data;
1402 QQmlType type(data->urlToType.value(url));
1404 if (type.sourceUrl() == url)
1410QQmlType QQmlMetaType::findOrCreateSpeculativeInlineComponentType(
const QUrl &url)
1412 QQmlMetaTypeDataPtr data;
1413 const auto it = data->urlToType.constFind(url);
1414 if (it != data->urlToType.constEnd())
1415 return QQmlType(*it);
1420 baseUrl.setFragment(QString());
1424 if (baseUrl.isEmpty())
1425 return doRegisterInlineComponentType(data, url);
1429 const auto baseIt = data->urlToType.constFind(baseUrl);
1430 if (baseIt == data->urlToType.constEnd()) {
1431 data->speculativeInlineComponentTypes.insert(url);
1432 return doRegisterInlineComponentType(data, url);
1437 const auto cu = data->compositeTypes.value((*baseIt)->typeId.iface());
1439 data->speculativeInlineComponentTypes.insert(url);
1440 return doRegisterInlineComponentType(data, url);
1445 Q_ASSERT(std::none_of(
1446 cu->inlineComponentData.constBegin(), cu->inlineComponentData.constEnd(),
1447 [&](
const QV4::CompiledData::InlineComponentData &icData) {
1448 return icData.qmlType.elementName() == url.fragment();
1456
1457
1458
1459
1460
1461QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(QObject *obj, QTypeRevision version)
1463 if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted)
1464 return QQmlPropertyCache::ConstPtr();
1465 return QQmlMetaType::propertyCache(obj->metaObject(), version);
1468QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(
1469 const QMetaObject *metaObject, QTypeRevision version)
1471 QQmlMetaTypeDataPtr data;
1472 return data->propertyCache(metaObject, version);
1475QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(
1476 const QQmlType &type, QTypeRevision version)
1478 QQmlMetaTypeDataPtr data;
1479 return data->propertyCache(type, version);
1483
1484
1485
1486
1487QQmlMetaObject QQmlMetaType::rawMetaObjectForType(QMetaType metaType)
1489 const QQmlMetaTypeDataPtr data;
1490 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1491 return QQmlMetaObject(composite);
1493 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1494 return (type && type->typeId == metaType) ? type->baseMetaObject :
nullptr;
1498
1499
1500
1501
1502QQmlMetaObject QQmlMetaType::metaObjectForType(QMetaType metaType)
1504 const QQmlMetaTypeDataPtr data;
1505 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1506 return QQmlMetaObject(composite);
1508 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1509 return (type && type->typeId == metaType)
1510 ? QQmlType(type).metaObject()
1515
1516
1517
1518
1519QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCacheForType(QMetaType metaType)
1521 QQmlMetaTypeDataPtr data;
1522 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1525 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1526 if (type && type->typeId == metaType) {
1527 if (
const QMetaObject *mo = QQmlType(type).metaObject())
1528 return data->propertyCache(mo, type->version);
1531 return QQmlPropertyCache::ConstPtr();
1535
1536
1537
1538
1539
1540
1541QQmlPropertyCache::ConstPtr QQmlMetaType::rawPropertyCacheForType(QMetaType metaType)
1543 QQmlMetaTypeDataPtr data;
1544 if (
auto composite = QQmlMetaType::findPropertyCacheInCompositeTypes(metaType))
1547 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1548 if (!type || type->typeId != metaType)
1549 return QQmlPropertyCache::ConstPtr();
1551 const QMetaObject *metaObject = type->isValueType()
1552 ? type->metaObjectForValueType()
1553 : type->baseMetaObject;
1556 ? data->propertyCache(metaObject, QTypeRevision())
1557 : QQmlPropertyCache::ConstPtr();
1561
1562
1563
1564
1565
1566QQmlPropertyCache::ConstPtr QQmlMetaType::rawPropertyCacheForType(
1567 QMetaType metaType, QTypeRevision version)
1569 QQmlMetaTypeDataPtr data;
1570 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1573 const QQmlTypePrivate *typePriv = data->idToType.value(metaType.id());
1574 if (!typePriv || typePriv->typeId != metaType)
1575 return QQmlPropertyCache::ConstPtr();
1577 const QQmlType type(typePriv);
1578 if (type.containsRevisionedAttributes()) {
1580 Q_ASSERT(type.metaObject());
1581 return data->propertyCache(type, version);
1584 if (
const QMetaObject *metaObject = type.metaObject())
1585 return data->propertyCache(metaObject, version);
1587 return QQmlPropertyCache::ConstPtr();
1590template<
typename From,
typename CanConvertPropCache,
typename CanConvertMetaObject>
1593 CanConvertPropCache &&canConvertPropCache, CanConvertMetaObject &&canConvertMetaObject)
1601 auto [it, end] = data->compositeTypes.equal_range(metaType.iface());
1604 if (canConvertPropCache(
1605 from, QQmlMetaTypeData::propertyCacheForPotentialInlineComponentType(
1609 }
while(++it != end);
1616 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1617 if (type && type->typeId == metaType && type->baseMetaObject)
1618 return canConvertMetaObject(from, type->baseMetaObject);
1621 if (
const QMetaObject *metaObject = metaType.metaObject())
1622 return canConvertMetaObject(from, metaObject);
1627bool QQmlMetaType::canConvert(QObject *o, QMetaType metaType)
1629 QQmlMetaTypeDataPtr data;
1631 return canConvertToPropCacheOrMetaObject(
1632 data, o, metaType, [](QObject *o,
const QQmlPropertyCache::ConstPtr &propCache) {
1633 return QQmlMetaObject::canConvert(o, propCache);
1634 }, [](QObject *o,
const QMetaObject *metaObject) {
1635 return QQmlMetaObject::canConvert(o, metaObject);
1640 const QQmlPropertyCache::ConstPtr &derived,
const QQmlPropertyCache::ConstPtr &base)
1642 for (QQmlPropertyCache::ConstPtr parent = derived; parent; parent = parent->parent()) {
1650bool QQmlMetaType::canConvert(
const QQmlPropertyCache::ConstPtr &from, QMetaType metaType)
1652 QQmlMetaTypeDataPtr data;
1654 return canConvertToPropCacheOrMetaObject(
1655 data, from, metaType,
1656 [](
const QQmlPropertyCache::ConstPtr &from,
const QQmlPropertyCache::ConstPtr &to) {
1657 return inherits(from, to);
1658 }, [&](
const QQmlPropertyCache::ConstPtr &from,
const QMetaObject *toMeta) {
1659 if (
const QMetaObject *fromMeta = from->metaObject())
1660 return QQmlMetaObject::canConvert(fromMeta, toMeta);
1661 return inherits(from, data->propertyCache(toMeta, QTypeRevision()));
1665void QQmlMetaType::unregisterType(
int typeIndex)
1667 QQmlMetaTypeDataPtr data;
1668 const QQmlType type = data->types.value(typeIndex).type;
1669 if (
const QQmlTypePrivate *d = type.priv()) {
1670 if (d->regType == QQmlType::CompositeType || d->regType == QQmlType::CompositeSingletonType) {
1671 removeFromInlineComponents(data->urlToType, d);
1672 removeFromInlineComponents(data->speculativeInlineComponentTypes, d);
1674 removeQQmlTypePrivate(data->idToType, d);
1675 removeQQmlTypePrivate(data->nameToType, d);
1676 removeQQmlTypePrivate(data->urlToType, d);
1677 removeQQmlTypePrivate(data->metaObjectToType, d);
1678 data->speculativeInlineComponentTypes.remove(d->sourceUrl());
1679 for (
auto & module : data->uriToModule)
1681 data->types[typeIndex] = QQmlMetaTypeData::Type();
1682 data->undeletableTypes.remove(type);
1686void QQmlMetaType::registerMetaObjectForType(
const QMetaObject *metaobject,
const QQmlTypePrivate *type)
1690 QQmlMetaTypeDataPtr data;
1691 data->metaObjectToType.insert(metaobject, type);
1696 for (
auto it = data->urlToType.begin(), end = data->urlToType.end();
1698 if (!QQmlMetaType::equalBaseUrls(it.key(), d->sourceUrl()))
1701 const QQmlTypePrivate *icPriv = *it;
1702 if (icPriv && icPriv->count() > 1)
1709 QQmlMetaTypeData *data,
1710 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
1713 auto doCheck = [&](
const QtPrivate::QMetaTypeInterface *iface) {
1717 const auto [begin, end] = std::as_const(data->compositeTypes).equal_range(iface);
1718 for (
auto it = begin; it != end; ++it) {
1719 if (*it == compilationUnit)
1724 doCheck(compilationUnit->metaType().iface());
1725 for (
auto &&inlineData: compilationUnit->inlineComponentData)
1726 doCheck(inlineData.qmlType.typeId().iface());
1731void QQmlMetaType::freeUnusedTypesAndCaches()
1733 QQmlMetaTypeDataPtr data;
1736 if (!data.isValid())
1739 bool droppedAtLeastOneComposite;
1741 droppedAtLeastOneComposite =
false;
1742 auto it = data->compositeTypes.cbegin();
1743 while (it != data->compositeTypes.cend()) {
1744 const auto &cu = *it;
1745 if (cu->count() <= doCountInternalCompositeTypeSelfReferences(data, cu)) {
1746 QQmlMetaTypeData::clearCompositeType(cu);
1747 it = data->compositeTypes.erase(it);
1748 droppedAtLeastOneComposite =
true;
1753 }
while (droppedAtLeastOneComposite);
1755 bool deletedAtLeastOneType;
1757 deletedAtLeastOneType =
false;
1758 auto it = data->types.begin();
1759 while (it != data->types.end()) {
1760 const QQmlTypePrivate *d = it->type.priv();
1761 if (d && d->count() == 1 && !hasActiveInlineComponents(data, d)) {
1762 deletedAtLeastOneType =
true;
1764 if (d->regType == QQmlType::CompositeType
1765 || d->regType == QQmlType::CompositeSingletonType) {
1766 removeFromInlineComponents(data->urlToType, d);
1767 removeFromInlineComponents(data->speculativeInlineComponentTypes, d);
1769 removeQQmlTypePrivate(data->idToType, d);
1770 removeQQmlTypePrivate(data->nameToType, d);
1771 removeQQmlTypePrivate(data->urlToType, d);
1772 removeQQmlTypePrivate(data->metaObjectToType, d);
1773 data->speculativeInlineComponentTypes.remove(d->sourceUrl());
1775 for (
auto &module : data->uriToModule)
1778 *it = QQmlMetaTypeData::Type();
1783 }
while (deletedAtLeastOneType);
1785 bool deletedAtLeastOneCache;
1787 deletedAtLeastOneCache =
false;
1788 auto it = data->propertyCaches.begin();
1789 while (it != data->propertyCaches.end()) {
1790 if ((*it)->count() == 1) {
1791 it = data->propertyCaches.erase(it);
1792 deletedAtLeastOneCache =
true;
1797 }
while (deletedAtLeastOneCache);
1801
1802
1803QList<QString> QQmlMetaType::qmlTypeNames()
1805 const QQmlMetaTypeDataPtr data;
1807 QList<QString> names;
1808 names.reserve(data->nameToType.size());
1809 QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.cbegin();
1810 while (it != data->nameToType.cend()) {
1812 names += t.qmlTypeName();
1820
1821
1822QList<QQmlType> QQmlMetaType::qmlTypes()
1824 const QQmlMetaTypeDataPtr data;
1826 QList<QQmlType> types;
1827 for (
const QQmlTypePrivate *t : data->nameToType)
1828 types.append(QQmlType(t));
1834
1835
1836QList<QQmlType> QQmlMetaType::qmlAllTypes()
1838 const QQmlMetaTypeDataPtr data;
1839 QList<QQmlType> types;
1840 types.reserve(data->types.size());
1842 data->types.constBegin(), data->types.constEnd(),
1843 std::back_inserter(types), [](
const auto &type) {
return type.type; });
1848
1849
1850QList<QQmlType> QQmlMetaType::qmlSingletonTypes()
1852 const QQmlMetaTypeDataPtr data;
1854 QList<QQmlType> retn;
1855 for (
const auto t : std::as_const(data->nameToType)) {
1857 if (type.isSingleton())
1865 quint32 numTypedFunctions = 0;
1866 for (
const QQmlPrivate::AOTCompiledFunction *function = unit->aotCompiledFunctions;
1867 function; ++function) {
1868 if (function->functionPtr)
1869 ++numTypedFunctions;
1873 return numTypedFunctions == unit->qmlData->functionTableSize;
1876const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(
1877 const QUrl &uri, QQmlMetaType::CacheMode mode, CachedUnitLookupError *status)
1879 Q_ASSERT(mode != RejectAll);
1880 const QQmlMetaTypeDataPtr data;
1882 for (
const auto lookup : std::as_const(data->lookupCachedQmlUnit)) {
1883 if (
const QQmlPrivate::CachedQmlUnit *unit = lookup(uri)) {
1885 if (!unit->qmlData->verifyHeader(QDateTime(), &error)) {
1886 qCDebug(DBG_DISK_CACHE) <<
"Error loading pre-compiled file " << uri <<
":" << error;
1888 *status = CachedUnitLookupError::VersionMismatch;
1892 if (mode == RequireFullyTyped && !isFullyTyped(unit)) {
1893 qCDebug(DBG_DISK_CACHE)
1894 <<
"Error loading pre-compiled file " << uri
1895 <<
": compilation unit contains functions not compiled to native code.";
1897 *status = CachedUnitLookupError::NotFullyTyped;
1902 *status = CachedUnitLookupError::NoError;
1907 qCDebug(DBG_DISK_CACHE) <<
"No pre-compiled unit found for" << uri;
1910 *status = CachedUnitLookupError::NoUnitFound;
1915void QQmlMetaType::prependCachedUnitLookupFunction(QQmlPrivate::QmlUnitCacheLookupFunction handler)
1917 QQmlMetaTypeDataPtr data;
1918 data->lookupCachedQmlUnit.prepend(handler);
1921void QQmlMetaType::removeCachedUnitLookupFunction(QQmlPrivate::QmlUnitCacheLookupFunction handler)
1923 QQmlMetaTypeDataPtr data;
1924 data->lookupCachedQmlUnit.removeAll(handler);
1928
1929
1930QString QQmlMetaType::prettyTypeName(
const QObject *object)
1937 QQmlType type = QQmlMetaType::qmlType(object->metaObject());
1938 if (type.isValid()) {
1939 typeName = type.qmlTypeName();
1940 const int lastSlash = typeName.lastIndexOf(QLatin1Char(
'/'));
1941 if (lastSlash != -1)
1942 typeName = typeName.mid(lastSlash + 1);
1945 if (typeName.isEmpty()) {
1946 typeName = QString::fromUtf8(object->metaObject()->className());
1947 int marker = typeName.indexOf(QLatin1String(
"_QMLTYPE_"));
1949 typeName = typeName.left(marker);
1951 marker = typeName.indexOf(QLatin1String(
"_QML_"));
1953 typeName = QStringView{typeName}.left(marker) + QLatin1Char(
'*');
1954 type = QQmlMetaType::qmlType(QMetaType::fromName(typeName.toUtf8()));
1955 if (type.isValid()) {
1956 QString qmlTypeName = type.qmlTypeName();
1957 const int lastSlash = qmlTypeName.lastIndexOf(QLatin1Char(
'/'));
1958 if (lastSlash != -1)
1959 qmlTypeName = qmlTypeName.mid(lastSlash + 1);
1960 if (!qmlTypeName.isEmpty())
1961 typeName = qmlTypeName;
1969QList<QQmlProxyMetaObject::ProxyData> QQmlMetaType::proxyData(
const QMetaObject *mo,
1970 const QMetaObject *baseMetaObject,
1971 QMetaObject *lastMetaObject)
1973 QList<QQmlProxyMetaObject::ProxyData> metaObjects;
1974 mo = mo->d.superdata;
1979 auto createProxyMetaObject = [&](
const QQmlTypePrivate *This,
1980 const QMetaObject *superdataBaseMetaObject,
1981 const QMetaObject *extMetaObject,
1982 QObject *(*extFunc)(QObject *)) {
1986 QMetaObjectBuilder builder;
1987 clone(builder, extMetaObject, superdataBaseMetaObject, baseMetaObject,
1988 extFunc ? QQmlMetaType::CloneAll : QQmlMetaType::CloneEnumsOnly);
1989 QMetaObject *mmo = builder.toMetaObject();
1990 mmo->d.superdata = baseMetaObject;
1991 if (!metaObjects.isEmpty())
1992 metaObjects.constLast().metaObject->d.superdata = mmo;
1993 else if (lastMetaObject)
1994 lastMetaObject->d.superdata = mmo;
1995 QQmlProxyMetaObject::ProxyData data = { mmo, extFunc, 0, 0 };
1996 metaObjects << data;
1997 registerMetaObjectForType(mmo, This);
2000 for (
const QQmlMetaTypeDataPtr data; mo; mo = mo->d.superdata) {
2007 if (
const QQmlTypePrivate *t = data->metaObjectToType.value(mo)) {
2008 if (t->regType == QQmlType::CppType) {
2009 createProxyMetaObject(
2010 t, t->baseMetaObject, t->extraData.cppTypeData->extMetaObject,
2011 t->extraData.cppTypeData->extFunc);
2012 }
else if (t->regType == QQmlType::SingletonType) {
2013 createProxyMetaObject(
2014 t, t->baseMetaObject, t->extraData.singletonTypeData->extMetaObject,
2015 t->extraData.singletonTypeData->extFunc);
2027 case QMetaType::UnknownType:
2028 case QMetaType::QStringList:
2029 case QMetaType::QObjectStar:
2030 case QMetaType::VoidStar:
2031 case QMetaType::Nullptr:
2032 case QMetaType::QVariant:
2033 case QMetaType::QLocale:
2034 case QMetaType::QImage:
2035 case QMetaType::QPixmap:
2042bool QQmlMetaType::isValueType(QMetaType type)
2044 if (type.flags().testFlag(QMetaType::PointerToQObject))
2047 if (!type.isValid() || isInternalType(type.id()))
2050 return valueType(type) !=
nullptr;
2053const QMetaObject *QQmlMetaType::metaObjectForValueType(QMetaType metaType)
2055 switch (metaType.id()) {
2056 case QMetaType::QPoint:
2057 return &QQmlPointValueType::staticMetaObject;
2058 case QMetaType::QPointF:
2059 return &QQmlPointFValueType::staticMetaObject;
2060 case QMetaType::QSize:
2061 return &QQmlSizeValueType::staticMetaObject;
2062 case QMetaType::QSizeF:
2063 return &QQmlSizeFValueType::staticMetaObject;
2064 case QMetaType::QRect:
2065 return &QQmlRectValueType::staticMetaObject;
2066 case QMetaType::QRectF:
2067 return &QQmlRectFValueType::staticMetaObject;
2068#if QT_CONFIG(easingcurve)
2069 case QMetaType::QEasingCurve:
2070 return &QQmlEasingValueType::staticMetaObject;
2079 if (!(metaType.flags() & QMetaType::PointerToQObject)) {
2080 const QQmlMetaTypeDataPtr data;
2081 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
2082 if (type && type->regType == QQmlType::CppType && type->typeId == metaType) {
2083 if (
const QMetaObject *mo = type->metaObjectForValueType())
2089 if (metaType.flags() & QMetaType::IsGadget)
2090 return metaType.metaObject();
2095QQmlValueType *QQmlMetaType::valueType(QMetaType type)
2097 QQmlMetaTypeDataPtr data;
2099 const auto it = data->metaTypeToValueType.constFind(type.id());
2100 if (it != data->metaTypeToValueType.constEnd())
2103 if (
const QMetaObject *mo = metaObjectForValueType(type))
2104 return *data->metaTypeToValueType.insert(type.id(),
new QQmlValueType(type, mo));
2105 return *data->metaTypeToValueType.insert(type.id(),
nullptr);
2108QQmlPropertyCache::ConstPtr QQmlMetaType::findPropertyCacheInCompositeTypes(QMetaType t)
2110 const QQmlMetaTypeDataPtr data;
2111 return data->findPropertyCacheInCompositeTypes(t);
2114void QQmlMetaType::registerInternalCompositeType(
2115 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
2117 QQmlMetaTypeDataPtr data;
2119 auto doInsert = [&data, &compilationUnit](
const QtPrivate::QMetaTypeInterface *iface) {
2121 Q_ASSERT(compilationUnit);
2126 auto it = data->compositeTypes.insert(iface, compilationUnit);
2132 const auto end = data->compositeTypes.end();
2133 while (++it != end && it.key() == iface) {
2134 if (*it == compilationUnit) {
2135 data->compositeTypes.erase(it);
2141 doInsert(compilationUnit->metaType().iface());
2142 for (
auto &&inlineData: compilationUnit->inlineComponentData)
2143 doInsert(inlineData.qmlType.typeId().iface());
2149 const QUrl baseUrl = compilationUnit->finalUrl();
2150 if (baseUrl.isEmpty())
2153 for (
auto it = data->speculativeInlineComponentTypes.begin();
2154 it != data->speculativeInlineComponentTypes.end();) {
2155 const QUrl &url = *it;
2156 if (!equalBaseUrls(url, baseUrl)) {
2161 const QString icName = url.fragment();
2162 if (compilationUnit->inlineComponentData.contains(icName)) {
2164 it = data->speculativeInlineComponentTypes.erase(it);
2169 const auto typeIt = data->urlToType.constFind(url);
2170 Q_ASSERT(typeIt != data->urlToType.constEnd());
2172 const QQmlTypePrivate *d = *typeIt;
2173 data->urlToType.erase(typeIt);
2174 data->idToType.remove(d->typeId.id());
2175 data->idToType.remove(d->listId.id());
2176 data->types[d->index] = {};
2177 it = data->speculativeInlineComponentTypes.erase(it);
2181void QQmlMetaType::unregisterInternalCompositeType(
2182 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
2184 QQmlMetaTypeDataPtr data;
2186 auto doRemove = [&](
const QtPrivate::QMetaTypeInterface *iface) {
2190 const auto [begin, end] = std::as_const(data->compositeTypes).equal_range(iface);
2191 for (
auto it = begin; it != end; ++it) {
2192 if (*it == compilationUnit) {
2193 QQmlMetaTypeData::clearCompositeType(compilationUnit);
2194 data->compositeTypes.erase(it);
2200 doRemove(compilationUnit->metaType().iface());
2201 for (
auto &&inlineData: compilationUnit->inlineComponentData)
2202 doRemove(inlineData.qmlType.typeId().iface());
2204 const QUrl baseUrl = compilationUnit->finalUrl();
2205 if (baseUrl.isEmpty())
2209 for (
auto it = data->speculativeInlineComponentTypes.begin();
2210 it != data->speculativeInlineComponentTypes.end();) {
2211 if (equalBaseUrls(*it, baseUrl))
2212 it = data->speculativeInlineComponentTypes.erase(it);
2218int QQmlMetaType::countInternalCompositeTypeSelfReferences(
2219 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
2221 QQmlMetaTypeDataPtr data;
2222 return doCountInternalCompositeTypeSelfReferences(data, compilationUnit);
2225QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlMetaType::obtainCompilationUnit(
2228 const QQmlMetaTypeDataPtr data;
2231 return data->compositeTypes.value(type.iface());
2234QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlMetaType::obtainCompilationUnit(
2237 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
2238 QQmlMetaTypeDataPtr data;
2240 auto found = data->urlToType.constFind(normalized);
2241 if (found == data->urlToType.constEnd())
2242 return QQmlRefPointer<QV4::CompiledData::CompilationUnit>();
2245 const auto composite = data->compositeTypes.constFind(found.value()->typeId.iface());
2246 return composite == data->compositeTypes.constEnd()
2247 ? QQmlRefPointer<QV4::CompiledData::CompilationUnit>()
2248 : composite.value();
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)