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.contains(uri))
312 qFatal(
"Cannot remove multiple registrations for %s", qPrintable(uri));
314 data->moduleTypeRegistrationFunctions.remove(uri);
317bool QQmlMetaType::qmlRegisterModuleTypes(
const QString &uri)
319 QQmlMetaTypeDataPtr data;
320 return data->registerModuleTypes(uri);
323void QQmlMetaType::clearTypeRegistrations()
326 QQmlMetaTypeDataPtr data;
328 data->uriToModule.clear();
330 data->idToType.clear();
331 data->nameToType.clear();
332 data->urlToType.clear();
333 data->speculativeInlineComponentTypes.clear();
334 data->metaObjectToType.clear();
335 data->undeletableTypes.clear();
336 data->propertyCaches.clear();
338 qDeleteAll(data->metaTypeToValueType);
339 data->metaTypeToValueType.clear();
341 data->moduleImports.clear();
343 data->clearCompositeTypes();
345 qDeleteAll(data->metaTypeToValueType);
346 data->metaTypeToValueType.clear();
348 data->clearCompositeMetaTypes();
351void QQmlMetaType::registerTypeAlias(
int typeIndex,
const QString &name)
353 QQmlMetaTypeDataPtr data;
354 const QQmlType type = data->types.value(typeIndex).type;
355 const QQmlTypePrivate *priv = type.priv();
356 data->nameToType.insert(name, priv);
359int QQmlMetaType::registerAutoParentFunction(
const QQmlPrivate::RegisterAutoParent &function)
361 if (function.structVersion > 1)
362 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
364 QQmlMetaTypeDataPtr data;
366 data->parentFunctions.append(function.function);
368 return data->parentFunctions.size() - 1;
371void QQmlMetaType::unregisterAutoParentFunction(
const QQmlPrivate::AutoParentFunction &function)
373 QQmlMetaTypeDataPtr data;
374 data->parentFunctions.removeOne(function);
377QQmlType QQmlMetaType::registerInterface(
const QQmlPrivate::RegisterInterface &type)
379 if (type.structVersion > 1)
380 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
382 QQmlMetaTypeDataPtr data;
383 QQmlTypePrivate *priv = createQQmlType(data, type);
387 data->idToType.insert(priv->typeId.id(), priv);
388 data->idToType.insert(priv->listId.id(), priv);
390 return QQmlType(priv);
396 if (typeType == QQmlType::CppType)
397 typeStr = QStringLiteral(
"element");
398 else if (typeType == QQmlType::SingletonType)
399 typeStr = QStringLiteral(
"singleton type");
400 else if (typeType == QQmlType::CompositeSingletonType)
401 typeStr = QStringLiteral(
"composite singleton type");
402 else if (typeType == QQmlType::SequentialContainerType)
403 typeStr = QStringLiteral(
"sequential container type");
405 typeStr = QStringLiteral(
"type");
411 QQmlType::RegistrationType typeType, QQmlMetaTypeData *data,
const char *uri,
412 const QString &typeName, QTypeRevision version, QMetaType::TypeFlags flags)
414 if (!typeName.isEmpty()) {
415 if (typeName.at(0).isLower() && (flags & QMetaType::PointerToQObject)) {
416 QString failure(QCoreApplication::translate(
"qmlRegisterType",
"Invalid QML %1 name \"%2\"; type names must begin with an uppercase letter"));
417 data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType), typeName));
421 if (typeName.at(0).isUpper()
422 && (flags & (QMetaType::IsGadget | QMetaType::PointerToGadget))) {
423 qCWarning(lcTypeRegistration).noquote()
424 << QCoreApplication::translate(
426 "Invalid QML %1 name \"%2\"; "
427 "value type names should begin with a lowercase letter")
428 .arg(registrationTypeString(typeType), typeName);
434 int typeNameLen = typeName.size();
435 for (
int ii = 0; ii < typeNameLen; ++ii) {
436 if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == u'_')) {
437 QString failure(QCoreApplication::translate(
"qmlRegisterType",
"Invalid QML %1 name \"%2\""));
438 data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType), typeName));
444 if (uri && !typeName.isEmpty()) {
445 QString nameSpace = QString::fromUtf8(uri);
447 if (qqtm && qqtm->lockLevel() != QQmlTypeModule::LockLevel::Open) {
448 QString failure(QCoreApplication::translate(
450 "Cannot install %1 '%2' into protected module '%3' version '%4'"));
451 data->recordTypeRegFailure(failure
452 .arg(registrationTypeString(typeType), typeName, nameSpace)
453 .arg(version.majorVersion()));
463 const QHashedString &uri, QTypeRevision version, QQmlMetaTypeData *data)
467 return data->addTypeModule(std::make_unique<QQmlTypeModule>(uri, version.majorVersion()));
475 if (!type->elementName.isEmpty())
476 data->nameToType.insert(type->elementName, type);
478 if (type->baseMetaObject)
479 data->metaObjectToType.insert(type->baseMetaObject, type);
481 if (type->regType == QQmlType::SequentialContainerType) {
482 if (type->listId.isValid())
483 data->idToType.insert(type->listId.id(), type);
485 if (type->typeId.isValid())
486 data->idToType.insert(type->typeId.id(), type);
488 if (type->listId.flags().testFlag(QMetaType::IsQmlList))
489 data->idToType.insert(type->listId.id(), type);
492 if (!type->module.isEmpty()) {
493 const QHashedString &mod = type->module;
501QQmlType QQmlMetaType::registerType(
const QQmlPrivate::RegisterType &type)
503 if (type.structVersion >
int(QQmlPrivate::RegisterType::CurrentVersion))
504 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
506 QQmlMetaTypeDataPtr data;
508 QString elementName = QString::fromUtf8(type.elementName);
509 if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.version,
510 QMetaType(type.typeId).flags())) {
514 QQmlTypePrivate *priv = createQQmlType(data, elementName, type);
515 addTypeToData(priv, data);
517 return QQmlType(priv);
520QQmlType QQmlMetaType::registerSingletonType(
521 const QQmlPrivate::RegisterSingletonType &type,
522 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
524 if (type.structVersion > 1)
525 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
527 QQmlMetaTypeDataPtr data;
529 QString typeName = QString::fromUtf8(type.typeName);
530 if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.version,
531 QMetaType(type.typeId).flags())) {
535 QQmlTypePrivate *priv = createQQmlType(data, typeName, type, siinfo);
537 addTypeToData(priv, data);
539 return QQmlType(priv);
542QQmlType QQmlMetaType::registerCompositeSingletonType(
543 const QQmlPrivate::RegisterCompositeSingletonType &type,
544 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
546 if (type.structVersion > 1)
547 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
550 QQmlMetaTypeDataPtr data;
552 QString typeName = QString::fromUtf8(type.typeName);
553 if (!checkRegistration(
554 QQmlType::CompositeSingletonType, data, type.uri, typeName, type.version, {})) {
558 QQmlTypePrivate *priv = createQQmlType(data, typeName, type, siinfo);
559 addTypeToData(priv, data);
561 data->urlToType.insert(siinfo->url, priv);
563 return QQmlType(priv);
566QQmlType QQmlMetaType::registerCompositeType(
const QQmlPrivate::RegisterCompositeType &type)
568 if (type.structVersion > 1)
569 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
572 QQmlMetaTypeDataPtr data;
574 QString typeName = QString::fromUtf8(type.typeName);
575 if (!checkRegistration(QQmlType::CompositeType, data, type.uri, typeName, type.version, {}))
578 QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
579 addTypeToData(priv, data);
581 data->urlToType.insert(QQmlMetaType::normalizedUrl(type.url), priv);
583 return QQmlType(priv);
606 QQmlMetaTypeData *data,
const QUrl &url,
const QHashedStringRef &qualifiedType,
607 QQmlMetaType::CompositeTypeLookupMode mode, QList<QQmlError> *errors, QTypeRevision version)
609 const int dot = qualifiedType.indexOf(QLatin1Char(
'.'));
610 const QString typeName = dot < 0
611 ? qualifiedType.toString()
612 : QString(qualifiedType.constData() + dot + 1, qualifiedType.length() - dot - 1);
614 QStringList failures;
634 QQmlType::RegistrationType registrationType;
636 case QQmlMetaType::Singleton:
637 registrationType = QQmlType::CompositeSingletonType;
639 case QQmlMetaType::NonSingleton:
640 registrationType = QQmlType::CompositeType;
642 case QQmlMetaType::JavaScript:
643 registrationType = QQmlType::JavaScriptType;
646 Q_UNREACHABLE_RETURN(QQmlType());
649 if (checkRegistration(registrationType, data,
nullptr, typeName, version, {})) {
656 auto *priv =
new QQmlTypePrivate(registrationType);
657 addQQmlMetaTypeInterfaces(
658 data, url, priv, QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(url));
660 priv->setName(QString(), typeName);
661 priv->version = version;
664 case QQmlMetaType::Singleton: {
665 QQmlType::SingletonInstanceInfo::Ptr siinfo = QQmlType::SingletonInstanceInfo::create();
667 siinfo->typeName = typeName.toUtf8();
668 priv->extraData.singletonTypeData->singletonInstanceInfo =
669 QQmlType::SingletonInstanceInfo::ConstPtr(
670 siinfo.take(), QQmlType::SingletonInstanceInfo::ConstPtr::Adopt);
673 case QQmlMetaType::NonSingleton: {
674 priv->extraData.compositeTypeData = url;
677 case QQmlMetaType::JavaScript: {
678 priv->extraData.javaScriptTypeData = url;
683 data->registerType(priv);
684 addTypeToData(priv, data);
685 return QQmlType(priv);
693 error.setDescription(failures.join(u'\n'));
694 errors->prepend(error);
696 qWarning(
"%s", failures.join(u'\n').toLatin1().constData());
701QQmlType QQmlMetaType::findCompositeType(
702 const QUrl &url,
const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit,
703 CompositeTypeLookupMode mode)
705 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
706 QQmlMetaTypeDataPtr data;
708 bool urlExists =
true;
709 auto found = data->urlToType.constFind(normalized);
710 if (found == data->urlToType.cend())
714 if (compilationUnit.isNull())
715 return QQmlType(*found);
716 const auto [begin, end]
717 = std::as_const(data->compositeTypes).equal_range(found.value()->typeId.iface());
719 return QQmlType(*found);
720 for (
auto it = begin; it != end; ++it) {
721 if (it.value() == compilationUnit)
722 return QQmlType(*found);
726 const QQmlType type = createTypeForUrl(
727 data, normalized, QHashedStringRef(), mode,
nullptr, QTypeRevision());
729 if (!urlExists && type.isValid())
730 data->urlToType.insert(normalized, type.priv());
737 QQmlTypePrivate *priv =
new QQmlTypePrivate(QQmlType::InlineComponentType);
738 priv->setName(QString(), url.fragment());
740 priv->extraData.inlineComponentTypeData = url;
741 data->registerType(priv);
743 addQQmlMetaTypeInterfaces(
744 data, url, priv, QQmlPropertyCacheCreatorBase::createClassNameForInlineComponent(url));
745 data->urlToType.insert(url, priv);
747 data->idToType.insert(priv->typeId.id(), priv);
748 data->idToType.insert(priv->listId.id(), priv);
750 return QQmlType(priv);
753QQmlType QQmlMetaType::findOrCreateFactualInlineComponentType(
754 const QUrl &url,
const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
756 QQmlMetaTypeDataPtr data;
760 const auto it = data->urlToType.constFind(url);
761 if (it == data->urlToType.constEnd())
762 return doRegisterInlineComponentType(data, url);
764 const auto [begin, end]
765 = std::as_const(data->compositeTypes).equal_range((*it)->typeId.iface());
767 data->speculativeInlineComponentTypes.remove(url);
768 return QQmlType(*it);
771 for (
auto jt = begin; jt != end; ++jt) {
772 if (*jt != compilationUnit)
775 data->speculativeInlineComponentTypes.remove(url);
776 return QQmlType(*it);
779 return doRegisterInlineComponentType(data, url);
782int QQmlMetaType::registerUnitCacheHook(
783 const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration)
785 if (hookRegistration.structVersion > 1)
786 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
788 QQmlMetaTypeDataPtr data;
789 data->lookupCachedQmlUnit << hookRegistration.lookupCachedQmlUnit;
793QQmlType QQmlMetaType::registerSequentialContainer(
794 const QQmlPrivate::RegisterSequentialContainer &container)
796 if (container.structVersion > 1)
797 qFatal(
"qmlRegisterSequenceContainer(): Cannot mix incompatible QML versions.");
799 QQmlMetaTypeDataPtr data;
801 if (!checkRegistration(QQmlType::SequentialContainerType, data, container.uri, QString(),
802 container.version, {})) {
806 QQmlTypePrivate *priv =
new QQmlTypePrivate(QQmlType::SequentialContainerType);
808 data->registerType(priv);
809 priv->setName(QString::fromUtf8(container.uri), QString());
810 priv->version = container.version;
811 priv->revision = container.revision;
812 priv->typeId = container.metaSequence.valueMetaType();
813 priv->listId = container.typeId;
814 priv->extraData.sequentialContainerTypeData = container.metaSequence;
816 addTypeToData(priv, data);
818 return QQmlType(priv);
821void QQmlMetaType::unregisterSequentialContainer(
int id)
826bool QQmlMetaType::protectModule(
const QString &uri, QTypeRevision version,
827 bool weakProtectAllVersions)
829 QQmlMetaTypeDataPtr data;
830 if (version.hasMajorVersion()) {
831 if (QQmlTypeModule *module = data->findTypeModule(uri, version)) {
832 if (!weakProtectAllVersions) {
833 module->setLockLevel(QQmlTypeModule::LockLevel::Strong);
841 const auto range = std::equal_range(
842 data->uriToModule.begin(), data->uriToModule.end(), uri,
843 std::less<ModuleUri>());
845 for (
auto it = range.first; it != range.second; ++it)
846 (*it)->setLockLevel(QQmlTypeModule::LockLevel::Weak);
848 return range.first != range.second;
851void QQmlMetaType::registerModuleImport(
const QString &uri, QTypeRevision moduleVersion,
852 const QQmlDirParser::Import &import)
854 QQmlMetaTypeDataPtr data;
856 data->moduleImports.insert(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import);
859void QQmlMetaType::unregisterModuleImport(
const QString &uri, QTypeRevision moduleVersion,
860 const QQmlDirParser::Import &import)
862 QQmlMetaTypeDataPtr data;
863 data->moduleImports.remove(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import);
866QList<QQmlDirParser::Import> QQmlMetaType::moduleImports(
867 const QString &uri, QTypeRevision version)
869 QQmlMetaTypeDataPtr data;
870 QList<QQmlDirParser::Import> result;
872 const auto unrevisioned = data->moduleImports.equal_range(
873 QQmlMetaTypeData::VersionedUri(uri, QTypeRevision()));
874 for (
auto it = unrevisioned.second; it != unrevisioned.first;)
875 result.append(*(--it));
877 if (version.hasMajorVersion()) {
878 const auto revisioned = data->moduleImports.equal_range(
879 QQmlMetaTypeData::VersionedUri(uri, version));
880 for (
auto it = revisioned.second; it != revisioned.first;)
881 result.append(*(--it));
886 const auto begin = data->moduleImports.begin();
887 auto it = unrevisioned.first;
891 const QQmlMetaTypeData::VersionedUri latestVersion = (--it).key();
892 if (latestVersion.uri != uri)
897 }
while (it != begin && (--it).key() == latestVersion);
902void QQmlMetaType::registerModule(
const char *uri, QTypeRevision version)
904 QQmlMetaTypeDataPtr data;
906 QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
909 if (version.hasMinorVersion())
910 module->addMinorVersion(version.minorVersion());
913int QQmlMetaType::typeId(
const char *uri, QTypeRevision version,
const char *qmlName)
915 QQmlMetaTypeDataPtr data;
917 QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
921 QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), version);
928void QQmlMetaType::registerUndeletableType(
const QQmlType &dtype)
930 QQmlMetaTypeDataPtr data;
931 data->undeletableTypes.insert(dtype);
935 QTypeRevision version)
938 QHashedString nameSpace(uri);
939 for (
const auto &typeAndCaches : std::as_const(data->types)) {
940 const QQmlType &type = typeAndCaches.type;
941 if (type.module() == nameSpace && type.version().majorVersion() == version.majorVersion())
948QQmlMetaType::RegistrationResult QQmlMetaType::registerPluginTypes(
949 QObject *instance,
const QString &basePath,
const QString &uri,
950 const QString &typeNamespace, QTypeRevision version, QList<QQmlError> *errors)
952 if (!typeNamespace.isEmpty() && typeNamespace != uri) {
957 error.setDescription(
958 QStringLiteral(
"Module namespace '%1' does not match import URI '%2'")
959 .arg(typeNamespace, uri));
960 errors->prepend(error);
962 return RegistrationResult::Failure;
965 QStringList failures;
966 QQmlMetaTypeDataPtr data;
968 QQmlMetaTypeRegistrationFailureRecorder failureRecorder(data, &failures);
969 if (!typeNamespace.isEmpty()) {
971 if (namespaceContainsRegistrations(data, typeNamespace, version)) {
975 error.setDescription(QStringLiteral(
"Namespace '%1' has already been used "
976 "for type registration")
977 .arg(typeNamespace));
978 errors->prepend(error);
980 return RegistrationResult::Failure;
984 qWarning().nospace() << qPrintable(
985 QStringLiteral(
"Module '%1' does not contain a module identifier directive - "
986 "it cannot be protected from external registrations.").arg(uri));
989 if (instance && !qobject_cast<QQmlEngineExtensionInterface *>(instance)) {
990 QQmlTypesExtensionInterface *iface = qobject_cast<QQmlTypesExtensionInterface *>(instance);
995 error.setDescription(QStringLiteral(
"Module loaded for URI '%1' does not implement "
996 "QQmlEngineExtensionInterface").arg(typeNamespace));
997 errors->prepend(error);
999 return RegistrationResult::Failure;
1002#if QT_DEPRECATED_SINCE(6
, 3
)
1003 if (
auto *plugin = qobject_cast<QQmlExtensionPlugin *>(instance)) {
1005 QQmlExtensionPluginPrivate::get(plugin)->baseUrl
1006 = QQmlImports::urlFromLocalFileOrQrcOrUrl(basePath);
1012 const QByteArray bytes = uri.toUtf8();
1013 const char *moduleId = bytes.constData();
1014 iface->registerTypes(moduleId);
1017 if (failures.isEmpty() && !data->registerModuleTypes(uri))
1018 return RegistrationResult::NoRegistrationFunction;
1020 if (!failures.isEmpty()) {
1022 for (
const QString &failure : std::as_const(failures)) {
1024 error.setDescription(failure);
1025 errors->prepend(error);
1028 return RegistrationResult::Failure;
1032 return RegistrationResult::Success;
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046QQmlType QQmlMetaType::typeForUrl(
1047 const QUrl &url,
const QHashedStringRef &qualifiedType, CompositeTypeLookupMode mode,
1048 QList<QQmlError> *errors, QTypeRevision version)
1051 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
1053 QQmlMetaTypeDataPtr data;
1055 QQmlType ret(data->urlToType.value(normalized));
1056 if (ret.isValid() && ret.sourceUrl() == normalized)
1060 const QQmlType type = createTypeForUrl(
1061 data, normalized, qualifiedType, mode, errors, version);
1062 data->urlToType.insert(normalized, type.priv());
1067
1068
1069QTypeRevision QQmlMetaType::latestModuleVersion(
const QString &uri)
1071 QQmlMetaTypeDataPtr data;
1072 auto upper = std::upper_bound(data->uriToModule.begin(), data->uriToModule.end(), uri,
1073 std::less<ModuleUri>());
1074 if (upper == data->uriToModule.begin())
1075 return QTypeRevision();
1077 const auto module = (--upper)->get();
1078 return (module->module() == uri)
1079 ? QTypeRevision::fromVersion(module->majorVersion(), module->maximumMinorVersion())
1084
1085
1086bool QQmlMetaType::isStronglyLockedModule(
const QString &uri, QTypeRevision version)
1088 QQmlMetaTypeDataPtr data;
1090 if (QQmlTypeModule* qqtm = data->findTypeModule(uri, version))
1091 return qqtm->lockLevel() == QQmlTypeModule::LockLevel::Strong;
1096
1097
1098
1099
1100
1101
1102QTypeRevision QQmlMetaType::matchingModuleVersion(
const QString &module, QTypeRevision version)
1104 if (!version.hasMajorVersion())
1105 return latestModuleVersion(module);
1107 QQmlMetaTypeDataPtr data;
1110 if (QQmlTypeModule *tm = data->findTypeModule(module, version)) {
1111 if (!version.hasMinorVersion())
1112 return QTypeRevision::fromVersion(version.majorVersion(), tm->maximumMinorVersion());
1114 if (tm->minimumMinorVersion() <= version.minorVersion()
1115 && tm->maximumMinorVersion() >= version.minorVersion()) {
1120 return QTypeRevision();
1123QQmlTypeModule *QQmlMetaType::typeModule(
const QString &uri, QTypeRevision version)
1125 QQmlMetaTypeDataPtr data;
1127 if (version.hasMajorVersion())
1128 return data->findTypeModule(uri, version);
1130 auto range = std::equal_range(data->uriToModule.begin(), data->uriToModule.end(),
1131 uri, std::less<ModuleUri>());
1133 return range.first == range.second ?
nullptr : (--range.second)->get();
1136QList<QQmlPrivate::AutoParentFunction> QQmlMetaType::parentFunctions()
1138 QQmlMetaTypeDataPtr data;
1139 return data->parentFunctions;
1142QObject *QQmlMetaType::toQObject(
const QVariant &v,
bool *ok)
1144 if (!v.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
1145 if (ok) *ok =
false;
1151 return *(QObject *
const *)v.constData();
1155
1156
1157QMetaType QQmlMetaType::listValueType(QMetaType metaType)
1159 if (isList(metaType)) {
1160 const auto iface = metaType.iface();
1161 if (iface && iface->metaObjectFn == &dynamicQmlListMarker)
1162 return QMetaType(
static_cast<
const QQmlListMetaTypeInterface *>(iface)->valueType);
1163 }
else if (metaType.flags() & QMetaType::PointerToQObject) {
1167 QQmlMetaTypeDataPtr data;
1169 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1171 if (type && type->listId == metaType)
1172 return type->typeId;
1174 return QMetaType {};
1177QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFunc(
1178 QQmlTypeLoader *typeLoader,
const QMetaObject *mo)
1180 QQmlMetaTypeDataPtr data;
1182 QQmlType type(data->metaObjectToType.value(mo));
1183 return type.attachedPropertiesFunction(typeLoader);
1186QMetaProperty QQmlMetaType::defaultProperty(
const QMetaObject *metaObject)
1188 int idx = metaObject->indexOfClassInfo(
"DefaultProperty");
1190 return QMetaProperty();
1192 QMetaClassInfo info = metaObject->classInfo(idx);
1194 return QMetaProperty();
1196 idx = metaObject->indexOfProperty(info.value());
1198 return QMetaProperty();
1200 return metaObject->property(idx);
1203QMetaProperty QQmlMetaType::defaultProperty(QObject *obj)
1206 return QMetaProperty();
1208 const QMetaObject *metaObject = obj->metaObject();
1209 return defaultProperty(metaObject);
1212QMetaMethod QQmlMetaType::defaultMethod(
const QMetaObject *metaObject)
1214 int idx = metaObject->indexOfClassInfo(
"DefaultMethod");
1216 return QMetaMethod();
1218 QMetaClassInfo info = metaObject->classInfo(idx);
1220 return QMetaMethod();
1222 idx = metaObject->indexOfMethod(info.value());
1224 return QMetaMethod();
1226 return metaObject->method(idx);
1229QMetaMethod QQmlMetaType::defaultMethod(QObject *obj)
1232 return QMetaMethod();
1234 const QMetaObject *metaObject = obj->metaObject();
1235 return defaultMethod(metaObject);
1239
1240
1241bool QQmlMetaType::isInterface(QMetaType metaType)
1243 const QQmlMetaTypeDataPtr data;
1244 return QQmlType(data->idToType.value(metaType.id())).isInterface();
1247const char *QQmlMetaType::interfaceIId(QMetaType metaType)
1249 const QQmlMetaTypeDataPtr data;
1250 const QQmlType type(data->idToType.value(metaType.id()));
1251 return (type.isInterface() && type.typeId() == metaType) ? type.interfaceIId() :
nullptr;
1254bool QQmlMetaType::isList(QMetaType type)
1256 if (type.flags().testFlag(QMetaType::IsQmlList))
1263
1264
1265
1266QQmlType QQmlMetaType::qmlType(
const QString &qualifiedName, QTypeRevision version)
1268 int slash = qualifiedName.indexOf(QLatin1Char(
'/'));
1272 QHashedStringRef module(qualifiedName.constData(), slash);
1273 QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.size() - slash - 1);
1275 return qmlType(name, module, version);
1279
1280
1281
1282
1283
1284
1285
1286QQmlType QQmlMetaType::qmlType(
const QHashedStringRef &name,
const QHashedStringRef &module,
1287 QTypeRevision version)
1289 const QQmlMetaTypeDataPtr data;
1291 const QHashedString key(QString::fromRawData(name.constData(), name.length()), name.hash());
1292 QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(key);
1293 while (it != data->nameToType.cend() && it.key() == name) {
1295 if (module.isEmpty() || t.availableInVersion(module, version))
1304
1305
1306
1307QQmlType QQmlMetaType::qmlType(
const QMetaObject *metaObject)
1309 const QQmlMetaTypeDataPtr data;
1310 return QQmlType(data->metaObjectToType.value(metaObject));
1314
1315
1316
1317
1318QQmlType QQmlMetaType::qmlType(
const QMetaObject *metaObject,
const QHashedStringRef &module,
1319 QTypeRevision version)
1321 const QQmlMetaTypeDataPtr data;
1323 const auto range = data->metaObjectToType.equal_range(metaObject);
1324 for (
auto it = range.first; it != range.second; ++it) {
1326 if (module.isEmpty() || t.availableInVersion(module, version))
1334
1335
1336
1337QQmlType QQmlMetaType::qmlTypeById(
int qmlTypeId)
1339 const QQmlMetaTypeDataPtr data;
1340 return data->types.value(qmlTypeId).type;
1344
1345
1346
1347
1348
1349
1350
1351
1352QQmlType QQmlMetaType::firstQmlTypeForAttachmentMetaObject(
const QMetaObject *attachmentMetaObject)
1354 const QQmlMetaTypeDataPtr data;
1355 if (
auto qmlTypePriv = data->metaObjectToType.value(attachmentMetaObject)) {
1357 if (qmlTypePriv->regType == QQmlType::CppType &&
1358 qmlTypePriv->extraData.cppTypeData->attachedPropertiesType == attachmentMetaObject)
1359 return QQmlType(qmlTypePriv);
1361 auto getAttachmentMetaObject = [](
const QQmlTypePrivate *priv) ->
const QMetaObject * {
1362 if (priv->regType != QQmlType::CppType)
1364 return priv->extraData.cppTypeData->attachedPropertiesType;
1366 auto it = std::find_if(data->metaObjectToType.constBegin(),
1367 data->metaObjectToType.constEnd(),
1368 [&](
const QQmlTypePrivate *type) {
return attachmentMetaObject == getAttachmentMetaObject(type); }
1370 if (it == data->metaObjectToType.constEnd())
1372 return QQmlType(*it);
1376
1377
1378
1379QQmlType QQmlMetaType::qmlType(QMetaType metaType)
1381 const QQmlMetaTypeDataPtr data;
1382 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1383 return (type && type->typeId == metaType) ? QQmlType(type) : QQmlType();
1386QQmlType QQmlMetaType::qmlListType(QMetaType metaType)
1388 const QQmlMetaTypeDataPtr data;
1389 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1390 return (type && type->listId == metaType) ? QQmlType(type) : QQmlType();
1394
1395
1396
1397
1398
1399QQmlType QQmlMetaType::qmlType(
const QUrl &unNormalizedUrl)
1401 const QUrl url = QQmlMetaType::normalizedUrl(unNormalizedUrl);
1402 const QQmlMetaTypeDataPtr data;
1404 QQmlType type(data->urlToType.value(url));
1406 if (type.sourceUrl() == url)
1412QQmlType QQmlMetaType::findOrCreateSpeculativeInlineComponentType(
const QUrl &url)
1414 QQmlMetaTypeDataPtr data;
1415 const auto it = data->urlToType.constFind(url);
1416 if (it != data->urlToType.constEnd())
1417 return QQmlType(*it);
1422 baseUrl.setFragment(QString());
1426 if (baseUrl.isEmpty())
1427 return doRegisterInlineComponentType(data, url);
1431 const auto baseIt = data->urlToType.constFind(baseUrl);
1432 if (baseIt == data->urlToType.constEnd()) {
1433 data->speculativeInlineComponentTypes.insert(url);
1434 return doRegisterInlineComponentType(data, url);
1439 const auto cu = data->compositeTypes.value((*baseIt)->typeId.iface());
1441 data->speculativeInlineComponentTypes.insert(url);
1442 return doRegisterInlineComponentType(data, url);
1447 Q_ASSERT(std::none_of(
1448 cu->inlineComponentData.constBegin(), cu->inlineComponentData.constEnd(),
1449 [&](
const QV4::CompiledData::InlineComponentData &icData) {
1450 return icData.qmlType.elementName() == url.fragment();
1458
1459
1460
1461
1462
1463QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(QObject *obj, QTypeRevision version)
1465 if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted)
1466 return QQmlPropertyCache::ConstPtr();
1467 return QQmlMetaType::propertyCache(obj->metaObject(), version);
1470QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(
1471 const QMetaObject *metaObject, QTypeRevision version)
1473 QQmlMetaTypeDataPtr data;
1474 return data->propertyCache(metaObject, version);
1477QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(
1478 const QQmlType &type, QTypeRevision version)
1480 QQmlMetaTypeDataPtr data;
1481 return data->propertyCache(type, version);
1485
1486
1487
1488
1489QQmlMetaObject QQmlMetaType::rawMetaObjectForType(QMetaType metaType)
1491 const QQmlMetaTypeDataPtr data;
1492 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1493 return QQmlMetaObject(composite);
1495 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1496 return (type && type->typeId == metaType) ? type->baseMetaObject :
nullptr;
1500
1501
1502
1503
1504QQmlMetaObject QQmlMetaType::metaObjectForType(QMetaType metaType)
1506 const QQmlMetaTypeDataPtr data;
1507 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1508 return QQmlMetaObject(composite);
1510 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1511 return (type && type->typeId == metaType)
1512 ? QQmlType(type).metaObject()
1517
1518
1519
1520
1521QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCacheForType(QMetaType metaType)
1523 QQmlMetaTypeDataPtr data;
1524 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1527 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1528 if (type && type->typeId == metaType) {
1529 if (
const QMetaObject *mo = QQmlType(type).metaObject())
1530 return data->propertyCache(mo, type->version);
1533 return QQmlPropertyCache::ConstPtr();
1537
1538
1539
1540
1541
1542
1543QQmlPropertyCache::ConstPtr QQmlMetaType::rawPropertyCacheForType(QMetaType metaType)
1545 QQmlMetaTypeDataPtr data;
1546 if (
auto composite = QQmlMetaType::findPropertyCacheInCompositeTypes(metaType))
1549 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1550 if (!type || type->typeId != metaType)
1551 return QQmlPropertyCache::ConstPtr();
1553 const QMetaObject *metaObject = type->isValueType()
1554 ? type->metaObjectForValueType()
1555 : type->baseMetaObject;
1558 ? data->propertyCache(metaObject, QTypeRevision())
1559 : QQmlPropertyCache::ConstPtr();
1563
1564
1565
1566
1567
1568QQmlPropertyCache::ConstPtr QQmlMetaType::rawPropertyCacheForType(
1569 QMetaType metaType, QTypeRevision version)
1571 QQmlMetaTypeDataPtr data;
1572 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1575 const QQmlTypePrivate *typePriv = data->idToType.value(metaType.id());
1576 if (!typePriv || typePriv->typeId != metaType)
1577 return QQmlPropertyCache::ConstPtr();
1579 const QQmlType type(typePriv);
1580 if (type.containsRevisionedAttributes()) {
1582 Q_ASSERT(type.metaObject());
1583 return data->propertyCache(type, version);
1586 if (
const QMetaObject *metaObject = type.metaObject())
1587 return data->propertyCache(metaObject, version);
1589 return QQmlPropertyCache::ConstPtr();
1592template<
typename From,
typename CanConvertPropCache,
typename CanConvertMetaObject>
1595 CanConvertPropCache &&canConvertPropCache, CanConvertMetaObject &&canConvertMetaObject)
1603 auto [it, end] = data->compositeTypes.equal_range(metaType.iface());
1606 if (canConvertPropCache(
1607 from, QQmlMetaTypeData::propertyCacheForPotentialInlineComponentType(
1611 }
while(++it != end);
1618 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1619 if (type && type->typeId == metaType && type->baseMetaObject)
1620 return canConvertMetaObject(from, type->baseMetaObject);
1623 if (
const QMetaObject *metaObject = metaType.metaObject())
1624 return canConvertMetaObject(from, metaObject);
1629bool QQmlMetaType::canConvert(QObject *o, QMetaType metaType)
1631 QQmlMetaTypeDataPtr data;
1633 return canConvertToPropCacheOrMetaObject(
1634 data, o, metaType, [](QObject *o,
const QQmlPropertyCache::ConstPtr &propCache) {
1635 return QQmlMetaObject::canConvert(o, propCache);
1636 }, [](QObject *o,
const QMetaObject *metaObject) {
1637 return QQmlMetaObject::canConvert(o, metaObject);
1642 const QQmlPropertyCache::ConstPtr &derived,
const QQmlPropertyCache::ConstPtr &base)
1644 for (QQmlPropertyCache::ConstPtr parent = derived; parent; parent = parent->parent()) {
1652bool QQmlMetaType::canConvert(
const QQmlPropertyCache::ConstPtr &from, QMetaType metaType)
1654 QQmlMetaTypeDataPtr data;
1656 return canConvertToPropCacheOrMetaObject(
1657 data, from, metaType,
1658 [](
const QQmlPropertyCache::ConstPtr &from,
const QQmlPropertyCache::ConstPtr &to) {
1659 return inherits(from, to);
1660 }, [&](
const QQmlPropertyCache::ConstPtr &from,
const QMetaObject *toMeta) {
1661 if (
const QMetaObject *fromMeta = from->metaObject())
1662 return QQmlMetaObject::canConvert(fromMeta, toMeta);
1663 return inherits(from, data->propertyCache(toMeta, QTypeRevision()));
1667void QQmlMetaType::unregisterType(
int typeIndex)
1669 QQmlMetaTypeDataPtr data;
1670 const QQmlType type = data->types.value(typeIndex).type;
1671 if (
const QQmlTypePrivate *d = type.priv()) {
1672 if (d->regType == QQmlType::CompositeType || d->regType == QQmlType::CompositeSingletonType) {
1673 removeFromInlineComponents(data->urlToType, d);
1674 removeFromInlineComponents(data->speculativeInlineComponentTypes, d);
1676 removeQQmlTypePrivate(data->idToType, d);
1677 removeQQmlTypePrivate(data->nameToType, d);
1678 removeQQmlTypePrivate(data->urlToType, d);
1679 removeQQmlTypePrivate(data->metaObjectToType, d);
1680 data->speculativeInlineComponentTypes.remove(d->sourceUrl());
1681 for (
auto & module : data->uriToModule)
1683 data->types[typeIndex] = QQmlMetaTypeData::Type();
1684 data->undeletableTypes.remove(type);
1688void QQmlMetaType::registerMetaObjectForType(
const QMetaObject *metaobject,
const QQmlTypePrivate *type)
1692 QQmlMetaTypeDataPtr data;
1693 data->metaObjectToType.insert(metaobject, type);
1698 for (
auto it = data->urlToType.begin(), end = data->urlToType.end();
1700 if (!QQmlMetaType::equalBaseUrls(it.key(), d->sourceUrl()))
1703 const QQmlTypePrivate *icPriv = *it;
1704 if (icPriv && icPriv->count() > 1)
1711 QQmlMetaTypeData *data,
1712 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
1715 auto doCheck = [&](
const QtPrivate::QMetaTypeInterface *iface) {
1719 const auto [begin, end] = std::as_const(data->compositeTypes).equal_range(iface);
1720 for (
auto it = begin; it != end; ++it) {
1721 if (*it == compilationUnit)
1726 doCheck(compilationUnit->metaType().iface());
1727 for (
auto &&inlineData: compilationUnit->inlineComponentData)
1728 doCheck(inlineData.qmlType.typeId().iface());
1733void QQmlMetaType::freeUnusedTypesAndCaches()
1735 QQmlMetaTypeDataPtr data;
1738 if (!data.isValid())
1741 bool droppedAtLeastOneComposite;
1743 droppedAtLeastOneComposite =
false;
1744 auto it = data->compositeTypes.cbegin();
1745 while (it != data->compositeTypes.cend()) {
1746 const auto &cu = *it;
1747 if (cu->count() <= doCountInternalCompositeTypeSelfReferences(data, cu)) {
1748 QQmlMetaTypeData::clearCompositeType(cu);
1749 it = data->compositeTypes.erase(it);
1750 droppedAtLeastOneComposite =
true;
1755 }
while (droppedAtLeastOneComposite);
1757 bool deletedAtLeastOneType;
1759 deletedAtLeastOneType =
false;
1760 auto it = data->types.begin();
1761 while (it != data->types.end()) {
1762 const QQmlTypePrivate *d = it->type.priv();
1763 if (d && d->count() == 1 && !hasActiveInlineComponents(data, d)) {
1764 deletedAtLeastOneType =
true;
1766 if (d->regType == QQmlType::CompositeType
1767 || d->regType == QQmlType::CompositeSingletonType) {
1768 removeFromInlineComponents(data->urlToType, d);
1769 removeFromInlineComponents(data->speculativeInlineComponentTypes, d);
1771 removeQQmlTypePrivate(data->idToType, d);
1772 removeQQmlTypePrivate(data->nameToType, d);
1773 removeQQmlTypePrivate(data->urlToType, d);
1774 removeQQmlTypePrivate(data->metaObjectToType, d);
1775 data->speculativeInlineComponentTypes.remove(d->sourceUrl());
1777 for (
auto &module : data->uriToModule)
1780 *it = QQmlMetaTypeData::Type();
1785 }
while (deletedAtLeastOneType);
1787 bool deletedAtLeastOneCache;
1789 deletedAtLeastOneCache =
false;
1790 auto it = data->propertyCaches.begin();
1791 while (it != data->propertyCaches.end()) {
1792 if ((*it)->count() == 1) {
1793 it = data->propertyCaches.erase(it);
1794 deletedAtLeastOneCache =
true;
1799 }
while (deletedAtLeastOneCache);
1803
1804
1805QList<QString> QQmlMetaType::qmlTypeNames()
1807 const QQmlMetaTypeDataPtr data;
1809 QList<QString> names;
1810 names.reserve(data->nameToType.size());
1811 QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.cbegin();
1812 while (it != data->nameToType.cend()) {
1814 names += t.qmlTypeName();
1822
1823
1824QList<QQmlType> QQmlMetaType::qmlTypes()
1826 const QQmlMetaTypeDataPtr data;
1828 QList<QQmlType> types;
1829 for (
const QQmlTypePrivate *t : data->nameToType)
1830 types.append(QQmlType(t));
1836
1837
1838QList<QQmlType> QQmlMetaType::qmlAllTypes()
1840 const QQmlMetaTypeDataPtr data;
1841 QList<QQmlType> types;
1842 types.reserve(data->types.size());
1844 data->types.constBegin(), data->types.constEnd(),
1845 std::back_inserter(types), [](
const auto &type) {
return type.type; });
1850
1851
1852QList<QQmlType> QQmlMetaType::qmlSingletonTypes()
1854 const QQmlMetaTypeDataPtr data;
1856 QList<QQmlType> retn;
1857 for (
const auto t : std::as_const(data->nameToType)) {
1859 if (type.isSingleton())
1867 quint32 numTypedFunctions = 0;
1868 for (
const QQmlPrivate::AOTCompiledFunction *function = unit->aotCompiledFunctions;
1869 function; ++function) {
1870 if (function->functionPtr)
1871 ++numTypedFunctions;
1875 return numTypedFunctions == unit->qmlData->functionTableSize;
1878const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(
1879 const QUrl &uri, QQmlMetaType::CacheMode mode, CachedUnitLookupError *status)
1881 Q_ASSERT(mode != RejectAll);
1882 const QQmlMetaTypeDataPtr data;
1884 for (
const auto lookup : std::as_const(data->lookupCachedQmlUnit)) {
1885 if (
const QQmlPrivate::CachedQmlUnit *unit = lookup(uri)) {
1887 if (!unit->qmlData->verifyHeader(QDateTime(), &error)) {
1888 qCDebug(DBG_DISK_CACHE) <<
"Error loading pre-compiled file " << uri <<
":" << error;
1890 *status = CachedUnitLookupError::VersionMismatch;
1894 if (mode == RequireFullyTyped && !isFullyTyped(unit)) {
1895 qCDebug(DBG_DISK_CACHE)
1896 <<
"Error loading pre-compiled file " << uri
1897 <<
": compilation unit contains functions not compiled to native code.";
1899 *status = CachedUnitLookupError::NotFullyTyped;
1904 *status = CachedUnitLookupError::NoError;
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)