From 92b1f9981d225ecee28da1f0a88fb3046000cb5e Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Mon, 27 Feb 2012 10:51:57 +1000 Subject: [PATCH] Allow function assignment to cause binding for non-var props This patch maintains the old function-assignment behaviour for non-var properties, and will be reverted soon. Change-Id: I523e464501106616c51ff7478f7eb7171c1ca350 Reviewed-by: Matthew Vogt --- src/qml/qml/v8/qv8qobjectwrapper.cpp | 29 +++++++++++++++++--- .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 6 +++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 59b58ca..4be93d1 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -582,11 +582,32 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert if (value->IsFunction()) { if (value->ToObject()->GetHiddenValue(engine->bindingFlagKey()).IsEmpty()) { if (!property->isVMEProperty()) { + // XXX TODO: uncomment the following lines // assigning a JS function to a non-var-property is not allowed. - QString error = QLatin1String("Cannot assign JavaScript function to ") + - QLatin1String(QMetaType::typeName(property->propType)); - v8::ThrowException(v8::Exception::Error(engine->toString(error))); - return; + //QString error = QLatin1String("Cannot assign JavaScript function to ") + + // QLatin1String(QMetaType::typeName(property->propType)); + //v8::ThrowException(v8::Exception::Error(engine->toString(error))); + //return; + // XXX TODO: remove the following transition behaviour + // Temporarily allow assignment of functions to non-var properties + // to mean binding assignment (as per old behaviour). + QQmlContextData *context = engine->callingContext(); + v8::Handle function = v8::Handle::Cast(value); + + v8::Local trace = + v8::StackTrace::CurrentStackTrace(1, (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber | + v8::StackTrace::kScriptName)); + v8::Local frame = trace->GetFrame(0); + int lineNumber = frame->GetLineNumber(); + int columNumber = frame->GetColumn(); + QString url = engine->toString(frame->GetScriptName()); + + newBinding = new QQmlBinding(&function, object, context); + newBinding->setSourceLocation(url, lineNumber, columNumber); + newBinding->setTarget(object, *property, context); + newBinding->setEvaluateFlags(newBinding->evaluateFlags() | + QQmlBinding::RequiresThisObject); + qWarning("WARNING: function assignment is DEPRECATED and will be removed! Wrap RHS in Qt.binding(): %s:%d", qPrintable(engine->toString(frame->GetScriptName())), frame->GetLineNumber()); } } else { // binding assignment. diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 9c8d1e7..4540639 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -5109,13 +5109,15 @@ void tst_qqmlecmascript::functionAssignment_afterBinding() QQmlComponent component(&engine, testFileUrl("functionAssignment.3.qml")); QString url = component.url().toString(); - QString w1 = url + ":16: Error: Cannot assign JavaScript function to int"; + //QString w1 = url + ":16: Error: Cannot assign JavaScript function to int"; // for now, function assignment = binding assignment + QString w1 = QLatin1String("WARNING: function assignment is DEPRECATED and will be removed! Wrap RHS in Qt.binding(): ") + url + QLatin1String(":16"); QTest::ignoreMessage(QtWarningMsg, w1.toLatin1().constData()); QObject *o = component.create(); QVERIFY(o != 0); QCOMPARE(o->property("t1"), QVariant::fromValue(4)); // should have bound - QCOMPARE(o->property("t2"), QVariant::fromValue(2)); // should not have changed + //QCOMPARE(o->property("t2"), QVariant::fromValue(2)); // should not have changed + QCOMPARE(o->property("t2"), QVariant::fromValue(4)); // for now, function assignment = binding assignment delete o; } -- 1.7.2.5