aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlproperty.cpp21
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp19
-rw-r--r--tests/auto/qml/qqmlproperty/data/invalidBinding.qml14
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp20
4 files changed, 71 insertions, 3 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 2d459421d9..b798215fa5 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1521,13 +1521,28 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
return true;
const char *valueType = 0;
- if (value.userType() == QVariant::Invalid) valueType = "null";
- else valueType = QMetaType::typeName(value.userType());
+ const char *propertyType = 0;
+
+ if (value.userType() == QMetaType::QObjectStar) {
+ if (QObject *o = *(QObject **)value.constData()) {
+ valueType = o->metaObject()->className();
+
+ const QMetaObject *propertyMetaObject = rawMetaObjectForType(QQmlEnginePrivate::get(engine), type);
+ propertyType = propertyMetaObject->className();
+ }
+ } else if (value.userType() != QVariant::Invalid) {
+ valueType = QMetaType::typeName(value.userType());
+ }
+
+ if (!valueType)
+ valueType = "null";
+ if (!propertyType)
+ propertyType = QMetaType::typeName(type);
expression->delayedError()->error.setDescription(QLatin1String("Unable to assign ") +
QLatin1String(valueType) +
QLatin1String(" to ") +
- QLatin1String(QMetaType::typeName(type)));
+ QLatin1String(propertyType));
return false;
}
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index 5bace305f1..25fbbd4861 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -51,6 +51,7 @@
#include <private/qqmlmetatype_p.h>
#include <private/qqmltrace_p.h>
#include <private/qqmlstringconverters_p.h>
+#include <private/qqmlproperty_p.h>
#include <QtQml/qqmlinfo.h>
#include <QtCore/qnumeric.h>
@@ -1656,6 +1657,24 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
if (data.isUndefined())
THROW_EXCEPTION_STR(instr->store.exceptionId, QLatin1String("Unable to assign undefined value"));
+ if (data.gettype() == QObjectStarType) {
+ if (QObject *dataObject = data.getQObject()) {
+ const QMetaObject *dataMo = dataObject->metaObject();
+
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine);
+ QMetaProperty receiver = output->metaObject()->property(instr->store.index);
+ const QMetaObject *receiverMo = QQmlPropertyPrivate::rawMetaObjectForType(ep, receiver.userType());
+
+ // Verify that these types are compatible
+ if (!QQmlPropertyPrivate::canConvert(dataMo, receiverMo)) {
+ THROW_EXCEPTION_STR(instr->store.exceptionId, QLatin1String("Unable to assign ") +
+ QLatin1String(dataMo->className()) +
+ QLatin1String(" to ") +
+ QLatin1String(receiverMo->className()));
+ }
+ }
+ }
+
int status = -1;
void *argv[] = { data.typeDataPtr(), 0, &status, &storeFlags };
QMetaObject::metacall(output, QMetaObject::WriteProperty,
diff --git a/tests/auto/qml/qqmlproperty/data/invalidBinding.qml b/tests/auto/qml/qqmlproperty/data/invalidBinding.qml
new file mode 100644
index 0000000000..58e83070ee
--- /dev/null
+++ b/tests/auto/qml/qqmlproperty/data/invalidBinding.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Item {
+ property Text text: myText
+
+ property Rectangle rectangle1: myText
+ property Rectangle rectangle2: getMyText()
+
+ function getMyText() { return myText; }
+
+ Text {
+ id: myText
+ }
+}
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 5ef8937dc1..2dde5f003d 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -133,6 +133,7 @@ private slots:
void aliasPropertyBindings();
void noContext();
void assignEmptyVariantMap();
+ void warnOnInvalidBinding();
void copy();
private:
@@ -1708,6 +1709,25 @@ void tst_qqmlproperty::assignEmptyVariantMap()
delete obj;
}
+void tst_qqmlproperty::warnOnInvalidBinding()
+{
+ QUrl testUrl(testFileUrl("invalidBinding.qml"));
+ QString expectedWarning;
+
+ // V4 error message for property-to-property binding
+ expectedWarning = testUrl.toString() + QString::fromLatin1(":6:36: Unable to assign QQuickText to QQuickRectangle");
+ QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData());
+
+ // V8 error message for function-to-property binding
+ expectedWarning = testUrl.toString() + QString::fromLatin1(":7:36: Unable to assign QQuickText to QQuickRectangle");
+ QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData());
+
+ QQmlComponent component(&engine, testUrl);
+ QObject *obj = component.create();
+ QVERIFY(obj);
+ delete obj;
+}
+
void tst_qqmlproperty::initTestCase()
{
QQmlDataTest::initTestCase();