From 902be8849cd5f04d902dba1ae0533c7298eda224 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 12 Jun 2013 07:27:51 +0200 Subject: [PATCH] Implement query (aka hasProperty) in QObject bindings Fixes tst_qqmlecmascript::in() auto-test. Change-Id: Ic42cc566f6ed8077f7aa7d75c0c92236c34c91b8 Reviewed-by: Lars Knoll --- src/qml/qml/v4/qv4qobjectwrapper.cpp | 45 +++++++++++++++++++++++++----------- src/qml/qml/v4/qv4qobjectwrapper_p.h | 4 ++++ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/qml/qml/v4/qv4qobjectwrapper.cpp b/src/qml/qml/v4/qv4qobjectwrapper.cpp index 5132d4f..815c278 100644 --- a/src/qml/qml/v4/qv4qobjectwrapper.cpp +++ b/src/qml/qml/v4/qv4qobjectwrapper.cpp @@ -308,6 +308,19 @@ void QObjectWrapper::deleteQObject(bool deleteInstantly) } } +QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const +{ + QHashedV4String propertystring(QV4::Value::fromString(name)); + + QQmlData *ddata = QQmlData::get(m_object, false); + if (!ddata) + return 0; + if (ddata && ddata->propertyCache) + return ddata->propertyCache->property(propertystring, m_object, qmlContext); + else + return QQmlPropertyCache::property(engine->v8Engine->engine(), m_object, propertystring, qmlContext, *local); +} + Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty, bool includeImports) { if (QQmlData::wasDeleted(m_object)) { @@ -332,24 +345,14 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml return method; } - QHashedV4String propertystring(QV4::Value::fromString(name)); - QV8Engine *v8Engine = ctx->engine->v8Engine; - - QQmlData *ddata = QQmlData::get(m_object, false); QQmlPropertyData local; - QQmlPropertyData *result = 0; - { - QHashedV4String propertystring(Value::fromString(name)); - if (ddata && ddata->propertyCache) - result = ddata->propertyCache->property(propertystring, m_object, qmlContext); - else - result = QQmlPropertyCache::property(ctx->engine->v8Engine->engine(), m_object, propertystring, qmlContext, local); - } + QQmlPropertyData *result = findProperty(ctx->engine, qmlContext, name, revisionMode, &local); if (!result) { if (includeImports && name->startsWithUpper()) { // Check for attached properties if (qmlContext && qmlContext->imports) { + QHashedV4String propertystring(QV4::Value::fromString(name)); QQmlTypeNameCache::Result r = qmlContext->imports->query(propertystring); if (hasProperty) @@ -359,9 +362,9 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml if (r.scriptIndex != -1) { return QV4::Value::undefinedValue(); } else if (r.type) { - return QmlTypeWrapper::create(v8Engine, m_object, r.type, QmlTypeWrapper::ExcludeEnums); + return QmlTypeWrapper::create(ctx->engine->v8Engine, m_object, r.type, QmlTypeWrapper::ExcludeEnums); } else if (r.importNamespace) { - return QmlTypeWrapper::create(v8Engine, m_object, qmlContext->imports, r.importNamespace, QmlTypeWrapper::ExcludeEnums); + return QmlTypeWrapper::create(ctx->engine->v8Engine, m_object, qmlContext->imports, r.importNamespace, QmlTypeWrapper::ExcludeEnums); } Q_ASSERT(!"Unreachable"); } @@ -371,6 +374,7 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml } QQmlData::flushPendingBinding(m_object, result->coreIndex); + QQmlData *ddata = QQmlData::get(m_object, false); if (revisionMode == QV4::QObjectWrapper::CheckRevision && result->hasRevision()) { if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result)) { @@ -679,6 +683,19 @@ void QObjectWrapper::put(Managed *m, ExecutionContext *ctx, String *name, const } } +PropertyAttributes QObjectWrapper::query(const Managed *m, String *name) +{ + const QObjectWrapper *that = static_cast(m); + ExecutionEngine *engine = that->engine(); + QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(engine); + QQmlPropertyData local; + if (that->findProperty(engine, qmlContext, name, IgnoreRevision, &local) + || name->isEqualTo(that->m_destroy) || name->isEqualTo(that->m_toString)) + return QV4::Attr_Data; + else + return QV4::Object::query(m, name); +} + QV4::Value QObjectWrapper::enumerateProperties(Object *object) { QObjectWrapper *that = static_cast(object); diff --git a/src/qml/qml/v4/qv4qobjectwrapper_p.h b/src/qml/qml/v4/qv4qobjectwrapper_p.h index 08087e9..5729b70 100644 --- a/src/qml/qml/v4/qv4qobjectwrapper_p.h +++ b/src/qml/qml/v4/qv4qobjectwrapper_p.h @@ -70,6 +70,7 @@ QT_BEGIN_NAMESPACE class QObject; class QQmlData; class QQmlPropertyCache; +class QQmlPropertyData; namespace QV4 { struct QObjectSlotDispatcher; @@ -100,12 +101,15 @@ private: QObjectWrapper(ExecutionEngine *engine, QObject *object); + QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const; + QQmlGuard m_object; String *m_destroy; String *m_toString; static Value get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProperty); static void put(Managed *m, ExecutionContext *ctx, String *name, const Value &value); + static PropertyAttributes query(const Managed *, String *name); static void markObjects(Managed *that); static Value enumerateProperties(Object *m_object); -- 2.7.4