summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2010-10-08 05:06:17 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2010-10-08 05:06:17 (GMT)
commit63e6b999144dfbd4ab230973d7e682361e8fe182 (patch)
tree932e2c1179c9b59b5777553373723cb855776283
parente17a5398bf20b89834d4d6c7f4d9203f192b101f (diff)
downloadQt-63e6b999144dfbd4ab230973d7e682361e8fe182.zip
Qt-63e6b999144dfbd4ab230973d7e682361e8fe182.tar.gz
Qt-63e6b999144dfbd4ab230973d7e682361e8fe182.tar.bz2
Allow aliases to value type properties
Task-number: QTBUG-14254
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp27
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp25
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject_p.h19
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/alias.10.qml8
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/alias.11.qml8
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.errors.txt1
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.qml6
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.errors.txt2
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.qml2
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.4.errors.txt2
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.errors.txt1
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.qml7
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.errors.txt1
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.qml6
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp44
15 files changed, 147 insertions, 12 deletions
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 7a29f24..74bc5bd 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -2565,8 +2565,8 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
QStringList alias = astNodeToStringList(node);
- if (alias.count() != 1 && alias.count() != 2)
- COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id> or <id>.<property>"));
+ if (alias.count() < 1 || alias.count() > 3)
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>"));
if (!compileState.ids.contains(alias.at(0)))
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0)));
@@ -2578,11 +2578,14 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
int propIdx = -1;
int flags = 0;
bool writable = false;
- if (alias.count() == 2) {
+ if (alias.count() == 2 || alias.count() == 3) {
propIdx = idObject->metaObject()->indexOfProperty(alias.at(1).toUtf8().constData());
- if (-1 == propIdx)
+ if (-1 == propIdx) {
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
+ } else if (propIdx > 0xFFFF) {
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Alias property exceeds alias bounds"));
+ }
QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
if (!aliasProperty.isScriptable())
@@ -2590,6 +2593,22 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
writable = aliasProperty.isWritable();
+ if (alias.count() == 3) {
+ QDeclarativeValueType *valueType = enginePrivate->valueTypes[aliasProperty.type()];
+ if (!valueType)
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
+
+ propIdx |= ((unsigned int)aliasProperty.type()) << 24;
+
+ int valueTypeIndex = valueType->metaObject()->indexOfProperty(alias.at(2).toUtf8().constData());
+ if (valueTypeIndex == -1)
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
+ Q_ASSERT(valueTypeIndex <= 0xFF);
+
+ aliasProperty = valueType->metaObject()->property(valueTypeIndex);
+ propIdx |= (valueTypeIndex << 16);
+ }
+
if (aliasProperty.isEnumType())
typeName = "int"; // Avoid introducing a dependency on the aliased metaobject
else
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index 37f08fc..e28062b 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -459,7 +459,7 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
id -= propOffset;
if (id < metaData->propertyCount) {
- int t = (metaData->propertyData() + id)->propertyType;
+ int t = (metaData->propertyData() + id)->propertyType;
bool needActivate = false;
if (t == -1) {
@@ -586,11 +586,26 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
connectAlias(id);
- if (d->propertyIdx == -1) {
+ if (d->isObjectAlias()) {
*reinterpret_cast<QObject **>(a[0]) = target;
return -1;
+ } else if (d->isValueTypeAlias()) {
+ // Value type property
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);
+
+ QDeclarativeValueType *valueType = ep->valueTypes[d->valueType()];
+ Q_ASSERT(valueType);
+
+ valueType->read(target, d->propertyIndex());
+ int rv = QMetaObject::metacall(valueType, c, d->valueTypeIndex(), a);
+
+ if (c == QMetaObject::WriteProperty)
+ valueType->write(target, d->propertyIndex(), 0x00);
+
+ return rv;
+
} else {
- return QMetaObject::metacall(target, c, d->propertyIdx, a);
+ return QMetaObject::metacall(target, c, d->propertyIndex(), a);
}
}
@@ -823,8 +838,8 @@ void QDeclarativeVMEMetaObject::connectAlias(int aliasId)
int sigIdx = methodOffset + aliasId + metaData->propertyCount;
QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx);
- if (d->propertyIdx != -1) {
- QMetaProperty prop = target->metaObject()->property(d->propertyIdx);
+ if (!d->isObjectAlias()) {
+ QMetaProperty prop = target->metaObject()->property(d->propertyIndex());
if (prop.hasNotifySignal())
QDeclarativePropertyPrivate::connect(target, prop.notifySignalIndex(), object, sigIdx);
}
diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h
index 4ccaa73..5134763 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject_p.h
+++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h
@@ -84,6 +84,25 @@ struct QDeclarativeVMEMetaData
int contextIdx;
int propertyIdx;
int flags;
+
+ bool isObjectAlias() const {
+ return propertyIdx == -1;
+ }
+ bool isPropertyAlias() const {
+ return !isObjectAlias() && !(propertyIdx & 0xFF000000);
+ }
+ bool isValueTypeAlias() const {
+ return !isObjectAlias() && (propertyIdx & 0xFF000000);
+ }
+ int propertyIndex() const {
+ return propertyIdx & 0x0000FFFF;
+ }
+ int valueTypeIndex() const {
+ return (propertyIdx & 0x00FF0000) >> 16;
+ }
+ int valueType() const {
+ return ((unsigned int)propertyIdx) >> 24;
+ }
};
struct PropertyData {
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/alias.10.qml b/tests/auto/declarative/qdeclarativelanguage/data/alias.10.qml
new file mode 100644
index 0000000..bf6352e
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/alias.10.qml
@@ -0,0 +1,8 @@
+import Test 1.0
+
+MyTypeObject {
+ id: root
+ property alias valueAlias: root.rectProperty
+
+ rectProperty: "10,11,9x8"
+}
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/alias.11.qml b/tests/auto/declarative/qdeclarativelanguage/data/alias.11.qml
new file mode 100644
index 0000000..fbd50d9
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/alias.11.qml
@@ -0,0 +1,8 @@
+import Test 1.0
+
+MyTypeObject {
+ id: root
+
+ property alias aliasProperty: root.rectProperty.x
+ rectProperty: "19,13,100x120"
+}
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.errors.txt
new file mode 100644
index 0000000..93652a7
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.errors.txt
@@ -0,0 +1 @@
+5:23:Invalid alias location
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.qml b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.qml
new file mode 100644
index 0000000..3ff7b16
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.qml
@@ -0,0 +1,6 @@
+import Test 1.0
+
+MyTypeObject {
+ id: root
+ property alias a: root.rectProperty.blah
+}
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.errors.txt
index 7260be4..fbf1b58 100644
--- a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.errors.txt
+++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.errors.txt
@@ -1 +1 @@
-5:23:Invalid alias reference. An alias reference must be specified as <id> or <id>.<property>
+5:23:Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.qml b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.qml
index cc71753..a363373 100644
--- a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.qml
@@ -2,5 +2,5 @@ import Test 1.0
MyTypeObject {
id: root
- property alias a: root.rectProperty.x
+ property alias a: root.rectProperty.x.y
}
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.4.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.4.errors.txt
index 7260be4..fbf1b58 100644
--- a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.4.errors.txt
+++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.4.errors.txt
@@ -1 +1 @@
-5:23:Invalid alias reference. An alias reference must be specified as <id> or <id>.<property>
+5:23:Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.errors.txt
new file mode 100644
index 0000000..93652a7
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.errors.txt
@@ -0,0 +1 @@
+5:23:Invalid alias location
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.qml b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.qml
new file mode 100644
index 0000000..4faa52d
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.qml
@@ -0,0 +1,7 @@
+import Test 1.0
+
+MyTypeObject {
+ id: root
+ property alias a: root.imaginary.x
+}
+
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.errors.txt
new file mode 100644
index 0000000..93652a7
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.errors.txt
@@ -0,0 +1 @@
+5:23:Invalid alias location
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.qml b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.qml
new file mode 100644
index 0000000..f183912
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.qml
@@ -0,0 +1,6 @@
+import Test 1.0
+
+MyTypeObject {
+ id: root
+ property alias a: root.floatProperty.x
+}
diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
index 2aac27e..6a45957 100644
--- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
+++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
@@ -349,6 +349,9 @@ void tst_qdeclarativelanguage::errors_data()
QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false;
QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false;
QTest::newRow("invalidAlias.7") << "invalidAlias.7.qml" << "invalidAlias.7.errors.txt" << false;
+ QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false;
+ QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false;
+ QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false;
QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false;
QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false;
@@ -1064,6 +1067,47 @@ void tst_qdeclarativelanguage::aliasProperties()
delete object;
}
+
+ // Valuetype alias
+ // Simple "int" alias
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("alias.10.qml"));
+ VERIFY_ERRORS(0);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ // Read through alias
+ QCOMPARE(object->property("valueAlias").toRect(), QRect(10, 11, 9, 8));
+ object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100)));
+ QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100));
+
+ // Write throught alias
+ object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9)));
+ QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9));
+ QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9));
+
+ delete object;
+ }
+
+ // Valuetype sub-alias
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("alias.11.qml"));
+ VERIFY_ERRORS(0);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ // Read through alias
+ QCOMPARE(object->property("aliasProperty").toInt(), 19);
+ object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111)));
+ QCOMPARE(object->property("aliasProperty").toInt(), 33);
+
+ // Write throught alias
+ object->setProperty("aliasProperty", QVariant(4));
+ QCOMPARE(object->property("aliasProperty").toInt(), 4);
+ QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111));
+
+ delete object;
+ }
}
// QTBUG-13374 Test that alias properties and signals can coexist