5#include "ftw/qhashedstring_p.h"
8#include <private/qqmlextensionplugin_p.h>
9#include <private/qqmlmetatypedata_p.h>
10#include <private/qqmlpropertycachecreator_p.h>
11#include <private/qqmlscriptblob_p.h>
12#include <private/qqmlscriptdata_p.h>
13#include <private/qqmltype_p_p.h>
14#include <private/qqmltypemodule_p.h>
15#include <private/qqmlvaluetype_p.h>
17#include <QtCore/qcoreapplication.h>
18#include <QtCore/qmutex.h>
19#include <QtCore/qloggingcategory.h>
26
27
28
29
31struct LockedData :
private QQmlMetaTypeData
33 friend class QQmlMetaTypeDataPtr;
36Q_GLOBAL_STATIC(LockedData, metaTypeData)
37Q_GLOBAL_STATIC(QRecursiveMutex, metaTypeDataLock)
39struct ModuleUri :
public QString
41 ModuleUri(
const QString &string) : QString(string) {}
42 ModuleUri(
const std::unique_ptr<QQmlTypeModule> &module) : QString(module->module()) {}
64 LockedData *data =
nullptr;
68 const QQmlPrivate::RegisterInterface &type)
70 auto *d =
new QQmlTypePrivate(QQmlType::InterfaceType);
71 d->extraData.interfaceTypeData = type.iid;
72 d->typeId = type.typeId;
73 d->listId = type.listId;
74 d->module = QString::fromUtf8(type.uri);
75 d->version = type.version;
76 data->registerType(d);
81 QQmlMetaTypeData *data,
const QString &elementName,
82 const QQmlPrivate::RegisterSingletonType &type,
83 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
85 auto *d =
new QQmlTypePrivate(QQmlType::SingletonType);
86 data->registerType(d);
88 d->setName(QString::fromUtf8(type.uri), elementName);
89 d->version = type.version;
91 if (type.qObjectApi) {
92 d->baseMetaObject = type.instanceMetaObject;
93 d->typeId = type.typeId;
94 d->revision = type.revision;
97 d->extraData.singletonTypeData->singletonInstanceInfo = siinfo;
98 d->extraData.singletonTypeData->extFunc = type.extensionObjectCreate;
99 d->extraData.singletonTypeData->extMetaObject = type.extensionMetaObject;
105 const QQmlPrivate::RegisterType &type)
107 QQmlTypePrivate *d =
new QQmlTypePrivate(QQmlType::CppType);
108 data->registerType(d);
109 d->setName(QString::fromUtf8(type.uri), elementName);
111 d->version = type.version;
112 d->revision = type.revision;
113 d->typeId = type.typeId;
114 d->listId = type.listId;
115 d->extraData.cppTypeData->allocationSize = type.objectSize;
116 d->extraData.cppTypeData->userdata = type.userdata;
117 d->extraData.cppTypeData->newFunc = type.create;
118 d->extraData.cppTypeData->noCreationReason = type.noCreationReason;
119 d->extraData.cppTypeData->createValueTypeFunc = type.createValueType;
120 d->baseMetaObject = type.metaObject;
121 d->extraData.cppTypeData->attachedPropertiesFunc = type.attachedPropertiesFunction;
122 d->extraData.cppTypeData->attachedPropertiesType = type.attachedPropertiesMetaObject;
123 d->extraData.cppTypeData->parserStatusCast = type.parserStatusCast;
124 d->extraData.cppTypeData->propertyValueSourceCast = type.valueSourceCast;
125 d->extraData.cppTypeData->propertyValueInterceptorCast = type.valueInterceptorCast;
126 d->extraData.cppTypeData->finalizerCast = type.has(QQmlPrivate::RegisterType::FinalizerCast)
129 d->extraData.cppTypeData->extFunc = type.extensionObjectCreate;
130 d->extraData.cppTypeData->customParser =
reinterpret_cast<QQmlCustomParser *>(type.customParser);
131 d->extraData.cppTypeData->registerEnumClassesUnscoped =
true;
132 d->extraData.cppTypeData->registerEnumsFromRelatedTypes =
true;
133 d->extraData.cppTypeData->constructValueType = type.has(QQmlPrivate::RegisterType::CreationMethod)
134 && type.creationMethod != QQmlPrivate::ValueTypeCreationMethod::None;
135 d->extraData.cppTypeData->populateValueType = type.has(QQmlPrivate::RegisterType::CreationMethod)
136 && type.creationMethod == QQmlPrivate::ValueTypeCreationMethod::Structured;
138 if (type.extensionMetaObject)
139 d->extraData.cppTypeData->extMetaObject = type.extensionMetaObject;
142 if (d->baseMetaObject) {
143 auto indexOfUnscoped = d->baseMetaObject->indexOfClassInfo(
"RegisterEnumClassesUnscoped");
144 if (indexOfUnscoped != -1
145 && qstrcmp(d->baseMetaObject->classInfo(indexOfUnscoped).value(),
"false") == 0) {
146 d->extraData.cppTypeData->registerEnumClassesUnscoped =
false;
149 auto indexOfRelated = d->baseMetaObject->indexOfClassInfo(
"RegisterEnumsFromRelatedTypes");
150 if (indexOfRelated != -1
151 && qstrcmp(d->baseMetaObject->classInfo(indexOfRelated).value(),
"false") == 0) {
152 d->extraData.cppTypeData->registerEnumsFromRelatedTypes =
false;
160 QQmlMetaTypeData *data,
const QUrl &url, QQmlTypePrivate *priv,
const QByteArray &className)
162 Q_ASSERT(!className.isEmpty());
163 QByteArray ptr = className +
'*';
164 QByteArray lst =
"QQmlListProperty<" + className +
'>';
166 QQmlMetaTypeData::CompositeMetaTypes &types = data->compositeMetaTypes[url];
168 Q_ASSERT(types.listType);
170 QMetaType::unregisterMetaType(QMetaType(types.type));
171 QMetaType::unregisterMetaType(QMetaType(types.listType));
173 types.type->name = std::move(ptr);
174 types.type->QMetaTypeInterface::name = types.type->name.constData();
175 types.listType->name = std::move(lst);
176 types.listType->QMetaTypeInterface::name = types.listType->name.constData();
178 types.type =
new QQmlMetaTypeInterface(std::move(ptr));
179 types.listType =
new QQmlListMetaTypeInterface(std::move(lst), types.type);
182 QMetaType ptr_type(types.type);
183 QMetaType lst_type(types.listType);
189 priv->typeId = ptr_type;
190 priv->listId = lst_type;
194 const QQmlPrivate::RegisterCompositeType &type)
196 auto *d =
new QQmlTypePrivate(QQmlType::CompositeType);
197 data->registerType(d);
198 d->setName(QString::fromUtf8(type.uri), elementName);
199 d->version = type.version;
201 const QUrl normalized = QQmlMetaType::normalizedUrl(type.url);
202 d->extraData.compositeTypeData = normalized;
203 addQQmlMetaTypeInterfaces(
204 data, normalized, d, QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(normalized));
209 QQmlMetaTypeData *data,
const QString &elementName,
210 const QQmlPrivate::RegisterCompositeSingletonType &type,
211 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
213 auto *d =
new QQmlTypePrivate(QQmlType::CompositeSingletonType);
214 data->registerType(d);
215 d->setName(QString::fromUtf8(type.uri), elementName);
217 d->version = type.version;
219 d->extraData.singletonTypeData->singletonInstanceInfo = siinfo;
220 const QUrl &url = siinfo->url;
221 addQQmlMetaTypeInterfaces(
222 data, url, d, QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(url));
226void QQmlMetaType::clone(QMetaObjectBuilder &builder,
const QMetaObject *mo,
227 const QMetaObject *ignoreStart,
const QMetaObject *ignoreEnd,
228 QQmlMetaType::ClonePolicy policy)
231 builder.setClassName(mo->className());
234 for (
int ii = mo->classInfoOffset(); ii < mo->classInfoCount(); ++ii) {
235 QMetaClassInfo info = mo->classInfo(ii);
237 int otherIndex = ignoreEnd->indexOfClassInfo(info.name());
238 if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
241 builder.addClassInfo(info.name(), info.value());
245 if (policy != QQmlMetaType::CloneEnumsOnly) {
247 for (
int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) {
248 QMetaMethod method = mo->method(ii);
251 QByteArray name = method.name();
255 for (
int ii = ignoreStart->methodOffset() + ignoreStart->methodCount();
256 !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount(); ++ii) {
258 QMetaMethod other = ignoreEnd->method(ii);
260 found = name == other.name();
263 QMetaMethodBuilder m = builder.addMethod(method);
265 m.setAccess(QMetaMethod::Private);
269 for (
int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) {
270 QMetaProperty property = mo->property(ii);
272 int otherIndex = ignoreEnd->indexOfProperty(property.name());
273 if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) {
274 builder.addProperty(QByteArray(
"__qml_ignore__") + property.name(),
278 builder.addProperty(property);
284 for (
int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) {
285 QMetaEnum enumerator = mo->enumerator(ii);
287 int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name());
288 if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) {
291 builder.addEnumerator(enumerator);
296void QQmlMetaType::qmlInsertModuleRegistration(
const QString &uri,
void (*registerFunction)())
298 QQmlMetaTypeDataPtr data;
299 if (data->moduleTypeRegistrationFunctions.contains(uri))
300 qFatal(
"Cannot add multiple registrations for %s", qPrintable(uri));
302 data->moduleTypeRegistrationFunctions.insert(uri, registerFunction);
305void QQmlMetaType::qmlRemoveModuleRegistration(
const QString &uri)
307 QQmlMetaTypeDataPtr data;
312 if (!data->moduleTypeRegistrationFunctions.remove(uri))
313 qFatal(
"Cannot remove multiple registrations for %s", qPrintable(uri));
316bool QQmlMetaType::qmlRegisterModuleTypes(
const QString &uri)
318 QQmlMetaTypeDataPtr data;
319 return data->registerModuleTypes(uri);
322void QQmlMetaType::clearTypeRegistrations()
325 QQmlMetaTypeDataPtr data;
327 data->uriToModule.clear();
329 data->idToType.clear();
330 data->nameToType.clear();
331 data->urlToType.clear();
332 data->speculativeInlineComponentTypes.clear();
333 data->metaObjectToType.clear();
334 data->undeletableTypes.clear();
335 data->propertyCaches.clear();
337 qDeleteAll(data->metaTypeToValueType);
338 data->metaTypeToValueType.clear();
340 data->moduleImports.clear();
342 data->clearCompositeTypes();
344 qDeleteAll(data->metaTypeToValueType);
345 data->metaTypeToValueType.clear();
347 data->clearCompositeMetaTypes();
350void QQmlMetaType::registerTypeAlias(
int typeIndex,
const QString &name)
352 QQmlMetaTypeDataPtr data;
353 const QQmlType type = data->types.value(typeIndex).type;
354 const QQmlTypePrivate *priv = type.priv();
355 data->nameToType.insert(name, priv);
358int QQmlMetaType::registerAutoParentFunction(
const QQmlPrivate::RegisterAutoParent &function)
360 if (function.structVersion > 1)
361 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
363 QQmlMetaTypeDataPtr data;
365 data->parentFunctions.append(function.function);
367 return data->parentFunctions.size() - 1;
370void QQmlMetaType::unregisterAutoParentFunction(
const QQmlPrivate::AutoParentFunction &function)
372 QQmlMetaTypeDataPtr data;
373 data->parentFunctions.removeOne(function);
376QQmlType QQmlMetaType::registerInterface(
const QQmlPrivate::RegisterInterface &type)
378 if (type.structVersion > 1)
379 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
381 QQmlMetaTypeDataPtr data;
382 QQmlTypePrivate *priv = createQQmlType(data, type);
386 data->idToType.insert(priv->typeId.id(), priv);
387 data->idToType.insert(priv->listId.id(), priv);
389 return QQmlType(priv);
395 if (typeType == QQmlType::CppType)
396 typeStr = QStringLiteral(
"element");
397 else if (typeType == QQmlType::SingletonType)
398 typeStr = QStringLiteral(
"singleton type");
399 else if (typeType == QQmlType::CompositeSingletonType)
400 typeStr = QStringLiteral(
"composite singleton type");
401 else if (typeType == QQmlType::SequentialContainerType)
402 typeStr = QStringLiteral(
"sequential container type");
404 typeStr = QStringLiteral(
"type");
410 QQmlType::RegistrationType typeType, QQmlMetaTypeData *data,
const char *uri,
411 const QString &typeName, QTypeRevision version, QMetaType::TypeFlags flags)
413 if (!typeName.isEmpty()) {
414 if (typeName.at(0).isLower() && (flags & QMetaType::PointerToQObject)) {
415 QString failure(QCoreApplication::translate(
"qmlRegisterType",
"Invalid QML %1 name \"%2\"; type names must begin with an uppercase letter"));
416 data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType), typeName));
420 if (typeName.at(0).isUpper()
421 && (flags & (QMetaType::IsGadget | QMetaType::PointerToGadget))) {
422 qCWarning(lcTypeRegistration).noquote()
423 << QCoreApplication::translate(
425 "Invalid QML %1 name \"%2\"; "
426 "value type names should begin with a lowercase letter")
427 .arg(registrationTypeString(typeType), typeName);
433 int typeNameLen = typeName.size();
434 for (
int ii = 0; ii < typeNameLen; ++ii) {
435 if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == u'_')) {
436 QString failure(QCoreApplication::translate(
"qmlRegisterType",
"Invalid QML %1 name \"%2\""));
437 data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType), typeName));
443 if (uri && !typeName.isEmpty()) {
444 QString nameSpace = QString::fromUtf8(uri);
446 if (qqtm && qqtm->lockLevel() != QQmlTypeModule::LockLevel::Open) {
447 QString failure(QCoreApplication::translate(
449 "Cannot install %1 '%2' into protected module '%3' version '%4'"));
450 data->recordTypeRegFailure(failure
451 .arg(registrationTypeString(typeType), typeName, nameSpace)
452 .arg(version.majorVersion()));
462 const QHashedString &uri, QTypeRevision version, QQmlMetaTypeData *data)
466 return data->addTypeModule(std::make_unique<QQmlTypeModule>(uri, version.majorVersion()));
474 if (!type->elementName.isEmpty())
475 data->nameToType.insert(type->elementName, type);
477 if (type->baseMetaObject)
478 data->metaObjectToType.insert(type->baseMetaObject, type);
480 if (type->regType == QQmlType::SequentialContainerType) {
481 if (type->listId.isValid())
482 data->idToType.insert(type->listId.id(), type);
484 if (type->typeId.isValid())
485 data->idToType.insert(type->typeId.id(), type);
487 if (type->listId.flags().testFlag(QMetaType::IsQmlList))
488 data->idToType.insert(type->listId.id(), type);
491 if (!type->module.isEmpty()) {
492 const QHashedString &mod = type->module;
500QQmlType QQmlMetaType::registerType(
const QQmlPrivate::RegisterType &type)
502 if (type.structVersion >
int(QQmlPrivate::RegisterType::CurrentVersion))
503 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
505 QQmlMetaTypeDataPtr data;
507 QString elementName = QString::fromUtf8(type.elementName);
508 if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.version,
509 QMetaType(type.typeId).flags())) {
513 QQmlTypePrivate *priv = createQQmlType(data, elementName, type);
514 addTypeToData(priv, data);
516 return QQmlType(priv);
519QQmlType QQmlMetaType::registerSingletonType(
520 const QQmlPrivate::RegisterSingletonType &type,
521 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
523 if (type.structVersion > 1)
524 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
526 QQmlMetaTypeDataPtr data;
528 QString typeName = QString::fromUtf8(type.typeName);
529 if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.version,
530 QMetaType(type.typeId).flags())) {
534 QQmlTypePrivate *priv = createQQmlType(data, typeName, type, siinfo);
536 addTypeToData(priv, data);
538 return QQmlType(priv);
541QQmlType QQmlMetaType::registerCompositeSingletonType(
542 const QQmlPrivate::RegisterCompositeSingletonType &type,
543 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
545 if (type.structVersion > 1)
546 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
549 QQmlMetaTypeDataPtr data;
551 QString typeName = QString::fromUtf8(type.typeName);
552 if (!checkRegistration(
553 QQmlType::CompositeSingletonType, data, type.uri, typeName, type.version, {})) {
557 QQmlTypePrivate *priv = createQQmlType(data, typeName, type, siinfo);
558 addTypeToData(priv, data);
560 data->urlToType.insert(siinfo->url, priv);
562 return QQmlType(priv);
565QQmlType QQmlMetaType::registerCompositeType(
const QQmlPrivate::RegisterCompositeType &type)
567 if (type.structVersion > 1)
568 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
571 QQmlMetaTypeDataPtr data;
573 QString typeName = QString::fromUtf8(type.typeName);
574 if (!checkRegistration(QQmlType::CompositeType, data, type.uri, typeName, type.version, {}))
577 QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
578 addTypeToData(priv, data);
580 data->urlToType.insert(QQmlMetaType::normalizedUrl(type.url), priv);
582 return QQmlType(priv);
605 QQmlMetaTypeData *data,
const QUrl &url,
const QHashedStringRef &qualifiedType,
606 QQmlMetaType::CompositeTypeLookupMode mode, QList<QQmlError> *errors, QTypeRevision version)
608 const int dot = qualifiedType.indexOf(QLatin1Char(
'.'));
609 const QString typeName = dot < 0
610 ? qualifiedType.toString()
611 : QString(qualifiedType.constData() + dot + 1, qualifiedType.length() - dot - 1);
613 QStringList failures;
633 QQmlType::RegistrationType registrationType;
635 case QQmlMetaType::Singleton:
636 registrationType = QQmlType::CompositeSingletonType;
638 case QQmlMetaType::NonSingleton:
639 registrationType = QQmlType::CompositeType;
641 case QQmlMetaType::JavaScript:
642 registrationType = QQmlType::JavaScriptType;
645 Q_UNREACHABLE_RETURN(QQmlType());
648 if (checkRegistration(registrationType, data,
nullptr, typeName, version, {})) {
655 auto *priv =
new QQmlTypePrivate(registrationType);
656 addQQmlMetaTypeInterfaces(
657 data, url, priv, QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(url));
659 priv->setName(QString(), typeName);
660 priv->version = version;
663 case QQmlMetaType::Singleton: {
664 QQmlType::SingletonInstanceInfo::Ptr siinfo = QQmlType::SingletonInstanceInfo::create();
666 siinfo->typeName = typeName.toUtf8();
667 priv->extraData.singletonTypeData->singletonInstanceInfo =
668 QQmlType::SingletonInstanceInfo::ConstPtr(
669 siinfo.take(), QQmlType::SingletonInstanceInfo::ConstPtr::Adopt);
672 case QQmlMetaType::NonSingleton: {
673 priv->extraData.compositeTypeData = url;
676 case QQmlMetaType::JavaScript: {
677 priv->extraData.javaScriptTypeData = url;
682 data->registerType(priv);
683 addTypeToData(priv, data);
684 return QQmlType(priv);
692 error.setDescription(failures.join(u'\n'));
693 errors->prepend(error);
695 qWarning(
"%s", failures.join(u'\n').toLatin1().constData());
700QQmlType QQmlMetaType::findCompositeType(
701 const QUrl &url,
const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit,
702 CompositeTypeLookupMode mode)
704 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
705 QQmlMetaTypeDataPtr data;
707 bool urlExists =
true;
708 auto found = data->urlToType.constFind(normalized);
709 if (found == data->urlToType.cend())
713 if (compilationUnit.isNull())
714 return QQmlType(*found);
715 const auto [begin, end]
716 = std::as_const(data->compositeTypes).equal_range(found.value()->typeId.iface());
718 return QQmlType(*found);
719 for (
auto it = begin; it != end; ++it) {
720 if (it.value() == compilationUnit)
721 return QQmlType(*found);
725 const QQmlType type = createTypeForUrl(
726 data, normalized, QHashedStringRef(), mode,
nullptr, QTypeRevision());
728 if (!urlExists && type.isValid())
729 data->urlToType.insert(normalized, type.priv());
736 QQmlTypePrivate *priv =
new QQmlTypePrivate(QQmlType::InlineComponentType);
737 priv->setName(QString(), url.fragment());
739 priv->extraData.inlineComponentTypeData = url;
740 data->registerType(priv);
742 addQQmlMetaTypeInterfaces(
743 data, url, priv, QQmlPropertyCacheCreatorBase::createClassNameForInlineComponent(url));
744 data->urlToType.insert(url, priv);
746 data->idToType.insert(priv->typeId.id(), priv);
747 data->idToType.insert(priv->listId.id(), priv);
749 return QQmlType(priv);
752QQmlType QQmlMetaType::findOrCreateFactualInlineComponentType(
753 const QUrl &url,
const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
755 QQmlMetaTypeDataPtr data;
759 const auto it = data->urlToType.constFind(url);
760 if (it == data->urlToType.constEnd())
761 return doRegisterInlineComponentType(data, url);
763 const auto [begin, end]
764 = std::as_const(data->compositeTypes).equal_range((*it)->typeId.iface());
766 data->speculativeInlineComponentTypes.remove(url);
767 return QQmlType(*it);
770 for (
auto jt = begin; jt != end; ++jt) {
771 if (*jt != compilationUnit)
774 data->speculativeInlineComponentTypes.remove(url);
775 return QQmlType(*it);
778 return doRegisterInlineComponentType(data, url);
781int QQmlMetaType::registerUnitCacheHook(
782 const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration)
784 if (hookRegistration.structVersion > 1)
785 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
787 QQmlMetaTypeDataPtr data;
788 data->lookupCachedQmlUnit << hookRegistration.lookupCachedQmlUnit;
792QQmlType QQmlMetaType::registerSequentialContainer(
793 const QQmlPrivate::RegisterSequentialContainer &container)
795 if (container.structVersion > 1)
796 qFatal(
"qmlRegisterSequenceContainer(): Cannot mix incompatible QML versions.");
798 QQmlMetaTypeDataPtr data;
800 if (!checkRegistration(QQmlType::SequentialContainerType, data, container.uri, QString(),
801 container.version, {})) {
805 QQmlTypePrivate *priv =
new QQmlTypePrivate(QQmlType::SequentialContainerType);
807 data->registerType(priv);
808 priv->setName(QString::fromUtf8(container.uri), QString());
809 priv->version = container.version;
810 priv->revision = container.revision;
811 priv->typeId = container.metaSequence.valueMetaType();
812 priv->listId = container.typeId;
813 priv->extraData.sequentialContainerTypeData = container.metaSequence;
815 addTypeToData(priv, data);
817 return QQmlType(priv);
820void QQmlMetaType::unregisterSequentialContainer(
int id)
825bool QQmlMetaType::protectModule(
const QString &uri, QTypeRevision version,
826 bool weakProtectAllVersions)
828 QQmlMetaTypeDataPtr data;
829 if (version.hasMajorVersion()) {
830 if (QQmlTypeModule *module = data->findTypeModule(uri, version)) {
831 if (!weakProtectAllVersions) {
832 module->setLockLevel(QQmlTypeModule::LockLevel::Strong);
840 const auto range = std::equal_range(
841 data->uriToModule.begin(), data->uriToModule.end(), uri,
842 std::less<ModuleUri>());
844 for (
auto it = range.first; it != range.second; ++it)
845 (*it)->setLockLevel(QQmlTypeModule::LockLevel::Weak);
847 return range.first != range.second;
850void QQmlMetaType::registerModuleImport(
const QString &uri, QTypeRevision moduleVersion,
851 const QQmlDirParser::Import &import)
853 QQmlMetaTypeDataPtr data;
855 data->moduleImports.insert(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import);
858void QQmlMetaType::unregisterModuleImport(
const QString &uri, QTypeRevision moduleVersion,
859 const QQmlDirParser::Import &import)
861 QQmlMetaTypeDataPtr data;
862 data->moduleImports.remove(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import);
865QList<QQmlDirParser::Import> QQmlMetaType::moduleImports(
866 const QString &uri, QTypeRevision version)
868 QQmlMetaTypeDataPtr data;
869 QList<QQmlDirParser::Import> result;
871 const auto unrevisioned = data->moduleImports.equal_range(
872 QQmlMetaTypeData::VersionedUri(uri, QTypeRevision()));
873 for (
auto it = unrevisioned.second; it != unrevisioned.first;)
874 result.append(*(--it));
876 if (version.hasMajorVersion()) {
877 const auto revisioned = data->moduleImports.equal_range(
878 QQmlMetaTypeData::VersionedUri(uri, version));
879 for (
auto it = revisioned.second; it != revisioned.first;)
880 result.append(*(--it));
885 const auto begin = data->moduleImports.begin();
886 auto it = unrevisioned.first;
890 const QQmlMetaTypeData::VersionedUri latestVersion = (--it).key();
891 if (latestVersion.uri != uri)
896 }
while (it != begin && (--it).key() == latestVersion);
901void QQmlMetaType::registerModule(
const char *uri, QTypeRevision version)
903 QQmlMetaTypeDataPtr data;
905 QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
908 if (version.hasMinorVersion())
909 module->addMinorVersion(version.minorVersion());
912int QQmlMetaType::typeId(
const char *uri, QTypeRevision version,
const char *qmlName)
914 QQmlMetaTypeDataPtr data;
916 QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
920 QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), version);
927void QQmlMetaType::registerUndeletableType(
const QQmlType &dtype)
929 QQmlMetaTypeDataPtr data;
930 data->undeletableTypes.insert(dtype);
934 QTypeRevision version)
938 for (
const auto &typeAndCaches : std::as_const(data->types)) {
939 const QQmlType &type = typeAndCaches.type;
940 if (type.module() == nameSpace && type.version().majorVersion() == version.majorVersion())
947QQmlMetaType::RegistrationResult QQmlMetaType::registerPluginTypes(
948 QObject *instance,
const QString &basePath,
const QString &uri,
949 const QString &typeNamespace, QTypeRevision version, QList<QQmlError> *errors)
951 if (!typeNamespace.isEmpty() && typeNamespace != uri) {
956 error.setDescription(
957 QStringLiteral(
"Module namespace '%1' does not match import URI '%2'")
958 .arg(typeNamespace, uri));
959 errors->prepend(error);
961 return RegistrationResult::Failure;
964 QStringList failures;
965 QQmlMetaTypeDataPtr data;
967 QQmlMetaTypeRegistrationFailureRecorder failureRecorder(data, &failures);
968 if (!typeNamespace.isEmpty()) {
970 if (namespaceContainsRegistrations(data, typeNamespace, version)) {
974 error.setDescription(QStringLiteral(
"Namespace '%1' has already been used "
975 "for type registration")
976 .arg(typeNamespace));
977 errors->prepend(error);
979 return RegistrationResult::Failure;
983 qWarning().nospace() << qPrintable(
984 QStringLiteral(
"Module '%1' does not contain a module identifier directive - "
985 "it cannot be protected from external registrations.").arg(uri));
988 if (instance && !qobject_cast<QQmlEngineExtensionInterface *>(instance)) {
989 QQmlTypesExtensionInterface *iface = qobject_cast<QQmlTypesExtensionInterface *>(instance);
994 error.setDescription(QStringLiteral(
"Module loaded for URI '%1' does not implement "
995 "QQmlEngineExtensionInterface").arg(typeNamespace));
996 errors->prepend(error);
998 return RegistrationResult::Failure;
1001#if QT_DEPRECATED_SINCE(6
, 3
)
1002 if (
auto *plugin = qobject_cast<QQmlExtensionPlugin *>(instance)) {
1004 QQmlExtensionPluginPrivate::get(plugin)->baseUrl
1005 = QQmlImports::urlFromLocalFileOrQrcOrUrl(basePath);
1011 const QByteArray bytes = uri.toUtf8();
1012 const char *moduleId = bytes.constData();
1013 iface->registerTypes(moduleId);
1016 if (failures.isEmpty() && !data->registerModuleTypes(uri))
1017 return RegistrationResult::NoRegistrationFunction;
1019 if (!failures.isEmpty()) {
1021 for (
const QString &failure : std::as_const(failures)) {
1023 error.setDescription(failure);
1024 errors->prepend(error);
1027 return RegistrationResult::Failure;
1031 return RegistrationResult::Success;
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045QQmlType QQmlMetaType::typeForUrl(
1046 const QUrl &url,
const QHashedStringRef &qualifiedType, CompositeTypeLookupMode mode,
1047 QList<QQmlError> *errors, QTypeRevision version)
1050 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
1052 QQmlMetaTypeDataPtr data;
1054 QQmlType ret(data->urlToType.value(normalized));
1055 if (ret.isValid() && ret.sourceUrl() == normalized)
1059 const QQmlType type = createTypeForUrl(
1060 data, normalized, qualifiedType, mode, errors, version);
1061 data->urlToType.insert(normalized, type.priv());
1066
1067
1068QTypeRevision QQmlMetaType::latestModuleVersion(
const QString &uri)
1070 QQmlMetaTypeDataPtr data;
1071 auto upper = std::upper_bound(data->uriToModule.begin(), data->uriToModule.end(), uri,
1072 std::less<ModuleUri>());
1073 if (upper == data->uriToModule.begin())
1074 return QTypeRevision();
1076 const auto module = (--upper)->get();
1077 return (module->module() == uri)
1078 ? QTypeRevision::fromVersion(module->majorVersion(), module->maximumMinorVersion())
1083
1084
1085bool QQmlMetaType::isStronglyLockedModule(
const QString &uri, QTypeRevision version)
1087 QQmlMetaTypeDataPtr data;
1089 if (QQmlTypeModule* qqtm = data->findTypeModule(uri, version))
1090 return qqtm->lockLevel() == QQmlTypeModule::LockLevel::Strong;
1095
1096
1097
1098
1099
1100
1101QTypeRevision QQmlMetaType::matchingModuleVersion(
const QString &module, QTypeRevision version)
1103 if (!version.hasMajorVersion())
1104 return latestModuleVersion(module);
1106 QQmlMetaTypeDataPtr data;
1109 if (QQmlTypeModule *tm = data->findTypeModule(module, version)) {
1110 if (!version.hasMinorVersion())
1111 return QTypeRevision::fromVersion(version.majorVersion(), tm->maximumMinorVersion());
1113 if (tm->minimumMinorVersion() <= version.minorVersion()
1114 && tm->maximumMinorVersion() >= version.minorVersion()) {
1119 return QTypeRevision();
1122QQmlTypeModule *QQmlMetaType::typeModule(
const QString &uri, QTypeRevision version)
1124 QQmlMetaTypeDataPtr data;
1126 if (version.hasMajorVersion())
1127 return data->findTypeModule(uri, version);
1129 auto range = std::equal_range(data->uriToModule.begin(), data->uriToModule.end(),
1130 uri, std::less<ModuleUri>());
1132 return range.first == range.second ?
nullptr : (--range.second)->get();
1135QList<QQmlPrivate::AutoParentFunction> QQmlMetaType::parentFunctions()
1137 QQmlMetaTypeDataPtr data;
1138 return data->parentFunctions;
1141QObject *QQmlMetaType::toQObject(
const QVariant &v,
bool *ok)
1143 if (!v.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
1144 if (ok) *ok =
false;
1150 return *(QObject *
const *)v.constData();
1154
1155
1156QMetaType QQmlMetaType::listValueType(QMetaType metaType)
1158 if (isList(metaType)) {
1159 const auto iface = metaType.iface();
1160 if (iface && iface->metaObjectFn == &dynamicQmlListMarker)
1161 return QMetaType(
static_cast<
const QQmlListMetaTypeInterface *>(iface)->valueType);
1162 }
else if (metaType.flags() & QMetaType::PointerToQObject) {
1166 QQmlMetaTypeDataPtr data;
1168 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1170 if (type && type->listId == metaType)
1171 return type->typeId;
1173 return QMetaType {};
1176QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFunc(
1177 QQmlTypeLoader *typeLoader,
const QMetaObject *mo)
1179 QQmlMetaTypeDataPtr data;
1181 QQmlType type(data->metaObjectToType.value(mo));
1182 return type.attachedPropertiesFunction(typeLoader);
1185QMetaProperty QQmlMetaType::defaultProperty(
const QMetaObject *metaObject)
1187 int idx = metaObject->indexOfClassInfo(
"DefaultProperty");
1189 return QMetaProperty();
1191 QMetaClassInfo info = metaObject->classInfo(idx);
1193 return QMetaProperty();
1195 idx = metaObject->indexOfProperty(info.value());
1197 return QMetaProperty();
1199 return metaObject->property(idx);
1202QMetaProperty QQmlMetaType::defaultProperty(QObject *obj)
1205 return QMetaProperty();
1207 const QMetaObject *metaObject = obj->metaObject();
1208 return defaultProperty(metaObject);
1211QMetaMethod QQmlMetaType::defaultMethod(
const QMetaObject *metaObject)
1213 int idx = metaObject->indexOfClassInfo(
"DefaultMethod");
1215 return QMetaMethod();
1217 QMetaClassInfo info = metaObject->classInfo(idx);
1219 return QMetaMethod();
1221 idx = metaObject->indexOfMethod(info.value());
1223 return QMetaMethod();
1225 return metaObject->method(idx);
1228QMetaMethod QQmlMetaType::defaultMethod(QObject *obj)
1231 return QMetaMethod();
1233 const QMetaObject *metaObject = obj->metaObject();
1234 return defaultMethod(metaObject);
1238
1239
1240bool QQmlMetaType::isInterface(QMetaType metaType)
1242 const QQmlMetaTypeDataPtr data;
1243 return QQmlType(data->idToType.value(metaType.id())).isInterface();
1246const char *QQmlMetaType::interfaceIId(QMetaType metaType)
1248 const QQmlMetaTypeDataPtr data;
1249 const QQmlType type(data->idToType.value(metaType.id()));
1250 return (type.isInterface() && type.typeId() == metaType) ? type.interfaceIId() :
nullptr;
1253bool QQmlMetaType::isList(QMetaType type)
1255 if (type.flags().testFlag(QMetaType::IsQmlList))
1262
1263
1264
1265QQmlType QQmlMetaType::qmlType(
const QString &qualifiedName, QTypeRevision version)
1267 int slash = qualifiedName.indexOf(QLatin1Char(
'/'));
1271 QHashedStringRef module(qualifiedName.constData(), slash);
1272 QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.size() - slash - 1);
1274 return qmlType(name, module, version);
1278
1279
1280
1281
1282
1283
1284
1285QQmlType QQmlMetaType::qmlType(
const QHashedStringRef &name,
const QHashedStringRef &module,
1286 QTypeRevision version)
1288 const QQmlMetaTypeDataPtr data;
1290 const QHashedString key(QString::fromRawData(name.constData(), name.length()), name.hash());
1291 QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(key);
1292 while (it != data->nameToType.cend() && QHashedStringRef(it.key()) == name) {
1294 if (module.isEmpty() || t.availableInVersion(module, version))
1303
1304
1305
1306QQmlType QQmlMetaType::qmlType(
const QMetaObject *metaObject)
1308 const QQmlMetaTypeDataPtr data;
1309 return QQmlType(data->metaObjectToType.value(metaObject));
1313
1314
1315
1316
1317QQmlType QQmlMetaType::qmlType(
const QMetaObject *metaObject,
const QHashedStringRef &module,
1318 QTypeRevision version)
1320 const QQmlMetaTypeDataPtr data;
1322 const auto range = data->metaObjectToType.equal_range(metaObject);
1323 for (
auto it = range.first; it != range.second; ++it) {
1325 if (module.isEmpty() || t.availableInVersion(module, version))
1333
1334
1335
1336QQmlType QQmlMetaType::qmlTypeById(
int qmlTypeId)
1338 const QQmlMetaTypeDataPtr data;
1339 return data->types.value(qmlTypeId).type;
1343
1344
1345
1346
1347
1348
1349
1350
1351QQmlType QQmlMetaType::firstQmlTypeForAttachmentMetaObject(
const QMetaObject *attachmentMetaObject)
1353 const QQmlMetaTypeDataPtr data;
1354 if (
auto qmlTypePriv = data->metaObjectToType.value(attachmentMetaObject)) {
1356 if (qmlTypePriv->regType == QQmlType::CppType &&
1357 qmlTypePriv->extraData.cppTypeData->attachedPropertiesType == attachmentMetaObject)
1358 return QQmlType(qmlTypePriv);
1360 auto getAttachmentMetaObject = [](
const QQmlTypePrivate *priv) ->
const QMetaObject * {
1361 if (priv->regType != QQmlType::CppType)
1363 return priv->extraData.cppTypeData->attachedPropertiesType;
1365 auto it = std::find_if(data->metaObjectToType.constBegin(),
1366 data->metaObjectToType.constEnd(),
1367 [&](
const QQmlTypePrivate *type) {
return attachmentMetaObject == getAttachmentMetaObject(type); }
1369 if (it == data->metaObjectToType.constEnd())
1371 return QQmlType(*it);
1375
1376
1377
1378QQmlType QQmlMetaType::qmlType(QMetaType metaType)
1380 const QQmlMetaTypeDataPtr data;
1381 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1382 return (type && type->typeId == metaType) ? QQmlType(type) : QQmlType();
1385QQmlType QQmlMetaType::qmlListType(QMetaType metaType)
1387 const QQmlMetaTypeDataPtr data;
1388 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1389 return (type && type->listId == metaType) ? QQmlType(type) : QQmlType();
1393
1394
1395
1396
1397
1398QQmlType QQmlMetaType::qmlType(
const QUrl &unNormalizedUrl)
1400 const QUrl url = QQmlMetaType::normalizedUrl(unNormalizedUrl);
1401 const QQmlMetaTypeDataPtr data;
1403 QQmlType type(data->urlToType.value(url));
1405 if (type.sourceUrl() == url)
1411QQmlType QQmlMetaType::findOrCreateSpeculativeInlineComponentType(
const QUrl &url)
1413 QQmlMetaTypeDataPtr data;
1414 const auto it = data->urlToType.constFind(url);
1415 if (it != data->urlToType.constEnd())
1416 return QQmlType(*it);
1421 baseUrl.setFragment(QString());
1425 if (baseUrl.isEmpty())
1426 return doRegisterInlineComponentType(data, url);
1430 const auto baseIt = data->urlToType.constFind(baseUrl);
1431 if (baseIt == data->urlToType.constEnd()) {
1432 data->speculativeInlineComponentTypes.insert(url);
1433 return doRegisterInlineComponentType(data, url);
1438 const auto cu = data->compositeTypes.value((*baseIt)->typeId.iface());
1440 data->speculativeInlineComponentTypes.insert(url);
1441 return doRegisterInlineComponentType(data, url);
1446 Q_ASSERT(std::none_of(
1447 cu->inlineComponentData.constBegin(), cu->inlineComponentData.constEnd(),
1448 [&](
const QV4::CompiledData::InlineComponentData &icData) {
1449 return icData.qmlType.elementName() == url.fragment();
1457
1458
1459
1460
1461
1462QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(QObject *obj, QTypeRevision version)
1464 if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted)
1465 return QQmlPropertyCache::ConstPtr();
1466 return QQmlMetaType::propertyCache(obj->metaObject(), version);
1469QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(
1470 const QMetaObject *metaObject, QTypeRevision version)
1472 QQmlMetaTypeDataPtr data;
1473 return data->propertyCache(metaObject, version);
1476QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(
1477 const QQmlType &type, QTypeRevision version)
1479 QQmlMetaTypeDataPtr data;
1480 return data->propertyCache(type, version);
1484
1485
1486
1487
1488QQmlMetaObject QQmlMetaType::rawMetaObjectForType(QMetaType metaType)
1490 const QQmlMetaTypeDataPtr data;
1491 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1492 return QQmlMetaObject(composite);
1494 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1495 return (type && type->typeId == metaType) ? type->baseMetaObject :
nullptr;
1499
1500
1501
1502
1503QQmlMetaObject QQmlMetaType::metaObjectForType(QMetaType metaType)
1505 const QQmlMetaTypeDataPtr data;
1506 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1507 return QQmlMetaObject(composite);
1509 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1510 return (type && type->typeId == metaType)
1511 ? QQmlType(type).metaObject()
1516
1517
1518
1519
1520QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCacheForType(QMetaType metaType)
1522 QQmlMetaTypeDataPtr data;
1523 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1526 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1527 if (type && type->typeId == metaType) {
1528 if (
const QMetaObject *mo = QQmlType(type).metaObject())
1529 return data->propertyCache(mo, type->version);
1532 return QQmlPropertyCache::ConstPtr();
1536
1537
1538
1539
1540
1541
1542QQmlPropertyCache::ConstPtr QQmlMetaType::rawPropertyCacheForType(QMetaType metaType)
1544 QQmlMetaTypeDataPtr data;
1545 if (
auto composite = QQmlMetaType::findPropertyCacheInCompositeTypes(metaType))
1548 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1549 if (!type || type->typeId != metaType)
1550 return QQmlPropertyCache::ConstPtr();
1552 const QMetaObject *metaObject = type->isValueType()
1553 ? type->metaObjectForValueType()
1554 : type->baseMetaObject;
1557 ? data->propertyCache(metaObject, QTypeRevision())
1558 : QQmlPropertyCache::ConstPtr();
1562
1563
1564
1565
1566
1567QQmlPropertyCache::ConstPtr QQmlMetaType::rawPropertyCacheForType(
1568 QMetaType metaType, QTypeRevision version)
1570 QQmlMetaTypeDataPtr data;
1571 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1574 const QQmlTypePrivate *typePriv = data->idToType.value(metaType.id());
1575 if (!typePriv || typePriv->typeId != metaType)
1576 return QQmlPropertyCache::ConstPtr();
1578 const QQmlType type(typePriv);
1579 if (type.containsRevisionedAttributes()) {
1581 Q_ASSERT(type.metaObject());
1582 return data->propertyCache(type, version);
1585 if (
const QMetaObject *metaObject = type.metaObject())
1586 return data->propertyCache(metaObject, version);
1588 return QQmlPropertyCache::ConstPtr();
1591template<
typename From,
typename CanConvertPropCache,
typename CanConvertMetaObject>
1594 CanConvertPropCache &&canConvertPropCache, CanConvertMetaObject &&canConvertMetaObject)
1602 auto [it, end] = data->compositeTypes.equal_range(metaType.iface());
1605 if (canConvertPropCache(
1606 from, QQmlMetaTypeData::propertyCacheForPotentialInlineComponentType(
1610 }
while(++it != end);
1617 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1618 if (type && type->typeId == metaType && type->baseMetaObject)
1619 return canConvertMetaObject(from, type->baseMetaObject);
1622 if (
const QMetaObject *metaObject = metaType.metaObject())
1623 return canConvertMetaObject(from, metaObject);
1628bool QQmlMetaType::canConvert(QObject *o, QMetaType metaType)
1630 QQmlMetaTypeDataPtr data;
1632 return canConvertToPropCacheOrMetaObject(
1633 data, o, metaType, [](QObject *o,
const QQmlPropertyCache::ConstPtr &propCache) {
1634 return QQmlMetaObject::canConvert(o, propCache);
1635 }, [](QObject *o,
const QMetaObject *metaObject) {
1636 return QQmlMetaObject::canConvert(o, metaObject);
1641 const QQmlPropertyCache::ConstPtr &derived,
const QQmlPropertyCache::ConstPtr &base)
1643 for (QQmlPropertyCache::ConstPtr parent = derived; parent; parent = parent->parent()) {
1651bool QQmlMetaType::canConvert(
const QQmlPropertyCache::ConstPtr &from, QMetaType metaType)
1653 QQmlMetaTypeDataPtr data;
1655 return canConvertToPropCacheOrMetaObject(
1656 data, from, metaType,
1657 [](
const QQmlPropertyCache::ConstPtr &from,
const QQmlPropertyCache::ConstPtr &to) {
1658 return inherits(from, to);
1659 }, [&](
const QQmlPropertyCache::ConstPtr &from,
const QMetaObject *toMeta) {
1660 if (
const QMetaObject *fromMeta = from->metaObject())
1661 return QQmlMetaObject::canConvert(fromMeta, toMeta);
1662 return inherits(from, data->propertyCache(toMeta, QTypeRevision()));
1666void QQmlMetaType::unregisterType(
int typeIndex)
1668 QQmlMetaTypeDataPtr data;
1669 const QQmlType type = data->types.value(typeIndex).type;
1670 if (
const QQmlTypePrivate *d = type.priv()) {
1671 if (d->regType == QQmlType::CompositeType || d->regType == QQmlType::CompositeSingletonType) {
1672 removeFromInlineComponents(data->urlToType, d);
1673 removeFromInlineComponents(data->speculativeInlineComponentTypes, d);
1675 removeQQmlTypePrivate(data->idToType, d);
1676 removeQQmlTypePrivate(data->nameToType, d);
1677 removeQQmlTypePrivate(data->urlToType, d);
1678 removeQQmlTypePrivate(data->metaObjectToType, d);
1679 data->speculativeInlineComponentTypes.remove(d->sourceUrl());
1680 for (
auto & module : data->uriToModule)
1682 data->types[typeIndex] = QQmlMetaTypeData::Type();
1683 data->undeletableTypes.remove(type);
1687void QQmlMetaType::registerMetaObjectForType(
const QMetaObject *metaobject,
const QQmlTypePrivate *type)
1691 QQmlMetaTypeDataPtr data;
1692 data->metaObjectToType.insert(metaobject, type);
1697 for (
auto it = data->urlToType.begin(), end = data->urlToType.end();
1699 if (!QQmlMetaType::equalBaseUrls(it.key(), d->sourceUrl()))
1702 const QQmlTypePrivate *icPriv = *it;
1703 if (icPriv && icPriv->count() > 1)
1710 QQmlMetaTypeData *data,
1711 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
1714 auto doCheck = [&](
const QtPrivate::QMetaTypeInterface *iface) {
1718 const auto [begin, end] = std::as_const(data->compositeTypes).equal_range(iface);
1719 for (
auto it = begin; it != end; ++it) {
1720 if (*it == compilationUnit)
1725 doCheck(compilationUnit->metaType().iface());
1726 for (
const auto &inlineData : std::as_const(compilationUnit->inlineComponentData))
1727 doCheck(inlineData.qmlType.typeId().iface());
1732void QQmlMetaType::freeUnusedTypesAndCaches()
1734 QQmlMetaTypeDataPtr data;
1737 if (!data.isValid())
1740 bool droppedAtLeastOneComposite;
1742 droppedAtLeastOneComposite =
false;
1743 auto it = data->compositeTypes.cbegin();
1744 while (it != data->compositeTypes.cend()) {
1745 const auto &cu = *it;
1746 if (cu->count() <= doCountInternalCompositeTypeSelfReferences(data, cu)) {
1747 QQmlMetaTypeData::clearCompositeType(cu);
1748 it = data->compositeTypes.erase(it);
1749 droppedAtLeastOneComposite =
true;
1754 }
while (droppedAtLeastOneComposite);
1756 bool deletedAtLeastOneType;
1758 deletedAtLeastOneType =
false;
1759 auto it = data->types.begin();
1760 while (it != data->types.end()) {
1761 const QQmlTypePrivate *d = it->type.priv();
1762 if (d && d->count() == 1 && !hasActiveInlineComponents(data, d)) {
1763 deletedAtLeastOneType =
true;
1765 if (d->regType == QQmlType::CompositeType
1766 || d->regType == QQmlType::CompositeSingletonType) {
1767 removeFromInlineComponents(data->urlToType, d);
1768 removeFromInlineComponents(data->speculativeInlineComponentTypes, d);
1770 removeQQmlTypePrivate(data->idToType, d);
1771 removeQQmlTypePrivate(data->nameToType, d);
1772 removeQQmlTypePrivate(data->urlToType, d);
1773 removeQQmlTypePrivate(data->metaObjectToType, d);
1774 data->speculativeInlineComponentTypes.remove(d->sourceUrl());
1776 for (
auto &module : data->uriToModule)
1779 *it = QQmlMetaTypeData::Type();
1784 }
while (deletedAtLeastOneType);
1786 bool deletedAtLeastOneCache;
1788 deletedAtLeastOneCache =
false;
1789 auto it = data->propertyCaches.begin();
1790 while (it != data->propertyCaches.end()) {
1791 if ((*it)->count() == 1) {
1792 it = data->propertyCaches.erase(it);
1793 deletedAtLeastOneCache =
true;
1798 }
while (deletedAtLeastOneCache);
1802
1803
1804QList<QString> QQmlMetaType::qmlTypeNames()
1806 const QQmlMetaTypeDataPtr data;
1808 QList<QString> names;
1809 names.reserve(data->nameToType.size());
1810 QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.cbegin();
1811 while (it != data->nameToType.cend()) {
1813 names += t.qmlTypeName();
1821
1822
1823QList<QQmlType> QQmlMetaType::qmlTypes()
1825 const QQmlMetaTypeDataPtr data;
1827 QList<QQmlType> types;
1828 for (
const QQmlTypePrivate *t : data->nameToType)
1829 types.append(QQmlType(t));
1835
1836
1837QList<QQmlType> QQmlMetaType::qmlAllTypes()
1839 const QQmlMetaTypeDataPtr data;
1840 QList<QQmlType> types;
1841 types.reserve(data->types.size());
1843 data->types.constBegin(), data->types.constEnd(),
1844 std::back_inserter(types), [](
const auto &type) {
return type.type; });
1849
1850
1851QList<QQmlType> QQmlMetaType::qmlSingletonTypes()
1853 const QQmlMetaTypeDataPtr data;
1855 QList<QQmlType> retn;
1856 for (
const auto t : std::as_const(data->nameToType)) {
1858 if (type.isSingleton())
1866 quint32 numTypedFunctions = 0;
1867 for (
const QQmlPrivate::AOTCompiledFunction *function = unit->aotCompiledFunctions;
1868 function; ++function) {
1869 if (function->functionPtr)
1870 ++numTypedFunctions;
1874 return numTypedFunctions == unit->qmlData->functionTableSize;
1877const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(
1878 const QUrl &uri, QQmlMetaType::CacheMode mode, CachedUnitLookupError *status)
1880 Q_ASSERT(mode != RejectAll);
1881 const QQmlMetaTypeDataPtr data;
1883 for (
const auto lookup : std::as_const(data->lookupCachedQmlUnit)) {
1884 if (
const QQmlPrivate::CachedQmlUnit *unit = lookup(uri)) {
1886 if (!unit->qmlData->verifyHeader(QDateTime(), &error)) {
1887 qCDebug(DBG_DISK_CACHE) <<
"Error loading pre-compiled file " << uri <<
":" << error;
1889 *status = CachedUnitLookupError::VersionMismatch;
1893 if (mode == RequireFullyTyped && !isFullyTyped(unit)) {
1894 qCDebug(DBG_DISK_CACHE)
1895 <<
"Error loading pre-compiled file " << uri
1896 <<
": compilation unit contains functions not compiled to native code.";
1898 *status = CachedUnitLookupError::NotFullyTyped;
1903 *status = CachedUnitLookupError::NoError;
1908 qCDebug(DBG_DISK_CACHE) <<
"No pre-compiled unit found for" << uri;
1911 *status = CachedUnitLookupError::NoUnitFound;
1916void QQmlMetaType::prependCachedUnitLookupFunction(QQmlPrivate::QmlUnitCacheLookupFunction handler)
1918 QQmlMetaTypeDataPtr data;
1919 data->lookupCachedQmlUnit.prepend(handler);
1922void QQmlMetaType::removeCachedUnitLookupFunction(QQmlPrivate::QmlUnitCacheLookupFunction handler)
1924 QQmlMetaTypeDataPtr data;
1925 data->lookupCachedQmlUnit.removeAll(handler);
1929
1930
1931QString QQmlMetaType::prettyTypeName(
const QObject *object)
1938 QQmlType type = QQmlMetaType::qmlType(object->metaObject());
1939 if (type.isValid()) {
1940 typeName = type.qmlTypeName();
1941 const int lastSlash = typeName.lastIndexOf(QLatin1Char(
'/'));
1942 if (lastSlash != -1)
1943 typeName = typeName.mid(lastSlash + 1);
1946 if (typeName.isEmpty()) {
1947 typeName = QString::fromUtf8(object->metaObject()->className());
1948 int marker = typeName.indexOf(QLatin1String(
"_QMLTYPE_"));
1950 typeName = typeName.left(marker);
1952 marker = typeName.indexOf(QLatin1String(
"_QML_"));
1954 typeName = QStringView{typeName}.left(marker) + QLatin1Char(
'*');
1955 type = QQmlMetaType::qmlType(QMetaType::fromName(typeName.toUtf8()));
1956 if (type.isValid()) {
1957 QString qmlTypeName = type.qmlTypeName();
1958 const int lastSlash = qmlTypeName.lastIndexOf(QLatin1Char(
'/'));
1959 if (lastSlash != -1)
1960 qmlTypeName = qmlTypeName.mid(lastSlash + 1);
1961 if (!qmlTypeName.isEmpty())
1962 typeName = qmlTypeName;
1970QList<QQmlProxyMetaObject::ProxyData> QQmlMetaType::proxyData(
const QMetaObject *mo,
1971 const QMetaObject *baseMetaObject,
1972 QMetaObject *lastMetaObject)
1974 QList<QQmlProxyMetaObject::ProxyData> metaObjects;
1975 mo = mo->d.superdata;
1980 auto createProxyMetaObject = [&](
const QQmlTypePrivate *This,
1981 const QMetaObject *superdataBaseMetaObject,
1982 const QMetaObject *extMetaObject,
1983 QObject *(*extFunc)(QObject *)) {
1987 QMetaObjectBuilder builder;
1988 clone(builder, extMetaObject, superdataBaseMetaObject, baseMetaObject,
1989 extFunc ? QQmlMetaType::CloneAll : QQmlMetaType::CloneEnumsOnly);
1990 QMetaObject *mmo = builder.toMetaObject();
1991 mmo->d.superdata = baseMetaObject;
1992 if (!metaObjects.isEmpty())
1993 metaObjects.constLast().metaObject->d.superdata = mmo;
1994 else if (lastMetaObject)
1995 lastMetaObject->d.superdata = mmo;
1996 QQmlProxyMetaObject::ProxyData data = { mmo, extFunc, 0, 0 };
1997 metaObjects << data;
1998 registerMetaObjectForType(mmo, This);
2001 for (
const QQmlMetaTypeDataPtr data; mo; mo = mo->d.superdata) {
2008 if (
const QQmlTypePrivate *t = data->metaObjectToType.value(mo)) {
2009 if (t->regType == QQmlType::CppType) {
2010 createProxyMetaObject(
2011 t, t->baseMetaObject, t->extraData.cppTypeData->extMetaObject,
2012 t->extraData.cppTypeData->extFunc);
2013 }
else if (t->regType == QQmlType::SingletonType) {
2014 createProxyMetaObject(
2015 t, t->baseMetaObject, t->extraData.singletonTypeData->extMetaObject,
2016 t->extraData.singletonTypeData->extFunc);
2028 case QMetaType::UnknownType:
2029 case QMetaType::QStringList:
2030 case QMetaType::QObjectStar:
2031 case QMetaType::VoidStar:
2032 case QMetaType::Nullptr:
2033 case QMetaType::QVariant:
2034 case QMetaType::QLocale:
2035 case QMetaType::QImage:
2036 case QMetaType::QPixmap:
2043bool QQmlMetaType::isValueType(QMetaType type)
2045 if (type.flags().testFlag(QMetaType::PointerToQObject))
2048 if (!type.isValid() || isInternalType(type.id()))
2051 return valueType(type) !=
nullptr;
2054const QMetaObject *QQmlMetaType::metaObjectForValueType(QMetaType metaType)
2056 switch (metaType.id()) {
2057 case QMetaType::QPoint:
2058 return &QQmlPointValueType::staticMetaObject;
2059 case QMetaType::QPointF:
2060 return &QQmlPointFValueType::staticMetaObject;
2061 case QMetaType::QSize:
2062 return &QQmlSizeValueType::staticMetaObject;
2063 case QMetaType::QSizeF:
2064 return &QQmlSizeFValueType::staticMetaObject;
2065 case QMetaType::QRect:
2066 return &QQmlRectValueType::staticMetaObject;
2067 case QMetaType::QRectF:
2068 return &QQmlRectFValueType::staticMetaObject;
2069#if QT_CONFIG(easingcurve)
2070 case QMetaType::QEasingCurve:
2071 return &QQmlEasingValueType::staticMetaObject;
2080 if (!(metaType.flags() & QMetaType::PointerToQObject)) {
2081 const QQmlMetaTypeDataPtr data;
2082 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
2083 if (type && type->regType == QQmlType::CppType && type->typeId == metaType) {
2084 if (
const QMetaObject *mo = type->metaObjectForValueType())
2090 if (metaType.flags() & QMetaType::IsGadget)
2091 return metaType.metaObject();
2096QQmlValueType *QQmlMetaType::valueType(QMetaType type)
2098 QQmlMetaTypeDataPtr data;
2100 const auto it = data->metaTypeToValueType.constFind(type.id());
2101 if (it != data->metaTypeToValueType.constEnd())
2104 if (
const QMetaObject *mo = metaObjectForValueType(type))
2105 return *data->metaTypeToValueType.insert(type.id(),
new QQmlValueType(type, mo));
2106 return *data->metaTypeToValueType.insert(type.id(),
nullptr);
2109QQmlPropertyCache::ConstPtr QQmlMetaType::findPropertyCacheInCompositeTypes(QMetaType t)
2111 const QQmlMetaTypeDataPtr data;
2112 return data->findPropertyCacheInCompositeTypes(t);
2115void QQmlMetaType::registerInternalCompositeType(
2116 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
2118 QQmlMetaTypeDataPtr data;
2120 auto doInsert = [&data, &compilationUnit](
const QtPrivate::QMetaTypeInterface *iface) {
2122 Q_ASSERT(compilationUnit);
2127 auto it = data->compositeTypes.insert(iface, compilationUnit);
2133 const auto end = data->compositeTypes.end();
2134 while (++it != end && it.key() == iface) {
2135 if (*it == compilationUnit) {
2136 data->compositeTypes.erase(it);
2142 doInsert(compilationUnit->metaType().iface());
2143 for (
const auto &inlineData : std::as_const(compilationUnit->inlineComponentData))
2144 doInsert(inlineData.qmlType.typeId().iface());
2150 const QUrl baseUrl = compilationUnit->finalUrl();
2151 if (baseUrl.isEmpty())
2154 for (
auto it = data->speculativeInlineComponentTypes.begin();
2155 it != data->speculativeInlineComponentTypes.end();) {
2156 const QUrl &url = *it;
2157 if (!equalBaseUrls(url, baseUrl)) {
2162 const QString icName = url.fragment();
2163 if (compilationUnit->inlineComponentData.contains(icName)) {
2165 it = data->speculativeInlineComponentTypes.erase(it);
2170 const auto typeIt = data->urlToType.constFind(url);
2171 Q_ASSERT(typeIt != data->urlToType.constEnd());
2173 const QQmlTypePrivate *d = *typeIt;
2174 data->urlToType.erase(typeIt);
2175 data->idToType.remove(d->typeId.id());
2176 data->idToType.remove(d->listId.id());
2177 data->types[d->index] = {};
2178 it = data->speculativeInlineComponentTypes.erase(it);
2182void QQmlMetaType::unregisterInternalCompositeType(
2183 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
2185 QQmlMetaTypeDataPtr data;
2187 auto doRemove = [&](
const QtPrivate::QMetaTypeInterface *iface) {
2191 const auto [begin, end] = std::as_const(data->compositeTypes).equal_range(iface);
2192 for (
auto it = begin; it != end; ++it) {
2193 if (*it == compilationUnit) {
2194 QQmlMetaTypeData::clearCompositeType(compilationUnit);
2195 data->compositeTypes.erase(it);
2201 doRemove(compilationUnit->metaType().iface());
2202 for (
const auto &inlineData : std::as_const(compilationUnit->inlineComponentData))
2203 doRemove(inlineData.qmlType.typeId().iface());
2205 const QUrl baseUrl = compilationUnit->finalUrl();
2206 if (baseUrl.isEmpty())
2210 for (
auto it = data->speculativeInlineComponentTypes.begin();
2211 it != data->speculativeInlineComponentTypes.end();) {
2212 if (equalBaseUrls(*it, baseUrl))
2213 it = data->speculativeInlineComponentTypes.erase(it);
2219void QQmlMetaType::deepClearCompositeType(
2220 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &oldUnit)
2222 unregisterInternalCompositeType(oldUnit);
2223 unregisterType(oldUnit->qmlType.index());
2224 for (
const auto &icData : std::as_const(oldUnit->inlineComponentData))
2225 unregisterType(icData.qmlType.index());
2228int QQmlMetaType::countInternalCompositeTypeSelfReferences(
2229 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
2231 QQmlMetaTypeDataPtr data;
2232 return doCountInternalCompositeTypeSelfReferences(data, compilationUnit);
2235QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlMetaType::obtainCompilationUnit(
2238 const QQmlMetaTypeDataPtr data;
2241 return data->compositeTypes.value(type.iface());
2244QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlMetaType::obtainCompilationUnit(
2247 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
2248 QQmlMetaTypeDataPtr data;
2250 auto found = data->urlToType.constFind(normalized);
2251 if (found == data->urlToType.constEnd())
2252 return QQmlRefPointer<QV4::CompiledData::CompilationUnit>();
2255 const auto composite = data->compositeTypes.constFind(found.value()->typeId.iface());
2256 return composite == data->compositeTypes.constEnd()
2257 ? QQmlRefPointer<QV4::CompiledData::CompilationUnit>()
2258 : composite.value();
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)