Ensure the this object is set correctly to the scope object in binding expressions

This is a regression from 5.1

Change-Id: I61ad372a02d937c195dad74bd9fcb8fd4410d97a
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Simon Hausmann 2013-11-04 02:48:16 +01:00 committed by The Qt Project
parent 22b83ec28a
commit 3a61da32e4
8 changed files with 22 additions and 37 deletions

View 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);
}
}

View 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);

View 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*)

View 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;

View 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();

View 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 =

View File

@ -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;
}
}
}

View 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"