summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qmlcontextscriptclass.cpp4
-rw-r--r--src/declarative/qml/qmlobjectscriptclass.cpp21
-rw-r--r--src/declarative/qml/qmlobjectscriptclass_p.h9
-rw-r--r--tests/auto/declarative/qmlecmascript/data/scriptErrors.qml1
-rw-r--r--tests/auto/declarative/qmlecmascript/testtypes.h1
-rw-r--r--tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp4
6 files changed, 35 insertions, 5 deletions
diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp
index 5635ceb..54a5ca3 100644
--- a/src/declarative/qml/qmlcontextscriptclass.cpp
+++ b/src/declarative/qml/qmlcontextscriptclass.cpp
@@ -173,7 +173,7 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje
if (scopeObject) {
QScriptClass::QueryFlags rv =
- ep->objectClass->queryProperty(scopeObject, name, flags, bindContext);
+ ep->objectClass->queryProperty(scopeObject, name, flags, bindContext, QmlObjectScriptClass::ImplicitObject);
if (rv) {
lastScopeObject = scopeObject;
lastContext = bindContext;
@@ -183,7 +183,7 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje
for (int ii = cp->defaultObjects.count() - 1; ii >= 0; --ii) {
QScriptClass::QueryFlags rv =
- ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext);
+ ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext, QmlObjectScriptClass::ImplicitObject);
if (rv) {
lastDefaultObject = ii;
diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp
index d7ab631..3d0581d 100644
--- a/src/declarative/qml/qmlobjectscriptclass.cpp
+++ b/src/declarative/qml/qmlobjectscriptclass.cpp
@@ -123,7 +123,8 @@ QmlObjectScriptClass::queryProperty(Object *object, const Identifier &name,
QScriptClass::QueryFlags
QmlObjectScriptClass::queryProperty(QObject *obj, const Identifier &name,
- QScriptClass::QueryFlags flags, QmlContext *evalContext)
+ QScriptClass::QueryFlags flags, QmlContext *evalContext,
+ QueryHints hints)
{
Q_UNUSED(flags);
lastData = 0;
@@ -179,6 +180,12 @@ QmlObjectScriptClass::queryProperty(QObject *obj, const Identifier &name,
}
}
+ if (!(hints & ImplicitObject)) {
+ local.coreIndex = -1;
+ lastData = &local;
+ return QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess;
+ }
+
return 0;
}
@@ -194,6 +201,9 @@ QScriptValue QmlObjectScriptClass::property(QObject *obj, const Identifier &name
else if (name == m_toStringId.identifier)
return m_toString;
+ if (lastData && !lastData->isValid())
+ return QmlEnginePrivate::getScriptEngine(engine)->undefinedValue();
+
Q_ASSERT(obj);
QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
@@ -263,11 +273,20 @@ void QmlObjectScriptClass::setProperty(QObject *obj,
Q_ASSERT(obj);
Q_ASSERT(lastData);
+ if (!lastData->isValid()) {
+ QString error = QLatin1String("Cannot assign to non-existant property \"") +
+ toString(name) + QLatin1Char('\"');
+ if (context())
+ context()->throwError(error);
+ return;
+ }
+
if (!(lastData->flags & QmlPropertyCache::Data::IsWritable)) {
QString error = QLatin1String("Cannot assign to read-only property \"") +
toString(name) + QLatin1Char('\"');
if (context())
context()->throwError(error);
+ return;
}
QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine);
diff --git a/src/declarative/qml/qmlobjectscriptclass_p.h b/src/declarative/qml/qmlobjectscriptclass_p.h
index d8ef1d2..20c68ce 100644
--- a/src/declarative/qml/qmlobjectscriptclass_p.h
+++ b/src/declarative/qml/qmlobjectscriptclass_p.h
@@ -76,11 +76,16 @@ public:
QObject *toQObject(const QScriptValue &) const;
int objectType(const QScriptValue &) const;
- enum QueryMode { IncludeAttachedProperties, SkipAttachedProperties };
+ enum QueryHint {
+ ImplicitObject = 0x01,
+ SkipAttachedProperties = 0x02
+ };
+ Q_DECLARE_FLAGS(QueryHints, QueryHint)
QScriptClass::QueryFlags queryProperty(QObject *, const Identifier &,
QScriptClass::QueryFlags flags,
- QmlContext *evalContext);
+ QmlContext *evalContext,
+ QueryHints hints = 0);
QScriptValue property(QObject *, const Identifier &);
void setProperty(QObject *, const Identifier &name, const QScriptValue &,
QmlContext *evalContext = 0);
diff --git a/tests/auto/declarative/qmlecmascript/data/scriptErrors.qml b/tests/auto/declarative/qmlecmascript/data/scriptErrors.qml
index 5c8b1f8..c2edb41 100644
--- a/tests/auto/declarative/qmlecmascript/data/scriptErrors.qml
+++ b/tests/auto/declarative/qmlecmascript/data/scriptErrors.qml
@@ -12,5 +12,6 @@ MyQmlObject {
onBasicSignal: { console.log(a.value); }
id: myObj
onAnotherBasicSignal: myObj.trueProperty = false;
+ onThirdBasicSignal: myObj.fakeProperty = "";
}
diff --git a/tests/auto/declarative/qmlecmascript/testtypes.h b/tests/auto/declarative/qmlecmascript/testtypes.h
index d7f7d31..ff20487 100644
--- a/tests/auto/declarative/qmlecmascript/testtypes.h
+++ b/tests/auto/declarative/qmlecmascript/testtypes.h
@@ -118,6 +118,7 @@ signals:
void stringChanged();
void objectChanged();
void anotherBasicSignal();
+ void thirdBasicSignal();
public slots:
void deleteMe() { delete this; }
diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp
index 30ecc51..749f803 100644
--- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp
+++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp
@@ -831,6 +831,7 @@ void tst_qmlecmascript::scriptErrors()
QString warning5 = url + ":10: TypeError: Result of expression 'a' [undefined] is not an object.";
QString warning6 = url + ":9: Unable to assign [undefined] to int";
QString warning7 = url + ":14: Error: Cannot assign to read-only property \"trueProperty\"";
+ QString warning8 = url + ":15: Error: Cannot assign to non-existant property \"fakeProperty\"";
QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData());
QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData());
@@ -845,6 +846,9 @@ void tst_qmlecmascript::scriptErrors()
QTest::ignoreMessage(QtWarningMsg, warning7.toLatin1().constData());
emit object->anotherBasicSignal();
+
+ QTest::ignoreMessage(QtWarningMsg, warning8.toLatin1().constData());
+ emit object->thirdBasicSignal();
}
/*