73 QQmlMetaTypeData *data,
const QString &elementName,
74 const QQmlPrivate::RegisterSingletonType &type,
75 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
77 auto *d =
new QQmlTypePrivate(QQmlType::SingletonType);
78 data->registerType(d);
80 d->setName(QString::fromUtf8(type.uri), elementName);
81 d->version = type.version;
83 if (type.qObjectApi) {
84 d->baseMetaObject = type.instanceMetaObject;
85 d->typeId = type.typeId;
86 d->revision = type.revision;
89 d->extraData.singletonTypeData->singletonInstanceInfo = siinfo;
90 d->extraData.singletonTypeData->extFunc = type.extensionObjectCreate;
91 d->extraData.singletonTypeData->extMetaObject = type.extensionMetaObject;
97 const QQmlPrivate::RegisterType &type)
99 QQmlTypePrivate *d =
new QQmlTypePrivate(QQmlType::CppType);
100 data->registerType(d);
101 d->setName(QString::fromUtf8(type.uri), elementName);
103 d->version = type.version;
104 d->revision = type.revision;
105 d->typeId = type.typeId;
106 d->listId = type.listId;
107 d->extraData.cppTypeData->allocationSize = type.objectSize;
108 d->extraData.cppTypeData->userdata = type.userdata;
109 d->extraData.cppTypeData->newFunc = type.create;
110 d->extraData.cppTypeData->noCreationReason = type.noCreationReason;
111 d->extraData.cppTypeData->createValueTypeFunc = type.createValueType;
112 d->baseMetaObject = type.metaObject;
113 d->extraData.cppTypeData->attachedPropertiesFunc = type.attachedPropertiesFunction;
114 d->extraData.cppTypeData->attachedPropertiesType = type.attachedPropertiesMetaObject;
115 d->extraData.cppTypeData->parserStatusCast = type.parserStatusCast;
116 d->extraData.cppTypeData->propertyValueSourceCast = type.valueSourceCast;
117 d->extraData.cppTypeData->propertyValueInterceptorCast = type.valueInterceptorCast;
118 d->extraData.cppTypeData->finalizerCast = type.has(QQmlPrivate::RegisterType::FinalizerCast)
121 d->extraData.cppTypeData->extFunc = type.extensionObjectCreate;
122 d->extraData.cppTypeData->customParser =
reinterpret_cast<QQmlCustomParser *>(type.customParser);
123 d->extraData.cppTypeData->registerEnumClassesUnscoped =
true;
124 d->extraData.cppTypeData->registerEnumsFromRelatedTypes =
true;
125 d->extraData.cppTypeData->constructValueType = type.has(QQmlPrivate::RegisterType::CreationMethod)
126 && type.creationMethod != QQmlPrivate::ValueTypeCreationMethod::None;
127 d->extraData.cppTypeData->populateValueType = type.has(QQmlPrivate::RegisterType::CreationMethod)
128 && type.creationMethod == QQmlPrivate::ValueTypeCreationMethod::Structured;
130 if (type.extensionMetaObject)
131 d->extraData.cppTypeData->extMetaObject = type.extensionMetaObject;
134 if (d->baseMetaObject) {
135 auto indexOfUnscoped = d->baseMetaObject->indexOfClassInfo(
"RegisterEnumClassesUnscoped");
136 if (indexOfUnscoped != -1
137 && qstrcmp(d->baseMetaObject->classInfo(indexOfUnscoped).value(),
"false") == 0) {
138 d->extraData.cppTypeData->registerEnumClassesUnscoped =
false;
141 auto indexOfRelated = d->baseMetaObject->indexOfClassInfo(
"RegisterEnumsFromRelatedTypes");
142 if (indexOfRelated != -1
143 && qstrcmp(d->baseMetaObject->classInfo(indexOfRelated).value(),
"false") == 0) {
144 d->extraData.cppTypeData->registerEnumsFromRelatedTypes =
false;
152 QQmlMetaTypeData *data,
const QUrl &url, QQmlTypePrivate *priv,
const QByteArray &className)
154 Q_ASSERT(!className.isEmpty());
155 QByteArray ptr = className +
'*';
156 QByteArray lst =
"QQmlListProperty<" + className +
'>';
158 QQmlMetaTypeData::CompositeMetaTypes &types = data->compositeMetaTypes[url];
160 Q_ASSERT(types.listType);
162 QMetaType::unregisterMetaType(QMetaType(types.type));
163 QMetaType::unregisterMetaType(QMetaType(types.listType));
165 types.type->name = std::move(ptr);
166 types.type->QMetaTypeInterface::name = types.type->name.constData();
167 types.listType->name = std::move(lst);
168 types.listType->QMetaTypeInterface::name = types.listType->name.constData();
170 types.type =
new QQmlMetaTypeInterface(std::move(ptr));
171 types.listType =
new QQmlListMetaTypeInterface(std::move(lst), types.type);
174 QMetaType ptr_type(types.type);
175 QMetaType lst_type(types.listType);
181 priv->typeId = ptr_type;
182 priv->listId = lst_type;
186 const QQmlPrivate::RegisterCompositeType &type)
188 auto *d =
new QQmlTypePrivate(QQmlType::CompositeType);
189 data->registerType(d);
190 d->setName(QString::fromUtf8(type.uri), elementName);
191 d->version = type.version;
193 const QUrl normalized = QQmlMetaType::normalizedUrl(type.url);
194 d->extraData.compositeTypeData = normalized;
195 addQQmlMetaTypeInterfaces(
196 data, normalized, d, QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(normalized));
201 QQmlMetaTypeData *data,
const QString &elementName,
202 const QQmlPrivate::RegisterCompositeSingletonType &type,
203 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
205 auto *d =
new QQmlTypePrivate(QQmlType::CompositeSingletonType);
206 data->registerType(d);
207 d->setName(QString::fromUtf8(type.uri), elementName);
209 d->version = type.version;
211 d->extraData.singletonTypeData->singletonInstanceInfo = siinfo;
212 const QUrl &url = siinfo->url;
213 addQQmlMetaTypeInterfaces(
214 data, url, d, QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(url));
218void QQmlMetaType::clone(QMetaObjectBuilder &builder,
const QMetaObject *mo,
219 const QMetaObject *ignoreStart,
const QMetaObject *ignoreEnd,
220 QQmlMetaType::ClonePolicy policy)
223 builder.setClassName(mo->className());
226 for (
int ii = mo->classInfoOffset(); ii < mo->classInfoCount(); ++ii) {
227 QMetaClassInfo info = mo->classInfo(ii);
229 int otherIndex = ignoreEnd->indexOfClassInfo(info.name());
230 if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
233 builder.addClassInfo(info.name(), info.value());
237 if (policy != QQmlMetaType::CloneEnumsOnly) {
239 for (
int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) {
240 QMetaMethod method = mo->method(ii);
243 QByteArray name = method.name();
247 for (
int ii = ignoreStart->methodOffset() + ignoreStart->methodCount();
248 !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount(); ++ii) {
250 QMetaMethod other = ignoreEnd->method(ii);
252 found = name == other.name();
255 QMetaMethodBuilder m = builder.addMethod(method);
257 m.setAccess(QMetaMethod::Private);
261 for (
int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) {
262 QMetaProperty property = mo->property(ii);
264 int otherIndex = ignoreEnd->indexOfProperty(property.name());
265 if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) {
266 builder.addProperty(QByteArray(
"__qml_ignore__") + property.name(),
270 builder.addProperty(property);
276 for (
int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) {
277 QMetaEnum enumerator = mo->enumerator(ii);
279 int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name());
280 if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) {
283 builder.addEnumerator(enumerator);
316void QQmlMetaType::clearTypeRegistrations()
319 QQmlMetaTypeDataPtr data;
321 data->uriToModule.clear();
323 data->idToType.clear();
324 data->nameToType.clear();
325 data->urlToType.clear();
326 data->typePropertyCaches.clear();
327 data->metaObjectToType.clear();
328 data->undeletableTypes.clear();
329 data->propertyCaches.clear();
331 qDeleteAll(data->metaTypeToValueType);
332 data->metaTypeToValueType.clear();
334 data->moduleImports.clear();
336 data->clearCompositeTypes();
338 qDeleteAll(data->metaTypeToValueType);
339 data->metaTypeToValueType.clear();
341 data->clearCompositeMetaTypes();
344void QQmlMetaType::registerTypeAlias(
int typeIndex,
const QString &name)
346 QQmlMetaTypeDataPtr data;
347 const QQmlType type = data->types.value(typeIndex);
348 const QQmlTypePrivate *priv = type.priv();
349 data->nameToType.insert(name, priv);
352int QQmlMetaType::registerAutoParentFunction(
const QQmlPrivate::RegisterAutoParent &function)
354 if (function.structVersion > 1)
355 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
357 QQmlMetaTypeDataPtr data;
359 data->parentFunctions.append(function.function);
361 return data->parentFunctions.size() - 1;
370QQmlType QQmlMetaType::registerInterface(
const QQmlPrivate::RegisterInterface &type)
372 if (type.structVersion > 1)
373 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
375 QQmlMetaTypeDataPtr data;
376 QQmlTypePrivate *priv = createQQmlType(data, type);
380 data->idToType.insert(priv->typeId.id(), priv);
381 data->idToType.insert(priv->listId.id(), priv);
383 data->interfaces.insert(type.typeId.id());
385 return QQmlType(priv);
391 if (typeType == QQmlType::CppType)
392 typeStr = QStringLiteral(
"element");
393 else if (typeType == QQmlType::SingletonType)
394 typeStr = QStringLiteral(
"singleton type");
395 else if (typeType == QQmlType::CompositeSingletonType)
396 typeStr = QStringLiteral(
"composite singleton type");
397 else if (typeType == QQmlType::SequentialContainerType)
398 typeStr = QStringLiteral(
"sequential container type");
400 typeStr = QStringLiteral(
"type");
406 QQmlType::RegistrationType typeType, QQmlMetaTypeData *data,
const char *uri,
407 const QString &typeName, QTypeRevision version, QMetaType::TypeFlags flags)
409 if (!typeName.isEmpty()) {
410 if (typeName.at(0).isLower() && (flags & QMetaType::PointerToQObject)) {
411 QString failure(QCoreApplication::translate(
"qmlRegisterType",
"Invalid QML %1 name \"%2\"; type names must begin with an uppercase letter"));
412 data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType), typeName));
416 if (typeName.at(0).isUpper()
417 && (flags & (QMetaType::IsGadget | QMetaType::PointerToGadget))) {
418 qCWarning(lcTypeRegistration).noquote()
419 << QCoreApplication::translate(
421 "Invalid QML %1 name \"%2\"; "
422 "value type names should begin with a lowercase letter")
423 .arg(registrationTypeString(typeType), typeName);
429 int typeNameLen = typeName.size();
430 for (
int ii = 0; ii < typeNameLen; ++ii) {
431 if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == u'_')) {
432 QString failure(QCoreApplication::translate(
"qmlRegisterType",
"Invalid QML %1 name \"%2\""));
433 data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType), typeName));
439 if (uri && !typeName.isEmpty()) {
440 QString nameSpace = QString::fromUtf8(uri);
442 if (qqtm && qqtm->lockLevel() != QQmlTypeModule::LockLevel::Open) {
443 QString failure(QCoreApplication::translate(
445 "Cannot install %1 '%2' into protected module '%3' version '%4'"));
446 data->recordTypeRegFailure(failure
447 .arg(registrationTypeString(typeType), typeName, nameSpace)
448 .arg(version.majorVersion()));
470 if (!type->elementName.isEmpty())
471 data->nameToType.insert(type->elementName, type);
473 if (type->baseMetaObject)
474 data->metaObjectToType.insert(type->baseMetaObject, type);
476 if (type->regType == QQmlType::SequentialContainerType) {
477 if (type->listId.isValid())
478 data->idToType.insert(type->listId.id(), type);
480 if (type->typeId.isValid())
481 data->idToType.insert(type->typeId.id(), type);
483 if (type->listId.flags().testFlag(QMetaType::IsQmlList))
484 data->idToType.insert(type->listId.id(), type);
487 if (!type->module.isEmpty()) {
488 const QHashedString &mod = type->module;
496QQmlType QQmlMetaType::registerType(
const QQmlPrivate::RegisterType &type)
498 if (type.structVersion >
int(QQmlPrivate::RegisterType::CurrentVersion))
499 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
501 QQmlMetaTypeDataPtr data;
503 QString elementName = QString::fromUtf8(type.elementName);
504 if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.version,
505 QMetaType(type.typeId).flags())) {
509 QQmlTypePrivate *priv = createQQmlType(data, elementName, type);
510 addTypeToData(priv, data);
512 return QQmlType(priv);
515QQmlType QQmlMetaType::registerSingletonType(
516 const QQmlPrivate::RegisterSingletonType &type,
517 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
519 if (type.structVersion > 1)
520 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
522 QQmlMetaTypeDataPtr data;
524 QString typeName = QString::fromUtf8(type.typeName);
525 if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.version,
526 QMetaType(type.typeId).flags())) {
530 QQmlTypePrivate *priv = createQQmlType(data, typeName, type, siinfo);
532 addTypeToData(priv, data);
534 return QQmlType(priv);
537QQmlType QQmlMetaType::registerCompositeSingletonType(
538 const QQmlPrivate::RegisterCompositeSingletonType &type,
539 const QQmlType::SingletonInstanceInfo::ConstPtr &siinfo)
541 if (type.structVersion > 1)
542 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
545 QQmlMetaTypeDataPtr data;
547 QString typeName = QString::fromUtf8(type.typeName);
548 if (!checkRegistration(
549 QQmlType::CompositeSingletonType, data, type.uri, typeName, type.version, {})) {
553 QQmlTypePrivate *priv = createQQmlType(data, typeName, type, siinfo);
554 addTypeToData(priv, data);
556 data->urlToType.insert(siinfo->url, priv);
558 return QQmlType(priv);
561QQmlType QQmlMetaType::registerCompositeType(
const QQmlPrivate::RegisterCompositeType &type)
563 if (type.structVersion > 1)
564 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
567 QQmlMetaTypeDataPtr data;
569 QString typeName = QString::fromUtf8(type.typeName);
570 if (!checkRegistration(QQmlType::CompositeType, data, type.uri, typeName, type.version, {}))
573 QQmlTypePrivate *priv = createQQmlType(data, typeName, type);
574 addTypeToData(priv, data);
576 data->urlToType.insert(QQmlMetaType::normalizedUrl(type.url), priv);
578 return QQmlType(priv);
601 QQmlMetaTypeData *data,
const QUrl &url,
const QHashedStringRef &qualifiedType,
602 QQmlMetaType::CompositeTypeLookupMode mode, QList<QQmlError> *errors, QTypeRevision version)
604 const int dot = qualifiedType.indexOf(QLatin1Char(
'.'));
605 const QString typeName = dot < 0
606 ? qualifiedType.toString()
607 : QString(qualifiedType.constData() + dot + 1, qualifiedType.length() - dot - 1);
609 QStringList failures;
629 QQmlType::RegistrationType registrationType;
631 case QQmlMetaType::Singleton:
632 registrationType = QQmlType::CompositeSingletonType;
634 case QQmlMetaType::NonSingleton:
635 registrationType = QQmlType::CompositeType;
637 case QQmlMetaType::JavaScript:
638 registrationType = QQmlType::JavaScriptType;
641 Q_UNREACHABLE_RETURN(QQmlType());
644 if (checkRegistration(registrationType, data,
nullptr, typeName, version, {})) {
651 auto *priv =
new QQmlTypePrivate(registrationType);
652 addQQmlMetaTypeInterfaces(
653 data, url, priv, QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(url));
655 priv->setName(QString(), typeName);
656 priv->version = version;
659 case QQmlMetaType::Singleton: {
660 QQmlType::SingletonInstanceInfo::Ptr siinfo = QQmlType::SingletonInstanceInfo::create();
662 siinfo->typeName = typeName.toUtf8();
663 priv->extraData.singletonTypeData->singletonInstanceInfo =
664 QQmlType::SingletonInstanceInfo::ConstPtr(
665 siinfo.take(), QQmlType::SingletonInstanceInfo::ConstPtr::Adopt);
668 case QQmlMetaType::NonSingleton: {
669 priv->extraData.compositeTypeData = url;
672 case QQmlMetaType::JavaScript: {
673 priv->extraData.javaScriptTypeData = url;
678 data->registerType(priv);
679 addTypeToData(priv, data);
680 return QQmlType(priv);
688 error.setDescription(failures.join(u'\n'));
689 errors->prepend(error);
691 qWarning(
"%s", failures.join(u'\n').toLatin1().constData());
696QQmlType QQmlMetaType::findCompositeType(
697 const QUrl &url,
const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit,
698 CompositeTypeLookupMode mode)
700 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
701 QQmlMetaTypeDataPtr data;
703 bool urlExists =
true;
704 auto found = data->urlToType.constFind(normalized);
705 if (found == data->urlToType.cend())
709 if (compilationUnit.isNull())
710 return QQmlType(*found);
711 const auto [begin, end]
712 = std::as_const(data->compositeTypes).equal_range(found.value()->typeId.iface());
714 return QQmlType(*found);
715 for (
auto it = begin; it != end; ++it) {
716 if (it.value() == compilationUnit)
717 return QQmlType(*found);
721 const QQmlType type = createTypeForUrl(
722 data, normalized, QHashedStringRef(), mode,
nullptr, QTypeRevision());
724 if (!urlExists && type.isValid())
725 data->urlToType.insert(normalized, type.priv());
732 QQmlTypePrivate *priv =
new QQmlTypePrivate(QQmlType::InlineComponentType);
733 priv->setName(QString(), url.fragment());
735 priv->extraData.inlineComponentTypeData = url;
736 data->registerType(priv);
738 addQQmlMetaTypeInterfaces(
739 data, url, priv, QQmlPropertyCacheCreatorBase::createClassNameForInlineComponent(url));
740 data->urlToType.insert(url, priv);
742 data->idToType.insert(priv->typeId.id(), priv);
743 data->idToType.insert(priv->listId.id(), priv);
745 return QQmlType(priv);
748QQmlType QQmlMetaType::findInlineComponentType(
749 const QUrl &url,
const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
751 QQmlMetaTypeDataPtr data;
755 const auto it = data->urlToType.constFind(url);
756 if (it != data->urlToType.constEnd()) {
757 const auto [begin, end]
758 = std::as_const(data->compositeTypes).equal_range((*it)->typeId.iface());
760 return QQmlType(*it);
761 for (
auto jt = begin; jt != end; ++jt) {
762 if (*jt == compilationUnit)
763 return QQmlType(*it);
767 return doRegisterInlineComponentType(data, url);
770int QQmlMetaType::registerUnitCacheHook(
771 const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration)
773 if (hookRegistration.structVersion > 1)
774 qFatal(
"qmlRegisterType(): Cannot mix incompatible QML versions.");
776 QQmlMetaTypeDataPtr data;
777 data->lookupCachedQmlUnit << hookRegistration.lookupCachedQmlUnit;
781QQmlType QQmlMetaType::registerSequentialContainer(
782 const QQmlPrivate::RegisterSequentialContainer &container)
784 if (container.structVersion > 1)
785 qFatal(
"qmlRegisterSequenceContainer(): Cannot mix incompatible QML versions.");
787 QQmlMetaTypeDataPtr data;
789 if (!checkRegistration(QQmlType::SequentialContainerType, data, container.uri, QString(),
790 container.version, {})) {
794 QQmlTypePrivate *priv =
new QQmlTypePrivate(QQmlType::SequentialContainerType);
796 data->registerType(priv);
797 priv->setName(QString::fromUtf8(container.uri), QString());
798 priv->version = container.version;
799 priv->revision = container.revision;
800 priv->typeId = container.metaSequence.valueMetaType();
801 priv->listId = container.typeId;
802 priv->extraData.sequentialContainerTypeData = container.metaSequence;
804 addTypeToData(priv, data);
806 return QQmlType(priv);
814bool QQmlMetaType::protectModule(
const QString &uri, QTypeRevision version,
815 bool weakProtectAllVersions)
817 QQmlMetaTypeDataPtr data;
818 if (version.hasMajorVersion()) {
819 if (QQmlTypeModule *module = data->findTypeModule(uri, version)) {
820 if (!weakProtectAllVersions) {
821 module->setLockLevel(QQmlTypeModule::LockLevel::Strong);
829 const auto range = std::equal_range(
830 data->uriToModule.begin(), data->uriToModule.end(), uri,
831 std::less<ModuleUri>());
833 for (
auto it = range.first; it != range.second; ++it)
834 (*it)->setLockLevel(QQmlTypeModule::LockLevel::Weak);
836 return range.first != range.second;
839void QQmlMetaType::registerModuleImport(
const QString &uri, QTypeRevision moduleVersion,
840 const QQmlDirParser::Import &import)
842 QQmlMetaTypeDataPtr data;
844 data->moduleImports.insert(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import);
847void QQmlMetaType::unregisterModuleImport(
const QString &uri, QTypeRevision moduleVersion,
848 const QQmlDirParser::Import &import)
850 QQmlMetaTypeDataPtr data;
851 data->moduleImports.remove(QQmlMetaTypeData::VersionedUri(uri, moduleVersion), import);
854QList<QQmlDirParser::Import> QQmlMetaType::moduleImports(
855 const QString &uri, QTypeRevision version)
857 QQmlMetaTypeDataPtr data;
858 QList<QQmlDirParser::Import> result;
860 const auto unrevisioned = data->moduleImports.equal_range(
861 QQmlMetaTypeData::VersionedUri(uri, QTypeRevision()));
862 for (
auto it = unrevisioned.second; it != unrevisioned.first;)
863 result.append(*(--it));
865 if (version.hasMajorVersion()) {
866 const auto revisioned = data->moduleImports.equal_range(
867 QQmlMetaTypeData::VersionedUri(uri, version));
868 for (
auto it = revisioned.second; it != revisioned.first;)
869 result.append(*(--it));
874 const auto begin = data->moduleImports.begin();
875 auto it = unrevisioned.first;
879 const QQmlMetaTypeData::VersionedUri latestVersion = (--it).key();
880 if (latestVersion.uri != uri)
885 }
while (it != begin && (--it).key() == latestVersion);
890void QQmlMetaType::registerModule(
const char *uri, QTypeRevision version)
892 QQmlMetaTypeDataPtr data;
894 QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
897 if (version.hasMinorVersion())
898 module->addMinorVersion(version.minorVersion());
901int QQmlMetaType::typeId(
const char *uri, QTypeRevision version,
const char *qmlName)
903 QQmlMetaTypeDataPtr data;
905 QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data);
909 QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), version);
935QQmlMetaType::RegistrationResult QQmlMetaType::registerPluginTypes(
936 QObject *instance,
const QString &basePath,
const QString &uri,
937 const QString &typeNamespace, QTypeRevision version, QList<QQmlError> *errors)
939 if (!typeNamespace.isEmpty() && typeNamespace != uri) {
944 error.setDescription(
945 QStringLiteral(
"Module namespace '%1' does not match import URI '%2'")
946 .arg(typeNamespace, uri));
947 errors->prepend(error);
949 return RegistrationResult::Failure;
952 QStringList failures;
953 QQmlMetaTypeDataPtr data;
955 QQmlMetaTypeRegistrationFailureRecorder failureRecorder(data, &failures);
956 if (!typeNamespace.isEmpty()) {
958 if (namespaceContainsRegistrations(data, typeNamespace, version)) {
962 error.setDescription(QStringLiteral(
"Namespace '%1' has already been used "
963 "for type registration")
964 .arg(typeNamespace));
965 errors->prepend(error);
967 return RegistrationResult::Failure;
971 qWarning().nospace() << qPrintable(
972 QStringLiteral(
"Module '%1' does not contain a module identifier directive - "
973 "it cannot be protected from external registrations.").arg(uri));
976 if (instance && !qobject_cast<QQmlEngineExtensionInterface *>(instance)) {
977 QQmlTypesExtensionInterface *iface = qobject_cast<QQmlTypesExtensionInterface *>(instance);
982 error.setDescription(QStringLiteral(
"Module loaded for URI '%1' does not implement "
983 "QQmlEngineExtensionInterface").arg(typeNamespace));
984 errors->prepend(error);
986 return RegistrationResult::Failure;
989#if QT_DEPRECATED_SINCE(6
, 3
)
990 if (
auto *plugin = qobject_cast<QQmlExtensionPlugin *>(instance)) {
992 QQmlExtensionPluginPrivate::get(plugin)->baseUrl
993 = QQmlImports::urlFromLocalFileOrQrcOrUrl(basePath);
999 const QByteArray bytes = uri.toUtf8();
1000 const char *moduleId = bytes.constData();
1001 iface->registerTypes(moduleId);
1004 if (failures.isEmpty() && !data->registerModuleTypes(uri))
1005 return RegistrationResult::NoRegistrationFunction;
1007 if (!failures.isEmpty()) {
1009 for (
const QString &failure : std::as_const(failures)) {
1011 error.setDescription(failure);
1012 errors->prepend(error);
1015 return RegistrationResult::Failure;
1019 return RegistrationResult::Success;
1033QQmlType QQmlMetaType::typeForUrl(
1034 const QUrl &url,
const QHashedStringRef &qualifiedType, CompositeTypeLookupMode mode,
1035 QList<QQmlError> *errors, QTypeRevision version)
1038 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
1040 QQmlMetaTypeDataPtr data;
1042 QQmlType ret(data->urlToType.value(normalized));
1043 if (ret.isValid() && ret.sourceUrl() == normalized)
1047 const QQmlType type = createTypeForUrl(
1048 data, normalized, qualifiedType, mode, errors, version);
1049 data->urlToType.insert(normalized, type.priv());
1056QTypeRevision QQmlMetaType::latestModuleVersion(
const QString &uri)
1058 QQmlMetaTypeDataPtr data;
1059 auto upper = std::upper_bound(data->uriToModule.begin(), data->uriToModule.end(), uri,
1060 std::less<ModuleUri>());
1061 if (upper == data->uriToModule.begin())
1062 return QTypeRevision();
1064 const auto module = (--upper)->get();
1065 return (module->module() == uri)
1066 ? QTypeRevision::fromVersion(module->majorVersion(), module->maximumMinorVersion())
1073bool QQmlMetaType::isStronglyLockedModule(
const QString &uri, QTypeRevision version)
1075 QQmlMetaTypeDataPtr data;
1077 if (QQmlTypeModule* qqtm = data->findTypeModule(uri, version))
1078 return qqtm->lockLevel() == QQmlTypeModule::LockLevel::Strong;
1089QTypeRevision QQmlMetaType::matchingModuleVersion(
const QString &module, QTypeRevision version)
1091 if (!version.hasMajorVersion())
1092 return latestModuleVersion(module);
1094 QQmlMetaTypeDataPtr data;
1097 if (QQmlTypeModule *tm = data->findTypeModule(module, version)) {
1098 if (!version.hasMinorVersion())
1099 return QTypeRevision::fromVersion(version.majorVersion(), tm->maximumMinorVersion());
1101 if (tm->minimumMinorVersion() <= version.minorVersion()
1102 && tm->maximumMinorVersion() >= version.minorVersion()) {
1107 return QTypeRevision();
1110QQmlTypeModule *QQmlMetaType::typeModule(
const QString &uri, QTypeRevision version)
1112 QQmlMetaTypeDataPtr data;
1114 if (version.hasMajorVersion())
1115 return data->findTypeModule(uri, version);
1117 auto range = std::equal_range(data->uriToModule.begin(), data->uriToModule.end(),
1118 uri, std::less<ModuleUri>());
1120 return range.first == range.second ?
nullptr : (--range.second)->get();
1144QMetaType QQmlMetaType::listValueType(QMetaType metaType)
1146 if (isList(metaType)) {
1147 const auto iface = metaType.iface();
1148 if (iface && iface->metaObjectFn == &dynamicQmlListMarker)
1149 return QMetaType(
static_cast<
const QQmlListMetaTypeInterface *>(iface)->valueType);
1150 }
else if (metaType.flags() & QMetaType::PointerToQObject) {
1154 QQmlMetaTypeDataPtr data;
1156 QQmlTypePrivate *type = data->idToType.value(metaType.id());
1158 if (type && type->listId == metaType)
1159 return type->typeId;
1161 return QMetaType {};
1164QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFunc(
1165 QQmlTypeLoader *typeLoader,
const QMetaObject *mo)
1167 QQmlMetaTypeDataPtr data;
1169 QQmlType type(data->metaObjectToType.value(mo));
1170 return type.attachedPropertiesFunction(typeLoader);
1173QMetaProperty QQmlMetaType::defaultProperty(
const QMetaObject *metaObject)
1175 int idx = metaObject->indexOfClassInfo(
"DefaultProperty");
1177 return QMetaProperty();
1179 QMetaClassInfo info = metaObject->classInfo(idx);
1181 return QMetaProperty();
1183 idx = metaObject->indexOfProperty(info.value());
1185 return QMetaProperty();
1187 return metaObject->property(idx);
1253QQmlType QQmlMetaType::qmlType(
const QString &qualifiedName, QTypeRevision version)
1255 int slash = qualifiedName.indexOf(QLatin1Char(
'/'));
1259 QHashedStringRef module(qualifiedName.constData(), slash);
1260 QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.size() - slash - 1);
1262 return qmlType(name, module, version);
1273QQmlType QQmlMetaType::qmlType(
const QHashedStringRef &name,
const QHashedStringRef &module,
1274 QTypeRevision version)
1276 const QQmlMetaTypeDataPtr data;
1278 const QHashedString key(QString::fromRawData(name.constData(), name.length()), name.hash());
1279 QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(key);
1280 while (it != data->nameToType.cend() && it.key() == name) {
1282 if (module.isEmpty() || t.availableInVersion(module, version))
1305QQmlType QQmlMetaType::qmlType(
const QMetaObject *metaObject,
const QHashedStringRef &module,
1306 QTypeRevision version)
1308 const QQmlMetaTypeDataPtr data;
1310 const auto range = data->metaObjectToType.equal_range(metaObject);
1311 for (
auto it = range.first; it != range.second; ++it) {
1313 if (module.isEmpty() || t.availableInVersion(module, version))
1357QQmlType QQmlMetaType::qmlType(
const QUrl &unNormalizedUrl)
1359 const QUrl url = QQmlMetaType::normalizedUrl(unNormalizedUrl);
1360 const QQmlMetaTypeDataPtr data;
1362 QQmlType type(data->urlToType.value(url));
1364 if (type.sourceUrl() == url)
1370QQmlType QQmlMetaType::fetchOrCreateInlineComponentTypeForUrl(
const QUrl &url)
1372 QQmlMetaTypeDataPtr data;
1373 const auto it = data->urlToType.constFind(url);
1374 if (it != data->urlToType.constEnd())
1375 return QQmlType(*it);
1377 return doRegisterInlineComponentType(data, url);
1386QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(QObject *obj, QTypeRevision version)
1388 if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted)
1389 return QQmlPropertyCache::ConstPtr();
1390 return QQmlMetaType::propertyCache(obj->metaObject(), version);
1393QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCache(
1394 const QMetaObject *metaObject, QTypeRevision version)
1396 QQmlMetaTypeDataPtr data;
1397 return data->propertyCache(metaObject, version);
1412QQmlMetaObject QQmlMetaType::rawMetaObjectForType(QMetaType metaType)
1414 const QQmlMetaTypeDataPtr data;
1415 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1416 return QQmlMetaObject(composite);
1418 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1419 return (type && type->typeId == metaType) ? type->baseMetaObject :
nullptr;
1427QQmlMetaObject QQmlMetaType::metaObjectForType(QMetaType metaType)
1429 const QQmlMetaTypeDataPtr data;
1430 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1431 return QQmlMetaObject(composite);
1433 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1434 return (type && type->typeId == metaType)
1435 ? QQmlType(type).metaObject()
1444QQmlPropertyCache::ConstPtr QQmlMetaType::propertyCacheForType(QMetaType metaType)
1446 QQmlMetaTypeDataPtr data;
1447 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1450 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1451 if (type && type->typeId == metaType) {
1452 if (
const QMetaObject *mo = QQmlType(type).metaObject())
1453 return data->propertyCache(mo, type->version);
1456 return QQmlPropertyCache::ConstPtr();
1466QQmlPropertyCache::ConstPtr QQmlMetaType::rawPropertyCacheForType(QMetaType metaType)
1468 QQmlMetaTypeDataPtr data;
1469 if (
auto composite = QQmlMetaType::findPropertyCacheInCompositeTypes(metaType))
1472 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1473 if (!type || type->typeId != metaType)
1474 return QQmlPropertyCache::ConstPtr();
1476 const QMetaObject *metaObject = type->isValueType()
1477 ? type->metaObjectForValueType()
1478 : type->baseMetaObject;
1481 ? data->propertyCache(metaObject, QTypeRevision())
1482 : QQmlPropertyCache::ConstPtr();
1491QQmlPropertyCache::ConstPtr QQmlMetaType::rawPropertyCacheForType(
1492 QMetaType metaType, QTypeRevision version)
1494 QQmlMetaTypeDataPtr data;
1495 if (
auto composite = data->findPropertyCacheInCompositeTypes(metaType))
1498 const QQmlTypePrivate *typePriv = data->idToType.value(metaType.id());
1499 if (!typePriv || typePriv->typeId != metaType)
1500 return QQmlPropertyCache::ConstPtr();
1502 const QQmlType type(typePriv);
1503 if (type.containsRevisionedAttributes()) {
1505 Q_ASSERT(type.metaObject());
1506 return data->propertyCache(type, version);
1509 if (
const QMetaObject *metaObject = type.metaObject())
1510 return data->propertyCache(metaObject, version);
1512 return QQmlPropertyCache::ConstPtr();
1515void QQmlMetaType::unregisterType(
int typeIndex)
1517 QQmlMetaTypeDataPtr data;
1518 const QQmlType type = data->types.value(typeIndex);
1519 if (
const QQmlTypePrivate *d = type.priv()) {
1520 if (d->regType == QQmlType::CompositeType || d->regType == QQmlType::CompositeSingletonType)
1521 removeFromInlineComponents(data->urlToType, d);
1522 removeQQmlTypePrivate(data->idToType, d);
1523 removeQQmlTypePrivate(data->nameToType, d);
1524 removeQQmlTypePrivate(data->urlToType, d);
1525 removeQQmlTypePrivate(data->metaObjectToType, d);
1526 for (
auto & module : data->uriToModule)
1528 data->clearPropertyCachesForVersion(typeIndex);
1529 data->types[typeIndex] = QQmlType();
1530 data->undeletableTypes.remove(type);
1557 QQmlMetaTypeData *data,
1558 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
1561 auto doCheck = [&](
const QtPrivate::QMetaTypeInterface *iface) {
1565 const auto [begin, end] = std::as_const(data->compositeTypes).equal_range(iface);
1566 for (
auto it = begin; it != end; ++it) {
1567 if (*it == compilationUnit)
1572 doCheck(compilationUnit->metaType().iface());
1573 for (
auto &&inlineData: compilationUnit->inlineComponentData)
1574 doCheck(inlineData.qmlType.typeId().iface());
1579void QQmlMetaType::freeUnusedTypesAndCaches()
1581 QQmlMetaTypeDataPtr data;
1584 if (!data.isValid())
1587 bool droppedAtLeastOneComposite;
1589 droppedAtLeastOneComposite =
false;
1590 auto it = data->compositeTypes.cbegin();
1591 while (it != data->compositeTypes.cend()) {
1592 const auto &cu = *it;
1593 if (cu->count() <= doCountInternalCompositeTypeSelfReferences(data, cu)) {
1594 QQmlMetaTypeData::clearCompositeType(cu);
1595 it = data->compositeTypes.erase(it);
1596 droppedAtLeastOneComposite =
true;
1601 }
while (droppedAtLeastOneComposite);
1603 bool deletedAtLeastOneType;
1605 deletedAtLeastOneType =
false;
1606 QList<QQmlType>::Iterator it = data->types.begin();
1607 while (it != data->types.end()) {
1608 const QQmlTypePrivate *d = (*it).priv();
1609 if (d && d->count() == 1 && !hasActiveInlineComponents(data, d)) {
1610 deletedAtLeastOneType =
true;
1612 if (d->regType == QQmlType::CompositeType
1613 || d->regType == QQmlType::CompositeSingletonType) {
1614 removeFromInlineComponents(data->urlToType, d);
1616 removeQQmlTypePrivate(data->idToType, d);
1617 removeQQmlTypePrivate(data->nameToType, d);
1618 removeQQmlTypePrivate(data->urlToType, d);
1619 removeQQmlTypePrivate(data->metaObjectToType, d);
1621 for (
auto &module : data->uriToModule)
1624 data->clearPropertyCachesForVersion(d->index);
1630 }
while (deletedAtLeastOneType);
1632 bool deletedAtLeastOneCache;
1634 deletedAtLeastOneCache =
false;
1635 auto it = data->propertyCaches.begin();
1636 while (it != data->propertyCaches.end()) {
1637 if ((*it)->count() == 1) {
1638 it = data->propertyCaches.erase(it);
1639 deletedAtLeastOneCache =
true;
1644 }
while (deletedAtLeastOneCache);
1650QList<QString> QQmlMetaType::qmlTypeNames()
1652 const QQmlMetaTypeDataPtr data;
1654 QList<QString> names;
1655 names.reserve(data->nameToType.size());
1656 QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.cbegin();
1657 while (it != data->nameToType.cend()) {
1659 names += t.qmlTypeName();
1718const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(
1719 const QUrl &uri, QQmlMetaType::CacheMode mode, CachedUnitLookupError *status)
1721 Q_ASSERT(mode != RejectAll);
1722 const QQmlMetaTypeDataPtr data;
1724 for (
const auto lookup : std::as_const(data->lookupCachedQmlUnit)) {
1725 if (
const QQmlPrivate::CachedQmlUnit *unit = lookup(uri)) {
1727 if (!unit->qmlData->verifyHeader(QDateTime(), &error)) {
1728 qCDebug(DBG_DISK_CACHE) <<
"Error loading pre-compiled file " << uri <<
":" << error;
1730 *status = CachedUnitLookupError::VersionMismatch;
1734 if (mode == RequireFullyTyped && !isFullyTyped(unit)) {
1735 qCDebug(DBG_DISK_CACHE)
1736 <<
"Error loading pre-compiled file " << uri
1737 <<
": compilation unit contains functions not compiled to native code.";
1739 *status = CachedUnitLookupError::NotFullyTyped;
1744 *status = CachedUnitLookupError::NoError;
1750 *status = CachedUnitLookupError::NoUnitFound;
1770QString QQmlMetaType::prettyTypeName(
const QObject *object)
1777 QQmlType type = QQmlMetaType::qmlType(object->metaObject());
1778 if (type.isValid()) {
1779 typeName = type.qmlTypeName();
1780 const int lastSlash = typeName.lastIndexOf(QLatin1Char(
'/'));
1781 if (lastSlash != -1)
1782 typeName = typeName.mid(lastSlash + 1);
1785 if (typeName.isEmpty()) {
1786 typeName = QString::fromUtf8(object->metaObject()->className());
1787 int marker = typeName.indexOf(QLatin1String(
"_QMLTYPE_"));
1789 typeName = typeName.left(marker);
1791 marker = typeName.indexOf(QLatin1String(
"_QML_"));
1793 typeName = QStringView{typeName}.left(marker) + QLatin1Char(
'*');
1794 type = QQmlMetaType::qmlType(QMetaType::fromName(typeName.toUtf8()));
1795 if (type.isValid()) {
1796 QString qmlTypeName = type.qmlTypeName();
1797 const int lastSlash = qmlTypeName.lastIndexOf(QLatin1Char(
'/'));
1798 if (lastSlash != -1)
1799 qmlTypeName = qmlTypeName.mid(lastSlash + 1);
1800 if (!qmlTypeName.isEmpty())
1801 typeName = qmlTypeName;
1809QList<QQmlProxyMetaObject::ProxyData> QQmlMetaType::proxyData(
const QMetaObject *mo,
1810 const QMetaObject *baseMetaObject,
1811 QMetaObject *lastMetaObject)
1813 QList<QQmlProxyMetaObject::ProxyData> metaObjects;
1814 mo = mo->d.superdata;
1819 auto createProxyMetaObject = [&](QQmlTypePrivate *This,
1820 const QMetaObject *superdataBaseMetaObject,
1821 const QMetaObject *extMetaObject,
1822 QObject *(*extFunc)(QObject *)) {
1826 QMetaObjectBuilder builder;
1827 clone(builder, extMetaObject, superdataBaseMetaObject, baseMetaObject,
1828 extFunc ? QQmlMetaType::CloneAll : QQmlMetaType::CloneEnumsOnly);
1829 QMetaObject *mmo = builder.toMetaObject();
1830 mmo->d.superdata = baseMetaObject;
1831 if (!metaObjects.isEmpty())
1832 metaObjects.constLast().metaObject->d.superdata = mmo;
1833 else if (lastMetaObject)
1834 lastMetaObject->d.superdata = mmo;
1835 QQmlProxyMetaObject::ProxyData data = { mmo, extFunc, 0, 0 };
1836 metaObjects << data;
1837 registerMetaObjectForType(mmo, This);
1840 for (
const QQmlMetaTypeDataPtr data; mo; mo = mo->d.superdata) {
1847 if (QQmlTypePrivate *t = data->metaObjectToType.value(mo)) {
1848 if (t->regType == QQmlType::CppType) {
1849 createProxyMetaObject(
1850 t, t->baseMetaObject, t->extraData.cppTypeData->extMetaObject,
1851 t->extraData.cppTypeData->extFunc);
1852 }
else if (t->regType == QQmlType::SingletonType) {
1853 createProxyMetaObject(
1854 t, t->baseMetaObject, t->extraData.singletonTypeData->extMetaObject,
1855 t->extraData.singletonTypeData->extFunc);
1893const QMetaObject *QQmlMetaType::metaObjectForValueType(QMetaType metaType)
1895 switch (metaType.id()) {
1896 case QMetaType::QPoint:
1897 return &QQmlPointValueType::staticMetaObject;
1898 case QMetaType::QPointF:
1899 return &QQmlPointFValueType::staticMetaObject;
1900 case QMetaType::QSize:
1901 return &QQmlSizeValueType::staticMetaObject;
1902 case QMetaType::QSizeF:
1903 return &QQmlSizeFValueType::staticMetaObject;
1904 case QMetaType::QRect:
1905 return &QQmlRectValueType::staticMetaObject;
1906 case QMetaType::QRectF:
1907 return &QQmlRectFValueType::staticMetaObject;
1908#if QT_CONFIG(easingcurve)
1909 case QMetaType::QEasingCurve:
1910 return &QQmlEasingValueType::staticMetaObject;
1919 if (!(metaType.flags() & QMetaType::PointerToQObject)) {
1920 const QQmlMetaTypeDataPtr data;
1921 const QQmlTypePrivate *type = data->idToType.value(metaType.id());
1922 if (type && type->regType == QQmlType::CppType && type->typeId == metaType) {
1923 if (
const QMetaObject *mo = type->metaObjectForValueType())
1929 if (metaType.flags() & QMetaType::IsGadget)
1930 return metaType.metaObject();
1935QQmlValueType *QQmlMetaType::valueType(QMetaType type)
1937 QQmlMetaTypeDataPtr data;
1939 const auto it = data->metaTypeToValueType.constFind(type.id());
1940 if (it != data->metaTypeToValueType.constEnd())
1943 if (
const QMetaObject *mo = metaObjectForValueType(type))
1944 return *data->metaTypeToValueType.insert(type.id(),
new QQmlValueType(type, mo));
1945 return *data->metaTypeToValueType.insert(type.id(),
nullptr);
1954void QQmlMetaType::registerInternalCompositeType(
1955 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
1957 QQmlMetaTypeDataPtr data;
1959 auto doInsert = [&data, &compilationUnit](
const QtPrivate::QMetaTypeInterface *iface) {
1961 Q_ASSERT(compilationUnit);
1966 auto it = data->compositeTypes.insert(iface, compilationUnit);
1972 const auto end = data->compositeTypes.end();
1973 while (++it != end && it.key() == iface) {
1974 if (*it == compilationUnit) {
1975 data->compositeTypes.erase(it);
1981 doInsert(compilationUnit->metaType().iface());
1982 for (
auto &&inlineData: compilationUnit->inlineComponentData)
1983 doInsert(inlineData.qmlType.typeId().iface());
1986void QQmlMetaType::unregisterInternalCompositeType(
1987 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit)
1989 QQmlMetaTypeDataPtr data;
1991 auto doRemove = [&](
const QtPrivate::QMetaTypeInterface *iface) {
1995 const auto [begin, end] = std::as_const(data->compositeTypes).equal_range(iface);
1996 for (
auto it = begin; it != end; ++it) {
1997 if (*it == compilationUnit) {
1998 QQmlMetaTypeData::clearCompositeType(compilationUnit);
1999 data->compositeTypes.erase(it);
2005 doRemove(compilationUnit->metaType().iface());
2006 for (
auto &&inlineData: compilationUnit->inlineComponentData)
2007 doRemove(inlineData.qmlType.typeId().iface());
2026QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlMetaType::obtainCompilationUnit(
2029 const QUrl normalized = QQmlMetaType::normalizedUrl(url);
2030 QQmlMetaTypeDataPtr data;
2032 auto found = data->urlToType.constFind(normalized);
2033 if (found == data->urlToType.constEnd())
2034 return QQmlRefPointer<QV4::CompiledData::CompilationUnit>();
2037 const auto composite = data->compositeTypes.constFind(found.value()->typeId.iface());
2038 return composite == data->compositeTypes.constEnd()
2039 ? QQmlRefPointer<QV4::CompiledData::CompilationUnit>()
2040 : composite.value();