Ensure the this object is set correctly to the scope object in binding expressions
authorSimon Hausmann <simon.hausmann@digia.com>
Mon, 4 Nov 2013 01:48:16 +0000 (02:48 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 5 Nov 2013 22:47:27 +0000 (23:47 +0100)
This is a regression from 5.1

Change-Id: I61ad372a02d937c195dad74bd9fcb8fd4410d97a
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/jsruntime/qv4qobjectwrapper.cpp
src/qml/qml/qqmlbinding.cpp
src/qml/qml/qqmlbinding_p.h
src/qml/qml/qqmljavascriptexpression.cpp
src/qml/qml/qqmljavascriptexpression_p.h
src/qml/qml/qqmlvaluetypewrapper.cpp
tests/auto/qml/qqmlecmascript/data/thisObject.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp

index d5aa9f4..4537b6c 100644 (file)
@@ -477,8 +477,6 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
             newBinding = new QQmlBinding(value, object, callingQmlContext, frame.source,
                                          qmlSourceCoordinate(frame.line), qmlSourceCoordinate(frame.column));
             newBinding->setTarget(object, *property, callingQmlContext);
-            newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
-                                         QQmlBinding::RequiresThisObject);
         }
     }
 
index a388178..557267d 100644 (file)
@@ -194,16 +194,6 @@ QQmlBinding::~QQmlBinding()
 {
 }
 
-void QQmlBinding::setEvaluateFlags(EvaluateFlags flags)
-{
-    setRequiresThisObject(flags & RequiresThisObject);
-}
-
-QQmlBinding::EvaluateFlags QQmlBinding::evaluateFlags() const
-{
-    return requiresThisObject()?RequiresThisObject:None;
-}
-
 void QQmlBinding::setNotifyOnValueChanged(bool v)
 {
     QQmlJavaScriptExpression::setNotifyOnValueChanged(v);
index e872482..9dd63a6 100644 (file)
@@ -76,9 +76,6 @@ class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression,
                                          public QQmlAbstractBinding
 {
 public:
-    enum EvaluateFlag { None = 0x00, RequiresThisObject = 0x01 };
-    Q_DECLARE_FLAGS(EvaluateFlags, EvaluateFlag)
-
     QQmlBinding(const QString &, QObject *, QQmlContext *);
     QQmlBinding(const QQmlScriptString &, QObject *, QQmlContext *);
     QQmlBinding(const QString &, QObject *, QQmlContextData *);
@@ -91,9 +88,6 @@ public:
     void setTarget(QObject *, const QQmlPropertyData &, QQmlContextData *);
     QQmlProperty property() const;
 
-    void setEvaluateFlags(EvaluateFlags flags);
-    EvaluateFlags evaluateFlags() const;
-
     void setNotifyOnValueChanged(bool);
 
     // Inherited from  QQmlAbstractExpression
@@ -177,8 +171,6 @@ void QQmlBinding::setEnabledFlag(bool v)
     m_ctxt.setFlag2Value(v);
 }
 
-Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlBinding::EvaluateFlags)
-
 QT_END_NAMESPACE
 
 Q_DECLARE_METATYPE(QQmlBinding*)
index 53b7504..3fd0003 100644 (file)
@@ -156,8 +156,8 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
     QV4::Scope scope(v4);
     QV4::ScopedValue result(scope, QV4::Primitive::undefinedValue());
     QV4::ExecutionContext *ctx = v4->current;
-    callData->thisObject = ep->v8engine()->global();
-    if (scopeObject() && requiresThisObject()) {
+    callData->thisObject = v4->globalObject;
+    if (scopeObject()) {
         QV4::ScopedValue value(scope, QV4::QObjectWrapper::wrap(ctx->engine, scopeObject()));
         if (value->isObject())
             callData->thisObject = value;
index 4435704..7d65f1c 100644 (file)
@@ -117,8 +117,6 @@ public:
     QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::ValueRef function, bool *isUndefined);
     QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::ValueRef function, QV4::CallData *callData, bool *isUndefined);
 
-    inline bool requiresThisObject() const;
-    inline void setRequiresThisObject(bool v);
     inline bool notifyOnValueChanged() const;
 
     void setNotifyOnValueChanged(bool v);
@@ -183,7 +181,6 @@ private:
     QPointerValuePair<VTable, QQmlDelayedError> m_vtable;
 
     // We store some flag bits in the following flag pointers.
-    //    m_scopeObject:flag1 - requiresThisObject
     //    activeGuards:flag1  - notifyOnValueChanged
     //    activeGuards:flag2  - useSharedContext
     QBiPointer<QObject, DeleteWatcher> m_scopeObject;
@@ -215,16 +212,6 @@ bool QQmlJavaScriptExpression::DeleteWatcher::wasDeleted() const
     return *_w == 0;
 }
 
-bool QQmlJavaScriptExpression::requiresThisObject() const
-{
-    return m_scopeObject.flag();
-}
-
-void QQmlJavaScriptExpression::setRequiresThisObject(bool v)
-{
-    m_scopeObject.setFlagValue(v);
-}
-
 bool QQmlJavaScriptExpression::notifyOnValueChanged() const
 {
     return activeGuards.flag();
index 6c9f90c..d6f35f1 100644 (file)
@@ -385,8 +385,6 @@ void QmlValueTypeWrapper::put(Managed *m, const StringRef name, const ValueRef v
             newBinding = new QQmlBinding(value, reference->object, context,
                                          frame.source, qmlSourceCoordinate(frame.line), qmlSourceCoordinate(frame.column));
             newBinding->setTarget(reference->object, cacheData, context);
-            newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
-                                         QQmlBinding::RequiresThisObject);
         }
 
         QQmlAbstractBinding *oldBinding =
diff --git a/tests/auto/qml/qqmlecmascript/data/thisObject.qml b/tests/auto/qml/qqmlecmascript/data/thisObject.qml
new file mode 100644 (file)
index 0000000..c93d030
--- /dev/null
@@ -0,0 +1,10 @@
+import QtQml 2.0
+QtObject {
+    property int value: 1
+    property QtObject subObject: QtObject {
+        property int value: 2
+        property int test: {
+            return this.value;
+        }
+    }
+}
index b1cf8c9..f464114 100644 (file)
@@ -307,6 +307,7 @@ private slots:
     void numberParsing();
     void stringParsing();
     void qtbug_32801();
+    void thisObject();
 
 private:
 //    static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -7311,6 +7312,15 @@ void tst_qqmlecmascript::qtbug_32801()
     QVERIFY(QMetaObject::invokeMethod(obj.data(), "emitTestSignal"));
 }
 
+void tst_qqmlecmascript::thisObject()
+{
+    QQmlComponent component(&engine, testFileUrl("thisObject.qml"));
+    QObject *object = component.create();
+    QVERIFY(object);
+    QCOMPARE(qvariant_cast<QObject*>(object->property("subObject"))->property("test").toInt(), 2);
+    delete object;
+}
+
 QTEST_MAIN(tst_qqmlecmascript)
 
 #include "tst_qqmlecmascript.moc"