7#include <private/qjsvalue_p.h>
8#include <private/qqmlbuiltinfunctions_p.h>
9#include <private/qqmlcomponent_p.h>
10#include <private/qqmldirdata_p.h>
11#include <private/qqmlengine_p.h>
12#include <private/qqmlfinalizer_p.h>
13#include <private/qqmlloggingcategorybase_p.h>
14#include <private/qqmlmetaobject_p.h>
15#include <private/qqmlmetatype_p.h>
16#include <private/qqmlmetatypedata_p.h>
17#include <private/qqmltype_p_p.h>
18#include <private/qqmltypemodule_p.h>
19#include <private/qqmltypewrapper_p.h>
20#include <private/qqmlvaluetypewrapper_p.h>
21#include <private/qv4alloca_p.h>
22#include <private/qv4dateobject_p.h>
23#include <private/qv4errorobject_p.h>
24#include <private/qv4identifiertable_p.h>
25#include <private/qv4lookup_p.h>
26#include <private/qv4qobjectwrapper_p.h>
28#include <QtQml/qqmlprivate.h>
30#include <QtCore/qmutex.h>
31#include <QtCore/qmetasequence.h>
36
37
38
39
40
41
42
43
44
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
64 QQmlData *data = QQmlData::get(object);
68 || !data->context->engine()
69 || data->deferredData.isEmpty()
70 || data->wasDeleted(object)) {
74 if (!data->propertyCache)
75 data->propertyCache = QQmlMetaType::propertyCache(object->metaObject());
77 QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine());
79 QQmlComponentPrivate::DeferredState state;
80 QQmlComponentPrivate::beginDeferred(ep, object, &state);
83 data->releaseDeferredData();
85 QQmlComponentPrivate::completeDeferred(ep, &state);
90 return QQmlEngine::contextForObject(obj);
95 QQmlData *data = QQmlData::get(obj);
96 if (!data || !data->context)
98 return data->context->engine();
102 QObject *object,
bool create)
107 QObject *rv = data->hasExtendedData() ? data->attachedProperties()->value(pf) : 0;
114 data->attachedProperties()->insert(pf, rv);
120 const QMetaObject *attachedMetaObject)
122 QQmlEngine *engine = object ? qmlEngine(object) :
nullptr;
123 return QQmlMetaType::attachedPropertiesFunc(
124 engine ? QQmlTypeLoader::get(engine) :
nullptr, attachedMetaObject);
132 QQmlData *data = QQmlData::get(object, createIfMissing);
139 return resolveAttachedProperties(func, data, object, createIfMissing);
143
144
145
146
147
148
149
150QObject *qmlExtendedObject(QObject *base)
152 return QQmlPrivate::qmlExtendedObject(base, 0);
155QObject *QQmlPrivate::qmlExtendedObject(QObject *object,
int index)
160 void *result =
nullptr;
161 QObjectPrivate *d = QObjectPrivate::get(object);
165 const int id = d->metaObject->metaCall(
166 object, QMetaObject::CustomCall,
167 QQmlProxyMetaObject::extensionObjectId(index), &result);
168 if (id != QQmlProxyMetaObject::extensionObjectId(index))
171 return static_cast<QObject *>(result);
174void QQmlPrivate::qmlRegistrationWarning(
175 QQmlPrivate::QmlRegistrationWarning warning, QMetaType metaType)
178 case UnconstructibleType:
181 <<
" is neither a default constructible QObject, nor a default- "
182 <<
"and copy-constructible Q_GADGET, nor a QObject marked as uncreatable.\n"
183 <<
"You should not use it as a QML type.";
185 case UnconstructibleSingleton:
187 <<
"Singleton" << metaType.name()
188 <<
"needs to be a concrete class with either a default constructor"
189 <<
"or, when adding a default constructor is infeasible, a public static"
190 <<
"create(QQmlEngine *, QJSEngine *) method.";
192 case NonQObjectWithAtached:
195 <<
"is not a QObject, but has attached properties. This won't work.";
200QMetaType QQmlPrivate::compositeMetaType(
201 QV4::ExecutableCompilationUnit *unit,
int elementNameId)
203 return QQmlTypePrivate::visibleQmlTypeByName(unit, elementNameId).typeId();
206QMetaType QQmlPrivate::compositeMetaType(
207 QV4::ExecutableCompilationUnit *unit,
const QString &elementName)
209 return QQmlTypePrivate::visibleQmlTypeByName(
210 unit->baseCompilationUnit(), elementName, unit->engine->typeLoader())
214QMetaType QQmlPrivate::compositeListMetaType(
215 QV4::ExecutableCompilationUnit *unit,
int elementNameId)
217 return QQmlTypePrivate::visibleQmlTypeByName(unit, elementNameId).qListTypeId();
220QMetaType QQmlPrivate::compositeListMetaType(
221 QV4::ExecutableCompilationUnit *unit,
const QString &elementName)
223 return QQmlTypePrivate::visibleQmlTypeByName(
224 unit->baseCompilationUnit(), elementName, unit->engine->typeLoader())
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268int qmlRegisterUncreatableMetaObject(
const QMetaObject &staticMetaObject,
269 const char *uri,
int versionMajor,
270 int versionMinor,
const char *qmlName,
271 const QString& reason)
273 QQmlPrivate::RegisterType type = {
274 QQmlPrivate::RegisterType::CurrentVersion,
283 uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &staticMetaObject,
285 QQmlAttachedPropertiesFunc(),
295 QTypeRevision::zero(),
297 QQmlPrivate::ValueTypeCreationMethod::None
300 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
304
305
306
307
308
309
310
311
312
313
314
315void qmlClearTypeRegistrations()
317 QQmlMetaType::clearTypeRegistrations();
318 QQmlEnginePrivate::baseModulesUninitialized =
true;
319 qmlClearEnginePlugins();
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
352 return QQmlMetaType::protectModule(QString::fromUtf8(uri),
353 QTypeRevision::fromMajorVersion(majVersion));
357
358
359
360
361
362
363
364
365
366
370 QQmlMetaType::registerModule(uri, QTypeRevision::fromVersion(versionMajor, versionMinor));
375 if (importMajor == QQmlModuleImportAuto)
376 return QQmlDirParser::Import(uri, QTypeRevision(), QQmlDirParser::Import::Auto);
377 else if (importMajor == QQmlModuleImportLatest)
378 return QQmlDirParser::Import(uri, QTypeRevision(), QQmlDirParser::Import::Default);
379 else if (importMinor == QQmlModuleImportLatest)
380 return QQmlDirParser::Import(uri, QTypeRevision::fromMajorVersion(importMajor), QQmlDirParser::Import::Default);
381 return QQmlDirParser::Import(uri, QTypeRevision::fromVersion(importMajor, importMinor), QQmlDirParser::Import::Default);
386 return moduleMajor == QQmlModuleImportModuleAny
388 : QTypeRevision::fromMajorVersion(moduleMajor);
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
452 const char *import,
int importMajor,
int importMinor)
454 QQmlMetaType::registerModuleImport(
455 QString::fromUtf8(uri), resolveModuleVersion(moduleMajor),
456 resolveImport(QString::fromUtf8(import), importMajor, importMinor));
461
462
463
464
465
466
467
468
469
470
472 const char *import,
int importMajor,
int importMinor)
474 QQmlMetaType::unregisterModuleImport(
475 QString::fromUtf8(uri), resolveModuleVersion(moduleMajor),
476 resolveImport(QString::fromUtf8(import), importMajor, importMinor));
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503int qmlTypeId(
const char *uri,
int versionMajor,
int versionMinor,
const char *qmlName)
505 auto revision = QTypeRevision::fromVersion(versionMajor, versionMinor);
506 int id = QQmlMetaType::typeId(uri, revision, qmlName);
510
511
512
513
514
516 QQmlTypeLoader *typeLoader = QQmlTypeLoader::get(&engine);
517 auto loadHelper = QQml::makeRefPointer<LoadHelper>(
518 typeLoader, uri, qmlName, QQmlTypeLoader::Synchronous);
519 const QQmlType type = loadHelper->type();
520 if (type.availableInVersion(revision))
530 error.setDescription(QStringLiteral(
"The registered singleton has already been deleted. "
531 "Ensure that it outlives the engine."));
532 QQmlEnginePrivate::get(engine)->warning(engine, error);
536 if (engine->thread() != instance->thread()) {
538 error.setDescription(QStringLiteral(
"Registered object must live in the same thread "
539 "as the engine it was registered with"));
540 QQmlEnginePrivate::get(engine)->warning(engine, error);
548#if QT_DEPRECATED_SINCE(6
, 3
)
549QObject *QQmlPrivate::SingletonFunctor::operator()(QQmlEngine *qeng, QJSEngine *)
551 if (!checkSingletonInstance(qeng, m_object))
556 error.setDescription(QStringLiteral(
"Singleton registered by registerSingletonInstance "
557 "must only be accessed from one engine"));
558 QQmlEnginePrivate::get(qeng)->warning(qeng, error);
562 alreadyCalled =
true;
563 QJSEngine::setObjectOwnership(m_object, QQmlEngine::CppOwnership);
568QObject *QQmlPrivate::SingletonInstanceFunctor::operator()(QQmlEngine *qeng, QJSEngine *)
570 if (!checkSingletonInstance(qeng, m_object))
575 QJSEngine::setObjectOwnership(m_object, QQmlEngine::CppOwnership);
576 }
else if (m_engine != qeng) {
578 error.setDescription(QLatin1String(
"Singleton registered by registerSingletonInstance must only be accessed from one engine"));
579 QQmlEnginePrivate::get(qeng)->warning(qeng, error);
588 QList<QTypeRevision> revisions;
591 const int propertyOffset = metaObject->propertyOffset();
592 const int propertyCount = metaObject->propertyCount();
593 for (
int coreIndex = propertyOffset, propertyEnd = propertyOffset + propertyCount;
594 coreIndex < propertyEnd; ++coreIndex) {
595 const QMetaProperty property = metaObject->property(coreIndex);
596 if (
int revision = property.revision())
597 revisions.append(QTypeRevision::fromEncodedVersion(revision));
599 const int methodOffset = metaObject->methodOffset();
600 const int methodCount = metaObject->methodCount();
601 for (
int methodIndex = methodOffset, methodEnd = methodOffset + methodCount;
602 methodIndex < methodEnd; ++methodIndex) {
603 const QMetaMethod method = metaObject->method(methodIndex);
604 if (
int revision = method.revision())
605 revisions.append(QTypeRevision::fromEncodedVersion(revision));
609 if (
const QMetaObject *superMeta = metaObject->superClass())
610 revisions += availableRevisions(superMeta);
615template<
typename Registration>
617 QTypeRevision defaultVersion)
619 const quint8 majorVersion = revision.hasMajorVersion() ? revision.majorVersion()
620 : defaultVersion.majorVersion();
621 registration->version = revision.hasMinorVersion()
622 ? QTypeRevision::fromVersion(majorVersion, revision.minorVersion())
623 : QTypeRevision::fromMajorVersion(majorVersion);
624 registration->revision = revision;
629 auto revisions = availableRevisions(metaObject);
630 revisions.append(added);
634static void uniqueRevisions(QList<QTypeRevision> *revisions, QTypeRevision defaultVersion,
637 bool revisionsHaveMajorVersions =
false;
640 const QList<QTypeRevision> origRevisions = *revisions;
641 for (QTypeRevision revision : origRevisions) {
643 if (revision.hasMajorVersion()) {
644 revisionsHaveMajorVersions =
true;
645 if (revision.majorVersion() < defaultVersion.majorVersion())
646 revisions->append(QTypeRevision::fromVersion(revision.majorVersion(), 254));
650 if (revisionsHaveMajorVersions) {
651 if (!added.hasMajorVersion()) {
653 revisions->append(QTypeRevision::fromVersion(defaultVersion.majorVersion(),
654 added.minorVersion()));
655 }
else if (added.majorVersion() < defaultVersion.majorVersion()) {
657 revisions->append(QTypeRevision::fromVersion(defaultVersion.majorVersion(), 0));
661 std::sort(revisions->begin(), revisions->end());
662 const auto it = std::unique(revisions->begin(), revisions->end());
663 revisions->erase(it, revisions->end());
667 const QQmlPrivate::RegisterSingletonType &type)
669 QQmlType::SingletonInstanceInfo::Ptr siinfo = QQmlType::SingletonInstanceInfo::create();
670 siinfo->scriptCallback = type.scriptApi;
671 siinfo->qobjectCallback = type.qObjectApi;
672 siinfo->typeName = type.typeName;
673 return QQmlType::SingletonInstanceInfo::ConstPtr(
674 siinfo.take(), QQmlType::SingletonInstanceInfo::ConstPtr::Adopt);
678 const QQmlPrivate::RegisterCompositeSingletonType &type)
680 QQmlType::SingletonInstanceInfo::Ptr siinfo = QQmlType::SingletonInstanceInfo::create();
681 siinfo->url = QQmlMetaType::normalizedUrl(type.url);
682 siinfo->typeName = type.typeName;
683 return QQmlType::SingletonInstanceInfo::ConstPtr(
684 siinfo.take(), QQmlType::SingletonInstanceInfo::ConstPtr::Adopt);
689 if (!dtype.isValid())
692 QQmlMetaType::registerUndeletableType(dtype);
693 return dtype.index();
696using ElementNames = QVarLengthArray<
const char *, 8>;
699 Q_ASSERT(metaObject);
700 const char *key =
"QML.Element";
702 const int offset = metaObject->classInfoOffset();
703 const int start = metaObject->classInfoCount() + offset - 1;
705 ElementNames elementNames;
707 for (
int i = start; i >= offset; --i) {
708 const QMetaClassInfo classInfo = metaObject->classInfo(i);
709 if (qstrcmp(key, classInfo.name()) == 0) {
710 const char *elementName = classInfo.value();
712 if (qstrcmp(elementName,
"auto") == 0) {
713 const char *strippedClassName = metaObject->className();
714 for (
const char *c = strippedClassName; *c !=
'\0'; c++) {
716 strippedClassName = c + 1;
718 elementName = strippedClassName;
719 }
else if (qstrcmp(elementName,
"anonymous") == 0) {
720 if (elementNames.isEmpty())
721 elementNames.push_back(
nullptr);
722 else if (elementNames[0] !=
nullptr)
723 qWarning() << metaObject->className() <<
"is both anonymous and named";
727 if (!elementNames.isEmpty() && elementNames[0] ==
nullptr) {
728 qWarning() << metaObject->className() <<
"is both anonymous and named";
729 elementNames[0] = elementName;
731 elementNames.push_back(elementName);
746 for (
int i = 1, end = elementNames->length(); i < end; ++i)
747 otherNames.append(QString::fromUtf8(elementNames->at(i)));
748 elementNames =
nullptr;
751 for (
const QString &otherName : std::as_const(otherNames))
752 QQmlMetaType::registerTypeAlias(typeId, otherName);
756 const ElementNames *elementNames;
757 QVarLengthArray<QString, 8> otherNames;
762 const QQmlPrivate::RegisterTypeAndRevisions &type,
763 const ElementNames &elementNames)
765 using namespace QQmlPrivate;
767 const bool isValueType = !(type.typeId.flags() & QMetaType::PointerToQObject);
768 const bool creatable = (elementNames[0] !=
nullptr || isValueType)
769 && boolClassInfo(type.classInfoMetaObject,
"QML.Creatable",
true);
771 QString noCreateReason;
772 ValueTypeCreationMethod creationMethod = ValueTypeCreationMethod::None;
775 noCreateReason = QString::fromUtf8(
776 classInfo(type.classInfoMetaObject,
"QML.UncreatableReason"));
777 if (noCreateReason.isEmpty())
778 noCreateReason = QLatin1String(
"Type cannot be created in QML.");
779 }
else if (isValueType) {
780 const char *method = classInfo(type.classInfoMetaObject,
"QML.CreationMethod");
781 if (qstrcmp(method,
"structured") == 0)
782 creationMethod = ValueTypeCreationMethod::Structured;
783 else if (qstrcmp(method,
"construct") == 0)
784 creationMethod = ValueTypeCreationMethod::Construct;
787 RegisterType typeRevision = {
788 QQmlPrivate::RegisterType::CurrentVersion,
791 creatable ? type.objectSize : 0,
795 type.createValueType,
800 type.attachedPropertiesFunction,
801 type.attachedPropertiesMetaObject,
802 type.parserStatusCast,
803 type.valueSourceCast,
804 type.valueInterceptorCast,
805 type.extensionObjectCreate,
806 type.extensionMetaObject,
809 type.structVersion > 0 ? type.finalizerCast : -1,
813 QQmlPrivate::RegisterSequentialContainer sequenceRevision = {
819 type.structVersion > 1 ? type.listMetaSequence : QMetaSequence(),
823 const QTypeRevision added = revisionClassInfo(
824 type.classInfoMetaObject,
"QML.AddedInVersion",
825 QTypeRevision::fromVersion(type.version.majorVersion(), 0));
826 const QTypeRevision removed = revisionClassInfo(
827 type.classInfoMetaObject,
"QML.RemovedInVersion");
828 const QList<QTypeRevision> furtherRevisions = revisionClassInfos(type.classInfoMetaObject,
831 auto revisions = prepareRevisions(type.metaObject, added) + furtherRevisions;
832 if (type.attachedPropertiesMetaObject)
833 revisions += availableRevisions(type.attachedPropertiesMetaObject);
834 uniqueRevisions(&revisions, type.version, added);
837 for (QTypeRevision revision : std::as_const(revisions)) {
838 if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
841 assignVersions(&typeRevision, revision, type.version);
844 if (typeRevision.version < added
845 || (removed.isValid() && !(typeRevision.version < removed))) {
846 typeRevision.elementName =
nullptr;
847 typeRevision.create =
nullptr;
848 typeRevision.userdata =
nullptr;
850 typeRevision.elementName = elementNames[0];
851 typeRevision.create = creatable ? type.create :
nullptr;
852 typeRevision.userdata = type.userdata;
855 typeRevision.customParser = type.customParserFactory();
856 const int id = qmlregister(TypeRegistration, &typeRevision);
858 type.qmlTypeIds->append(id);
860 if (typeRevision.elementName)
861 aliasRegistrar.registerAliases(id);
863 if (sequenceRevision.metaSequence != QMetaSequence()) {
864 sequenceRevision.version = typeRevision.version;
865 sequenceRevision.revision = typeRevision.revision;
866 const int id = QQmlPrivate::qmlregister(
867 QQmlPrivate::SequentialContainerRegistration, &sequenceRevision);
869 type.qmlTypeIds->append(id);
875 const QQmlPrivate::RegisterSingletonTypeAndRevisions &type,
876 const ElementNames &elementNames)
878 using namespace QQmlPrivate;
880 RegisterSingletonType revisionRegistration = {
887 type.instanceMetaObject,
889 type.extensionObjectCreate,
890 type.extensionMetaObject,
893 const QQmlType::SingletonInstanceInfo::ConstPtr siinfo
894 = singletonInstanceInfo(revisionRegistration);
896 const QTypeRevision added = revisionClassInfo(
897 type.classInfoMetaObject,
"QML.AddedInVersion",
898 QTypeRevision::fromVersion(type.version.majorVersion(), 0));
899 const QTypeRevision removed = revisionClassInfo(
900 type.classInfoMetaObject,
"QML.RemovedInVersion");
901 const QList<QTypeRevision> furtherRevisions = revisionClassInfos(type.classInfoMetaObject,
904 auto revisions = prepareRevisions(type.instanceMetaObject, added) + furtherRevisions;
905 uniqueRevisions(&revisions, type.version, added);
908 for (QTypeRevision revision : std::as_const(revisions)) {
909 if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
912 assignVersions(&revisionRegistration, revision, type.version);
915 if (revisionRegistration.version < added
916 || (removed.isValid() && !(revisionRegistration.version < removed))) {
917 revisionRegistration.typeName =
nullptr;
918 revisionRegistration.qObjectApi =
nullptr;
920 revisionRegistration.typeName = elementNames[0];
921 revisionRegistration.qObjectApi = type.qObjectApi;
924 const int id = finalizeType(
925 QQmlMetaType::registerSingletonType(revisionRegistration, siinfo));
927 type.qmlTypeIds->append(id);
929 if (revisionRegistration.typeName)
930 aliasRegistrar.registerAliases(id);
935
936
937
938int QQmlPrivate::qmlregister(RegistrationType type,
void *data)
941 case AutoParentRegistration:
942 return QQmlMetaType::registerAutoParentFunction(
943 *
reinterpret_cast<RegisterAutoParent *>(data));
944 case QmlUnitCacheHookRegistration:
945 return QQmlMetaType::registerUnitCacheHook(
946 *
reinterpret_cast<RegisterQmlUnitCacheHook *>(data));
947 case TypeAndRevisionsRegistration: {
948 const RegisterTypeAndRevisions &type = *
reinterpret_cast<RegisterTypeAndRevisions *>(data);
949 if (type.structVersion > 1 && type.forceAnonymous) {
950 doRegisterTypeAndRevisions(type, {
nullptr});
952 const ElementNames names = classElementNames(type.classInfoMetaObject);
953 if (names.isEmpty()) {
954 qWarning().nospace() <<
"Missing QML.Element class info for "
955 << type.classInfoMetaObject->className();
957 doRegisterTypeAndRevisions(type, names);
963 case SingletonAndRevisionsRegistration: {
964 const RegisterSingletonTypeAndRevisions &type
965 = *
reinterpret_cast<RegisterSingletonTypeAndRevisions *>(data);
966 const ElementNames names = classElementNames(type.classInfoMetaObject);
967 if (names.isEmpty()) {
968 qWarning().nospace() <<
"Missing QML.Element class info for "
969 << type.classInfoMetaObject->className();
971 doRegisterSingletonAndRevisions(type, names);
975 case SequentialContainerAndRevisionsRegistration: {
976 const RegisterSequentialContainerAndRevisions &type
977 = *
reinterpret_cast<RegisterSequentialContainerAndRevisions *>(data);
978 RegisterSequentialContainer revisionRegistration = {
988 const QTypeRevision added = revisionClassInfo(
989 type.classInfoMetaObject,
"QML.AddedInVersion",
990 QTypeRevision::fromMinorVersion(0));
991 QList<QTypeRevision> revisions = revisionClassInfos(
992 type.classInfoMetaObject,
"QML.ExtraVersion");
993 revisions.append(added);
994 uniqueRevisions(&revisions, type.version, added);
996 for (QTypeRevision revision : std::as_const(revisions)) {
997 if (revision < added)
999 if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
1002 assignVersions(&revisionRegistration, revision, type.version);
1003 const int id = qmlregister(SequentialContainerRegistration, &revisionRegistration);
1004 if (type.qmlTypeIds)
1005 type.qmlTypeIds->append(id);
1009 case TypeRegistration:
1010 return finalizeType(
1011 QQmlMetaType::registerType(*
reinterpret_cast<RegisterType *>(data)));
1012 case InterfaceRegistration:
1013 return finalizeType(
1014 QQmlMetaType::registerInterface(*
reinterpret_cast<RegisterInterface *>(data)));
1015 case SingletonRegistration:
1016 return finalizeType(QQmlMetaType::registerSingletonType(
1017 *
reinterpret_cast<RegisterSingletonType *>(data),
1018 singletonInstanceInfo(*
reinterpret_cast<RegisterSingletonType *>(data))));
1019 case CompositeRegistration:
1020 return finalizeType(QQmlMetaType::registerCompositeType(
1021 *
reinterpret_cast<RegisterCompositeType *>(data)));
1022 case CompositeSingletonRegistration:
1023 return finalizeType(QQmlMetaType::registerCompositeSingletonType(
1024 *
reinterpret_cast<RegisterCompositeSingletonType *>(data),
1025 singletonInstanceInfo(*
reinterpret_cast<RegisterCompositeSingletonType *>(data))));
1026 case SequentialContainerRegistration:
1027 return finalizeType(QQmlMetaType::registerSequentialContainer(
1028 *
reinterpret_cast<RegisterSequentialContainer *>(data)));
1036void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data)
1039 case AutoParentRegistration:
1040 QQmlMetaType::unregisterAutoParentFunction(
reinterpret_cast<AutoParentFunction>(data));
1042 case QmlUnitCacheHookRegistration:
1043 QQmlMetaType::removeCachedUnitLookupFunction(
1044 reinterpret_cast<QmlUnitCacheLookupFunction>(data));
1046 case SequentialContainerRegistration:
1047 QQmlMetaType::unregisterSequentialContainer(data);
1049 case TypeRegistration:
1050 case InterfaceRegistration:
1051 case SingletonRegistration:
1052 case CompositeRegistration:
1053 case CompositeSingletonRegistration:
1054 QQmlMetaType::unregisterType(data);
1056 case TypeAndRevisionsRegistration:
1057 case SingletonAndRevisionsRegistration:
1058 case SequentialContainerAndRevisionsRegistration:
1068QList<QTypeRevision> QQmlPrivate::revisionClassInfos(
const QMetaObject *metaObject,
1071 QList<QTypeRevision> revisions;
1072 for (
int index = indexOfOwnClassInfo(metaObject, key); index != -1;
1073 index = indexOfOwnClassInfo(metaObject, key, index - 1)) {
1074 revisions.push_back(QTypeRevision::fromEncodedVersion(
1075 QLatin1StringView(metaObject->classInfo(index).value()).toInt()));
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114int qmlRegisterTypeNotAvailable(
1115 const char *uri,
int versionMajor,
int versionMinor,
1116 const char *qmlName,
const QString &message)
1119 uri, versionMajor, versionMinor, qmlName, message);
1125 const char *uri,
int versionMajor,
const QMetaObject *classInfoMetaObject,
1126 QList<
int> *qmlTypeIds,
const QMetaObject *extension,
bool)
1130 RegisterTypeAndRevisions type = {
1132 QmlMetaType<T>::self(),
1133 QmlMetaType<T>::list(),
1140 QTypeRevision::fromMajorVersion(versionMajor),
1142 &QQmlTypeNotAvailable::staticMetaObject,
1143 classInfoMetaObject,
1145 attachedPropertiesFunc<T>(),
1146 attachedPropertiesMetaObject<T>(),
1148 StaticCastSelector<T, QQmlParserStatus>::cast(),
1149 StaticCastSelector<T, QQmlPropertyValueSource>::cast(),
1150 StaticCastSelector<T, QQmlPropertyValueInterceptor>::cast(),
1154 qmlCreateCustomParser<T>,
1156 QQmlPrivate::StaticCastSelector<T, QQmlFinalizerHook>::cast(),
1158 QmlMetaType<T>::sequence(),
1161 qmlregister(TypeAndRevisionsRegistration, &type);
1179 QQmlEngine *engine = aotContext->qmlEngine();
1180 return engine ? QQmlEnginePrivate::get(aotContext->qmlEngine())->propertyCapture :
nullptr;
1213static bool markPointer(
const QVariant &element, QV4::MarkStack *markStack)
1215 if (!element.metaType().flags().testFlag(QMetaType::PointerToQObject))
1218 QV4::QObjectWrapper::markWrapper(
1219 *
static_cast<QObject *
const *>(element.constData()), markStack);
1225#define ADD_CASE(Type, id, T)
1226 case QMetaType::Type:
1228 const QMetaType elementMetaType = element.metaType();
1229 switch (elementMetaType.id()) {
1230 case QMetaType::QVariantMap:
1231 for (
const QVariant &variant : *
static_cast<
const QVariantMap *>(element.constData()))
1232 elements->push_back(variant);
1234 case QMetaType::QVariantHash:
1235 for (
const QVariant &variant : *
static_cast<
const QVariantHash *>(element.constData()))
1236 elements->push_back(variant);
1238 case QMetaType::QVariantList:
1239 for (
const QVariant &variant : *
static_cast<
const QVariantList *>(element.constData()))
1240 elements->push_back(variant);
1242 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(ADD_CASE)
1243 QT_FOR_EACH_STATIC_CORE_CLASS(ADD_CASE)
1244 QT_FOR_EACH_STATIC_GUI_CLASS(ADD_CASE)
1245 case QMetaType::QStringList:
1246 case QMetaType::QByteArrayList:
1252 if (elementMetaType == QMetaType::fromType<QJSValue>()
1253 || elementMetaType == QMetaType::fromType<QJSManagedValue>()
1254 || elementMetaType == QMetaType::fromType<QJSPrimitiveValue>()) {
1260 QMetaSequence::Iterable iterable;
1261 if (!QMetaType::convert(
1262 element.metaType(), element.constData(),
1263 QMetaType::fromType<QMetaSequence::Iterable>(), &iterable)) {
1267 switch (iterable.metaContainer().valueMetaType().id()) {
1268 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(ADD_CASE)
1269 QT_FOR_EACH_STATIC_CORE_CLASS(ADD_CASE)
1270 QT_FOR_EACH_STATIC_GUI_CLASS(ADD_CASE)
1271 case QMetaType::QStringList:
1272 case QMetaType::QByteArrayList:
1278 for (
auto it = iterable.constBegin(), end = iterable.constEnd(); it != end; ++it)
1279 elements->push_back(*it);
1322static bool inherits(
const QQmlPropertyCache *descendent,
const QQmlPropertyCache *ancestor)
1324 for (
const QQmlPropertyCache *cache = descendent; cache; cache = cache->parent().data()) {
1325 if (cache == ancestor)
1424 void *
a[] = {
target,
nullptr };
1436 void *
a[] = {
source,
nullptr };
1528template<
typename Op>
1558 void *
args[] = {
nullptr };
1577 const bool isUnsigned = enumType.flags() & QMetaType::IsUnsignedEnumeration;
1578 switch (enumType.sizeOf()) {
1581 ? numberType == QMetaType::fromType<quint8>()
1582 : numberType == QMetaType::fromType<qint8>();
1585 ? numberType == QMetaType::fromType<ushort>()
1586 : numberType == QMetaType::fromType<
short>();
1593 ? (numberType == QMetaType::fromType<
int>()
1594 || numberType == QMetaType::fromType<uint>())
1595 : numberType == QMetaType::fromType<
int>();
1598 ? numberType == QMetaType::fromType<qulonglong>()
1599 : numberType == QMetaType::fromType<qlonglong>();
1608 return !type.isValid()
1609 || type == QMetaType::fromType<QVariant>()
1610 || type == QMetaType::fromType<QJSPrimitiveValue>();
1615 if (source == target)
1618 if ((source.flags() & QMetaType::IsQmlList)
1619 && (target.flags() & QMetaType::IsQmlList)) {
1625 if (target.flags() & QMetaType::PointerToQObject) {
1628 const QMetaObject *targetMetaObject = target.metaObject();
1629 const QMetaObject *sourceMetaObject = source.metaObject();
1630 if (!sourceMetaObject)
1631 sourceMetaObject = QQmlMetaType::metaObjectForType(source).metaObject();
1633 while (sourceMetaObject && sourceMetaObject != targetMetaObject)
1634 sourceMetaObject = sourceMetaObject->superClass();
1636 return sourceMetaObject !=
nullptr;
1639 if (target.flags() & QMetaType::IsEnumeration)
1640 return isEnumUnderlyingType(target, source);
1642 if (source.flags() & QMetaType::IsEnumeration)
1643 return isEnumUnderlyingType(source, target);
1645 if (!source.isValid())
1646 return canHoldVoid(target);
1717template<QV4::Lookup::Call FallbackCall>
1719 const AOTCompiledContext *aotContext, QV4::Lookup *lookup, QObject *object)
1721 QV4::Scope scope(aotContext->engine->handle());
1722 QV4::PropertyKey id = scope.engine->identifierTable->asPropertyKey(
1723 aotContext->compilationUnit->runtimeStrings[lookup->nameIndex]);
1725 Q_ASSERT(id.isString());
1727 QV4::ScopedString name(scope, id.asStringOrSymbol());
1729 Q_ASSERT(!name->equals(scope.engine->id_toString()));
1730 Q_ASSERT(!name->equals(scope.engine->id_destroy()));
1732 QQmlData *ddata = QQmlData::get(object,
true);
1734 if (ddata->isQueuedForDeletion)
1737 const QQmlPropertyData *property;
1738 if (!ddata->propertyCache) {
1739 property = QQmlPropertyCache::property(object, name, aotContext->qmlContext,
nullptr);
1741 property = ddata->propertyCache->property(
1742 name.getPointer(), object, aotContext->qmlContext);
1746 const QMetaObject *metaObject = object->metaObject();
1750 const int coreIndex = metaObject->indexOfProperty(
1751 name->toQStringNoThrow().toUtf8().constData());
1755 const QMetaProperty property = metaObject->property(coreIndex);
1757 lookup->releasePropertyCache();
1759 lookup->qobjectFallbackLookup.metaObject = quintptr(metaObject) + 1;
1760 lookup->qobjectFallbackLookup.metaType = quintptr(property.metaType().iface()) + 1;
1761 lookup->qobjectFallbackLookup.coreIndex = coreIndex;
1762 lookup->qobjectFallbackLookup.notifyIndex =
1763 QMetaObjectPrivate::signalIndex(property.notifySignal());
1765 if constexpr (FallbackCall == QV4::Lookup::Call::ContextGetterScopeObjectPropertyFallback
1766 || FallbackCall == QV4::Lookup::Call::GetterQObjectPropertyFallback) {
1767 lookup->qobjectFallbackLookup.isConstantOrResettable = property.isConstant() ? 1 : 0;
1768 }
else if constexpr (FallbackCall == QV4::Lookup::Call::SetterQObjectPropertyFallback) {
1769 lookup->qobjectFallbackLookup.isConstantOrResettable = property.isResettable() ? 1 : 0;
1774 Q_ASSERT(ddata->propertyCache);
1776 QV4::setupQObjectLookup(lookup, ddata, property);
1782template<QV4::Lookup::Call ObjectCall, QV4::Lookup::Call FallbackCall,
LookupType Type>
1785 QV4::ExecutionEngine *v4 = aotContext->engine->handle();
1786 if (v4->hasException) {
1787 v4->amendException();
1791 QV4::Lookup *lookup = aotContext->compilationUnit->runtimeLookups + index;
1792 switch (initObjectLookup<FallbackCall>(aotContext, lookup, object)) {
1794 lookup->call = ObjectCall;
1798 lookup->call = FallbackCall;
1802 v4->throwTypeError();
1811 QV4::Lookup *lookup, QV4::ExecutableCompilationUnit *compilationUnit,
1812 const QMetaObject *metaObject)
1814 Q_ASSERT(metaObject);
1815 const QByteArray name = compilationUnit->runtimeStrings[lookup->nameIndex]->toQString().toUtf8();
1816 int coreIndex = metaObject->indexOfProperty(name.constData());
1817 QMetaType lookupType = metaObject->property(coreIndex).metaType();
1819 QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(
1820 QMetaObject::ReadProperty, &metaObject, &coreIndex);
1822 lookup->qgadgetLookup.metaObject = quintptr(metaObject) + 1;
1823 lookup->qgadgetLookup.coreIndex = coreIndex;
1824 lookup->qgadgetLookup.metaType = lookupType.iface();
1888#if QT_CONFIG(translation)
1938 if (type == QMetaType::fromType<QVariant>())
1939 return !
static_cast<
const QVariant *>(value)->isValid();
1940 if (type == QMetaType::fromType<QJSValue>())
1941 return static_cast<
const QJSValue *>(value)->isUndefined();
1942 if (type == QMetaType::fromType<QJSPrimitiveValue>()) {
1943 return static_cast<
const QJSPrimitiveValue *>(value)->type()
1944 == QJSPrimitiveValue::Undefined;
2043 QStringLiteral(
"Value is null and could not be converted to an object"));
2069 QStringLiteral(
"A QmlLoggingCatgory was provided without a valid name"));
2137 const QQmlType &type,
const QV4::CompiledData::ParameterType ¶meter)
2139 return parameter.isList() ? type.qListTypeId() : type.typeId();
2190 for (
int i = 0;
i <
argc; ++
i)
2264 const AOTCompiledContext *aotContext, QV4::Lookup *lookup,
const QString &object)
2266 aotContext->engine->handle()->throwTypeError(
2267 QStringLiteral(
"Property '%1' of object %2 is not a function").arg(
2268 aotContext->compilationUnit->runtimeStrings[lookup->nameIndex]->toQString(),
2296 QV4::QObjectMethod *method, QV4::Lookup *lookup,
int relativeMethodIndex)
2298 Q_ASSERT(lookup->qobjectMethodLookup.method.get() == method->d());
2300 const auto *d = method->d();
2301 const int methodCount = d->methodCount;
2303 if (methodCount == 1) {
2312 lookup->qobjectMethodLookup.propertyData = d->methods;
2316 for (
int i = 0, end = d->methodCount; i != end; ++i) {
2317 const QMetaMethod metaMethod = d->methods[i].metaMethod();
2318 if (metaMethod.relativeMethodIndex() != relativeMethodIndex)
2321 lookup->qobjectMethodLookup.propertyData = d->methods + i;
2671template<QV4::Lookup::Call call>
2672static void initTypeWrapperLookup(
2673 const AOTCompiledContext *context, QV4::Lookup *lookup, uint importNamespace)
2675 Q_ASSERT(!context->engine->hasError());
2676 if (importNamespace != AOTCompiledContext::InvalidStringId) {
2677 QV4::Scope scope(context->engine->handle());
2678 QV4::ScopedString import(scope, context->compilationUnit->runtimeStrings[importNamespace]);
2680 QQmlTypeLoader *typeLoader = scope.engine->typeLoader();
2681 Q_ASSERT(typeLoader);
2682 if (
const QQmlImportRef *importRef
2683 = context->qmlContext->imports()->query(import, typeLoader).importNamespace) {
2685 QV4::Scoped<QV4::QQmlTypeWrapper> wrapper(
2686 scope, QV4::QQmlTypeWrapper::create(
2687 scope.engine,
nullptr, context->qmlContext->imports(), importRef));
2690 wrapper = lookup->getter(context->engine->handle(), wrapper);
2693 lookup->releasePropertyCache();
2695 lookup->call = call;
2697 case QV4::Lookup::Call::ContextGetterSingleton:
2698 lookup->qmlContextSingletonLookup.singletonObject.set(scope.engine, wrapper->heapObject());
2700 case QV4::Lookup::Call::ContextGetterType:
2701 lookup->qmlTypeLookup.qmlTypeWrapper.set(scope.engine, wrapper->heapObject());
2708 scope.engine->throwTypeError();
2710 QV4::ExecutionEngine *v4 = context->engine->handle();
2711 lookup->contextGetter(v4,
nullptr);
2712 if (lookup->call != call) {
2714 = QLatin1String(call == QV4::Lookup::Call::ContextGetterSingleton
2715 ?
"%1 was a singleton at compile time, "
2716 "but is not a singleton anymore."
2717 :
"%1 was not a singleton at compile time, "
2718 "but is a singleton now.")
2719 .arg(context->compilationUnit->runtimeStrings[lookup->nameIndex]->toQString());
2720 v4->throwTypeError(error);
3000 QStringLiteral(
"Value is null and could not be converted to an object"));
3054 QV4::Lookup *lookup,
const QMetaObject *metaObject,
void *target,
void *value)
3056 void *args[] = { value,
nullptr };
3057 metaObject->d.static_metacall(
3058 reinterpret_cast<QObject *>(target), QMetaObject::WriteProperty,
3059 lookup->qgadgetLookup.coreIndex, args);
3064 QV4::Lookup *lookup,
const QMetaObject *metaObject,
void *target, QV4::ExecutionEngine *v4)
3066 const QMetaProperty property = metaObject->property(lookup->qgadgetLookup.coreIndex);
3067 if (property.isResettable()) {
3068 void *args[] = {
nullptr };
3069 metaObject->d.static_metacall(
3070 reinterpret_cast<QObject *>(target), QMetaObject::ResetProperty,
3071 lookup->qgadgetLookup.coreIndex, args);
3074 QLatin1String(
"Cannot assign [undefined] to ") +
3075 QLatin1String(property.metaType().name()));
3082 QV4::ExecutionEngine *v4, QV4::Lookup *lookup,
const QMetaObject *metaObject,
3083 void *target,
void *value)
3085 QVariant *variant =
static_cast<QVariant *>(value);
3086 const QMetaType propType = metaObject->property(lookup->qgadgetLookup.coreIndex).metaType();
3087 if (propType == QMetaType::fromType<QVariant>())
3088 return storeValueProperty(lookup, metaObject, target, variant);
3090 if (!variant->isValid())
3091 return resetValueProperty(lookup, metaObject, target, v4);
3093 if (isTypeCompatible(variant->metaType(), propType))
3094 return storeValueProperty(lookup, metaObject, target, variant->data());
3096 QVariant converted(propType);
3097 QV4::Scope scope(v4);
3098 QV4::ScopedValue val(scope, v4->fromVariant(*variant));
3099 if (v4->metaTypeFromJS(val, propType, converted.data())
3100 || QMetaType::convert(
3101 variant->metaType(), variant->constData(), propType, converted.data())) {
3102 return storeValueProperty(lookup, metaObject, target, converted.data());
3106 QLatin1String(
"Cannot assign ") + QLatin1String(variant->metaType().name())
3107 + QLatin1String(
" to ") + QLatin1String(propType.name()));
3139void initValueLookup(
3140 const AOTCompiledContext *aotContext, uint index,
const QMetaObject *metaObject)
3142 QV4::ExecutionEngine *v4 = aotContext->engine->handle();
3143 if (v4->hasException) {
3144 v4->amendException();
3148 QV4::Lookup *lookup = aotContext->compilationUnit->runtimeLookups + index;
3149 initValueLookup(lookup, aotContext->compilationUnit, metaObject);
3150 lookup->call = QV4::Lookup::Call::SetterValueTypeProperty;
3214 Validator(QQmlEngine *engine, QV4::CompiledData::CompilationUnit *cu);
3216 bool validateLookup(
const Lookup &lookup,
const Signature &signature);
3219 bool validatePropertyLookup(
const QMetaObject *mo,
const QString &member,
3220 const PropertySignature &expected)
const;
3221 bool validateEnumKeyLookup(
const QMetaObject *mo,
const QString &member,
3222 const QString &enumName,
const EnumKeySignature &expected)
const;
3223 bool validateMethodLookup(
const QMetaObject *mo,
const QString &member,
3224 const MethodSignature &expected)
const;
3225 bool methodMatchesSignature(
const QMetaMethod &method,
const QString &member,
3226 const MethodSignature &expected)
const;
3228 bool typesMatch(
const QMetaType &actual,
const Type &expected)
const;
3229 const QMetaObject *metaObjectForType(
const Type &type)
const;
3230 QQmlRefPointer<QQmlTypeData> getTypeFromModule(
const QString &moduleName,
3231 const QString &typeName)
const;
3232 QString qrcUrlForModule(
const QString &moduleName)
const;
3233 const QMetaObject *baseMOAtDepth(
const QMetaObject *mo,
int depth)
const;
3235 QQmlEngine *m_engine =
nullptr;
3236 QV4::CompiledData::CompilationUnit *m_compilationUnit =
nullptr;
3237 QQmlTypeLoader *m_loader =
nullptr;
3240Validator::Validator(QQmlEngine *engine, QV4::CompiledData::CompilationUnit *cu)
3241 : m_engine(engine), m_compilationUnit(cu), m_loader(QQmlTypeLoader::get(engine))
3244 Q_ASSERT(m_compilationUnit);
3248bool Validator::validateLookup(
const Lookup &lookup,
const Signature &signature)
3250 if (!m_engine || !m_compilationUnit || !m_loader)
3253 const auto *mo = metaObjectForType(lookup.base);
3257 if (
const auto *sig = std::get_if<PropertySignature>(&signature)) {
3258 return validatePropertyLookup(mo, lookup.member, *sig);
3259 }
else if (
const auto *sig = std::get_if<EnumKeySignature>(&signature)) {
3260 return validateEnumKeyLookup(mo, lookup.enumName, lookup.member, *sig);
3261 }
else if (
const auto *sig = std::get_if<MethodSignature>(&signature)) {
3262 return validateMethodLookup(mo, lookup.member, *sig);
3265 Q_UNREACHABLE_RETURN(
false);
3268bool Validator::validatePropertyLookup(
const QMetaObject *mo,
const QString &member,
3269 const PropertySignature &expected)
const
3271 const int index = mo->indexOfProperty(member.toUtf8());
3275 const auto prop = mo->property(index);
3276 if (!prop.isValid())
3279 if (prop.relativePropertyIndex() != expected.relativeIndex)
3282 return typesMatch(prop.metaType(), expected.type);
3285bool Validator::validateEnumKeyLookup(
const QMetaObject *mo,
const QString &enumName,
3286 const QString &member,
const EnumKeySignature &expected)
const
3288 const int index = mo->indexOfEnumerator(enumName.toUtf8());
3292 const auto enumerator = mo->enumerator(index);
3293 if (!enumerator.isValid())
3296 if (enumerator.isFlag() != (expected.isFlag == IsFlag::Yes))
3299 const auto actualValue = enumerator.keyToValue64(member.toUtf8());
3300 return actualValue.has_value() && expected.value == *actualValue;
3303bool Validator::methodMatchesSignature(
const QMetaMethod &method,
const QString &member,
3304 const MethodSignature &expected)
const
3306 if (method.nameView() != member.toUtf8())
3309 if (method.relativeMethodIndex() != expected.relativeIndex)
3312 if ((method.methodType() == QMetaMethod::Signal) != (expected.isSignal == IsSignal::Yes))
3315 if (!typesMatch(method.returnMetaType(), expected.types[0]))
3318 const int paramCount = method.parameterCount();
3319 const auto &expectedParamNames = expected.paramNames;
3320 if (paramCount !=
int(expectedParamNames.size()))
3323 const auto actualParameterNames = method.parameterNames();
3324 for (
int i = 0; i < paramCount; ++i) {
3325 if (actualParameterNames[i] != expectedParamNames[i].toUtf8())
3329 const auto &expectedParamTypes = expected.types;
3330 for (
int i = 0; i < paramCount; ++i) {
3331 if (!typesMatch(method.parameterMetaType(i), expectedParamTypes[i + 1]))
3337bool Validator::validateMethodLookup(
const QMetaObject *mo,
const QString &member,
3338 const MethodSignature &expected)
const
3341 for (
int i = mo->methodCount() - 1; i >= 0; --i) {
3342 if (methodMatchesSignature(mo->method(i), member, expected))
3349static QByteArrayView trimConstPointer(QByteArrayView typeName)
3351 QByteArrayView noConst = typeName.trimmed();
3352 const QByteArrayView c =
"const";
3353 if (noConst.startsWith(c))
3354 noConst.slice(c.length());
3355 QByteArrayView res = noConst.trimmed();
3356 for (
auto it = typeName.crbegin(); it != typeName.crend(); ++it) {
3357 if (*it ==
' ' || *it ==
'*')
3358 res = res.chopped(1);
3365bool Validator::typesMatch(
const QMetaType &actual,
const Type &expected)
const
3367 if (expected.isComposite == IsComposite::No) {
3369 const QByteArray actualStar = trimConstPointer(actual.name()) +
'*';
3370 const QByteArray expectedStar = trimConstPointer(expected.name.toLatin1()) +
'*';
3371 return QMetaType::fromName(actualStar) == QMetaType::fromName(expectedStar);
3374 const auto *actualMo = actual.metaObject();
3378 const auto *expectedMO = metaObjectForType(expected);
3382 return actualMo == expectedMO;
3385const QMetaObject *Validator::metaObjectForType(
const Type &type)
const
3387 if (type.isComposite == IsComposite::No) {
3388 const QString &extensionTypeName = type.icNameOrExtensionTypeName;
3389 const QString &typeName = extensionTypeName.isEmpty() ? type.name : extensionTypeName;
3390 const QString typeNameStar = typeName + u'*';
3391 const QMetaType mt = QMetaType::fromName(typeNameStar.toUtf8());
3392 return mt.metaObject();
3395 if (type.module.isEmpty() || type.name.isEmpty())
3398 const auto typeData = getTypeFromModule(type.module, type.name);
3399 if (typeData.isNull())
3402 if (type.isInlineComponent == IsIC::Yes)
3403 return typeData->qmlType(type.icNameOrExtensionTypeName).typeId().metaObject();
3405 const auto *cu = typeData->compilationUnit();
3409 return cu->metaType().metaObject();
3412QQmlRefPointer<QQmlTypeData> Validator::getTypeFromModule(
const QString &moduleName,
3413 const QString &typeName)
const
3416 if (moduleName == s_thisCuModule && typeName == s_thisCuType) {
3417 typeUrl = m_compilationUnit->finalUrlString();
3419 Q_ASSERT(moduleName != s_thisCuModule);
3420 Q_ASSERT(typeName != s_thisCuType);
3422 QString moduleUrl = qrcUrlForModule(moduleName);
3423 if (moduleUrl.isEmpty())
3426 QQmlDirParser parser;
3427 const QUrl qmldirUrl(moduleUrl + QStringLiteral(
"qmldir"));
3428 const auto *data = m_loader->getQmldir(qmldirUrl).data();
3429 if (!parser.parse(data->content()))
3432 const auto &components = parser.components();
3433 const auto it = components.constFind(typeName);
3434 if (it == components.constEnd())
3437 typeUrl = moduleUrl + it->fileName;
3440 return m_loader->getType(QUrl(typeUrl), QQmlTypeLoader::Synchronous);
3443QString Validator::qrcUrlForModule(
const QString &moduleName)
const
3445 for (
const auto &url : m_loader->urlsForModule(moduleName)) {
3446 if (url.startsWith(QStringLiteral(
"qrc")))
3452bool validateLookupSignature(QQmlEngine *engine, QV4::CompiledData::CompilationUnit *cu,
3453 const Lookup &lookup,
const Signature &signature)
3455 Validator validator(engine, cu);
3456 return validator.validateLookup(lookup, signature);
3464
3465
3466
3467
3468
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
PropertyResult loadFallbackAsVariant(QV4::Lookup *lookup, QObject *object, void *target, const AOTCompiledContext *aotContext)
static ObjectLookupResult initObjectLookup(const AOTCompiledContext *aotContext, QV4::Lookup *lookup, QObject *object)
void qmlRegisterTypeAndRevisions< QQmlTypeNotAvailable, void >(const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject, QList< int > *qmlTypeIds, const QMetaObject *extension, bool)
PropertyResult writeBackObjectAsVariant(QV4::Lookup *lookup, QObject *object, void *source)
static PropertyResult writeBackFallbackProperty(QV4::Lookup *lookup, QObject *object, void *source)
static PropertyResult changeFallbackProperty(QV4::Lookup *lookup, QObject *object, Op op)
static FallbackPropertyQmlData findFallbackPropertyQmlData(QV4::Lookup *lookup, QObject *object)
static void throwIsNotAFunctionError(const AOTCompiledContext *aotContext, QV4::Lookup *lookup, const QString &object)
static bool markPointer(const QVariant &element, QV4::MarkStack *markStack)
PropertyResult loadObjectProperty(QV4::Lookup *lookup, QObject *object, void *target, const AOTCompiledContext *aotContext)
static bool isEnumUnderlyingType(QMetaType enumType, QMetaType numberType)
static PropertyResult storeFallbackAsVariant(QV4::ExecutionEngine *v4, QV4::Lookup *lookup, QObject *object, void *value)
static void iterateVariant(const QVariant &element, std::vector< QVariant > *elements)
static PropertyResult changeObjectProperty(QV4::Lookup *lookup, QObject *object, Op op)
static PropertyResult storeObjectProperty(QV4::Lookup *lookup, QObject *object, void *value)
PropertyResult loadObjectAsVariant(QV4::Lookup *lookup, QObject *object, void *target, const AOTCompiledContext *aotContext)
static bool callQObjectMethod(QV4::ExecutionEngine *engine, QV4::Lookup *lookup, QObject *thisObject, void **args, int argc)
ObjectPropertyQmlData findObjectPropertyQmlData(QV4::Lookup *lookup, QObject *object)
static void captureFallbackProperty(QObject *object, int coreIndex, int notifyIndex, bool isConstant, const AOTCompiledContext *aotContext)
static void initValueLookup(QV4::Lookup *lookup, QV4::ExecutableCompilationUnit *compilationUnit, const QMetaObject *metaObject)
static bool inherits(const QQmlPropertyCache *descendent, const QQmlPropertyCache *ancestor)
static bool canHoldVoid(QMetaType type)
static bool tryEnsureMethodsCache(QV4::QObjectMethod *method, QObject *object)
static void captureObjectProperty(QObject *object, const QQmlPropertyCache *propertyCache, const QQmlPropertyData *property, const AOTCompiledContext *aotContext)
PropertyResult writeBackFallbackAsVariant(QV4::Lookup *lookup, QObject *object, void *source)
static PropertyResult storeFallbackProperty(QV4::Lookup *lookup, QObject *object, void *value)
static bool isUndefined(const void *value, QMetaType type)
static bool callQObjectMethodAsVariant(QV4::ExecutionEngine *engine, QV4::Lookup *lookup, QObject *thisObject, void **args, int argc)
static QMetaType jsTypedFunctionArgument(const QQmlType &type, const QV4::CompiledData::ParameterType ¶meter)
static PropertyResult resetFallbackProperty(QV4::Lookup *lookup, QObject *object, QV4::ExecutionEngine *v4)
static void resolveQObjectMethodOverload(QV4::QObjectMethod *method, QV4::Lookup *lookup, int relativeMethodIndex)
static PropertyResult loadFallbackProperty(QV4::Lookup *lookup, QObject *object, void *target, const AOTCompiledContext *aotContext)
static bool callArrowFunction(QV4::ExecutionEngine *engine, QV4::ArrowFunction *function, QObject *thisObject, void **args, int argc)
static PropertyResult resetObjectProperty(QV4::Lookup *lookup, QObject *object, QV4::ExecutionEngine *v4)
static PropertyResult storeObjectAsVariant(QV4::ExecutionEngine *v4, QV4::Lookup *lookup, QObject *object, void *value)
static bool callQObjectMethodWithTypes(QV4::ExecutionEngine *engine, QV4::Lookup *lookup, QObject *thisObject, void **args, QMetaType *types, int argc)
static bool isTypeCompatible(QMetaType source, QMetaType target)
PropertyResult writeBackObjectProperty(QV4::Lookup *lookup, QObject *object, void *source)
void initObjectLookup(const AOTCompiledContext *aotContext, uint index, QObject *object)
static QQmlPropertyCapture * propertyCapture(const AOTCompiledContext *aotContext)
Combined button and popup list for selecting options.
QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *object, const QMetaObject *attachedMetaObject)
static QList< QTypeRevision > availableRevisions(const QMetaObject *metaObject)
static void doRegisterSingletonAndRevisions(const QQmlPrivate::RegisterSingletonTypeAndRevisions &type, const ElementNames &elementNames)
static ElementNames classElementNames(const QMetaObject *metaObject)
QObject * qmlAttachedPropertiesObject(QObject *object, QQmlAttachedPropertiesFunc func, bool createIfMissing)
static void uniqueRevisions(QList< QTypeRevision > *revisions, QTypeRevision defaultVersion, QTypeRevision added)
void assignVersions(Registration *registration, QTypeRevision revision, QTypeRevision defaultVersion)
static int finalizeType(const QQmlType &dtype)
QQmlEngine * qmlEngine(const QObject *obj)
QQmlContext * qmlContext(const QObject *obj)
static QObject * resolveAttachedProperties(QQmlAttachedPropertiesFunc pf, QQmlData *data, QObject *object, bool create)
QT_BEGIN_NAMESPACE void qmlExecuteDeferred(QObject *object)
\inmodule QtQml \title Functions to register C++ types to QML
static QList< QTypeRevision > prepareRevisions(const QMetaObject *metaObject, QTypeRevision added)
static QQmlDirParser::Import resolveImport(const QString &uri, int importMajor, int importMinor)
static bool checkSingletonInstance(QQmlEngine *engine, QObject *instance)
static void doRegisterTypeAndRevisions(const QQmlPrivate::RegisterTypeAndRevisions &type, const ElementNames &elementNames)
static QTypeRevision resolveModuleVersion(int moduleMajor)
static QQmlType::SingletonInstanceInfo::ConstPtr singletonInstanceInfo(const QQmlPrivate::RegisterSingletonType &type)
Q_QML_EXPORT void qmlRegisterModuleImport(const char *uri, int moduleMajor, const char *import, int importMajor=QQmlModuleImportLatest, int importMinor=QQmlModuleImportLatest)
Q_QML_EXPORT bool qmlProtectModule(const char *uri, int majVersion)
Q_QML_EXPORT void qmlUnregisterModuleImport(const char *uri, int moduleMajor, const char *import, int importMajor=QQmlModuleImportLatest, int importMinor=QQmlModuleImportLatest)
Q_QML_EXPORT void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor)
AliasRegistrar(const ElementNames *elementNames)
void registerAliases(int typeId)
const QMetaObject * metaObject