diff options
-rw-r--r-- | src/qml/qml/qqmlcontextwrapper.cpp | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 11 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 2 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/data/SubObject.qml | 8 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/data/contextObjectOnLazyBindings.qml | 10 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 13 |
6 files changed, 40 insertions, 5 deletions
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index 07ef86e16f..54bf986b8e 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -387,6 +387,7 @@ void QmlContextWrapper::registerQmlDependencies(ExecutionEngine *engine, const C capture->captureProperty(&qmlContext->idValues[*idObjectDependency].bindings); } + Q_ASSERT(qmlContext->contextObject); const quint32 *contextPropertyDependency = compiledFunction->qmlContextPropertiesDependencyTable(); const int contextPropertyDependencyCount = compiledFunction->nDependingContextProperties; for (int i = 0; i < contextPropertyDependencyCount; ++i) { diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index d0852bbef2..0825b8ec53 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -213,7 +213,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI context->importedScripts = sharedState->creationContext->importedScripts; } - QObject *instance = createInstance(objectToCreate, parent); + QObject *instance = createInstance(objectToCreate, parent, /*isContextObject*/true); if (instance) { QQmlData *ddata = QQmlData::get(instance); Q_ASSERT(ddata); @@ -221,8 +221,6 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI ddata->compiledData->release(); ddata->compiledData = compiledData; ddata->compiledData->addref(); - - context->contextObject = instance; } Q_QML_VME_PROFILE(sharedState->profiler, stop()); @@ -1014,7 +1012,7 @@ void QQmlObjectCreator::recordError(const QV4::CompiledData::Location &location, errors << error; } -QObject *QQmlObjectCreator::createInstance(int index, QObject *parent) +QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject) { ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine)); @@ -1111,6 +1109,11 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent) if (idEntry != objectIndexToId.constEnd()) context->setIdProperty(idEntry.value(), instance); + // Register the context object in the context early on in order for pending binding + // initialization to find it available. + if (isContextObject) + context->contextObject = instance; + QBitArray bindingsToSkip; if (customParser) { QHash<int, QQmlCompiledData::CustomParserData>::ConstIterator entry = compiledData->customParserData.find(index); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 9fd52a9f48..379a3b2970 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -96,7 +96,7 @@ private: void init(QQmlContextData *parentContext); - QObject *createInstance(int index, QObject *parent = 0); + QObject *createInstance(int index, QObject *parent = 0, bool isContextObject = false); bool populateInstance(int index, QObject *instance, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty, diff --git a/tests/auto/qml/qqmlecmascript/data/SubObject.qml b/tests/auto/qml/qqmlecmascript/data/SubObject.qml new file mode 100644 index 0000000000..4658edd1db --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/SubObject.qml @@ -0,0 +1,8 @@ +import QtQml 2.0 +QtObject { + property int testValue: -1 + property int subValue; + onSubValueChanged: { + testValue = this.someExpression + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/contextObjectOnLazyBindings.qml b/tests/auto/qml/qqmlecmascript/data/contextObjectOnLazyBindings.qml new file mode 100644 index 0000000000..33b21c74a8 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/contextObjectOnLazyBindings.qml @@ -0,0 +1,10 @@ +import QtQml 2.0 +QtObject { + property SubObject subObject: SubObject { + subValue: 20; + property int someExpression: { + return someValue; + } + } + property int someValue: 42 +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index b6c564a6ce..085bf24430 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -320,6 +320,7 @@ private slots: void singletonWithEnum(); void lazyBindingEvaluation(); void varPropertyAccessOnObjectWithInvalidContext(); + void contextObjectOnLazyBindings(); private: // static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter); @@ -7579,6 +7580,18 @@ void tst_qqmlecmascript::varPropertyAccessOnObjectWithInvalidContext() QVERIFY(obj->property("success") == true); } +void tst_qqmlecmascript::contextObjectOnLazyBindings() +{ + QQmlComponent component(&engine, testFileUrl("contextObjectOnLazyBindings.qml")); + QScopedPointer<QObject> obj(component.create()); + if (obj.isNull()) + qDebug() << component.errors().first().toString(); + QVERIFY(!obj.isNull()); + QObject *subObject = qvariant_cast<QObject*>(obj->property("subObject")); + QVERIFY(subObject); + QCOMPARE(subObject->property("testValue").toInt(), int(42)); +} + QTEST_MAIN(tst_qqmlecmascript) #include "tst_qqmlecmascript.moc" |