summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-04-15 01:48:06 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2011-04-15 01:48:06 (GMT)
commitb4b85257ccff6ba21bcbcbd46a9f7f09884abe79 (patch)
tree394547f947fcc2b1f1e9cc75bb779509d08bd356
parentead56475cc6ecd7a6e7e17d63f0e22cf930bcae4 (diff)
downloadQt-b4b85257ccff6ba21bcbcbd46a9f7f09884abe79.zip
Qt-b4b85257ccff6ba21bcbcbd46a9f7f09884abe79.tar.gz
Qt-b4b85257ccff6ba21bcbcbd46a9f7f09884abe79.tar.bz2
Resolve unqualified attached properties correctly
When resolving unqualified attached properties, we should use the scope object, not the context object. Otherwise they will always resolve to the root object of the context, regardless of where they are written. In this example, QtObject { id: root QtObject { id: me property int a: AttachedObject.x } } the attached object should be loaded on the "me" object, not the "root" object. Change-Id: I386f886f62df7b8020c3ff703cdfc891d5739713 Reviewed-by: Martin Jones
-rw-r--r--src/declarative/qml/qdeclarativecontextscriptclass.cpp16
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.2.qml22
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.h5
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp10
4 files changed, 43 insertions, 10 deletions
diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp
index bb4ece4..3abd787 100644
--- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp
@@ -227,6 +227,7 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContextData *bindConte
if (data) {
lastData = data;
lastContext = bindContext;
+ lastScopeObject = scopeObject;
return QScriptClass::HandlesReadAccess;
}
}
@@ -268,17 +269,12 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name)
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
- if (lastScopeObject) {
-
- return ep->objectClass->property(lastScopeObject, name);
-
- } else if (lastData) {
+ if (lastData) {
if (lastData->type) {
- return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->type));
+ return Value(scriptEngine, ep->typeNameClass->newObject(lastScopeObject, lastData->type));
} else if (lastData->typeNamespace) {
- return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject,
- lastData->typeNamespace));
+ return Value(scriptEngine, ep->typeNameClass->newObject(lastScopeObject, lastData->typeNamespace));
} else {
int index = lastData->importedScriptIndex;
if (index < bindContext->importedScripts.count()) {
@@ -288,6 +284,10 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name)
}
}
+ } else if (lastScopeObject) {
+
+ return ep->objectClass->property(lastScopeObject, name);
+
} else if (lastPropertyIndex != -1) {
QScriptValue rv;
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.2.qml
new file mode 100644
index 0000000..a7184c9
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.2.qml
@@ -0,0 +1,22 @@
+import Qt.test 1.0
+import Qt.test 1.0 as Namespace
+
+MyQmlObject {
+ property alias a: me.a
+ property alias b: me.a
+ property alias c: me.a
+ property alias d: me.a
+
+ property MyQmlObject obj
+ obj: MyQmlObject {
+ MyQmlObject.value2: 13
+
+ id: me
+ property int a: MyQmlObject.value2 * 2
+ property int b: Namespace.MyQmlObject.value2 * 2
+ property int c: me.Namespace.MyQmlObject.value * 2
+ property int d: me.Namespace.MyQmlObject.value * 2
+ }
+}
+
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
index 94cec3f..ad38d27 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
@@ -60,17 +60,18 @@ class MyQmlAttachedObject : public QObject
{
Q_OBJECT
Q_PROPERTY(int value READ value CONSTANT)
- Q_PROPERTY(int value2 READ value2 WRITE setValue2)
+ Q_PROPERTY(int value2 READ value2 WRITE setValue2 NOTIFY value2Changed)
public:
MyQmlAttachedObject(QObject *parent) : QObject(parent), m_value2(0) {}
int value() const { return 19; }
int value2() const { return m_value2; }
- void setValue2(int v) { m_value2 = v; }
+ void setValue2(int v) { if (m_value2 == v) return; m_value2 = v; emit value2Changed(); }
void emitMySignal() { emit mySignal(); }
signals:
+ void value2Changed();
void mySignal();
private:
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 7876671..1ec12fe 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -650,6 +650,16 @@ void tst_qdeclarativeecmascript::attachedProperties()
}
{
+ QDeclarativeComponent component(&engine, TEST_FILE("attachedProperty.2.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("a").toInt(), 26);
+ QCOMPARE(object->property("b").toInt(), 26);
+ QCOMPARE(object->property("c").toInt(), 26);
+ QCOMPARE(object->property("d").toInt(), 26);
+ }
+
+ {
QDeclarativeComponent component(&engine, TEST_FILE("writeAttachedProperty.qml"));
QObject *object = component.create();
QVERIFY(object != 0);