diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-05-25 04:31:40 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-05-25 04:31:40 (GMT) |
commit | 2b3e7706f4459569520c77b9fb3ff2bc006e60f1 (patch) | |
tree | 44e99c4de3bd9f742e524cc81d91b8e8c67f7691 | |
parent | 527d7d17d4c4b3ff44c6a0d7eb7f2d024549aac7 (diff) | |
download | Qt-2b3e7706f4459569520c77b9fb3ff2bc006e60f1.zip Qt-2b3e7706f4459569520c77b9fb3ff2bc006e60f1.tar.gz Qt-2b3e7706f4459569520c77b9fb3ff2bc006e60f1.tar.bz2 |
Reading/writing a non-existent property throws an exception
QTBUG-10659
8 files changed, 28 insertions, 34 deletions
diff --git a/src/declarative/qml/qdeclarativeglobalscriptclass.cpp b/src/declarative/qml/qdeclarativeglobalscriptclass.cpp index 6e107fb..35cb2b4 100644 --- a/src/declarative/qml/qdeclarativeglobalscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeglobalscriptclass.cpp @@ -98,7 +98,9 @@ QDeclarativeGlobalScriptClass::property(const QScriptValue &object, Q_UNUSED(object); Q_UNUSED(name); Q_UNUSED(id); - return engine()->undefinedValue(); + QString error = QLatin1String("Cannot access non-existent property \"") + + name.toString() + QLatin1Char('\"'); + return engine()->currentContext()->throwError(error); } void QDeclarativeGlobalScriptClass::setProperty(QScriptValue &object, @@ -113,24 +115,5 @@ void QDeclarativeGlobalScriptClass::setProperty(QScriptValue &object, engine()->currentContext()->throwError(error); } -/* This method is for the use of tst_qdeclarativeecmascript::callQtInvokables() only */ -void QDeclarativeGlobalScriptClass::explicitSetProperty(const QString &name, const QScriptValue &value) -{ - QScriptValue globalObject = engine()->globalObject(); - - QScriptValue v = engine()->newObject(); - - QScriptValueIterator iter(v); - while (iter.hasNext()) { - iter.next(); - v.setProperty(iter.scriptName(), iter.value()); - } - - v.setProperty(name, value); - v.setScriptClass(this); - - engine()->setGlobalObject(v); -} - QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeglobalscriptclass_p.h b/src/declarative/qml/qdeclarativeglobalscriptclass_p.h index 7690edd..3fe766f 100644 --- a/src/declarative/qml/qdeclarativeglobalscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeglobalscriptclass_p.h @@ -73,8 +73,6 @@ public: virtual void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value); - void explicitSetProperty(const QString &, const QScriptValue &); - const QScriptValue &globalObject() const { return m_globalObject; } const QSet<QString> &illegalNames() const { return m_illegalNames; } diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index aca01b2..be2be8b 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -93,6 +93,7 @@ QDeclarativeObjectScriptClass::QDeclarativeObjectScriptClass(QDeclarativeEngine m_destroyId = createPersistentIdentifier(QLatin1String("destroy")); m_toString = scriptEngine->newFunction(tostring); m_toStringId = createPersistentIdentifier(QLatin1String("toString")); + m_valueOfId = createPersistentIdentifier(QLatin1String("valueOf")); } QDeclarativeObjectScriptClass::~QDeclarativeObjectScriptClass() @@ -157,7 +158,8 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam lastTNData = 0; if (name == m_destroyId.identifier || - name == m_toStringId.identifier) + name == m_toStringId.identifier || + name == m_valueOfId.identifier) return QScriptClass::HandlesReadAccess; if (!obj) @@ -211,11 +213,15 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) if (name == m_destroyId.identifier) return Value(scriptEngine, m_destroy); - else if (name == m_toStringId.identifier) + else if (name == m_toStringId.identifier || + name == m_valueOfId.identifier) return Value(scriptEngine, m_toString); - if (lastData && !lastData->isValid()) - return Value(); + if (lastData && !lastData->isValid()) { + QString error = QLatin1String("Cannot access non-existent property \"") + + toString(name) + QLatin1Char('\"'); + return Value(scriptEngine, context()->throwError(error)); + } Q_ASSERT(obj); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h index 4b27e53..34c71a0 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h @@ -139,6 +139,7 @@ private: PersistentIdentifier m_destroyId; PersistentIdentifier m_toStringId; + PersistentIdentifier m_valueOfId; QScriptValue m_destroy; QScriptValue m_toString; diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/eval.qml b/tests/auto/declarative/qdeclarativeecmascript/data/eval.qml index bc2df98..faa5106 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/eval.qml +++ b/tests/auto/declarative/qdeclarativeecmascript/data/eval.qml @@ -16,7 +16,7 @@ QtObject { test1 = (eval("a") == 7); test2 = (eval("b") == 9); - test3 = (eval("c") == undefined); + try { eval("c") } catch(e) { test3 = true; } test4 = (eval("console") == console); test5 = (eval("Qt") == Qt); } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/function.qml b/tests/auto/declarative/qdeclarativeecmascript/data/function.qml index b435f58..e524189 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/function.qml +++ b/tests/auto/declarative/qdeclarativeecmascript/data/function.qml @@ -14,6 +14,7 @@ QtObject { test1 = (func1(4) == 11); test2 = (func2("Hello World!") == Qt.atob("Hello World!")); - test3 = (func3() == undefined); + + try { func3(); } catch(e) { test3 = true; } } } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.js b/tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.js index 3ffdb33..a20fc28 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.js +++ b/tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.js @@ -2,5 +2,5 @@ function test(target) { - var a = target.a; + try { var a = target.a; } catch(e) {} } diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index e75abac..217ed11 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -997,11 +997,11 @@ void tst_qdeclarativeecmascript::scriptErrors() QString url = component.url().toString(); QString warning1 = url.left(url.length() - 3) + "js:2: Error: Invalid write to global property \"a\""; - QString warning2 = url + ":5: TypeError: Result of expression 'a' [undefined] is not an object."; + QString warning2 = url + ":5: Error: Cannot access non-existent property \"a\""; QString warning3 = url.left(url.length() - 3) + "js:4: Error: Invalid write to global property \"a\""; - QString warning4 = url + ":10: TypeError: Result of expression 'a' [undefined] is not an object."; - QString warning5 = url + ":8: TypeError: Result of expression 'a' [undefined] is not an object."; - QString warning6 = url + ":7: Unable to assign [undefined] to int x"; + QString warning4 = url + ":10: Error: Cannot access non-existent property \"a\""; + QString warning5 = url + ":8: Error: Cannot access non-existent property \"a\""; + QString warning6 = url + ":7: Error: Cannot access non-existent property \"undefinedObject\""; QString warning7 = url + ":12: Error: Cannot assign to read-only property \"trueProperty\""; QString warning8 = url + ":13: Error: Cannot assign to non-existent property \"fakeProperty\""; @@ -1317,7 +1317,12 @@ void tst_qdeclarativeecmascript::callQtInvokables() QDeclarativeEngine qmlengine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&qmlengine); QScriptEngine *engine = &ep->scriptEngine; - ep->globalClass->explicitSetProperty("object", ep->objectClass->newQObject(&o)); + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(engine); + scriptContext->pushScope(ep->globalClass->globalObject()); + QScriptValue scope = engine->newObject(); + scope.setProperty("object", ep->objectClass->newQObject(&o)); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); // Non-existent methods o.reset(); |