diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index 44e05fbfcc..ced169407a 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -136,7 +136,6 @@ Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit, JSTypedFunction *synthesized = new JSTypedFunction; - QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine->qmlEngine()); auto findQmlType = [&](const CompiledData::ParameterType ¶m) { const quint32 type = param.typeNameIndexOrCommonType(); if (param.indexIsCommonType()) { @@ -158,7 +157,7 @@ Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit, : QQmlType(); } - return enginePrivate->typeLoader.getType(qmltype.sourceUrl())->compilationUnit()->qmlType; + return qmltype; }; for (quint16 i = 0; i < nFormals; ++i) diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index d96a4d7d97..88e559f54f 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -1962,14 +1962,8 @@ bool AOTCompiledContext::loadTypeLookup(uint index, void *target) const const QV4::Heap::QQmlTypeWrapper *typeWrapper = static_cast( l->qmlTypeLookup.qmlTypeWrapper); - QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine()); QMetaType metaType = typeWrapper->type().typeId(); - if (!metaType.isValid()) { - metaType = ep->typeLoader.getType(typeWrapper->type().sourceUrl()) - ->compilationUnit()->qmlType.typeId(); - } - *static_cast(target) = QQmlMetaType::metaObjectForType(metaType).metaObject(); return true; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index abd07611fb..10b69cf850 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -673,6 +673,8 @@ QQmlType QQmlMetaType::findCompositeType( } if (urlExists) { + if (compilationUnit.isNull()) + return QQmlType(*found); const auto composite = data->compositeTypes.constFind(found.value()->typeId.iface()); if (composite == data->compositeTypes.constEnd() || composite.value() == compilationUnit) return QQmlType(*found); @@ -1893,8 +1895,11 @@ void QQmlMetaType::registerInternalCompositeType( auto doInsert = [&data, &compilationUnit](const QtPrivate::QMetaTypeInterface *iface) { Q_ASSERT(iface); - const auto it = data->compositeTypes.constFind(iface); - Q_ASSERT(it == data->compositeTypes.constEnd() || *it == compilationUnit); + Q_ASSERT(compilationUnit); + + // We can't assert on anything else here. We may get a completely new type as exposed + // by the qmldiskcache test that changes a QML file in place during the execution + // of the test. data->compositeTypes.insert(iface, compilationUnit); }; diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 4d64ce6146..05e669a856 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -683,14 +683,9 @@ inline QQmlError QQmlPropertyCacheCreator::createMetaObject( compositeType = objectContainer->qmlTypeForComponent(icName); Q_ASSERT(compositeType.isValid()); } else if (selfReference) { - compositeType = objectContainer->qmlTypeForComponent(); + compositeType = objectContainer->qmlTypeForComponent(); } else { - QQmlRefPointer tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl()); - Q_ASSERT(tdata); - Q_ASSERT(tdata->isComplete()); - - auto compilationUnit = tdata->compilationUnit(); - compositeType = compilationUnit->qmlTypeForComponent(); + compositeType = qmltype; } if (p->isList()) { @@ -766,15 +761,7 @@ inline QMetaType QQmlPropertyCacheCreator::metaTypeForParameter return param.isList() ? qmlType.qListTypeId() : qmlType.typeId(); } - QQmlRefPointer tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl()); - Q_ASSERT(tdata); - Q_ASSERT(tdata->isComplete()); - - auto compilationUnit = tdata->compilationUnit(); - - return param.isList() - ? compilationUnit->qmlType.qListTypeId() - : compilationUnit->qmlType.typeId(); + return param.isList() ? qmltype.qListTypeId() : qmltype.typeId(); } template diff --git a/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle1.qml b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle1.qml new file mode 100644 index 0000000000..6186faa00b --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle1.qml @@ -0,0 +1,15 @@ +import QtQml + +QtObject { + id: self + property QtObject b + property Component c + function a() : TypeAnnotationCycle2 { return c.createObject() as TypeAnnotationCycle2 } + + Component.onCompleted: { + c = Qt.createComponent("TypeAnnotationCycle2.qml"); + let v = a(); + v.addTypeAnnotationCycle1(self as TypeAnnotationCycle1); + b = v.b; + } +} diff --git a/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle2.qml b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle2.qml new file mode 100644 index 0000000000..9e3ffa86d2 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle2.qml @@ -0,0 +1,6 @@ +import QtQml + +QtObject { + property QtObject b + function addTypeAnnotationCycle1(c: TypeAnnotationCycle1) { b = c; } +} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index acbb21f2d6..cfe098ff37 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -432,6 +432,7 @@ private slots: void callMethodOfAttachedDerived(); void multiVersionSingletons(); + void typeAnnotationCycle(); private: QQmlEngine engine; @@ -8285,6 +8286,16 @@ void tst_qqmllanguage::multiVersionSingletons() } } +void tst_qqmllanguage::typeAnnotationCycle() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("TypeAnnotationCycle1.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer o(c.create()); + QVERIFY(!o.isNull()); + QCOMPARE(o->property("b").value(), o.data()); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc"