Remove warning produced by 'parent' reference.
authorMatthew Vogt <matthew.vogt@nokia.com>
Thu, 23 Feb 2012 04:55:16 +0000 (14:55 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 23 Feb 2012 06:02:04 +0000 (07:02 +0100)
When Qt.createQmlObject is invoked from QML, any contained references
to parent produce a warning from V8.  To prevent this, move the
assignment of the parent object to before the initial execution of the
bindings.

Task-number: QTBUG-24464
Change-Id: Ib330822f1ca46ec5a6af648a56197da09669c3f2
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
tests/auto/declarative/qdeclarativecomponent/data/createParentReference.qml [new file with mode: 0644]
tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp

index 12f06e6..d338508 100644 (file)
@@ -1096,8 +1096,17 @@ v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args)
         V8THROW_ERROR("Qt.createQmlObject(): Component is not ready");
 
     QObject *obj = component.beginCreate(effectiveContext);
-    if (obj)
+    if (obj) {
         QDeclarativeData::get(obj, true)->setImplicitDestructible();
+
+        obj->setParent(parentArg);
+
+        QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
+        for (int ii = 0; ii < functions.count(); ++ii) {
+            if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg))
+                break;
+        }
+    }
     component.completeCreate();
 
     if (component.isError()) {
@@ -1107,14 +1116,6 @@ v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args)
 
     Q_ASSERT(obj);
 
-    obj->setParent(parentArg);
-
-    QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
-    for (int ii = 0; ii < functions.count(); ++ii) {
-        if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg))
-            break;
-    }
-
     return v8engine->newQObject(obj);
 }
 
diff --git a/tests/auto/declarative/qdeclarativecomponent/data/createParentReference.qml b/tests/auto/declarative/qdeclarativecomponent/data/createParentReference.qml
new file mode 100644 (file)
index 0000000..daa5d3c
--- /dev/null
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+
+Item {
+    id: root
+    width: 100
+    height: 100
+
+    function createChild() {
+        Qt.createQmlObject("import QtQuick 2.0;" +
+                           "Item { width: parent.width; }", root);
+    }
+}
index c529649..993c706 100644 (file)
@@ -71,6 +71,7 @@ private slots:
     void qmlCreateObject();
     void qmlCreateObjectWithProperties();
     void qmlIncubateObject();
+    void qmlCreateParentReference();
 
 private:
     QDeclarativeEngine engine;
@@ -181,6 +182,37 @@ void tst_qdeclarativecomponent::qmlCreateObjectWithProperties()
     delete testBindingThisObj;
 }
 
+static QStringList warnings;
+static void msgHandler(QtMsgType, const char *warning)
+{
+    warnings << QString::fromUtf8(warning);
+}
+
+void tst_qdeclarativecomponent::qmlCreateParentReference()
+{
+    QDeclarativeEngine engine;
+
+    QCOMPARE(engine.outputWarningsToStandardError(), true);
+
+    warnings.clear();
+    QtMsgHandler old = qInstallMsgHandler(msgHandler);
+
+    QDeclarativeComponent component(&engine, testFileUrl("createParentReference.qml"));
+    QVERIFY2(component.errorString().isEmpty(), component.errorString().toUtf8());
+    QObject *object = component.create();
+    QVERIFY(object != 0);
+
+    QVERIFY(QMetaObject::invokeMethod(object, "createChild"));
+    delete object;
+
+    qInstallMsgHandler(old);
+
+    engine.setOutputWarningsToStandardError(false);
+    QCOMPARE(engine.outputWarningsToStandardError(), false);
+
+    QCOMPARE(warnings.count(), 0);
+}
+
 QTEST_MAIN(tst_qdeclarativecomponent)
 
 #include "tst_qdeclarativecomponent.moc"