diff options
author | Kent Hansen <[email protected]> | 2012-01-18 09:50:31 +0100 |
---|---|---|
committer | Qt by Nokia <[email protected]> | 2012-01-20 23:35:18 +0100 |
commit | 45a83b43ea431a27a7ea05e7e621013dfcfe409a (patch) | |
tree | fc379a3d1e7ba1297ca0cd7dd896f084447c4ca8 | |
parent | b4cd91c2409d5487cb576899f22f654a5bff93e2 (diff) |
Add QJSValue::hasProperty() and hasOwnProperty() functions
These functions provide a way of querying whether a property exists,
without relying on the QJSValue invalid type (which will be removed).
Task-number: QTBUG-23604
Change-Id: I2efd53a1e54cc202ecc022d12730b2775384cf53
Reviewed-by: Simon Hausmann <[email protected]>
Reviewed-by: Jędrzej Nowacki <[email protected]>
-rw-r--r-- | src/declarative/qml/v8/qjsvalue.cpp | 28 | ||||
-rw-r--r-- | src/declarative/qml/v8/qjsvalue.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/v8/qjsvalue_impl_p.h | 20 | ||||
-rw-r--r-- | src/declarative/qml/v8/qjsvalue_p.h | 2 | ||||
-rw-r--r-- | tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp | 51 | ||||
-rw-r--r-- | tests/auto/declarative/qjsvalue/tst_qjsvalue.h | 4 |
6 files changed, 107 insertions, 1 deletions
diff --git a/src/declarative/qml/v8/qjsvalue.cpp b/src/declarative/qml/v8/qjsvalue.cpp index 7df1d04847..9980463a8f 100644 --- a/src/declarative/qml/v8/qjsvalue.cpp +++ b/src/declarative/qml/v8/qjsvalue.cpp @@ -866,7 +866,7 @@ bool QJSValue::instanceOf(const QJSValue &other) const occurred, property() returns the value that was thrown (typically an \c{Error} object). - \sa setProperty(), propertyFlags(), QJSValueIterator + \sa setProperty(), hasProperty(), QJSValueIterator */ QJSValue QJSValue::property(const QString& name) const { @@ -944,6 +944,32 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) } /*! + Returns true if this object has a property of the given \a name, + otherwise returns false. + + \sa property(), hasOwnProperty() +*/ +bool QJSValue::hasProperty(const QString &name) const +{ + Q_D(const QJSValue); + QScriptIsolate api(d->engine()); + return d->hasProperty(name); +} + +/*! + Returns true if this object has an own (not prototype-inherited) + property of the given \a name, otherwise returns false. + + \sa property(), hasProperty() +*/ +bool QJSValue::hasOwnProperty(const QString &name) const +{ + Q_D(const QJSValue); + QScriptIsolate api(d->engine()); + return d->hasOwnProperty(name); +} + +/*! Returns the flags of the property with the given \a name. \sa property() diff --git a/src/declarative/qml/v8/qjsvalue.h b/src/declarative/qml/v8/qjsvalue.h index 6dcfe43d79..756081d842 100644 --- a/src/declarative/qml/v8/qjsvalue.h +++ b/src/declarative/qml/v8/qjsvalue.h @@ -128,6 +128,9 @@ public: QJSValue property(const QString &name) const; void setProperty(const QString &name, const QJSValue &value); + bool hasProperty(const QString &name) const; + bool hasOwnProperty(const QString &name) const; + QJSValue property(quint32 arrayIndex) const; void setProperty(quint32 arrayIndex, const QJSValue &value); diff --git a/src/declarative/qml/v8/qjsvalue_impl_p.h b/src/declarative/qml/v8/qjsvalue_impl_p.h index 9e8259931a..6e1cc4bbaf 100644 --- a/src/declarative/qml/v8/qjsvalue_impl_p.h +++ b/src/declarative/qml/v8/qjsvalue_impl_p.h @@ -880,6 +880,26 @@ inline bool QJSValuePrivate::deleteProperty(const QString& name) return self->Delete(QJSConverter::toString(name)); } +inline bool QJSValuePrivate::hasProperty(const QString &name) const +{ + if (!isObject()) + return false; + + v8::HandleScope handleScope; + v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value)); + return self->Has(QJSConverter::toString(name)); +} + +inline bool QJSValuePrivate::hasOwnProperty(const QString &name) const +{ + if (!isObject()) + return false; + + v8::HandleScope handleScope; + v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value)); + return self->HasOwnProperty(QJSConverter::toString(name)); +} + inline QJSValue::PropertyFlags QJSValuePrivate::propertyFlags(const QString& name) const { if (!isObject()) diff --git a/src/declarative/qml/v8/qjsvalue_p.h b/src/declarative/qml/v8/qjsvalue_p.h index 364742532c..c3677e351d 100644 --- a/src/declarative/qml/v8/qjsvalue_p.h +++ b/src/declarative/qml/v8/qjsvalue_p.h @@ -130,6 +130,8 @@ public: template<typename T> inline QScriptPassPointer<QJSValuePrivate> property(T name) const; inline bool deleteProperty(const QString& name); + inline bool hasProperty(const QString &name) const; + inline bool hasOwnProperty(const QString &name) const; inline QJSValue::PropertyFlags propertyFlags(const QString& name) const; inline QJSValue::PropertyFlags propertyFlags(v8::Handle<v8::String> name) const; diff --git a/tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp b/tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp index e3e259dcbc..e8073bc69a 100644 --- a/tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp @@ -1792,6 +1792,57 @@ static QJSValue getSet__proto__(QScriptContext *ctx, QScriptEngine *) } #endif +void tst_QJSValue::hasProperty_basic() +{ + QJSEngine eng; + QJSValue obj = eng.newObject(); + QVERIFY(obj.hasProperty("hasOwnProperty")); // inherited from Object.prototype + QVERIFY(!obj.hasOwnProperty("hasOwnProperty")); + + QVERIFY(!obj.hasProperty("foo")); + QVERIFY(!obj.hasOwnProperty("foo")); + obj.setProperty("foo", 123); + QVERIFY(obj.hasProperty("foo")); + QVERIFY(obj.hasOwnProperty("foo")); + + QVERIFY(!obj.hasProperty("bar")); + QVERIFY(!obj.hasOwnProperty("bar")); +} + +void tst_QJSValue::hasProperty_globalObject() +{ + QJSEngine eng; + QJSValue global = eng.globalObject(); + QVERIFY(global.hasProperty("Math")); + QVERIFY(global.hasOwnProperty("Math")); + QVERIFY(!global.hasProperty("NoSuchStandardProperty")); + QVERIFY(!global.hasOwnProperty("NoSuchStandardProperty")); + + QVERIFY(!global.hasProperty("foo")); + QVERIFY(!global.hasOwnProperty("foo")); + global.setProperty("foo", 123); + QVERIFY(global.hasProperty("foo")); + QVERIFY(global.hasOwnProperty("foo")); +} + +void tst_QJSValue::hasProperty_changePrototype() +{ + QJSEngine eng; + QJSValue obj = eng.newObject(); + QJSValue proto = eng.newObject(); + obj.setPrototype(proto); + + QVERIFY(!obj.hasProperty("foo")); + QVERIFY(!obj.hasOwnProperty("foo")); + proto.setProperty("foo", 123); + QVERIFY(obj.hasProperty("foo")); + QVERIFY(!obj.hasOwnProperty("foo")); + + obj.setProperty("foo", 456); // override prototype property + QVERIFY(obj.hasProperty("foo")); + QVERIFY(obj.hasOwnProperty("foo")); +} + void tst_QJSValue::getSetProperty_HooliganTask162051() { QJSEngine eng; diff --git a/tests/auto/declarative/qjsvalue/tst_qjsvalue.h b/tests/auto/declarative/qjsvalue/tst_qjsvalue.h index 2e11832f07..7f7c04abe8 100644 --- a/tests/auto/declarative/qjsvalue/tst_qjsvalue.h +++ b/tests/auto/declarative/qjsvalue/tst_qjsvalue.h @@ -113,6 +113,10 @@ private slots: void equals(); void strictlyEquals(); + void hasProperty_basic(); + void hasProperty_globalObject(); + void hasProperty_changePrototype(); + void getSetPrototype_cyclicPrototype(); void getSetPrototype_evalCyclicPrototype(); void getSetPrototype_eval(); |