summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-10-02 07:09:09 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-10-05 02:40:47 (GMT)
commit3490b478ed02859f0355438efba900cd853e9c13 (patch)
treef554feca685671aef6775da255150a122597c258
parentb3605d7f45c1cdb61bbd2a572e58bd29aaea6956 (diff)
downloadQt-3490b478ed02859f0355438efba900cd853e9c13.zip
Qt-3490b478ed02859f0355438efba900cd853e9c13.tar.gz
Qt-3490b478ed02859f0355438efba900cd853e9c13.tar.bz2
Reenable types/enums and move scripts into an isolated scope
-rwxr-xr-xdemos/declarative/samegame/content/samegame.js5
-rw-r--r--demos/declarative/samegame/samegame.qml4
-rw-r--r--src/declarative/qml/qml.pri10
-rw-r--r--src/declarative/qml/qmlcompileddata.cpp4
-rw-r--r--src/declarative/qml/qmlcompiler.cpp1
-rw-r--r--src/declarative/qml/qmlcompiler_p.h2
-rw-r--r--src/declarative/qml/qmlcomponent.cpp3
-rw-r--r--src/declarative/qml/qmlcontext.cpp5
-rw-r--r--src/declarative/qml/qmlcontext_p.h6
-rw-r--r--src/declarative/qml/qmlcontextscriptclass.cpp43
-rw-r--r--src/declarative/qml/qmlcontextscriptclass_p.h3
-rw-r--r--src/declarative/qml/qmlengine.cpp377
-rw-r--r--src/declarative/qml/qmlengine_p.h75
-rw-r--r--src/declarative/qml/qmlintegercache.cpp4
-rw-r--r--src/declarative/qml/qmlintegercache_p.h9
-rw-r--r--src/declarative/qml/qmlobjectscriptclass.cpp22
-rw-r--r--src/declarative/qml/qmlobjectscriptclass_p.h6
-rw-r--r--src/declarative/qml/qmlpropertycache.cpp12
-rw-r--r--src/declarative/qml/qmlpropertycache_p.h10
-rw-r--r--src/declarative/qml/qmltypenamecache.cpp93
-rw-r--r--src/declarative/qml/qmltypenamecache_p.h113
-rw-r--r--src/declarative/qml/qmltypenamescriptclass.cpp159
-rw-r--r--src/declarative/qml/qmltypenamescriptclass_p.h90
-rw-r--r--src/declarative/qml/qmlvaluetypescriptclass.cpp150
-rw-r--r--src/declarative/qml/qmlvaluetypescriptclass_p.h89
-rw-r--r--src/declarative/util/qmlscript.cpp10
26 files changed, 922 insertions, 383 deletions
diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js
index 09057eb..7deafde 100755
--- a/demos/declarative/samegame/content/samegame.js
+++ b/demos/declarative/samegame/content/samegame.js
@@ -22,6 +22,11 @@ function timeStr(msecs) {
return ret;
}
+function getTileSize()
+{
+ return tileSize;
+}
+
function initBoard()
{
for(var i = 0; i<maxIndex; i++){
diff --git a/demos/declarative/samegame/samegame.qml b/demos/declarative/samegame/samegame.qml
index ede4362..2d00208 100644
--- a/demos/declarative/samegame/samegame.qml
+++ b/demos/declarative/samegame/samegame.qml
@@ -23,8 +23,8 @@ Rectangle {
property int score: 0
z: 20; anchors.centerIn: parent
- width: parent.width - (parent.width % tileSize);
- height: parent.height - (parent.height % tileSize);
+ width: parent.width - (parent.width % getTileSize());
+ height: parent.height - (parent.height % getTileSize());
MouseRegion {
id: gameMR
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index eb761e3..e46dd3f 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -37,9 +37,12 @@ SOURCES += qml/qmlparser.cpp \
qml/qmlwatcher.cpp \
qml/qmlpropertycache.cpp \
qml/qmlintegercache.cpp \
+ qml/qmltypenamecache.cpp \
qml/qmlobjectscriptclass.cpp \
qml/qmlcontextscriptclass.cpp \
- qml/qmlglobalscriptclass.cpp
+ qml/qmlglobalscriptclass.cpp \
+ qml/qmlvaluetypescriptclass.cpp \
+ qml/qmltypenamescriptclass.cpp
HEADERS += qml/qmlparser_p.h \
qml/qmlinstruction_p.h \
@@ -94,9 +97,12 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlwatcher_p.h \
qml/qmlpropertycache_p.h \
qml/qmlintegercache_p.h \
+ qml/qmltypenamecache_p.h \
qml/qmlobjectscriptclass_p.h \
qml/qmlcontextscriptclass_p.h \
- qml/qmlglobalscriptclass_p.h
+ qml/qmlglobalscriptclass_p.h \
+ qml/qmlvaluetypescriptclass_p.h \
+ qml/qmltypenamescriptclass_p.h
# for qtscript debugger
contains(QT_CONFIG, scripttools):QT += scripttools
diff --git a/src/declarative/qml/qmlcompileddata.cpp b/src/declarative/qml/qmlcompileddata.cpp
index a603d4e..8c3c355 100644
--- a/src/declarative/qml/qmlcompileddata.cpp
+++ b/src/declarative/qml/qmlcompileddata.cpp
@@ -150,6 +150,7 @@ int QmlCompiledData::indexForLocation(const QmlParser::LocationSpan &l)
}
QmlCompiledData::QmlCompiledData()
+: importCache(0)
{
}
@@ -163,6 +164,9 @@ QmlCompiledData::~QmlCompiledData()
for (int ii = 0; ii < propertyCaches.count(); ++ii)
propertyCaches.at(ii)->release();
+ if (importCache)
+ importCache->release();
+
qDeleteAll(programs);
}
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 5cb2158..4b5c5bf 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -644,6 +644,7 @@ void QmlCompiler::compileTree(Object *tree)
output->bytecode << def;
output->imports = unit->imports;
+ output->importCache = output->imports.cache(engine);
Q_ASSERT(tree->metatype);
static_cast<QMetaObject &>(output->root) = *tree->metaObject();
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 1cb66c7..fd361fd 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -64,6 +64,7 @@
#include <private/qbitfield_p.h>
#include <private/qmlpropertycache_p.h>
#include <private/qmlintegercache_p.h>
+#include <private/qmltypenamecache_p.h>
QT_BEGIN_NAMESPACE
@@ -81,6 +82,7 @@ public:
QByteArray name;
QUrl url;
QmlEnginePrivate::Imports imports;
+ QmlTypeNameCache *importCache;
struct TypeReference
{
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index fedc2da..5b1cbeb 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -517,7 +517,8 @@ QmlComponentPrivate::beginCreate(QmlContext *context, const QBitField &bindings)
static_cast<QmlContextPrivate *>(QObjectPrivate::get(context));
QmlContext *ctxt = new QmlContext(context, 0, true);
static_cast<QmlContextPrivate*>(ctxt->d_func())->url = cc->url;
- static_cast<QmlContextPrivate*>(ctxt->d_func())->imports = cc->imports;
+ static_cast<QmlContextPrivate*>(ctxt->d_func())->imports = cc->importCache;
+ cc->importCache->addref();
QmlVME vme;
QObject *rv = vme.run(ctxt, cc, start, count, bindings);
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index 5e74d1a..968597c 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
QmlContextPrivate::QmlContextPrivate()
: parent(0), engine(0), isInternal(false), propertyNames(0), notifyIndex(-1),
- highPriorityCount(0), expressions(0), idValues(0), idValueCount(0)
+ highPriorityCount(0), imports(0), expressions(0), idValues(0), idValueCount(0)
{
}
@@ -307,6 +307,9 @@ QmlContext::~QmlContext()
if (d->propertyNames)
d->propertyNames->release();
+
+ if (d->imports)
+ d->imports->release();
}
void QmlContextPrivate::invalidateEngines()
diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h
index 64faa6d..8fd2e92 100644
--- a/src/declarative/qml/qmlcontext_p.h
+++ b/src/declarative/qml/qmlcontext_p.h
@@ -62,6 +62,7 @@
#include <private/qguard_p.h>
#include <private/qmlengine_p.h>
#include <private/qmlintegercache_p.h>
+#include <private/qmltypenamecache_p.h>
QT_BEGIN_NAMESPACE
@@ -93,8 +94,11 @@ public:
QScriptValueList scopeChain;
+ QList<QScriptValue> scripts;
+
QUrl url;
- QmlEnginePrivate::Imports imports;
+
+ QmlTypeNameCache *imports;
void init();
diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp
index baea60a..d8ae4f0 100644
--- a/src/declarative/qml/qmlcontextscriptclass.cpp
+++ b/src/declarative/qml/qmlcontextscriptclass.cpp
@@ -42,6 +42,7 @@
#include "qmlcontextscriptclass_p.h"
#include <private/qmlengine_p.h>
#include <private/qmlcontext_p.h>
+#include <private/qmltypenamescriptclass_p.h>
QT_BEGIN_NAMESPACE
@@ -56,7 +57,7 @@ struct ContextData {
*/
QmlContextScriptClass::QmlContextScriptClass(QmlEngine *bindEngine)
: QScriptDeclarativeClass(QmlEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine),
- lastPropertyIndex(-1), lastDefaultObject(-1)
+ lastData(0), lastPropertyIndex(-1), lastDefaultObject(-1)
{
}
@@ -76,21 +77,32 @@ QmlContextScriptClass::queryProperty(const Object &object, const Identifier &nam
QScriptClass::QueryFlags flags)
{
Q_UNUSED(flags);
+
+ lastPropertyIndex = -1;
+ lastDefaultObject = -1;
+ lastData = 0;
+
QmlContext *bindContext = ((ContextData *)object)->context.data();
if (!bindContext)
return 0;
QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
QmlContextPrivate *cp = QmlContextPrivate::get(bindContext);
-
- lastPropertyIndex = -1;
- lastDefaultObject = -1;
lastPropertyIndex = cp->propertyNames?cp->propertyNames->value(name):-1;
if (lastPropertyIndex != -1)
return QScriptClass::HandlesReadAccess;
// ### Check for attached properties
+ if (ep->currentExpression && cp->imports && bindContext == ep->currentExpression->context()) {
+ QmlTypeNameCache::Data *data = cp->imports->data(name);
+
+ if (data) {
+ lastData = data;
+ return QScriptClass::HandlesReadAccess;
+ }
+ }
+
#if 0
QmlType *type = 0; ImportedNamespace *ns = 0;
if (currentExpression && bindContext == currentExpression->context() &&
@@ -117,6 +129,11 @@ QmlContextScriptClass::queryProperty(const Object &object, const Identifier &nam
}
}
+ for (int ii = 0; ii < cp->scripts.count(); ++ii) {
+ lastFunction = QScriptDeclarativeClass::function(cp->scripts.at(ii), name);
+ if (lastFunction.isValid())
+ return QScriptClass::HandlesReadAccess;
+ }
return 0;
}
@@ -145,7 +162,14 @@ QScriptValue QmlContextScriptClass::property(const Object &object, const Identif
}
#endif
- if (lastPropertyIndex != -1) {
+ if (lastData) {
+
+ if (lastData->type)
+ return ep->typeNameClass->newObject(cp->defaultObjects.at(0), lastData->type);
+ else
+ return ep->typeNameClass->newObject(cp->defaultObjects.at(0), lastData->typeNamespace);
+
+ } else if (lastPropertyIndex != -1) {
QScriptValue rv;
if (lastPropertyIndex < cp->idValueCount) {
@@ -161,15 +185,18 @@ QScriptValue QmlContextScriptClass::property(const Object &object, const Identif
}
ep->capturedProperties <<
- QmlEnginePrivate::CapturedProperty(bindContext, -1,
- lastPropertyIndex + cp->notifyIndex);
+ QmlEnginePrivate::CapturedProperty(bindContext, -1, lastPropertyIndex + cp->notifyIndex);
return rv;
- } else {
+ } else if(lastDefaultObject != -1) {
// Default object property
return ep->objectClass->property(cp->defaultObjects.at(lastDefaultObject), name);
+ } else {
+
+ return lastFunction;
+
}
}
diff --git a/src/declarative/qml/qmlcontextscriptclass_p.h b/src/declarative/qml/qmlcontextscriptclass_p.h
index 9ef090d..a00e567 100644
--- a/src/declarative/qml/qmlcontextscriptclass_p.h
+++ b/src/declarative/qml/qmlcontextscriptclass_p.h
@@ -55,6 +55,7 @@
#include <QtScript/qscriptclass.h>
#include <private/qscriptdeclarativeclass_p.h>
+#include <private/qmltypenamecache_p.h>
QT_BEGIN_NAMESPACE
@@ -77,8 +78,10 @@ protected:
private:
QmlEngine *engine;
+ QmlTypeNameCache::Data *lastData;
int lastPropertyIndex;
int lastDefaultObject;
+ QScriptValue lastFunction;
uint m_id;
};
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 4afd245..e67e42f 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -85,6 +85,7 @@
#include <private/qmlstringconverters_p.h>
#include <private/qmlxmlhttprequest_p.h>
#include <private/qmlsqldatabase_p.h>
+#include <private/qmltypenamescriptclass_p.h>
#ifdef Q_OS_WIN // for %APPDATA%
#include "qt_windows.h"
@@ -274,114 +275,6 @@ QmlEnginePrivate::CapturedProperty::CapturedProperty(const QmlMetaProperty &p)
{
}
-struct QmlTypeNameBridge
-{
- QObject *object;
- QmlType *type;
- QmlEnginePrivate::ImportedNamespace *ns;
-};
-Q_DECLARE_METATYPE(QmlTypeNameBridge);
-
-struct QmlValueTypeReference {
- QmlValueType *type;
- QGuard<QObject> object;
- int property;
-};
-Q_DECLARE_METATYPE(QmlValueTypeReference);
-
-void QmlEnginePrivate::setPropertyObject(const QScriptValue &value, uint id)
-{
- Q_ASSERT(id == resolveData.safetyCheckId);
- Q_Q(QmlEngine);
-
- resolveData.property.write(QmlScriptClass::toVariant(q, value));
-}
-
-QScriptClass::QueryFlags
-QmlEnginePrivate::queryObject(const QString &propName,
- uint *id, QObject *obj)
-{
- resolveData.safetyCheckId++;
- *id = resolveData.safetyCheckId;
- resolveData.clear();
-
- QScriptClass::QueryFlags rv = 0;
-
- QmlContext *ctxt = QmlEngine::contextForObject(obj);
- if (!ctxt)
- ctxt = rootContext;
- QmlMetaProperty prop(obj, propName, ctxt);
-
- if (prop.type() == QmlMetaProperty::Invalid) {
- QPair<const QMetaObject *, QString> key =
- qMakePair(obj->metaObject(), propName);
- bool isFunction = false;
- if (functionCache.contains(key)) {
- isFunction = functionCache.value(key);
- } else {
- QScriptValue sobj = scriptEngine.newQObject(obj);
- QScriptValue func = sobj.property(propName);
- isFunction = func.isFunction();
- functionCache.insert(key, isFunction);
- }
-
- if (isFunction) {
- resolveData.object = obj;
- resolveData.isFunction = true;
- rv |= QScriptClass::HandlesReadAccess;
- }
- } else {
- resolveData.object = obj;
- resolveData.property = prop;
-
- rv |= QScriptClass::HandlesReadAccess;
- if (prop.isWritable())
- rv |= QScriptClass::HandlesWriteAccess;
- }
-
- return rv;
-}
-
-QScriptValue QmlEnginePrivate::propertyObject(const QString &propName,
- QObject *obj, uint id)
-{
- Q_ASSERT(id == resolveData.safetyCheckId);
- Q_ASSERT(resolveData.object);
-
- if (resolveData.isFunction) {
- // ### Optimize
- QScriptValue sobj = scriptEngine.newQObject(obj);
- QScriptValue func = sobj.property(propName);
- return func;
- } else {
- const QmlMetaProperty &prop = resolveData.property;
-
- if (prop.needsChangedNotifier())
- capturedProperties << CapturedProperty(prop);
-
- int propType = prop.propertyType();
- if (propType < QVariant::UserType && valueTypes[propType]) {
- QmlValueTypeReference ref;
- ref.type = valueTypes[propType];
- ref.object = obj;
- ref.property = prop.coreIndex();
- return scriptEngine.newObject(valueTypeClass, scriptEngine.newVariant(QVariant::fromValue(ref)));
- }
-
- QVariant var = prop.read();
- QObject *varobj = (propType < QVariant::UserType)?0:QmlMetaType::toQObject(var);
- if (!varobj)
- varobj = qvariant_cast<QObject *>(var);
- if (varobj) {
- return objectClass->newQObject(varobj);
- } else {
- return qScriptValueFromValue(&scriptEngine, var);
- }
- }
-
- return QScriptValue();
-}
-
/*!
\class QmlEngine
\brief The QmlEngine class provides an environment for instantiating QML components.
@@ -1039,6 +932,35 @@ QScriptValue QmlEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
return qScriptValueFromValue(engine, qVariantFromValue(finalColor));
}
+
+QScriptValue QmlEnginePrivate::scriptValueFromVariant(const QVariant &val)
+{
+ if (QmlMetaType::isObject(val.userType())) {
+ QObject *rv = *(QObject **)val.constData();
+ return objectClass->newQObject(rv);
+ } else {
+ return qScriptValueFromValue(&scriptEngine, val);
+ }
+}
+
+QVariant QmlEnginePrivate::scriptValueToVariant(const QScriptValue &val)
+{
+ QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
+ if (dc == objectClass)
+ return QVariant::fromValue(objectClass->toQObject(val));
+ else if (dc == contextClass)
+ return QVariant();
+
+ QScriptClass *sc = val.scriptClass();
+ if (!sc) {
+ return val.toVariant();
+ } else if (sc == valueTypeClass) {
+ return valueTypeClass->toVariant(val);
+ } else {
+ return QVariant();
+ }
+}
+
QmlScriptClass::QmlScriptClass(QmlEngine *bindengine)
: QScriptClass(QmlEnginePrivate::getScriptEngine(bindengine)),
engine(bindengine)
@@ -1060,175 +982,13 @@ QVariant QmlScriptClass::toVariant(QmlEngine *engine, const QScriptValue &val)
if (!sc) {
return val.toVariant();
} else if (sc == ep->valueTypeClass) {
- QmlValueTypeReference ref =
- qvariant_cast<QmlValueTypeReference>(val.data().toVariant());
-
- if (!ref.object)
- return QVariant();
-
- QMetaProperty p = ref.object->metaObject()->property(ref.property);
- return p.read(ref.object);
+ return ep->valueTypeClass->toVariant(val);
}
return QVariant();
}
/////////////////////////////////////////////////////////////
-QmlTypeNameScriptClass::QmlTypeNameScriptClass(QmlEngine *engine)
-: QmlScriptClass(engine), object(0), type(0)
-{
-}
-
-QmlTypeNameScriptClass::~QmlTypeNameScriptClass()
-{
-}
-
-QmlTypeNameScriptClass::QueryFlags
-QmlTypeNameScriptClass::queryProperty(const QScriptValue &scriptObject,
- const QScriptString &name,
- QueryFlags flags, uint *id)
-{
- Q_UNUSED(flags);
-
- QmlTypeNameBridge bridge =
- qvariant_cast<QmlTypeNameBridge>(scriptObject.data().toVariant());
-
- object = 0;
- type = 0;
- QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
-
- if (bridge.ns) {
- QmlType *type = 0;
- ep->resolveTypeInNamespace(bridge.ns, name.toString().toUtf8(),
- &type, 0, 0, 0);
- if (type) {
- object = bridge.object;
- this->type = type;
- return HandlesReadAccess;
- } else {
- return 0;
- }
-
- } else {
- Q_ASSERT(bridge.type);
- QString strName = name.toString();
- if (strName.at(0).isUpper()) {
- // Must be an enum
- // ### Optimize
- const char *enumName = strName.toUtf8().constData();
- const QMetaObject *metaObject = bridge.type->baseMetaObject();
- for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
- QMetaEnum e = metaObject->enumerator(ii);
- int value = e.keyToValue(enumName);
- if (value != -1) {
- enumValue = value;
- return HandlesReadAccess;
- }
- }
- return 0;
- } else {
- // Must be an attached property
- this->object = qmlAttachedPropertiesObjectById(bridge.type->index(), bridge.object);
- if (!this->object)
- return 0;
- return ep->queryObject(strName, id, this->object);
- }
- }
-}
-
-QScriptValue QmlTypeNameScriptClass::property(const QScriptValue &,
- const QScriptString &propName,
- uint id)
-{
- QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
- if (type) {
- QmlTypeNameBridge tnb = { object, type, 0 };
- return ep->scriptEngine.newObject(ep->typeNameClass, ep->scriptEngine.newVariant(qVariantFromValue(tnb)));
- } else if (object) {
- return ep->propertyObject(propName, object, id);
- } else {
- return QScriptValue(enumValue);
- }
-}
-
-/////////////////////////////////////////////////////////////
-QmlValueTypeScriptClass::QmlValueTypeScriptClass(QmlEngine *bindEngine)
-: QmlScriptClass(bindEngine)
-{
-}
-
-QmlValueTypeScriptClass::~QmlValueTypeScriptClass()
-{
-}
-
-QmlValueTypeScriptClass::QueryFlags
-QmlValueTypeScriptClass::queryProperty(const QScriptValue &object,
- const QScriptString &name,
- QueryFlags flags, uint *id)
-{
- Q_UNUSED(flags);
- QmlValueTypeReference ref =
- qvariant_cast<QmlValueTypeReference>(object.data().toVariant());
-
- if (!ref.object)
- return 0;
-
- QByteArray propName = name.toString().toUtf8();
-
- int idx = ref.type->metaObject()->indexOfProperty(propName.constData());
- if (idx == -1)
- return 0;
- *id = idx;
-
- QMetaProperty prop = ref.object->metaObject()->property(idx);
-
- QmlValueTypeScriptClass::QueryFlags rv =
- QmlValueTypeScriptClass::HandlesReadAccess;
- if (prop.isWritable())
- rv |= QmlValueTypeScriptClass::HandlesWriteAccess;
-
- return rv;
-}
-
-QScriptValue QmlValueTypeScriptClass::property(const QScriptValue &object,
- const QScriptString &name,
- uint id)
-{
- Q_UNUSED(name);
- QmlValueTypeReference ref =
- qvariant_cast<QmlValueTypeReference>(object.data().toVariant());
-
- if (!ref.object)
- return QScriptValue();
-
- ref.type->read(ref.object, ref.property);
-
- QMetaProperty p = ref.type->metaObject()->property(id);
- QVariant rv = p.read(ref.type);
-
- return static_cast<QmlEnginePrivate *>(QObjectPrivate::get(engine))->scriptEngine.newVariant(rv);
-}
-
-void QmlValueTypeScriptClass::setProperty(QScriptValue &object,
- const QScriptString &name,
- uint id,
- const QScriptValue &value)
-{
- Q_UNUSED(name);
- QmlValueTypeReference ref =
- qvariant_cast<QmlValueTypeReference>(object.data().toVariant());
-
- if (!ref.object)
- return;
-
- QVariant v = QmlScriptClass::toVariant(engine, value);
-
- ref.type->read(ref.object, ref.property);
- QMetaProperty p = ref.type->metaObject()->property(id);
- p.write(ref.type, v);
- ref.type->write(ref.object, ref.property);
-}
-
struct QmlEnginePrivate::ImportedNamespace {
QStringList urls;
QList<int> majversions;
@@ -1395,6 +1155,7 @@ public:
int ref;
private:
+ friend class QmlEnginePrivate::Imports;
QmlEnginePrivate::ImportedNamespace unqualifiedset;
QHash<QString,QmlEnginePrivate::ImportedNamespace* > set;
};
@@ -1425,6 +1186,80 @@ QmlEnginePrivate::Imports::~Imports()
delete d;
}
+#include <QtDeclarative/qmlmetatype.h>
+#include <private/qmltypenamecache_p.h>
+static QmlTypeNameCache *cacheForNamespace(QmlEngine *engine, const QmlEnginePrivate::ImportedNamespace &set, QmlTypeNameCache *cache)
+{
+ if (!cache)
+ cache = new QmlTypeNameCache(engine);
+
+ QList<QmlType *> types = QmlMetaType::qmlTypes();
+
+ for (int ii = 0; ii < set.urls.count(); ++ii) {
+ if (!set.isBuiltin.at(ii))
+ continue;
+
+ QByteArray base = set.urls.at(ii).toUtf8() + "/";
+ int major = set.majversions.at(ii);
+ int minor = set.minversions.at(ii);
+
+ foreach (QmlType *type, types) {
+ if (type->qmlTypeName().startsWith(base) &&
+ type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) &&
+ type->majorVersion() == major && type->minMinorVersion() <= minor &&
+ type->maxMinorVersion() >= minor) {
+
+ QString name = QString::fromUtf8(type->qmlTypeName().mid(base.length()));
+
+ cache->add(name, type);
+ }
+ }
+ }
+
+ return cache;
+}
+
+QmlTypeNameCache *QmlEnginePrivate::Imports::cache(QmlEngine *engine) const
+{
+ const QmlEnginePrivate::ImportedNamespace &set = d->unqualifiedset;
+
+ QmlTypeNameCache *cache = new QmlTypeNameCache(engine);
+
+ for (QHash<QString,QmlEnginePrivate::ImportedNamespace* >::ConstIterator iter = d->set.begin();
+ iter != d->set.end(); ++iter) {
+
+ QmlTypeNameCache::Data *d = cache->data(iter.key());
+ if (d) {
+ if (!d->typeNamespace)
+ cacheForNamespace(engine, *(*iter), d->typeNamespace);
+ } else {
+ QmlTypeNameCache *nc = cacheForNamespace(engine, *(*iter), 0);
+ cache->add(iter.key(), nc);
+ nc->release();
+ }
+ }
+
+ cacheForNamespace(engine, set, cache);
+
+ return cache;
+}
+
+/*
+QStringList QmlEnginePrivate::Imports::unqualifiedSet() const
+{
+ QStringList rv;
+
+ const QmlEnginePrivate::ImportedNamespace &set = d->unqualifiedset;
+
+ for (int ii = 0; ii < set.urls.count(); ++ii) {
+ if (set.isBuiltin.at(ii))
+ rv << set.urls.at(ii);
+ }
+
+ return rv;
+}
+*/
+
/*!
Sets the base URL to be used for all relative file imports added.
*/
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index 231388d..7978023 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -75,6 +75,7 @@
#include <private/qmlpropertycache_p.h>
#include <private/qmlobjectscriptclass_p.h>
#include <private/qmlcontextscriptclass_p.h>
+#include <private/qmlvaluetypescriptclass_p.h>
QT_BEGIN_NAMESPACE
@@ -92,6 +93,8 @@ class QNetworkReply;
class QNetworkAccessManager;
class QmlAbstractBinding;
class QScriptDeclarativeClass;
+class QmlTypeNameScriptClass;
+class QmlTypeNameCache;
class QmlEnginePrivate : public QObjectPrivate
{
@@ -102,13 +105,6 @@ public:
void init();
- QScriptClass::QueryFlags queryObject(const QString &name, uint *id,
- QObject *);
- QScriptValue propertyObject(const QString &propName, QObject *,
- uint id = 0);
- void setPropertyObject(const QScriptValue &, uint id);
-
-
struct CapturedProperty {
CapturedProperty(QObject *o, int c, int n)
: object(o), coreIndex(c), notifyIndex(n) {}
@@ -128,25 +124,6 @@ public:
#endif
struct ImportedNamespace;
- struct ResolveData {
- ResolveData() : safetyCheckId(0) {}
- int safetyCheckId;
-
- void clear() {
- object = 0; context = 0;
- type = 0; ns = 0;
- contextIndex = -1; isFunction = false;
- }
- QObject *object;
- QmlContext *context;
-
- QmlType *type;
- QmlEnginePrivate::ImportedNamespace *ns;
-
- int contextIndex;
- bool isFunction;
- QmlMetaProperty property;
- } resolveData;
QmlContextScriptClass *contextClass;
QmlObjectScriptClass *objectClass;
QmlValueTypeScriptClass *valueTypeClass;
@@ -211,9 +188,6 @@ public:
}
QmlValueTypeFactory valueTypes;
- // ### Fixme
- typedef QHash<QPair<const QMetaObject *, QString>, bool> FunctionCache;
- FunctionCache functionCache;
QHash<const QMetaObject *, QmlPropertyCache *> propertyCache;
QmlPropertyCache *cache(QObject *obj) {
@@ -228,6 +202,7 @@ public:
return rv;
}
+ // ### This whole class is embarrassing
struct Imports {
Imports();
~Imports();
@@ -237,6 +212,8 @@ public:
void setBaseUrl(const QUrl& url);
QUrl baseUrl() const;
+ QmlTypeNameCache *cache(QmlEngine *) const;
+
private:
friend class QmlEnginePrivate;
QmlImportsPrivate *d;
@@ -261,6 +238,9 @@ public:
QHash<int, int> m_qmlLists;
QHash<int, QmlCompiledData *> m_compositeTypes;
+ QScriptValue scriptValueFromVariant(const QVariant &);
+ QVariant scriptValueToVariant(const QScriptValue &);
+
static QScriptValue qmlScriptObject(QObject*, QmlEngine*);
static QScriptValue createComponent(QScriptContext*, QScriptEngine*);
static QScriptValue createQmlObject(QScriptContext*, QScriptEngine*);
@@ -292,43 +272,6 @@ protected:
QmlEngine *engine;
};
-class QmlTypeNameScriptClass : public QmlScriptClass
-{
-public:
- QmlTypeNameScriptClass(QmlEngine *);
- ~QmlTypeNameScriptClass();
-
- virtual QueryFlags queryProperty(const QScriptValue &object,
- const QScriptString &name,
- QueryFlags flags, uint *id);
- virtual QScriptValue property(const QScriptValue &object,
- const QScriptString &name,
- uint id);
-
-private:
- QObject *object;
- QmlType *type;
- quint32 enumValue;
-};
-
-class QmlValueTypeScriptClass : public QmlScriptClass
-{
-public:
- QmlValueTypeScriptClass(QmlEngine *);
- ~QmlValueTypeScriptClass();
-
- virtual QueryFlags queryProperty(const QScriptValue &object,
- const QScriptString &name,
- QueryFlags flags, uint *id);
- virtual QScriptValue property(const QScriptValue &object,
- const QScriptString &name,
- uint id);
- virtual void setProperty(QScriptValue &object,
- const QScriptString &name,
- uint id,
- const QScriptValue &value);
-};
-
QT_END_NAMESPACE
#endif // QMLENGINE_P_H
diff --git a/src/declarative/qml/qmlintegercache.cpp b/src/declarative/qml/qmlintegercache.cpp
index 1bc4086..564faaa 100644
--- a/src/declarative/qml/qmlintegercache.cpp
+++ b/src/declarative/qml/qmlintegercache.cpp
@@ -62,9 +62,7 @@ void QmlIntegerCache::add(const QString &id, int value)
QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine);
// ### use contextClass
- QScriptDeclarativeClass::PersistentIdentifier<Data> *d =
- enginePriv->objectClass->createPersistentIdentifier<Data>(id);
- d->value = value;
+ Data *d = new Data(enginePriv->objectClass->createPersistentIdentifier(id), value);
stringCache.insert(id, d);
identifierCache.insert(d->identifier, d);
diff --git a/src/declarative/qml/qmlintegercache_p.h b/src/declarative/qml/qmlintegercache_p.h
index fda80c6..e11e0be 100644
--- a/src/declarative/qml/qmlintegercache_p.h
+++ b/src/declarative/qml/qmlintegercache_p.h
@@ -74,12 +74,15 @@ public:
static QmlIntegerCache *createForEnums(QmlType *, QmlEngine *);
private:
- struct Data {
+ struct Data : public QScriptDeclarativeClass::PersistentIdentifier {
+ Data(const QScriptDeclarativeClass::PersistentIdentifier &i, int v)
+ : QScriptDeclarativeClass::PersistentIdentifier(i), value(v) {}
+
int value;
};
- typedef QHash<QString, QScriptDeclarativeClass::PersistentIdentifier<Data> *> StringCache;
- typedef QHash<QScriptDeclarativeClass::Identifier, QScriptDeclarativeClass::PersistentIdentifier<Data> *> IdentifierCache;
+ typedef QHash<QString, Data *> StringCache;
+ typedef QHash<QScriptDeclarativeClass::Identifier, Data *> IdentifierCache;
StringCache stringCache;
IdentifierCache identifierCache;
diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp
index bb5f191..6a34a2f 100644
--- a/src/declarative/qml/qmlobjectscriptclass.cpp
+++ b/src/declarative/qml/qmlobjectscriptclass.cpp
@@ -64,14 +64,13 @@ QmlObjectScriptClass::QmlObjectScriptClass(QmlEngine *bindEngine)
QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(bindEngine);
m_destroy = scriptEngine->newFunction(destroy);
- m_destroyId = createPersistentIdentifier<Dummy>(QLatin1String("destroy"));
+ m_destroyId = createPersistentIdentifier(QLatin1String("destroy"));
m_toString = scriptEngine->newFunction(tostring);
- m_toStringId = createPersistentIdentifier<Dummy>(QLatin1String("toString"));
+ m_toStringId = createPersistentIdentifier(QLatin1String("toString"));
}
QmlObjectScriptClass::~QmlObjectScriptClass()
{
- delete m_destroyId;
}
QScriptValue QmlObjectScriptClass::newQObject(QObject *object)
@@ -100,8 +99,8 @@ QmlObjectScriptClass::queryProperty(QObject *obj, const Identifier &name,
Q_UNUSED(flags);
lastData = 0;
- if (name == m_destroyId->identifier ||
- name == m_toStringId->identifier)
+ if (name == m_destroyId.identifier ||
+ name == m_toStringId.identifier)
return QScriptClass::HandlesReadAccess;
if (!obj)
@@ -140,9 +139,9 @@ QScriptValue QmlObjectScriptClass::property(const Object &object, const Identifi
QScriptValue QmlObjectScriptClass::property(QObject *obj, const Identifier &name)
{
- if (name == m_destroyId->identifier)
+ if (name == m_destroyId.identifier)
return m_destroy;
- else if (name == m_toStringId->identifier)
+ else if (name == m_toStringId.identifier)
return m_toString;
Q_ASSERT(lastData);
@@ -156,6 +155,11 @@ QScriptValue QmlObjectScriptClass::property(QObject *obj, const Identifier &name
QScriptValue sobj = scriptEngine->newQObject(obj);
return sobj.property(toString(name));
} else {
+ if (lastData->propType < QVariant::UserType) {
+ QmlValueType *valueType = enginePriv->valueTypes[lastData->propType];
+ if (valueType)
+ return enginePriv->valueTypeClass->newObject(obj, lastData->coreIndex, valueType);
+ }
QVariant var = obj->metaObject()->property(lastData->coreIndex).read(obj);
if (!(lastData->flags & QmlPropertyCache::Data::IsConstant)) {
@@ -167,7 +171,7 @@ QScriptValue QmlObjectScriptClass::property(QObject *obj, const Identifier &name
QObject *rv = *(QObject **)var.constData();
return newQObject(rv);
} else {
- return qScriptValueFromValue(scriptEngine, var);
+ return enginePriv->scriptValueFromVariant(var);
}
}
@@ -250,5 +254,5 @@ QScriptValue QmlObjectScriptClass::destroy(QScriptContext *context, QScriptEngin
return engine->nullValue();
}
-
QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/qmlobjectscriptclass_p.h b/src/declarative/qml/qmlobjectscriptclass_p.h
index cd67fac..c86abdb 100644
--- a/src/declarative/qml/qmlobjectscriptclass_p.h
+++ b/src/declarative/qml/qmlobjectscriptclass_p.h
@@ -86,13 +86,11 @@ protected:
virtual void destroyed(const Object &);
private:
- uint m_id;
QmlPropertyCache::Data *lastData;
QmlPropertyCache::Data local;
- struct Dummy {};
- PersistentIdentifier<Dummy> *m_destroyId;
- PersistentIdentifier<Dummy> *m_toStringId;
+ PersistentIdentifier m_destroyId;
+ PersistentIdentifier m_toStringId;
QScriptValue m_destroy;
QScriptValue m_toString;
diff --git a/src/declarative/qml/qmlpropertycache.cpp b/src/declarative/qml/qmlpropertycache.cpp
index cc4c2ab..d7b087b 100644
--- a/src/declarative/qml/qmlpropertycache.cpp
+++ b/src/declarative/qml/qmlpropertycache.cpp
@@ -155,8 +155,8 @@ QmlPropertyCache *QmlPropertyCache::create(QmlEngine *engine, const QMetaObject
QMetaProperty p = metaObject->property(ii);
QString propName = QLatin1String(p.name());
- QScriptDeclarativeClass::PersistentIdentifier<RData> *data =
- enginePriv->objectClass->createPersistentIdentifier<RData>(propName);
+ RData *data = new RData;
+ data->identifier = enginePriv->objectClass->createPersistentIdentifier(propName);
data->load(p);
@@ -166,7 +166,7 @@ QmlPropertyCache *QmlPropertyCache::create(QmlEngine *engine, const QMetaObject
continue;
cache->stringCache.insert(propName, data);
- cache->identifierCache.insert(data->identifier, data);
+ cache->identifierCache.insert(data->identifier.identifier, data);
data->addref();
data->addref();
}
@@ -183,13 +183,13 @@ QmlPropertyCache *QmlPropertyCache::create(QmlEngine *engine, const QMetaObject
if (cache->stringCache.contains(methodName))
continue;
- QScriptDeclarativeClass::PersistentIdentifier<RData> *data =
- enginePriv->objectClass->createPersistentIdentifier<RData>(methodName);
+ RData *data = new RData;
+ data->identifier = enginePriv->objectClass->createPersistentIdentifier(methodName);
data->load(m);
cache->stringCache.insert(methodName, data);
- cache->identifierCache.insert(data->identifier, data);
+ cache->identifierCache.insert(data->identifier.identifier, data);
data->addref();
data->addref();
}
diff --git a/src/declarative/qml/qmlpropertycache_p.h b/src/declarative/qml/qmlpropertycache_p.h
index 82b8737..f1b1219 100644
--- a/src/declarative/qml/qmlpropertycache_p.h
+++ b/src/declarative/qml/qmlpropertycache_p.h
@@ -113,11 +113,13 @@ public:
Data *property(int) const;
private:
- struct RData : public Data, public QmlRefCount {};
+ struct RData : public Data, public QmlRefCount {
+ QScriptDeclarativeClass::PersistentIdentifier identifier;
+ };
- typedef QVector<QScriptDeclarativeClass::PersistentIdentifier<RData> *> IndexCache;
- typedef QHash<QString, QScriptDeclarativeClass::PersistentIdentifier<RData> *> StringCache;
- typedef QHash<QScriptDeclarativeClass::Identifier, QScriptDeclarativeClass::PersistentIdentifier<RData> *> IdentifierCache;
+ typedef QVector<RData *> IndexCache;
+ typedef QHash<QString, RData *> StringCache;
+ typedef QHash<QScriptDeclarativeClass::Identifier, RData *> IdentifierCache;
IndexCache indexCache;
StringCache stringCache;
diff --git a/src/declarative/qml/qmltypenamecache.cpp b/src/declarative/qml/qmltypenamecache.cpp
new file mode 100644
index 0000000..2b0f2c9
--- /dev/null
+++ b/src/declarative/qml/qmltypenamecache.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmltypenamecache_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QmlTypeNameCache::QmlTypeNameCache(QmlEngine *e)
+: engine(e)
+{
+}
+
+QmlTypeNameCache::~QmlTypeNameCache()
+{
+ qDeleteAll(stringCache);
+}
+
+void QmlTypeNameCache::add(const QString &name, QmlType *type)
+{
+ if (stringCache.contains(name))
+ return;
+
+ QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
+
+ RData *data = new RData;
+ // ### Use typename class
+ data->identifier = ep->objectClass->createPersistentIdentifier(name);
+ data->type = type;
+ stringCache.insert(name, data);
+ identifierCache.insert(data->identifier.identifier, data);
+}
+
+void QmlTypeNameCache::add(const QString &name, QmlTypeNameCache *typeNamespace)
+{
+ if (stringCache.contains(name))
+ return;
+
+ QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
+
+ RData *data = new RData;
+ // ### Use typename class
+ data->identifier = ep->objectClass->createPersistentIdentifier(name);
+ data->typeNamespace = typeNamespace;
+ stringCache.insert(name, data);
+ identifierCache.insert(data->identifier.identifier, data);
+ typeNamespace->addref();
+}
+
+QmlTypeNameCache::Data *QmlTypeNameCache::data(const QString &id) const
+{
+ return stringCache.value(id);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/qmltypenamecache_p.h b/src/declarative/qml/qmltypenamecache_p.h
new file mode 100644
index 0000000..6022b43
--- /dev/null
+++ b/src/declarative/qml/qmltypenamecache_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLTYPENAMECACHE_P_H
+#define QMLTYPENAMECACHE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qmlrefcount_p.h>
+#include <private/qscriptdeclarativeclass_p.h>
+#include <private/qmlengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QmlType;
+class QmlEngine;
+class QmlTypeNameCache : public QmlRefCount
+{
+public:
+ QmlTypeNameCache(QmlEngine *);
+ virtual ~QmlTypeNameCache();
+
+ struct Data {
+ inline Data();
+ inline ~Data();
+ QmlType *type;
+ QmlTypeNameCache *typeNamespace;
+ };
+
+ void add(const QString &, QmlType *);
+ void add(const QString &, QmlTypeNameCache *);
+
+ Data *data(const QString &) const;
+ inline Data *data(const QScriptDeclarativeClass::Identifier &id) const;
+
+private:
+ struct RData : public Data {
+ QScriptDeclarativeClass::PersistentIdentifier identifier;
+ };
+ typedef QHash<QString, RData *> StringCache;
+ typedef QHash<QScriptDeclarativeClass::Identifier, RData *> IdentifierCache;
+
+ StringCache stringCache;
+ IdentifierCache identifierCache;
+ QmlEngine *engine;
+};
+
+QmlTypeNameCache::Data::Data()
+: type(0), typeNamespace(0)
+{
+}
+
+QmlTypeNameCache::Data::~Data()
+{
+ if (typeNamespace) typeNamespace->release();
+}
+
+QmlTypeNameCache::Data *QmlTypeNameCache::data(const QScriptDeclarativeClass::Identifier &id) const
+{
+ return identifierCache.value(id);
+}
+
+QT_END_NAMESPACE
+
+#endif // QMLTYPENAMECACHE_P_H
+
diff --git a/src/declarative/qml/qmltypenamescriptclass.cpp b/src/declarative/qml/qmltypenamescriptclass.cpp
new file mode 100644
index 0000000..29e2978
--- /dev/null
+++ b/src/declarative/qml/qmltypenamescriptclass.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmltypenamescriptclass_p.h"
+#include <private/qmlengine_p.h>
+#include <private/qmltypenamecache_p.h>
+
+QT_BEGIN_NAMESPACE
+
+struct TypeNameData {
+ TypeNameData(QObject *o, QmlType *t) : object(o), type(t), typeNamespace(0) {}
+ TypeNameData(QObject *o, QmlTypeNameCache *n) : object(o), type(0), typeNamespace(n) {
+ if (typeNamespace) typeNamespace->addref();
+ }
+ ~TypeNameData() {
+ if (typeNamespace) typeNamespace->release();
+ }
+
+ QObject *object;
+ QmlType *type;
+ QmlTypeNameCache *typeNamespace;
+};
+
+QmlTypeNameScriptClass::QmlTypeNameScriptClass(QmlEngine *bindEngine)
+: QScriptDeclarativeClass(QmlEnginePrivate::getScriptEngine(bindEngine)),
+ engine(bindEngine), object(0), type(0)
+{
+}
+
+QmlTypeNameScriptClass::~QmlTypeNameScriptClass()
+{
+}
+
+QScriptValue QmlTypeNameScriptClass::newObject(QObject *object, QmlType *type)
+{
+ QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
+
+ return QScriptDeclarativeClass::newObject(scriptEngine, this, (Object)new TypeNameData(object, type));
+}
+
+QScriptValue QmlTypeNameScriptClass::newObject(QObject *object, QmlTypeNameCache *ns)
+{
+ QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
+
+ return QScriptDeclarativeClass::newObject(scriptEngine, this, (Object)new TypeNameData(object, ns));
+}
+
+
+QScriptClass::QueryFlags
+QmlTypeNameScriptClass::queryProperty(const Object &obj, const Identifier &name,
+ QScriptClass::QueryFlags flags)
+{
+ Q_UNUSED(flags);
+
+ TypeNameData *data = (TypeNameData *)obj;
+
+ object = 0;
+ type = 0;
+ QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
+
+ if (data->typeNamespace) {
+
+ QmlTypeNameCache::Data *d = data->typeNamespace->data(name);
+ if (d && d->type) {
+ type = d->type;
+ return QScriptClass::HandlesReadAccess;
+ } else {
+ return 0;
+ }
+
+ } else {
+ Q_ASSERT(data->type);
+
+ QString strName = toString(name);
+
+ if (strName.at(0).isUpper()) {
+ // Must be an enum
+ // ### Optimize
+ const char *enumName = strName.toUtf8().constData();
+ const QMetaObject *metaObject = data->type->baseMetaObject();
+ for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
+ QMetaEnum e = metaObject->enumerator(ii);
+ int value = e.keyToValue(enumName);
+ if (value != -1) {
+ enumValue = value;
+ return QScriptClass::HandlesReadAccess;
+ }
+ }
+ return 0;
+ } else {
+ // Must be an attached property
+ object = qmlAttachedPropertiesObjectById(data->type->index(), data->object);
+ if (!object) return 0;
+ return ep->objectClass->queryProperty(object, name, flags);
+ }
+ }
+}
+
+QScriptValue QmlTypeNameScriptClass::property(const Object &obj, const Identifier &name)
+{
+ QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
+ if (type) {
+ return newObject(object, type);
+ } else if (object) {
+ return ep->objectClass->property(((TypeNameData *)obj)->object, name);
+ } else {
+ return QScriptValue(enumValue);
+ }
+}
+
+void QmlTypeNameScriptClass::setProperty(const Object &o, const Identifier &n, const QScriptValue &v)
+{
+ Q_ASSERT(object);
+ Q_ASSERT(!type);
+
+ QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
+ ep->objectClass->setProperty(((TypeNameData *)o)->object, n, v);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/qmltypenamescriptclass_p.h b/src/declarative/qml/qmltypenamescriptclass_p.h
new file mode 100644
index 0000000..c642ea4
--- /dev/null
+++ b/src/declarative/qml/qmltypenamescriptclass_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLTYPENAMESCRIPTCLASS_P_H
+#define QMLTYPENAMESCRIPTCLASS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#include <QtScript/qscriptclass.h>
+#include <private/qscriptdeclarativeclass_p.h>
+#include <private/qmlengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QmlEngine;
+class QmlType;
+class QmlTypeNameCache;
+class QmlTypeNameScriptClass : public QScriptDeclarativeClass
+{
+public:
+ QmlTypeNameScriptClass(QmlEngine *);
+ ~QmlTypeNameScriptClass();
+
+ QScriptValue newObject(QObject *, QmlType *);
+ QScriptValue newObject(QObject *, QmlTypeNameCache *);
+
+protected:
+ virtual QScriptClass::QueryFlags queryProperty(const Object &, const Identifier &,
+ QScriptClass::QueryFlags flags);
+
+ virtual QScriptValue property(const Object &, const Identifier &);
+ virtual void setProperty(const Object &, const Identifier &name, const QScriptValue &);
+
+private:
+ QmlEngine *engine;
+ QObject *object;
+ QmlType *type;
+ quint32 enumValue;
+};
+
+QT_END_NAMESPACE
+
+#endif // QMLTYPENAMESCRIPTCLASS_P_H
+
diff --git a/src/declarative/qml/qmlvaluetypescriptclass.cpp b/src/declarative/qml/qmlvaluetypescriptclass.cpp
new file mode 100644
index 0000000..da6c73d
--- /dev/null
+++ b/src/declarative/qml/qmlvaluetypescriptclass.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlvaluetypescriptclass_p.h"
+#include <private/qmlengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QmlValueTypeReference {
+ QmlValueType *type;
+ QGuard<QObject> object;
+ int property;
+};
+Q_DECLARE_METATYPE(QmlValueTypeReference);
+
+QmlValueTypeScriptClass::QmlValueTypeScriptClass(QmlEngine *bindEngine)
+: QScriptClass(QmlEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine)
+{
+}
+
+QmlValueTypeScriptClass::~QmlValueTypeScriptClass()
+{
+}
+
+QScriptValue QmlValueTypeScriptClass::newObject(QObject *object, int coreIndex, QmlValueType *type)
+{
+ QmlValueTypeReference ref = { type, object, coreIndex };
+ return QScriptValue();
+}
+
+QmlValueTypeScriptClass::QueryFlags
+QmlValueTypeScriptClass::queryProperty(const QScriptValue &object,
+ const QScriptString &name,
+ QueryFlags flags, uint *id)
+{
+ Q_UNUSED(flags);
+ QmlValueTypeReference ref =
+ qvariant_cast<QmlValueTypeReference>(object.data().toVariant());
+
+ if (!ref.object)
+ return 0;
+
+ QByteArray propName = name.toString().toUtf8();
+
+ int idx = ref.type->metaObject()->indexOfProperty(propName.constData());
+ if (idx == -1)
+ return 0;
+ *id = idx;
+
+ QMetaProperty prop = ref.object->metaObject()->property(idx);
+
+ QmlValueTypeScriptClass::QueryFlags rv =
+ QmlValueTypeScriptClass::HandlesReadAccess;
+ if (prop.isWritable())
+ rv |= QmlValueTypeScriptClass::HandlesWriteAccess;
+
+ return rv;
+}
+
+QScriptValue QmlValueTypeScriptClass::property(const QScriptValue &object,
+ const QScriptString &name,
+ uint id)
+{
+ Q_UNUSED(name);
+ QmlValueTypeReference ref =
+ qvariant_cast<QmlValueTypeReference>(object.data().toVariant());
+
+ if (!ref.object)
+ return QScriptValue();
+
+ ref.type->read(ref.object, ref.property);
+
+ QMetaProperty p = ref.type->metaObject()->property(id);
+ QVariant rv = p.read(ref.type);
+
+ return static_cast<QmlEnginePrivate *>(QObjectPrivate::get(engine))->scriptEngine.newVariant(rv);
+}
+
+void QmlValueTypeScriptClass::setProperty(QScriptValue &object,
+ const QScriptString &name,
+ uint id,
+ const QScriptValue &value)
+{
+ Q_UNUSED(name);
+ QmlValueTypeReference ref =
+ qvariant_cast<QmlValueTypeReference>(object.data().toVariant());
+
+ if (!ref.object)
+ return;
+
+ QVariant v = QmlScriptClass::toVariant(engine, value);
+
+ ref.type->read(ref.object, ref.property);
+ QMetaProperty p = ref.type->metaObject()->property(id);
+ p.write(ref.type, v);
+ ref.type->write(ref.object, ref.property);
+}
+
+QVariant QmlValueTypeScriptClass::toVariant(const QScriptValue &val)
+{
+ QmlValueTypeReference ref =
+ qvariant_cast<QmlValueTypeReference>(val.data().toVariant());
+
+ if (!ref.object)
+ return QVariant();
+
+ QMetaProperty p = ref.object->metaObject()->property(ref.property);
+ return p.read(ref.object);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/qmlvaluetypescriptclass_p.h b/src/declarative/qml/qmlvaluetypescriptclass_p.h
new file mode 100644
index 0000000..d656a22
--- /dev/null
+++ b/src/declarative/qml/qmlvaluetypescriptclass_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLVALUETYPESCRIPTCLASS_P_H
+#define QMLVALUETYPESCRIPTCLASS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#include <QtScript/qscriptclass.h>
+#include <private/qscriptdeclarativeclass_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QmlEngine;
+class QmlValueType;
+class QmlValueTypeScriptClass : public QScriptClass
+{
+public:
+ QmlValueTypeScriptClass(QmlEngine *);
+ ~QmlValueTypeScriptClass();
+
+ QScriptValue newObject(QObject *object, int coreIndex, QmlValueType *);
+
+ virtual QueryFlags queryProperty(const QScriptValue &object,
+ const QScriptString &name,
+ QueryFlags flags, uint *id);
+ virtual QScriptValue property(const QScriptValue &object,
+ const QScriptString &name,
+ uint id);
+ virtual void setProperty(QScriptValue &object,
+ const QScriptString &name,
+ uint id,
+ const QScriptValue &value);
+
+ QVariant toVariant(const QScriptValue &);
+private:
+ QmlEngine *engine;
+};
+
+QT_END_NAMESPACE
+
+#endif // QMLVALUETYPESCRIPTCLASS_P_H
+
diff --git a/src/declarative/util/qmlscript.cpp b/src/declarative/util/qmlscript.cpp
index de2128d..2031a54 100644
--- a/src/declarative/util/qmlscript.cpp
+++ b/src/declarative/util/qmlscript.cpp
@@ -179,10 +179,14 @@ void QmlScriptPrivate::addScriptToEngine(const QString &script, const QString &s
QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
QScriptContext *scriptContext = scriptEngine->pushContext();
- for (int i = context->d_func()->scopeChain.size() - 1; i > -1; --i) {
+ for (int i = context->d_func()->scopeChain.size() - 1; i >= 0; --i) {
scriptContext->pushScope(context->d_func()->scopeChain.at(i));
}
- scriptContext->setActivationObject(context->d_func()->scopeChain.at(0));
+
+ QScriptValue scope = scriptEngine->newObject();
+ scriptContext->pushScope(scope);
+
+ scriptContext->setActivationObject(scope);
QScriptValue val = scriptEngine->evaluate(script, source);
if (scriptEngine->hasUncaughtException()) {
@@ -200,6 +204,8 @@ void QmlScriptPrivate::addScriptToEngine(const QString &script, const QString &s
}
scriptEngine->popContext();
+
+ context->d_func()->scripts.append(scope);
}
QT_END_NAMESPACE