7#include <private/qjsvalue_p.h>
8#include <private/qqmlbuiltinfunctions_p.h>
9#include <private/qqmlcomponent_p.h>
10#include <private/qqmlengine_p.h>
11#include <private/qqmlfinalizer_p.h>
12#include <private/qqmlimport_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/qqmltypenamecache_p.h>
20#include <private/qqmltypewrapper_p.h>
21#include <private/qqmlvaluetypewrapper_p.h>
22#include <private/qv4alloca_p.h>
23#include <private/qv4dateobject_p.h>
24#include <private/qv4errorobject_p.h>
25#include <private/qv4identifiertable_p.h>
26#include <private/qv4lookup_p.h>
27#include <private/qv4qobjectwrapper_p.h>
29#include <QtQml/qqmlprivate.h>
31#include <QtCore/qmutex.h>
32#include <QtCore/qmetasequence.h>
37
38
39
40
41
42
43
44
45
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
65 QQmlData *data = QQmlData::get(object);
69 || !data->context->engine()
70 || data->deferredData.isEmpty()
71 || data->wasDeleted(object)) {
75 if (!data->propertyCache)
76 data->propertyCache = QQmlMetaType::propertyCache(object->metaObject());
78 QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine());
80 QQmlComponentPrivate::DeferredState state;
81 QQmlComponentPrivate::beginDeferred(ep, object, &state);
84 data->releaseDeferredData();
86 QQmlComponentPrivate::completeDeferred(ep, &state);
91 return QQmlEngine::contextForObject(obj);
96 QQmlData *data = QQmlData::get(obj);
97 if (!data || !data->context)
99 return data->context->engine();
103 QObject *object,
bool create)
108 QObject *rv = data->hasExtendedData() ? data->attachedProperties()->value(pf) : 0;
115 data->attachedProperties()->insert(pf, rv);
121 const QMetaObject *attachedMetaObject)
123 QQmlEngine *engine = object ? qmlEngine(object) :
nullptr;
124 return QQmlMetaType::attachedPropertiesFunc(
125 engine ? QQmlTypeLoader::get(engine) :
nullptr, attachedMetaObject);
133 QQmlData *data = QQmlData::get(object, createIfMissing);
140 return resolveAttachedProperties(func, data, object, createIfMissing);
144
145
146
147
148
149
150
151QObject *qmlExtendedObject(QObject *base)
153 return QQmlPrivate::qmlExtendedObject(base, 0);
156QObject *QQmlPrivate::qmlExtendedObject(QObject *object,
int index)
161 void *result =
nullptr;
162 QObjectPrivate *d = QObjectPrivate::get(object);
166 const int id = d->metaObject->metaCall(
167 object, QMetaObject::CustomCall,
168 QQmlProxyMetaObject::extensionObjectId(index), &result);
169 if (id != QQmlProxyMetaObject::extensionObjectId(index))
172 return static_cast<QObject *>(result);
175void QQmlPrivate::qmlRegistrationWarning(
176 QQmlPrivate::QmlRegistrationWarning warning, QMetaType metaType)
179 case UnconstructibleType:
182 <<
" is neither a default constructible QObject, nor a default- "
183 <<
"and copy-constructible Q_GADGET, nor a QObject marked as uncreatable.\n"
184 <<
"You should not use it as a QML type.";
186 case UnconstructibleSingleton:
188 <<
"Singleton" << metaType.name()
189 <<
"needs to be a concrete class with either a default constructor"
190 <<
"or, when adding a default constructor is infeasible, a public static"
191 <<
"create(QQmlEngine *, QJSEngine *) method.";
193 case NonQObjectWithAtached:
196 <<
"is not a QObject, but has attached properties. This won't work.";
201QMetaType QQmlPrivate::compositeMetaType(
202 QV4::ExecutableCompilationUnit *unit,
int elementNameId)
204 return QQmlTypePrivate::visibleQmlTypeByName(unit, elementNameId).typeId();
207QMetaType QQmlPrivate::compositeMetaType(
208 QV4::ExecutableCompilationUnit *unit,
const QString &elementName)
210 return QQmlTypePrivate::visibleQmlTypeByName(
211 unit->baseCompilationUnit(), elementName, unit->engine->typeLoader())
215QMetaType QQmlPrivate::compositeListMetaType(
216 QV4::ExecutableCompilationUnit *unit,
int elementNameId)
218 return QQmlTypePrivate::visibleQmlTypeByName(unit, elementNameId).qListTypeId();
221QMetaType QQmlPrivate::compositeListMetaType(
222 QV4::ExecutableCompilationUnit *unit,
const QString &elementName)
224 return QQmlTypePrivate::visibleQmlTypeByName(
225 unit->baseCompilationUnit(), elementName, unit->engine->typeLoader())
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
268
269int qmlRegisterUncreatableMetaObject(
const QMetaObject &staticMetaObject,
270 const char *uri,
int versionMajor,
271 int versionMinor,
const char *qmlName,
272 const QString& reason)
274 QQmlPrivate::RegisterType type = {
275 QQmlPrivate::RegisterType::CurrentVersion,
284 uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &staticMetaObject,
286 QQmlAttachedPropertiesFunc(),
296 QTypeRevision::zero(),
298 QQmlPrivate::ValueTypeCreationMethod::None
301 return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
305
306
307
308
309
310
311
312
313
314
315
316void qmlClearTypeRegistrations()
318 QQmlMetaType::clearTypeRegistrations();
319 QQmlEnginePrivate::baseModulesUninitialized =
true;
320 qmlClearEnginePlugins();
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
350
353 return QQmlMetaType::protectModule(QString::fromUtf8(uri),
354 QTypeRevision::fromMajorVersion(majVersion));
358
359
360
361
362
363
364
365
366
367
371 QQmlMetaType::registerModule(uri, QTypeRevision::fromVersion(versionMajor, versionMinor));
376 if (importMajor == QQmlModuleImportAuto)
377 return QQmlDirParser::Import(uri, QTypeRevision(), QQmlDirParser::Import::Auto);
378 else if (importMajor == QQmlModuleImportLatest)
379 return QQmlDirParser::Import(uri, QTypeRevision(), QQmlDirParser::Import::Default);
380 else if (importMinor == QQmlModuleImportLatest)
381 return QQmlDirParser::Import(uri, QTypeRevision::fromMajorVersion(importMajor), QQmlDirParser::Import::Default);
382 return QQmlDirParser::Import(uri, QTypeRevision::fromVersion(importMajor, importMinor), QQmlDirParser::Import::Default);
387 return moduleMajor == QQmlModuleImportModuleAny
389 : QTypeRevision::fromMajorVersion(moduleMajor);
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
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
451
453 const char *import,
int importMajor,
int importMinor)
455 QQmlMetaType::registerModuleImport(
456 QString::fromUtf8(uri), resolveModuleVersion(moduleMajor),
457 resolveImport(QString::fromUtf8(import), importMajor, importMinor));
462
463
464
465
466
467
468
469
470
471
473 const char *import,
int importMajor,
int importMinor)
475 QQmlMetaType::unregisterModuleImport(
476 QString::fromUtf8(uri), resolveModuleVersion(moduleMajor),
477 resolveImport(QString::fromUtf8(import), importMajor, importMinor));
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504int qmlTypeId(
const char *uri,
int versionMajor,
int versionMinor,
const char *qmlName)
506 auto revision = QTypeRevision::fromVersion(versionMajor, versionMinor);
507 int id = QQmlMetaType::typeId(uri, revision, qmlName);
511
512
513
514
515
517 QQmlTypeLoader *typeLoader = QQmlTypeLoader::get(&engine);
518 auto loadHelper = QQml::makeRefPointer<LoadHelper>(
519 typeLoader, uri, qmlName, QQmlTypeLoader::Synchronous);
520 const QQmlType type = loadHelper->type();
521 if (type.availableInVersion(revision))
531 error.setDescription(QStringLiteral(
"The registered singleton has already been deleted. "
532 "Ensure that it outlives the engine."));
533 QQmlEnginePrivate::get(engine)->warning(engine, error);
537 if (engine->thread() != instance->thread()) {
539 error.setDescription(QStringLiteral(
"Registered object must live in the same thread "
540 "as the engine it was registered with"));
541 QQmlEnginePrivate::get(engine)->warning(engine, error);
549#if QT_DEPRECATED_SINCE(6
, 3
)
550QObject *QQmlPrivate::SingletonFunctor::operator()(QQmlEngine *qeng, QJSEngine *)
552 if (!checkSingletonInstance(qeng, m_object))
557 error.setDescription(QStringLiteral(
"Singleton registered by registerSingletonInstance "
558 "must only be accessed from one engine"));
559 QQmlEnginePrivate::get(qeng)->warning(qeng, error);
563 alreadyCalled =
true;
564 QJSEngine::setObjectOwnership(m_object, QQmlEngine::CppOwnership);
569QObject *QQmlPrivate::SingletonInstanceFunctor::operator()(QQmlEngine *qeng, QJSEngine *)
571 if (!checkSingletonInstance(qeng, m_object))
576 QJSEngine::setObjectOwnership(m_object, QQmlEngine::CppOwnership);
577 }
else if (m_engine != qeng) {
579 error.setDescription(QLatin1String(
"Singleton registered by registerSingletonInstance must only be accessed from one engine"));
580 QQmlEnginePrivate::get(qeng)->warning(qeng, error);
589 QList<QTypeRevision> revisions;
592 const int propertyOffset = metaObject->propertyOffset();
593 const int propertyCount = metaObject->propertyCount();
594 for (
int coreIndex = propertyOffset, propertyEnd = propertyOffset + propertyCount;
595 coreIndex < propertyEnd; ++coreIndex) {
596 const QMetaProperty property = metaObject->property(coreIndex);
597 if (
int revision = property.revision())
598 revisions.append(QTypeRevision::fromEncodedVersion(revision));
600 const int methodOffset = metaObject->methodOffset();
601 const int methodCount = metaObject->methodCount();
602 for (
int methodIndex = methodOffset, methodEnd = methodOffset + methodCount;
603 methodIndex < methodEnd; ++methodIndex) {
604 const QMetaMethod method = metaObject->method(methodIndex);
605 if (
int revision = method.revision())
606 revisions.append(QTypeRevision::fromEncodedVersion(revision));
610 if (
const QMetaObject *superMeta = metaObject->superClass())
611 revisions += availableRevisions(superMeta);
616template<
typename Registration>
618 QTypeRevision defaultVersion)
620 const quint8 majorVersion = revision.hasMajorVersion() ? revision.majorVersion()
621 : defaultVersion.majorVersion();
622 registration->version = revision.hasMinorVersion()
623 ? QTypeRevision::fromVersion(majorVersion, revision.minorVersion())
624 : QTypeRevision::fromMajorVersion(majorVersion);
625 registration->revision = revision;
630 auto revisions = availableRevisions(metaObject);
631 revisions.append(added);
635static void uniqueRevisions(QList<QTypeRevision> *revisions, QTypeRevision defaultVersion,
638 bool revisionsHaveMajorVersions =
false;
641 const QList<QTypeRevision> origRevisions = *revisions;
642 for (QTypeRevision revision : origRevisions) {
644 if (revision.hasMajorVersion()) {
645 revisionsHaveMajorVersions =
true;
646 if (revision.majorVersion() < defaultVersion.majorVersion())
647 revisions->append(QTypeRevision::fromVersion(revision.majorVersion(), 254));
651 if (revisionsHaveMajorVersions) {
652 if (!added.hasMajorVersion()) {
654 revisions->append(QTypeRevision::fromVersion(defaultVersion.majorVersion(),
655 added.minorVersion()));
656 }
else if (added.majorVersion() < defaultVersion.majorVersion()) {
658 revisions->append(QTypeRevision::fromVersion(defaultVersion.majorVersion(), 0));
662 std::sort(revisions->begin(), revisions->end());
663 const auto it = std::unique(revisions->begin(), revisions->end());
664 revisions->erase(it, revisions->end());
668 const QQmlPrivate::RegisterSingletonType &type)
670 QQmlType::SingletonInstanceInfo::Ptr siinfo = QQmlType::SingletonInstanceInfo::create();
671 siinfo->scriptCallback = type.scriptApi;
672 siinfo->qobjectCallback = type.qObjectApi;
673 siinfo->typeName = type.typeName;
674 return QQmlType::SingletonInstanceInfo::ConstPtr(
675 siinfo.take(), QQmlType::SingletonInstanceInfo::ConstPtr::Adopt);
679 const QQmlPrivate::RegisterCompositeSingletonType &type)
681 QQmlType::SingletonInstanceInfo::Ptr siinfo = QQmlType::SingletonInstanceInfo::create();
682 siinfo->url = QQmlMetaType::normalizedUrl(type.url);
683 siinfo->typeName = type.typeName;
684 return QQmlType::SingletonInstanceInfo::ConstPtr(
685 siinfo.take(), QQmlType::SingletonInstanceInfo::ConstPtr::Adopt);
690 if (!dtype.isValid())
693 QQmlMetaType::registerUndeletableType(dtype);
694 return dtype.index();
697using ElementNames = QVarLengthArray<
const char *, 8>;
700 Q_ASSERT(metaObject);
701 const char *key =
"QML.Element";
703 const int offset = metaObject->classInfoOffset();
704 const int start = metaObject->classInfoCount() + offset - 1;
706 ElementNames elementNames;
708 for (
int i = start; i >= offset; --i) {
709 const QMetaClassInfo classInfo = metaObject->classInfo(i);
710 if (qstrcmp(key, classInfo.name()) == 0) {
711 const char *elementName = classInfo.value();
713 if (qstrcmp(elementName,
"auto") == 0) {
714 const char *strippedClassName = metaObject->className();
715 for (
const char *c = strippedClassName; *c !=
'\0'; c++) {
717 strippedClassName = c + 1;
719 elementName = strippedClassName;
720 }
else if (qstrcmp(elementName,
"anonymous") == 0) {
721 if (elementNames.isEmpty())
722 elementNames.push_back(
nullptr);
723 else if (elementNames[0] !=
nullptr)
724 qWarning() << metaObject->className() <<
"is both anonymous and named";
728 if (!elementNames.isEmpty() && elementNames[0] ==
nullptr) {
729 qWarning() << metaObject->className() <<
"is both anonymous and named";
730 elementNames[0] = elementName;
732 elementNames.push_back(elementName);
747 for (
int i = 1, end = elementNames->length(); i < end; ++i)
748 otherNames.append(QString::fromUtf8(elementNames->at(i)));
749 elementNames =
nullptr;
752 for (
const QString &otherName : std::as_const(otherNames))
753 QQmlMetaType::registerTypeAlias(typeId, otherName);
757 const ElementNames *elementNames;
758 QVarLengthArray<QString, 8> otherNames;
763 const QQmlPrivate::RegisterTypeAndRevisions &type,
764 const ElementNames &elementNames)
766 using namespace QQmlPrivate;
768 const bool isValueType = !(type.typeId.flags() & QMetaType::PointerToQObject);
769 const bool creatable = (elementNames[0] !=
nullptr || isValueType)
770 && boolClassInfo(type.classInfoMetaObject,
"QML.Creatable",
true);
772 QString noCreateReason;
773 ValueTypeCreationMethod creationMethod = ValueTypeCreationMethod::None;
776 noCreateReason = QString::fromUtf8(
777 classInfo(type.classInfoMetaObject,
"QML.UncreatableReason"));
778 if (noCreateReason.isEmpty())
779 noCreateReason = QLatin1String(
"Type cannot be created in QML.");
780 }
else if (isValueType) {
781 const char *method = classInfo(type.classInfoMetaObject,
"QML.CreationMethod");
782 if (qstrcmp(method,
"structured") == 0)
783 creationMethod = ValueTypeCreationMethod::Structured;
784 else if (qstrcmp(method,
"construct") == 0)
785 creationMethod = ValueTypeCreationMethod::Construct;
788 RegisterType typeRevision = {
789 QQmlPrivate::RegisterType::CurrentVersion,
792 creatable ? type.objectSize : 0,
796 type.createValueType,
801 type.attachedPropertiesFunction,
802 type.attachedPropertiesMetaObject,
803 type.parserStatusCast,
804 type.valueSourceCast,
805 type.valueInterceptorCast,
806 type.extensionObjectCreate,
807 type.extensionMetaObject,
810 type.structVersion > 0 ? type.finalizerCast : -1,
814 QQmlPrivate::RegisterSequentialContainer sequenceRevision = {
820 type.structVersion > 1 ? type.listMetaSequence : QMetaSequence(),
824 const QTypeRevision added = revisionClassInfo(
825 type.classInfoMetaObject,
"QML.AddedInVersion",
826 QTypeRevision::fromVersion(type.version.majorVersion(), 0));
827 const QTypeRevision removed = revisionClassInfo(
828 type.classInfoMetaObject,
"QML.RemovedInVersion");
829 const QList<QTypeRevision> furtherRevisions = revisionClassInfos(type.classInfoMetaObject,
832 auto revisions = prepareRevisions(type.metaObject, added) + furtherRevisions;
833 if (type.attachedPropertiesMetaObject)
834 revisions += availableRevisions(type.attachedPropertiesMetaObject);
835 uniqueRevisions(&revisions, type.version, added);
838 for (QTypeRevision revision : std::as_const(revisions)) {
839 if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
842 assignVersions(&typeRevision, revision, type.version);
845 if (typeRevision.version < added
846 || (removed.isValid() && !(typeRevision.version < removed))) {
847 typeRevision.elementName =
nullptr;
848 typeRevision.create =
nullptr;
849 typeRevision.userdata =
nullptr;
851 typeRevision.elementName = elementNames[0];
852 typeRevision.create = creatable ? type.create :
nullptr;
853 typeRevision.userdata = type.userdata;
856 typeRevision.customParser = type.customParserFactory();
857 const int id = qmlregister(TypeRegistration, &typeRevision);
859 type.qmlTypeIds->append(id);
861 if (typeRevision.elementName)
862 aliasRegistrar.registerAliases(id);
864 if (sequenceRevision.metaSequence != QMetaSequence()) {
865 sequenceRevision.version = typeRevision.version;
866 sequenceRevision.revision = typeRevision.revision;
867 const int id = QQmlPrivate::qmlregister(
868 QQmlPrivate::SequentialContainerRegistration, &sequenceRevision);
870 type.qmlTypeIds->append(id);
876 const QQmlPrivate::RegisterSingletonTypeAndRevisions &type,
877 const ElementNames &elementNames)
879 using namespace QQmlPrivate;
881 RegisterSingletonType revisionRegistration = {
888 type.instanceMetaObject,
890 type.extensionObjectCreate,
891 type.extensionMetaObject,
894 const QQmlType::SingletonInstanceInfo::ConstPtr siinfo
895 = singletonInstanceInfo(revisionRegistration);
897 const QTypeRevision added = revisionClassInfo(
898 type.classInfoMetaObject,
"QML.AddedInVersion",
899 QTypeRevision::fromVersion(type.version.majorVersion(), 0));
900 const QTypeRevision removed = revisionClassInfo(
901 type.classInfoMetaObject,
"QML.RemovedInVersion");
902 const QList<QTypeRevision> furtherRevisions = revisionClassInfos(type.classInfoMetaObject,
905 auto revisions = prepareRevisions(type.instanceMetaObject, added) + furtherRevisions;
906 uniqueRevisions(&revisions, type.version, added);
909 for (QTypeRevision revision : std::as_const(revisions)) {
910 if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
913 assignVersions(&revisionRegistration, revision, type.version);
916 if (revisionRegistration.version < added
917 || (removed.isValid() && !(revisionRegistration.version < removed))) {
918 revisionRegistration.typeName =
nullptr;
919 revisionRegistration.qObjectApi =
nullptr;
921 revisionRegistration.typeName = elementNames[0];
922 revisionRegistration.qObjectApi = type.qObjectApi;
925 const int id = finalizeType(
926 QQmlMetaType::registerSingletonType(revisionRegistration, siinfo));
928 type.qmlTypeIds->append(id);
930 if (revisionRegistration.typeName)
931 aliasRegistrar.registerAliases(id);
936
937
938
939int QQmlPrivate::qmlregister(RegistrationType type,
void *data)
942 case AutoParentRegistration:
943 return QQmlMetaType::registerAutoParentFunction(
944 *
reinterpret_cast<RegisterAutoParent *>(data));
945 case QmlUnitCacheHookRegistration:
946 return QQmlMetaType::registerUnitCacheHook(
947 *
reinterpret_cast<RegisterQmlUnitCacheHook *>(data));
948 case TypeAndRevisionsRegistration: {
949 const RegisterTypeAndRevisions &type = *
reinterpret_cast<RegisterTypeAndRevisions *>(data);
950 if (type.structVersion > 1 && type.forceAnonymous) {
951 doRegisterTypeAndRevisions(type, {
nullptr});
953 const ElementNames names = classElementNames(type.classInfoMetaObject);
954 if (names.isEmpty()) {
955 qWarning().nospace() <<
"Missing QML.Element class info for "
956 << type.classInfoMetaObject->className();
958 doRegisterTypeAndRevisions(type, names);
964 case SingletonAndRevisionsRegistration: {
965 const RegisterSingletonTypeAndRevisions &type
966 = *
reinterpret_cast<RegisterSingletonTypeAndRevisions *>(data);
967 const ElementNames names = classElementNames(type.classInfoMetaObject);
968 if (names.isEmpty()) {
969 qWarning().nospace() <<
"Missing QML.Element class info for "
970 << type.classInfoMetaObject->className();
972 doRegisterSingletonAndRevisions(type, names);
976 case SequentialContainerAndRevisionsRegistration: {
977 const RegisterSequentialContainerAndRevisions &type
978 = *
reinterpret_cast<RegisterSequentialContainerAndRevisions *>(data);
979 RegisterSequentialContainer revisionRegistration = {
989 const QTypeRevision added = revisionClassInfo(
990 type.classInfoMetaObject,
"QML.AddedInVersion",
991 QTypeRevision::fromMinorVersion(0));
992 QList<QTypeRevision> revisions = revisionClassInfos(
993 type.classInfoMetaObject,
"QML.ExtraVersion");
994 revisions.append(added);
995 uniqueRevisions(&revisions, type.version, added);
997 for (QTypeRevision revision : std::as_const(revisions)) {
998 if (revision < added)
1000 if (revision.hasMajorVersion() && revision.majorVersion() > type.version.majorVersion())
1003 assignVersions(&revisionRegistration, revision, type.version);
1004 const int id = qmlregister(SequentialContainerRegistration, &revisionRegistration);
1005 if (type.qmlTypeIds)
1006 type.qmlTypeIds->append(id);
1010 case TypeRegistration:
1011 return finalizeType(
1012 QQmlMetaType::registerType(*
reinterpret_cast<RegisterType *>(data)));
1013 case InterfaceRegistration:
1014 return finalizeType(
1015 QQmlMetaType::registerInterface(*
reinterpret_cast<RegisterInterface *>(data)));
1016 case SingletonRegistration:
1017 return finalizeType(QQmlMetaType::registerSingletonType(
1018 *
reinterpret_cast<RegisterSingletonType *>(data),
1019 singletonInstanceInfo(*
reinterpret_cast<RegisterSingletonType *>(data))));
1020 case CompositeRegistration:
1021 return finalizeType(QQmlMetaType::registerCompositeType(
1022 *
reinterpret_cast<RegisterCompositeType *>(data)));
1023 case CompositeSingletonRegistration:
1024 return finalizeType(QQmlMetaType::registerCompositeSingletonType(
1025 *
reinterpret_cast<RegisterCompositeSingletonType *>(data),
1026 singletonInstanceInfo(*
reinterpret_cast<RegisterCompositeSingletonType *>(data))));
1027 case SequentialContainerRegistration:
1028 return finalizeType(QQmlMetaType::registerSequentialContainer(
1029 *
reinterpret_cast<RegisterSequentialContainer *>(data)));
1037void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data)
1040 case AutoParentRegistration:
1041 QQmlMetaType::unregisterAutoParentFunction(
reinterpret_cast<AutoParentFunction>(data));
1043 case QmlUnitCacheHookRegistration:
1044 QQmlMetaType::removeCachedUnitLookupFunction(
1045 reinterpret_cast<QmlUnitCacheLookupFunction>(data));
1047 case SequentialContainerRegistration:
1048 QQmlMetaType::unregisterSequentialContainer(data);
1050 case TypeRegistration:
1051 case InterfaceRegistration:
1052 case SingletonRegistration:
1053 case CompositeRegistration:
1054 case CompositeSingletonRegistration:
1055 QQmlMetaType::unregisterType(data);
1057 case TypeAndRevisionsRegistration:
1058 case SingletonAndRevisionsRegistration:
1059 case SequentialContainerAndRevisionsRegistration:
1069QList<QTypeRevision> QQmlPrivate::revisionClassInfos(
const QMetaObject *metaObject,
1072 QList<QTypeRevision> revisions;
1073 for (
int index = indexOfOwnClassInfo(metaObject, key); index != -1;
1074 index = indexOfOwnClassInfo(metaObject, key, index - 1)) {
1075 revisions.push_back(QTypeRevision::fromEncodedVersion(
1076 QLatin1StringView(metaObject->classInfo(index).value()).toInt()));
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
1114
1115int qmlRegisterTypeNotAvailable(
1116 const char *uri,
int versionMajor,
int versionMinor,
1117 const char *qmlName,
const QString &message)
1120 uri, versionMajor, versionMinor, qmlName, message);
1126 const char *uri,
int versionMajor,
const QMetaObject *classInfoMetaObject,
1127 QList<
int> *qmlTypeIds,
const QMetaObject *extension,
bool)
1131 RegisterTypeAndRevisions type = {
1133 QmlMetaType<T>::self(),
1134 QmlMetaType<T>::list(),
1141 QTypeRevision::fromMajorVersion(versionMajor),
1143 &QQmlTypeNotAvailable::staticMetaObject,
1144 classInfoMetaObject,
1146 attachedPropertiesFunc<T>(),
1147 attachedPropertiesMetaObject<T>(),
1149 StaticCastSelector<T, QQmlParserStatus>::cast(),
1150 StaticCastSelector<T, QQmlPropertyValueSource>::cast(),
1151 StaticCastSelector<T, QQmlPropertyValueInterceptor>::cast(),
1155 qmlCreateCustomParser<T>,
1157 QQmlPrivate::StaticCastSelector<T, QQmlFinalizerHook>::cast(),
1159 QmlMetaType<T>::sequence(),
1162 qmlregister(TypeAndRevisionsRegistration, &type);
1180 QQmlEngine *engine = aotContext->qmlEngine();
1181 return engine ? QQmlEnginePrivate::get(aotContext->qmlEngine())->propertyCapture :
nullptr;
1214static bool markPointer(
const QVariant &element, QV4::MarkStack *markStack)
1216 if (!element.metaType().flags().testFlag(QMetaType::PointerToQObject))
1219 QV4::QObjectWrapper::markWrapper(
1220 *
static_cast<QObject *
const *>(element.constData()), markStack);
1226#define ADD_CASE(Type, id, T)
1227 case QMetaType::Type:
1229 const QMetaType elementMetaType = element.metaType();
1230 switch (elementMetaType.id()) {
1231 case QMetaType::QVariantMap:
1232 for (
const QVariant &variant : *
static_cast<
const QVariantMap *>(element.constData()))
1233 elements->push_back(variant);
1235 case QMetaType::QVariantHash:
1236 for (
const QVariant &variant : *
static_cast<
const QVariantHash *>(element.constData()))
1237 elements->push_back(variant);
1239 case QMetaType::QVariantList:
1240 for (
const QVariant &variant : *
static_cast<
const QVariantList *>(element.constData()))
1241 elements->push_back(variant);
1243 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(ADD_CASE)
1244 QT_FOR_EACH_STATIC_CORE_CLASS(ADD_CASE)
1245 QT_FOR_EACH_STATIC_GUI_CLASS(ADD_CASE)
1246 case QMetaType::QStringList:
1247 case QMetaType::QByteArrayList:
1253 if (elementMetaType == QMetaType::fromType<QJSValue>()
1254 || elementMetaType == QMetaType::fromType<QJSManagedValue>()
1255 || elementMetaType == QMetaType::fromType<QJSPrimitiveValue>()) {
1261 QMetaSequence::Iterable iterable;
1262 if (!QMetaType::convert(
1263 element.metaType(), element.constData(),
1264 QMetaType::fromType<QMetaSequence::Iterable>(), &iterable)) {
1268 switch (iterable.metaContainer().valueMetaType().id()) {
1269 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(ADD_CASE)
1270 QT_FOR_EACH_STATIC_CORE_CLASS(ADD_CASE)
1271 QT_FOR_EACH_STATIC_GUI_CLASS(ADD_CASE)
1272 case QMetaType::QStringList:
1273 case QMetaType::QByteArrayList:
1279 for (
auto it = iterable.constBegin(), end = iterable.constEnd(); it != end; ++it)
1280 elements->push_back(*it);
1323static bool inherits(
const QQmlPropertyCache *descendent,
const QQmlPropertyCache *ancestor)
1325 for (
const QQmlPropertyCache *cache = descendent; cache; cache = cache->parent().data()) {
1326 if (cache == ancestor)
1425 void *
a[] = {
target,
nullptr };
1437 void *
a[] = {
source,
nullptr };
1529template<
typename Op>
1559 void *
args[] = {
nullptr };
1578 const bool isUnsigned = enumType.flags() & QMetaType::IsUnsignedEnumeration;
1579 switch (enumType.sizeOf()) {
1582 ? numberType == QMetaType::fromType<quint8>()
1583 : numberType == QMetaType::fromType<qint8>();
1586 ? numberType == QMetaType::fromType<ushort>()
1587 : numberType == QMetaType::fromType<
short>();
1594 ? (numberType == QMetaType::fromType<
int>()
1595 || numberType == QMetaType::fromType<uint>())
1596 : numberType == QMetaType::fromType<
int>();
1599 ? numberType == QMetaType::fromType<qulonglong>()
1600 : numberType == QMetaType::fromType<qlonglong>();
1609 return !type.isValid()
1610 || type == QMetaType::fromType<QVariant>()
1611 || type == QMetaType::fromType<QJSPrimitiveValue>();
1616 if (source == target)
1619 if ((source.flags() & QMetaType::IsQmlList)
1620 && (target.flags() & QMetaType::IsQmlList)) {
1626 if (target.flags() & QMetaType::PointerToQObject) {
1629 const QMetaObject *targetMetaObject = target.metaObject();
1630 const QMetaObject *sourceMetaObject = source.metaObject();
1631 if (!sourceMetaObject)
1632 sourceMetaObject = QQmlMetaType::metaObjectForType(source).metaObject();
1634 while (sourceMetaObject && sourceMetaObject != targetMetaObject)
1635 sourceMetaObject = sourceMetaObject->superClass();
1637 return sourceMetaObject !=
nullptr;
1640 if (target.flags() & QMetaType::IsEnumeration)
1641 return isEnumUnderlyingType(target, source);
1643 if (source.flags() & QMetaType::IsEnumeration)
1644 return isEnumUnderlyingType(source, target);
1646 if (!source.isValid())
1647 return canHoldVoid(target);
1718template<QV4::Lookup::Call FallbackCall>
1720 const AOTCompiledContext *aotContext, QV4::Lookup *lookup, QObject *object)
1722 QV4::Scope scope(aotContext->engine->handle());
1723 QV4::PropertyKey id = scope.engine->identifierTable->asPropertyKey(
1724 aotContext->compilationUnit->runtimeStrings[lookup->nameIndex]);
1726 Q_ASSERT(id.isString());
1728 QV4::ScopedString name(scope, id.asStringOrSymbol());
1730 Q_ASSERT(!name->equals(scope.engine->id_toString()));
1731 Q_ASSERT(!name->equals(scope.engine->id_destroy()));
1733 QQmlData *ddata = QQmlData::get(object,
true);
1735 if (ddata->isQueuedForDeletion)
1738 const QQmlPropertyData *property;
1739 if (!ddata->propertyCache) {
1740 property = QQmlPropertyCache::property(object, name, aotContext->qmlContext,
nullptr);
1742 property = ddata->propertyCache->property(
1743 name.getPointer(), object, aotContext->qmlContext);
1747 const QMetaObject *metaObject = object->metaObject();
1751 const int coreIndex = metaObject->indexOfProperty(
1752 name->toQStringNoThrow().toUtf8().constData());
1756 const QMetaProperty property = metaObject->property(coreIndex);
1758 lookup->releasePropertyCache();
1760 lookup->qobjectFallbackLookup.metaObject = quintptr(metaObject) + 1;
1761 lookup->qobjectFallbackLookup.metaType = quintptr(property.metaType().iface()) + 1;
1762 lookup->qobjectFallbackLookup.coreIndex = coreIndex;
1763 lookup->qobjectFallbackLookup.notifyIndex =
1764 QMetaObjectPrivate::signalIndex(property.notifySignal());
1766 if constexpr (FallbackCall == QV4::Lookup::Call::ContextGetterScopeObjectPropertyFallback
1767 || FallbackCall == QV4::Lookup::Call::GetterQObjectPropertyFallback) {
1768 lookup->qobjectFallbackLookup.isConstantOrResettable = property.isConstant() ? 1 : 0;
1769 }
else if constexpr (FallbackCall == QV4::Lookup::Call::SetterQObjectPropertyFallback) {
1770 lookup->qobjectFallbackLookup.isConstantOrResettable = property.isResettable() ? 1 : 0;
1775 Q_ASSERT(ddata->propertyCache);
1777 QV4::setupQObjectLookup(lookup, ddata, property);
1783template<QV4::Lookup::Call ObjectCall, QV4::Lookup::Call FallbackCall,
LookupType Type>
1786 QV4::ExecutionEngine *v4 = aotContext->engine->handle();
1787 if (v4->hasException) {
1788 v4->amendException();
1792 QV4::Lookup *lookup = aotContext->compilationUnit->runtimeLookups + index;
1793 switch (initObjectLookup<FallbackCall>(aotContext, lookup, object)) {
1795 lookup->call = ObjectCall;
1799 lookup->call = FallbackCall;
1803 v4->throwTypeError();
1812 QV4::Lookup *lookup, QV4::ExecutableCompilationUnit *compilationUnit,
1813 const QMetaObject *metaObject)
1815 Q_ASSERT(metaObject);
1816 const QByteArray name = compilationUnit->runtimeStrings[lookup->nameIndex]->toQString().toUtf8();
1817 int coreIndex = metaObject->indexOfProperty(name.constData());
1818 QMetaType lookupType = metaObject->property(coreIndex).metaType();
1820 QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(
1821 QMetaObject::ReadProperty, &metaObject, &coreIndex);
1823 lookup->qgadgetLookup.metaObject = quintptr(metaObject) + 1;
1824 lookup->qgadgetLookup.coreIndex = coreIndex;
1825 lookup->qgadgetLookup.metaType = lookupType.iface();
1889#if QT_CONFIG(translation)
1939 if (type == QMetaType::fromType<QVariant>())
1940 return !
static_cast<
const QVariant *>(value)->isValid();
1941 if (type == QMetaType::fromType<QJSValue>())
1942 return static_cast<
const QJSValue *>(value)->isUndefined();
1943 if (type == QMetaType::fromType<QJSPrimitiveValue>()) {
1944 return static_cast<
const QJSPrimitiveValue *>(value)->type()
1945 == QJSPrimitiveValue::Undefined;
2044 QStringLiteral(
"Value is null and could not be converted to an object"));
2070 QStringLiteral(
"A QmlLoggingCatgory was provided without a valid name"));
2138 const QQmlType &type,
const QV4::CompiledData::ParameterType ¶meter)
2140 return parameter.isList() ? type.qListTypeId() : type.typeId();
2191 for (
int i = 0;
i <
argc; ++
i)
2265 const AOTCompiledContext *aotContext, QV4::Lookup *lookup,
const QString &object)
2267 aotContext->engine->handle()->throwTypeError(
2268 QStringLiteral(
"Property '%1' of object %2 is not a function").arg(
2269 aotContext->compilationUnit->runtimeStrings[lookup->nameIndex]->toQString(),
2297 QV4::QObjectMethod *method, QV4::Lookup *lookup,
int relativeMethodIndex)
2299 Q_ASSERT(lookup->qobjectMethodLookup.method.get() == method->d());
2301 const auto *d = method->d();
2302 const int methodCount = d->methodCount;
2304 if (methodCount == 1) {
2313 lookup->qobjectMethodLookup.propertyData = d->methods;
2317 for (
int i = 0, end = d->methodCount; i != end; ++i) {
2318 const QMetaMethod metaMethod = d->methods[i].metaMethod();
2319 if (metaMethod.relativeMethodIndex() != relativeMethodIndex)
2322 lookup->qobjectMethodLookup.propertyData = d->methods + i;
2672template<QV4::Lookup::Call call>
2673static void initTypeWrapperLookup(
2674 const AOTCompiledContext *context, QV4::Lookup *lookup, uint importNamespace)
2676 Q_ASSERT(!context->engine->hasError());
2677 if (importNamespace != AOTCompiledContext::InvalidStringId) {
2678 QV4::Scope scope(context->engine->handle());
2679 QV4::ScopedString import(scope, context->compilationUnit->runtimeStrings[importNamespace]);
2681 QQmlTypeLoader *typeLoader = scope.engine->typeLoader();
2682 Q_ASSERT(typeLoader);
2683 if (
const QQmlImportRef *importRef
2684 = context->qmlContext->imports()->query(import, typeLoader).importNamespace) {
2686 QV4::Scoped<QV4::QQmlTypeWrapper> wrapper(
2687 scope, QV4::QQmlTypeWrapper::create(
2688 scope.engine,
nullptr, context->qmlContext->imports(), importRef));
2691 wrapper = lookup->getter(context->engine->handle(), wrapper);
2694 lookup->releasePropertyCache();
2696 lookup->call = call;
2698 case QV4::Lookup::Call::ContextGetterSingleton:
2699 lookup->qmlContextSingletonLookup.singletonObject.set(scope.engine, wrapper->heapObject());
2701 case QV4::Lookup::Call::ContextGetterType:
2702 lookup->qmlTypeLookup.qmlTypeWrapper.set(scope.engine, wrapper->heapObject());
2709 scope.engine->throwTypeError();
2711 QV4::ExecutionEngine *v4 = context->engine->handle();
2712 lookup->contextGetter(v4,
nullptr);
2713 if (lookup->call != call) {
2715 = QLatin1String(call == QV4::Lookup::Call::ContextGetterSingleton
2716 ?
"%1 was a singleton at compile time, "
2717 "but is not a singleton anymore."
2718 :
"%1 was not a singleton at compile time, "
2719 "but is a singleton now.")
2720 .arg(context->compilationUnit->runtimeStrings[lookup->nameIndex]->toQString());
2721 v4->throwTypeError(error);
3001 QStringLiteral(
"Value is null and could not be converted to an object"));
3055 QV4::Lookup *lookup,
const QMetaObject *metaObject,
void *target,
void *value)
3057 void *args[] = { value,
nullptr };
3058 metaObject->d.static_metacall(
3059 reinterpret_cast<QObject *>(target), QMetaObject::WriteProperty,
3060 lookup->qgadgetLookup.coreIndex, args);
3065 QV4::Lookup *lookup,
const QMetaObject *metaObject,
void *target, QV4::ExecutionEngine *v4)
3067 const QMetaProperty property = metaObject->property(lookup->qgadgetLookup.coreIndex);
3068 if (property.isResettable()) {
3069 void *args[] = {
nullptr };
3070 metaObject->d.static_metacall(
3071 reinterpret_cast<QObject *>(target), QMetaObject::ResetProperty,
3072 lookup->qgadgetLookup.coreIndex, args);
3075 QLatin1String(
"Cannot assign [undefined] to ") +
3076 QLatin1String(property.metaType().name()));
3083 QV4::ExecutionEngine *v4, QV4::Lookup *lookup,
const QMetaObject *metaObject,
3084 void *target,
void *value)
3086 QVariant *variant =
static_cast<QVariant *>(value);
3087 const QMetaType propType = metaObject->property(lookup->qgadgetLookup.coreIndex).metaType();
3088 if (propType == QMetaType::fromType<QVariant>())
3089 return storeValueProperty(lookup, metaObject, target, variant);
3091 if (!variant->isValid())
3092 return resetValueProperty(lookup, metaObject, target, v4);
3094 if (isTypeCompatible(variant->metaType(), propType))
3095 return storeValueProperty(lookup, metaObject, target, variant->data());
3097 QVariant converted(propType);
3098 QV4::Scope scope(v4);
3099 QV4::ScopedValue val(scope, v4->fromVariant(*variant));
3100 if (v4->metaTypeFromJS(val, propType, converted.data())
3101 || QMetaType::convert(
3102 variant->metaType(), variant->constData(), propType, converted.data())) {
3103 return storeValueProperty(lookup, metaObject, target, converted.data());
3107 QLatin1String(
"Cannot assign ") + QLatin1String(variant->metaType().name())
3108 + QLatin1String(
" to ") + QLatin1String(propType.name()));
3140void initValueLookup(
3141 const AOTCompiledContext *aotContext, uint index,
const QMetaObject *metaObject)
3143 QV4::ExecutionEngine *v4 = aotContext->engine->handle();
3144 if (v4->hasException) {
3145 v4->amendException();
3149 QV4::Lookup *lookup = aotContext->compilationUnit->runtimeLookups + index;
3150 initValueLookup(lookup, aotContext->compilationUnit, metaObject);
3151 lookup->call = QV4::Lookup::Call::SetterValueTypeProperty;
3215 Validator(QQmlEngine *engine, QV4::CompiledData::CompilationUnit *cu);
3217 bool validateLookup(
const Lookup &lookup,
const Signature &signature);
3220 bool validatePropertyLookup(
const QMetaObject *mo,
const QString &member,
3221 const PropertySignature &expected)
const;
3222 bool validateEnumKeyLookup(
const QMetaObject *mo,
const QString &member,
3223 const QString &enumName,
const EnumKeySignature &expected)
const;
3224 bool validateMethodLookup(
const QMetaObject *mo,
const QString &member,
3225 const MethodSignature &expected)
const;
3226 bool methodMatchesSignature(
const QMetaMethod &method,
const QString &member,
3227 const MethodSignature &expected)
const;
3229 bool typesMatch(
const QMetaType &actual,
const Type &expected)
const;
3230 const QMetaObject *metaObjectForType(
const Type &type)
const;
3231 QQmlType compositeType(
const Type &type)
const;
3232 const QQmlImportInstance *findImport(
const QString &module, QTypeRevision version)
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 return compositeType(type).typeId().metaObject();
3398QQmlType Validator::compositeType(
const Type &type)
const
3400 const QString icName =
3401 type.isInlineComponent == IsIC::Yes ? type.icNameOrExtensionTypeName : QString();
3403 if (type.module == s_thisCuModule && type.name == s_thisCuType)
3404 return m_compilationUnit->qmlTypeForComponent(icName);
3406 Q_ASSERT(type.module != s_thisCuModule);
3407 Q_ASSERT(type.name != s_thisCuType);
3409 if (type.module.isEmpty() || type.name.isEmpty())
3412 const QQmlImportInstance *import = findImport(type.module, type.version);
3419 if (!import->resolveType(m_loader, type.name,
nullptr, &qmlType) || !qmlType.isComposite())
3425 m_loader->getType(qmlType.sourceUrl(), QQmlTypeLoader::Synchronous)->compilationUnit();
3426 return cu ? cu->qmlTypeForComponent(icName) : QQmlType();
3429const QQmlImportInstance *Validator::findImport(
const QString &module, QTypeRevision version)
const
3438 QList<
const QV4::CompiledData::CompilationUnit *> pending{ m_compilationUnit };
3439 QSet<
const QV4::CompiledData::CompilationUnit *> seen{ m_compilationUnit };
3440 while (!pending.isEmpty()) {
3441 const QV4::CompiledData::CompilationUnit *cu = pending.takeFirst();
3442 Q_ASSERT(cu->typeNameCache);
3443 if (
const QQmlImportInstance *import =
3444 cu->typeNameCache->findImportByModuleUri(module, version)) {
3448 for (
const QV4::ResolvedTypeReference *ref : cu->resolvedTypes) {
3449 const QV4::CompiledData::CompilationUnit *dependency = ref->compilationUnit().data();
3450 if (dependency && !seen.contains(dependency)) {
3451 seen.insert(dependency);
3452 pending.append(dependency);
3460bool validateLookupSignature(QQmlEngine *engine, QV4::CompiledData::CompilationUnit *cu,
3461 const Lookup &lookup,
const Signature &signature)
3463 Validator validator(engine, cu);
3464 return validator.validateLookup(lookup, signature);
3472
3473
3474
3475
3476
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
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
3535
3536
3537
3538
3539
3540
3541
3542
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
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
3709
3710
3711
3712
3713
3714
3715
3716
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
3744
3745
3746
3747
3748
3749
3750
3751
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
3803
3804
3805
3806
3807
3808
3809
3810
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
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
3920
3921
3922
3923
3924
3925
3926
3927
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
3968
3969
3970
3971
3972
3973
3974
3975
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
4064
4065
4066
4067
4068
4069
4070
4071
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
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