diff options
author | Martin Jones <martin.jones@nokia.com> | 2010-04-28 05:20:09 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2010-04-28 05:20:09 (GMT) |
commit | 5c3ec68c09f73d8b6178906884416677e8054299 (patch) | |
tree | 384f47ecd5eab52aefb123dab7afe57fe2c065d6 | |
parent | c102278ade3445c72db4b3b7c6ae592ef72eee22 (diff) | |
parent | ad15433463b0d28e7bd024cba8641e00dd8d376f (diff) | |
download | Qt-5c3ec68c09f73d8b6178906884416677e8054299.zip Qt-5c3ec68c09f73d8b6178906884416677e8054299.tar.gz Qt-5c3ec68c09f73d8b6178906884416677e8054299.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
-rw-r--r-- | src/declarative/qml/qdeclarativecompiler.cpp | 21 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecompiler_p.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine.cpp | 473 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine_p.h | 56 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeparser_p.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativepropertycache.cpp | 29 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativepropertycache_p.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativescriptparser.cpp | 75 | ||||
-rw-r--r-- | src/declarative/util/qdeclarativeopenmetaobject.cpp | 2 | ||||
-rw-r--r-- | tests/auto/declarative/examples/tst_examples.cpp | 2 | ||||
-rw-r--r-- | tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp | 4 | ||||
-rw-r--r-- | tests/benchmarks/declarative/compilation/compilation.pro | 11 | ||||
-rw-r--r-- | tests/benchmarks/declarative/compilation/data/BoomBlock.qml | 65 | ||||
-rw-r--r-- | tests/benchmarks/declarative/compilation/tst_compilation.cpp | 90 |
14 files changed, 503 insertions, 330 deletions
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 1727687..f64efcb 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -688,14 +688,12 @@ void QDeclarativeCompiler::compileTree(Object *tree) def.type = QDeclarativeInstruction::SetDefault; output->bytecode << def; - output->imports = unit->imports; - output->importCache = new QDeclarativeTypeNameCache(engine); for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) output->importCache->add(importedScriptIndexes.at(ii), ii); - output->imports.cache(output->importCache, engine); + unit->imports.cache(output->importCache, engine); Q_ASSERT(tree->metatype); @@ -938,19 +936,28 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) meta.storeMeta.propertyCache = output->propertyCaches.count(); // ### Surely the creation of this property cache could be more efficient QDeclarativePropertyCache *propertyCache = 0; - if (tr.component && QDeclarativeComponentPrivate::get(tr.component)->cc->rootPropertyCache) { + if (tr.component) propertyCache = QDeclarativeComponentPrivate::get(tr.component)->cc->rootPropertyCache->copy(); - } else { - propertyCache = QDeclarativePropertyCache::create(engine, obj->metaObject()->superClass()); - } + else + propertyCache = QDeclarativeEnginePrivate::get(engine)->cache(obj->metaObject()->superClass())->copy(); + propertyCache->append(engine, obj->metaObject(), QDeclarativePropertyCache::Data::NoFlags, QDeclarativePropertyCache::Data::IsVMEFunction); + if (obj == unitRoot) { propertyCache->addref(); output->rootPropertyCache = propertyCache; } + output->propertyCaches << propertyCache; output->bytecode << meta; + } else if (obj == unitRoot) { + if (tr.component) + output->rootPropertyCache = QDeclarativeComponentPrivate::get(tr.component)->cc->rootPropertyCache; + else + output->rootPropertyCache = QDeclarativeEnginePrivate::get(engine)->cache(obj->metaObject()); + + output->rootPropertyCache->addref(); } // Set the object id diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index fefab7a..cd612d8 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -84,7 +84,6 @@ public: QString name; QUrl url; - QDeclarativeEnginePrivate::Imports imports; QDeclarativeTypeNameCache *importCache; struct TypeReference diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 0ee6dfe..1f7f4a0 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1676,280 +1676,300 @@ static bool greaterThan(const QString &s1, const QString &s2) class QDeclarativeImportsPrivate { public: - QDeclarativeImportsPrivate() : ref(1) - { - } + QDeclarativeImportsPrivate(); + ~QDeclarativeImportsPrivate(); - ~QDeclarativeImportsPrivate() - { - foreach (QDeclarativeEnginePrivate::ImportedNamespace* s, set.values()) - delete s; - } + bool importExtension(const QString &absoluteFilePath, const QString &uri, + QDeclarativeEngine *engine, QDeclarativeDirComponents* components, + QString *errorString); - QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded; + QString resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine); + bool add(const QUrl& base, const QDeclarativeDirComponents &qmldircomponentsnetwork, + const QString& uri_arg, const QString& prefix, + int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, + QDeclarativeEngine *engine, QString *errorString); + bool find(const QByteArray& type, int *vmajor, int *vminor, + QDeclarativeType** type_return, QUrl* url_return, QString *errorString); - bool importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine, QDeclarativeDirComponents* components, QString *errorString) { - QFile file(absoluteFilePath); - QString filecontent; - if (file.open(QFile::ReadOnly)) { - filecontent = QString::fromUtf8(file.readAll()); - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath; - } else { - if (errorString) - *errorString = QDeclarativeEngine::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath); - return false; - } - QDir dir = QFileInfo(file).dir(); + QDeclarativeEnginePrivate::ImportedNamespace *findNamespace(const QString& type); - QDeclarativeDirParser qmldirParser; - qmldirParser.setSource(filecontent); - qmldirParser.parse(); + QUrl base; + int ref; - if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { - qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); +private: + friend struct QDeclarativeEnginePrivate::Imports; + QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded; + QDeclarativeEnginePrivate::ImportedNamespace unqualifiedset; + QHash<QString,QDeclarativeEnginePrivate::ImportedNamespace* > set; +}; - foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { +QDeclarativeEnginePrivate::Imports::Imports(const Imports ©) +: d(copy.d) +{ + ++d->ref; +} - QString resolvedFilePath = - QDeclarativeEnginePrivate::get(engine) - ->resolvePlugin(dir, plugin.path, - plugin.name); +QDeclarativeEnginePrivate::Imports & +QDeclarativeEnginePrivate::Imports::operator =(const Imports ©) +{ + ++copy.d->ref; + if (--d->ref == 0) + delete d; + d = copy.d; + return *this; +} - if (!resolvedFilePath.isEmpty()) { - if (!engine->importPlugin(resolvedFilePath, uri, errorString)) { - if (errorString) - *errorString = QDeclarativeEngine::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(*errorString); - return false; - } - } else { - if (errorString) - *errorString = QDeclarativeEngine::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name); - return false; - } - } - } +QDeclarativeEnginePrivate::Imports::Imports() +: d(new QDeclarativeImportsPrivate) +{ +} - if (components) - *components = qmldirParser.components(); +QDeclarativeEnginePrivate::Imports::~Imports() +{ + if (--d->ref == 0) + delete d; +} - return true; +QDeclarativeImportsPrivate::QDeclarativeImportsPrivate() +: ref(1) +{ +} + +QDeclarativeImportsPrivate::~QDeclarativeImportsPrivate() +{ + foreach (QDeclarativeEnginePrivate::ImportedNamespace* s, set.values()) + delete s; +} + +bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine, + QDeclarativeDirComponents* components, QString *errorString) +{ + QFile file(absoluteFilePath); + QString filecontent; + if (file.open(QFile::ReadOnly)) { + filecontent = QString::fromUtf8(file.readAll()); + if (qmlImportTrace()) + qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath; + } else { + if (errorString) + *errorString = QDeclarativeEngine::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath); + return false; } + QDir dir = QFileInfo(file).dir(); - QString resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine) - { - QString dir = dir_arg; - if (dir.endsWith(QLatin1Char('/')) || dir.endsWith(QLatin1Char('\\'))) - dir.chop(1); + QDeclarativeDirParser qmldirParser; + qmldirParser.setSource(filecontent); + qmldirParser.parse(); - QStringList paths = QDeclarativeEnginePrivate::get(engine)->fileImportPath; - qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents. + if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { + qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); - QString stableRelativePath = dir; - foreach( QString path, paths) { - if (dir.startsWith(path)) { - stableRelativePath = dir.mid(path.length()+1); - break; + + foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { + + QString resolvedFilePath = + QDeclarativeEnginePrivate::get(engine) + ->resolvePlugin(dir, plugin.path, + plugin.name); + + if (!resolvedFilePath.isEmpty()) { + if (!engine->importPlugin(resolvedFilePath, uri, errorString)) { + if (errorString) + *errorString = QDeclarativeEngine::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(*errorString); + return false; + } + } else { + if (errorString) + *errorString = QDeclarativeEngine::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name); + return false; } } - stableRelativePath.replace(QLatin1Char('/'), QLatin1Char('.')); - stableRelativePath.replace(QLatin1Char('\\'), QLatin1Char('.')); - return stableRelativePath; } + if (components) + *components = qmldirParser.components(); + return true; +} +QString QDeclarativeImportsPrivate::resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine) +{ + QString dir = dir_arg; + if (dir.endsWith(QLatin1Char('/')) || dir.endsWith(QLatin1Char('\\'))) + dir.chop(1); - bool add(const QUrl& base, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine, QString *errorString) - { - QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; - QString uri = uri_arg; - QDeclarativeEnginePrivate::ImportedNamespace *s; - if (prefix.isEmpty()) { - s = &unqualifiedset; - } else { - s = set.value(prefix); - if (!s) - set.insert(prefix,(s=new QDeclarativeEnginePrivate::ImportedNamespace)); + QStringList paths = QDeclarativeEnginePrivate::get(engine)->fileImportPath; + qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents. + + QString stableRelativePath = dir; + foreach( QString path, paths) { + if (dir.startsWith(path)) { + stableRelativePath = dir.mid(path.length()+1); + break; } + } + stableRelativePath.replace(QLatin1Char('/'), QLatin1Char('.')); + stableRelativePath.replace(QLatin1Char('\\'), QLatin1Char('.')); + return stableRelativePath; +} +bool QDeclarativeImportsPrivate::add(const QUrl& base, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri_arg, + const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, + QDeclarativeEngine *engine, QString *errorString) +{ + QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; + QString uri = uri_arg; + QDeclarativeEnginePrivate::ImportedNamespace *s; + if (prefix.isEmpty()) { + s = &unqualifiedset; + } else { + s = set.value(prefix); + if (!s) + set.insert(prefix,(s=new QDeclarativeEnginePrivate::ImportedNamespace)); + } - QString url = uri; - if (importType == QDeclarativeScriptParser::Import::Library) { - url.replace(QLatin1Char('.'), QLatin1Char('/')); - bool found = false; - QString dir; + QString url = uri; + if (importType == QDeclarativeScriptParser::Import::Library) { + url.replace(QLatin1Char('.'), QLatin1Char('/')); + bool found = false; + QString dir; - foreach (const QString &p, - QDeclarativeEnginePrivate::get(engine)->fileImportPath) { - dir = p+QLatin1Char('/')+url; - QFileInfo fi(dir+QLatin1String("/qmldir")); - const QString absoluteFilePath = fi.absoluteFilePath(); + foreach (const QString &p, + QDeclarativeEnginePrivate::get(engine)->fileImportPath) { + dir = p+QLatin1Char('/')+url; - if (fi.isFile()) { - found = true; + QFileInfo fi(dir+QLatin1String("/qmldir")); + const QString absoluteFilePath = fi.absoluteFilePath(); - url = QUrl::fromLocalFile(fi.absolutePath()).toString(); - uri = resolvedUri(dir, engine); - if (!importExtension(absoluteFilePath, uri, engine, &qmldircomponents, errorString)) - return false; - break; - } + if (fi.isFile()) { + found = true; + + url = QUrl::fromLocalFile(fi.absolutePath()).toString(); + uri = resolvedUri(dir, engine); + if (!importExtension(absoluteFilePath, uri, engine, &qmldircomponents, errorString)) + return false; + break; } + } + if (!found) { + found = QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin); if (!found) { - found = QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin); - if (!found) { - if (errorString) { - bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), -1, -1); - if (anyversion) - *errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); - else - *errorString = QDeclarativeEngine::tr("module \"%1\" is not installed").arg(uri_arg); - } - return false; + if (errorString) { + bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), -1, -1); + if (anyversion) + *errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); + else + *errorString = QDeclarativeEngine::tr("module \"%1\" is not installed").arg(uri_arg); } + return false; } - } else { + } + } else { - if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) { - QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir"))); - QString localFileOrQrc = toLocalFileOrQrc(importUrl); - if (!localFileOrQrc.isEmpty()) { - QString dir = toLocalFileOrQrc(base.resolved(QUrl(uri))); - if (dir.isEmpty() || !QDir().exists(dir)) { - if (errorString) - *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri_arg); - return false; // local import dirs must exist - } - uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine); - if (uri.endsWith(QLatin1Char('/'))) - uri.chop(1); - if (QFile::exists(localFileOrQrc)) { - if (!importExtension(localFileOrQrc,uri,engine,&qmldircomponents,errorString)) - return false; - } - } else { - if (prefix.isEmpty()) { - // directory must at least exist for valid import - QString localFileOrQrc = toLocalFileOrQrc(base.resolved(QUrl(uri))); - if (localFileOrQrc.isEmpty() || !QDir().exists(localFileOrQrc)) { - if (errorString) { - if (localFileOrQrc.isEmpty()) - *errorString = QDeclarativeEngine::tr("import \"%1\" has no qmldir and no namespace").arg(uri); - else - *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri); - } - return false; + if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) { + QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir"))); + QString localFileOrQrc = toLocalFileOrQrc(importUrl); + if (!localFileOrQrc.isEmpty()) { + QString dir = toLocalFileOrQrc(base.resolved(QUrl(uri))); + if (dir.isEmpty() || !QDir().exists(dir)) { + if (errorString) + *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri_arg); + return false; // local import dirs must exist + } + uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine); + if (uri.endsWith(QLatin1Char('/'))) + uri.chop(1); + if (QFile::exists(localFileOrQrc)) { + if (!importExtension(localFileOrQrc,uri,engine,&qmldircomponents,errorString)) + return false; + } + } else { + if (prefix.isEmpty()) { + // directory must at least exist for valid import + QString localFileOrQrc = toLocalFileOrQrc(base.resolved(QUrl(uri))); + if (localFileOrQrc.isEmpty() || !QDir().exists(localFileOrQrc)) { + if (errorString) { + if (localFileOrQrc.isEmpty()) + *errorString = QDeclarativeEngine::tr("import \"%1\" has no qmldir and no namespace").arg(uri); + else + *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri); } + return false; } } } - - url = base.resolved(QUrl(url)).toString(); - if (url.endsWith(QLatin1Char('/'))) - url.chop(1); } - if (vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) { - QList<QDeclarativeDirParser::Component>::ConstIterator it = qmldircomponents.begin(); - for (; it != qmldircomponents.end(); ++it) { - if (it->majorVersion > vmaj || (it->majorVersion == vmaj && it->minorVersion >= vmin)) - break; - } - if (it == qmldircomponents.end()) { - *errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); - return false; - } - } - - s->uris.prepend(uri); - s->urls.prepend(url); - s->majversions.prepend(vmaj); - s->minversions.prepend(vmin); - s->isLibrary.prepend(importType == QDeclarativeScriptParser::Import::Library); - s->qmlDirComponents.prepend(qmldircomponents); - return true; + url = base.resolved(QUrl(url)).toString(); + if (url.endsWith(QLatin1Char('/'))) + url.chop(1); } - bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, - QUrl* url_return, QString *errorString) - { - QDeclarativeEnginePrivate::ImportedNamespace *s = 0; - int slash = type.indexOf('/'); - if (slash >= 0) { - QString namespaceName = QString::fromUtf8(type.left(slash)); - s = set.value(namespaceName); - if (!s) { - if (errorString) - *errorString = QDeclarativeEngine::tr("- %1 is not a namespace").arg(namespaceName); - return false; - } - int nslash = type.indexOf('/',slash+1); - if (nslash > 0) { - if (errorString) - *errorString = QDeclarativeEngine::tr("- nested namespaces not allowed"); - return false; - } - } else { - s = &unqualifiedset; + if (vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) { + QList<QDeclarativeDirParser::Component>::ConstIterator it = qmldircomponents.begin(); + for (; it != qmldircomponents.end(); ++it) { + if (it->majorVersion > vmaj || (it->majorVersion == vmaj && it->minorVersion >= vmin)) + break; } - QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) - if (s) { - if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString)) - return true; - if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) { - // qualified, and only 1 url - *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml"))); - return true; - } + if (it == qmldircomponents.end()) { + *errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); + return false; } - - return false; - } - - QDeclarativeEnginePrivate::ImportedNamespace *findNamespace(const QString& type) - { - return set.value(type); } - QUrl base; - int ref; - -private: - friend struct QDeclarativeEnginePrivate::Imports; - QDeclarativeEnginePrivate::ImportedNamespace unqualifiedset; - QHash<QString,QDeclarativeEnginePrivate::ImportedNamespace* > set; -}; - -QDeclarativeEnginePrivate::Imports::Imports(const Imports ©) : - d(copy.d) -{ - ++d->ref; + s->uris.prepend(uri); + s->urls.prepend(url); + s->majversions.prepend(vmaj); + s->minversions.prepend(vmin); + s->isLibrary.prepend(importType == QDeclarativeScriptParser::Import::Library); + s->qmlDirComponents.prepend(qmldircomponents); + return true; } -QDeclarativeEnginePrivate::Imports &QDeclarativeEnginePrivate::Imports::operator =(const Imports ©) +bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, + QUrl* url_return, QString *errorString) { - ++copy.d->ref; - if (--d->ref == 0) - delete d; - d = copy.d; - return *this; -} + QDeclarativeEnginePrivate::ImportedNamespace *s = 0; + int slash = type.indexOf('/'); + if (slash >= 0) { + QString namespaceName = QString::fromUtf8(type.left(slash)); + s = set.value(namespaceName); + if (!s) { + if (errorString) + *errorString = QDeclarativeEngine::tr("- %1 is not a namespace").arg(namespaceName); + return false; + } + int nslash = type.indexOf('/',slash+1); + if (nslash > 0) { + if (errorString) + *errorString = QDeclarativeEngine::tr("- nested namespaces not allowed"); + return false; + } + } else { + s = &unqualifiedset; + } + QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) + if (s) { + if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString)) + return true; + if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) { + // qualified, and only 1 url + *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml"))); + return true; + } + } -QDeclarativeEnginePrivate::Imports::Imports() : - d(new QDeclarativeImportsPrivate) -{ + return false; } -QDeclarativeEnginePrivate::Imports::~Imports() +QDeclarativeEnginePrivate::ImportedNamespace *QDeclarativeImportsPrivate::findNamespace(const QString& type) { - if (--d->ref == 0) - delete d; + return set.value(type); } static QDeclarativeTypeNameCache *cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeEnginePrivate::ImportedNamespace &set, QDeclarativeTypeNameCache *cache) @@ -2000,22 +2020,6 @@ void QDeclarativeEnginePrivate::Imports::cache(QDeclarativeTypeNameCache *cache, cacheForNamespace(engine, set, cache); } -/* -QStringList QDeclarativeEnginePrivate::Imports::unqualifiedSet() const -{ - QStringList rv; - - const QDeclarativeEnginePrivate::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. */ @@ -2054,7 +2058,6 @@ void QDeclarativeEngine::addImportPath(const QString& path) } } - /*! Returns the list of directories where the engine searches for installed modules in a URL-based directory structure. diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 743275e..ca033bf 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -244,18 +244,8 @@ public: QDeclarativeValueTypeFactory valueTypes; QHash<const QMetaObject *, QDeclarativePropertyCache *> propertyCache; - QDeclarativePropertyCache *cache(QObject *obj) { - Q_Q(QDeclarativeEngine); - if (!obj || QObjectPrivate::get(obj)->metaObject || - QObjectPrivate::get(obj)->wasDeleted) return 0; - const QMetaObject *mo = obj->metaObject(); - QDeclarativePropertyCache *rv = propertyCache.value(mo); - if (!rv) { - rv = QDeclarativePropertyCache::create(q, mo); - propertyCache.insert(mo, rv); - } - return rv; - } + inline QDeclarativePropertyCache *cache(QObject *obj); + inline QDeclarativePropertyCache *cache(const QMetaObject *); // ### This whole class is embarrassing struct Imports { @@ -361,6 +351,48 @@ public: static void defineModule(); }; +/*! +Returns a QDeclarativePropertyCache for \a obj if one is available. + +If \a obj is null, being deleted or contains a dynamic meta object 0 +is returned. +*/ +QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QObject *obj) +{ + Q_Q(QDeclarativeEngine); + if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted) + return 0; + + const QMetaObject *mo = obj->metaObject(); + QDeclarativePropertyCache *rv = propertyCache.value(mo); + if (!rv) { + rv = new QDeclarativePropertyCache(q, mo); + propertyCache.insert(mo, rv); + } + return rv; +} + +/*! +Returns a QDeclarativePropertyCache for \a metaObject. + +As the cache is persisted for the life of the engine, \a metaObject must be +a static "compile time" meta-object, or a meta-object that is otherwise known to +exist for the lifetime of the QDeclarativeEngine. +*/ +QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(const QMetaObject *metaObject) +{ + Q_Q(QDeclarativeEngine); + Q_ASSERT(metaObject); + + QDeclarativePropertyCache *rv = propertyCache.value(metaObject); + if (!rv) { + rv = new QDeclarativePropertyCache(q, metaObject); + propertyCache.insert(metaObject, rv); + } + + return rv; +} + QT_END_NAMESPACE #endif // QDECLARATIVEENGINE_P_H diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 0870cfb..25777f5 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -188,9 +188,6 @@ namespace QDeclarativeParser QList<int> lineNumbers; QList<Pragmas> pragmas; }; -#if 0 - QList<ScriptBlock> scripts; -#endif // The bytes to cast instances by to get to the QDeclarativeParserStatus // interface. -1 indicates the type doesn't support this interface. diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 888945b..f04a706 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -106,9 +106,25 @@ void QDeclarativePropertyCache::Data::load(const QMetaMethod &m) } +/*! +Creates a new empty QDeclarativePropertyCache. +*/ QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e) : QDeclarativeCleanup(e), engine(e) { + Q_ASSERT(engine); +} + +/*! +Creates a new QDeclarativePropertyCache of \a metaObject. +*/ +QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e, const QMetaObject *metaObject) +: QDeclarativeCleanup(e), engine(e) +{ + Q_ASSERT(engine); + Q_ASSERT(metaObject); + + update(engine, metaObject); } QDeclarativePropertyCache::~QDeclarativePropertyCache() @@ -135,7 +151,7 @@ void QDeclarativePropertyCache::clear() } QDeclarativePropertyCache::Data QDeclarativePropertyCache::create(const QMetaObject *metaObject, - const QString &property) + const QString &property) { Q_ASSERT(metaObject); @@ -245,17 +261,6 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb } } -// ### Optimize - check engine for the parent meta object etc. -QDeclarativePropertyCache *QDeclarativePropertyCache::create(QDeclarativeEngine *engine, const QMetaObject *metaObject) -{ - Q_ASSERT(engine); - Q_ASSERT(metaObject); - - QDeclarativePropertyCache *cache = new QDeclarativePropertyCache(engine); - cache->update(engine, metaObject); - return cache; -} - void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaObject *metaObject) { Q_ASSERT(engine); diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 6b64a96..b01e5cc 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -69,6 +69,7 @@ class QDeclarativePropertyCache : public QDeclarativeRefCount, public QDeclarati { public: QDeclarativePropertyCache(QDeclarativeEngine *); + QDeclarativePropertyCache(QDeclarativeEngine *, const QMetaObject *); virtual ~QDeclarativePropertyCache(); struct Data { diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp index 8b96733..219d759 100644 --- a/src/declarative/qml/qdeclarativescriptparser.cpp +++ b/src/declarative/qml/qdeclarativescriptparser.cpp @@ -104,17 +104,13 @@ public: void operator()(const QString &code, AST::Node *node); protected: + Object *defineObjectBinding(AST::UiQualifiedId *propertyName, bool onAssignment, - AST::UiQualifiedId *objectTypeName, + const QString &objectType, + AST::SourceLocation typeLocation, LocationSpan location, AST::UiObjectInitializer *initializer = 0); - Object *defineObjectBinding_helper(AST::UiQualifiedId *propertyName, bool onAssignment, - const QString &objectType, - AST::SourceLocation typeLocation, - LocationSpan location, - AST::UiObjectInitializer *initializer = 0); - QDeclarativeParser::Variant getVariant(AST::ExpressionNode *expr); LocationSpan location(AST::SourceLocation start, AST::SourceLocation end); @@ -240,12 +236,12 @@ QString ProcessAST::asString(AST::UiQualifiedId *node) const } Object * -ProcessAST::defineObjectBinding_helper(AST::UiQualifiedId *propertyName, - bool onAssignment, - const QString &objectType, - AST::SourceLocation typeLocation, - LocationSpan location, - AST::UiObjectInitializer *initializer) +ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName, + bool onAssignment, + const QString &objectType, + AST::SourceLocation typeLocation, + LocationSpan location, + AST::UiObjectInitializer *initializer) { int lastTypeDot = objectType.lastIndexOf(QLatin1Char('.')); bool isType = !objectType.isEmpty() && @@ -355,41 +351,6 @@ ProcessAST::defineObjectBinding_helper(AST::UiQualifiedId *propertyName, } } -Object *ProcessAST::defineObjectBinding(AST::UiQualifiedId *qualifiedId, bool onAssignment, - AST::UiQualifiedId *objectTypeName, - LocationSpan location, - AST::UiObjectInitializer *initializer) -{ - const QString objectType = asString(objectTypeName); - const AST::SourceLocation typeLocation = objectTypeName->identifierToken; - - if (objectType == QLatin1String("Script")) { - - AST::UiObjectMemberList *it = initializer->members; - for (; it; it = it->next) { - AST::UiScriptBinding *scriptBinding = AST::cast<AST::UiScriptBinding *>(it->member); - if (! scriptBinding) - continue; - - QString propertyName = asString(scriptBinding->qualifiedId); - if (propertyName == QLatin1String("source")) { - if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement *>(scriptBinding->statement)) { - QDeclarativeParser::Variant string = getVariant(stmt->expression); - if (string.isStringList()) { - QStringList urls = string.asStringList(); - // We need to add this as a resource - for (int ii = 0; ii < urls.count(); ++ii) - _parser->_refUrls << QUrl(urls.at(ii)); - } - } - } - } - - } - - return defineObjectBinding_helper(qualifiedId, onAssignment, objectType, typeLocation, location, initializer); -} - LocationSpan ProcessAST::location(AST::UiQualifiedId *id) { return location(id->identifierToken, id->identifierToken); @@ -664,10 +625,11 @@ bool ProcessAST::visit(AST::UiObjectDefinition *node) LocationSpan l = location(node->firstSourceLocation(), node->lastSourceLocation()); - defineObjectBinding(/*propertyName = */ 0, false, - node->qualifiedTypeNameId, - l, - node->initializer); + const QString objectType = asString(node->qualifiedTypeNameId); + const AST::SourceLocation typeLocation = node->qualifiedTypeNameId->identifierToken; + + defineObjectBinding(/*propertyName = */ 0, false, objectType, + typeLocation, l, node->initializer); return false; } @@ -679,10 +641,11 @@ bool ProcessAST::visit(AST::UiObjectBinding *node) LocationSpan l = location(node->qualifiedTypeNameId->identifierToken, node->initializer->rbraceToken); - defineObjectBinding(node->qualifiedId, node->hasOnToken, - node->qualifiedTypeNameId, - l, - node->initializer); + const QString objectType = asString(node->qualifiedTypeNameId); + const AST::SourceLocation typeLocation = node->qualifiedTypeNameId->identifierToken; + + defineObjectBinding(node->qualifiedId, node->hasOnToken, objectType, + typeLocation, l, node->initializer); return false; } diff --git a/src/declarative/util/qdeclarativeopenmetaobject.cpp b/src/declarative/util/qdeclarativeopenmetaobject.cpp index 0e5aaa6..ba5d534 100644 --- a/src/declarative/util/qdeclarativeopenmetaobject.cpp +++ b/src/declarative/util/qdeclarativeopenmetaobject.cpp @@ -305,7 +305,7 @@ void QDeclarativeOpenMetaObject::setCached(bool c) QDeclarativeData *qmldata = QDeclarativeData::get(d->object, true); if (d->cacheProperties) { if (!d->type->d->cache) - d->type->d->cache = QDeclarativePropertyCache::create(d->type->d->engine, this); + d->type->d->cache = new QDeclarativePropertyCache(d->type->d->engine, this); qmldata->propertyCache = d->type->d->cache; d->type->d->cache->addref(); } else { diff --git a/tests/auto/declarative/examples/tst_examples.cpp b/tests/auto/declarative/examples/tst_examples.cpp index 16b0cbe..058fda1 100644 --- a/tests/auto/declarative/examples/tst_examples.cpp +++ b/tests/auto/declarative/examples/tst_examples.cpp @@ -89,6 +89,8 @@ tst_examples::tst_examples() excludedDirs << "examples/declarative/imageprovider"; excludedDirs << "demos/declarative/minehunt"; + excludedDirs << "doc/src/snippets/declarative/graphicswidgets"; + #ifdef QT_NO_WEBKIT excludedDirs << "examples/declarative/webview"; excludedDirs << "demos/declarative/webbrowser"; diff --git a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp index a951827..6c19566 100644 --- a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp +++ b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp @@ -419,10 +419,8 @@ void tst_qdeclarativedom::loadSyntaxErrors() void tst_qdeclarativedom::loadRemoteErrors() { QByteArray qml = "import Qt 4.7\n" + "import \"http://localhost/exampleQmlScript.js\" as Script\n" "Item {\n" - " Script {\n" - " source: \"http://localhost/exampleQmlScript.js\"" - " }\n" "}"; QDeclarativeDomDocument document; QVERIFY(false == document.load(&engine, qml)); diff --git a/tests/benchmarks/declarative/compilation/compilation.pro b/tests/benchmarks/declarative/compilation/compilation.pro new file mode 100644 index 0000000..32f4aba --- /dev/null +++ b/tests/benchmarks/declarative/compilation/compilation.pro @@ -0,0 +1,11 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_compilation +QT += declarative +macx:CONFIG -= app_bundle + +CONFIG += release + +SOURCES += tst_compilation.cpp + +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/benchmarks/declarative/compilation/data/BoomBlock.qml b/tests/benchmarks/declarative/compilation/data/BoomBlock.qml new file mode 100644 index 0000000..47f43c2 --- /dev/null +++ b/tests/benchmarks/declarative/compilation/data/BoomBlock.qml @@ -0,0 +1,65 @@ +import Qt 4.7 +import Qt.labs.particles 1.0 + +Item { + id: block + property bool dying: false + property bool spawned: false + property int type: 0 + property int targetX: 0 + property int targetY: 0 + + SpringFollow on x { enabled: spawned; to: targetX; spring: 2; damping: 0.2 } + SpringFollow on y { to: targetY; spring: 2; damping: 0.2 } + + Image { + id: img + source: { + if(type == 0){ + "pics/redStone.png"; + } else if(type == 1) { + "pics/blueStone.png"; + } else { + "pics/greenStone.png"; + } + } + opacity: 0 + Behavior on opacity { NumberAnimation { duration: 200 } } + anchors.fill: parent + } + + Particles { + id: particles + + width: 1; height: 1 + anchors.centerIn: parent + + emissionRate: 0 + lifeSpan: 700; lifeSpanDeviation: 600 + angle: 0; angleDeviation: 360; + velocity: 100; velocityDeviation: 30 + source: { + if(type == 0){ + "pics/redStar.png"; + } else if (type == 1) { + "pics/blueStar.png"; + } else { + "pics/greenStar.png"; + } + } + } + + states: [ + State { + name: "AliveState"; when: spawned == true && dying == false + PropertyChanges { target: img; opacity: 1 } + }, + + State { + name: "DeathState"; when: dying == true + StateChangeScript { script: particles.burst(50); } + PropertyChanges { target: img; opacity: 0 } + StateChangeScript { script: block.destroy(1000); } + } + ] +} diff --git a/tests/benchmarks/declarative/compilation/tst_compilation.cpp b/tests/benchmarks/declarative/compilation/tst_compilation.cpp new file mode 100644 index 0000000..5694d5b --- /dev/null +++ b/tests/benchmarks/declarative/compilation/tst_compilation.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QDeclarativeEngine> +#include <QDeclarativeComponent> +#include <QFile> + +#ifdef Q_OS_SYMBIAN +// In Symbian OS test data is located in applications private dir +// Application private dir is default serach path for files, so SRCDIR can be set to empty +#define SRCDIR "" +#endif + +class tst_compilation : public QObject +{ + Q_OBJECT +public: + tst_compilation(); + +private slots: + void boomblock(); + +private: + QDeclarativeEngine engine; +}; + +tst_compilation::tst_compilation() +{ +} + +inline QUrl TEST_FILE(const QString &filename) +{ + return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename); +} + +void tst_compilation::boomblock() +{ + QFile f(SRCDIR + QLatin1String("/data/BoomBlock.qml")); + QVERIFY(f.open(QIODevice::ReadOnly)); + QByteArray data = f.readAll(); + + QBENCHMARK { + QDeclarativeComponent c(&engine); + c.setData(data, QUrl()); +// QVERIFY(c.isReady()); + } +} + +QTEST_MAIN(tst_compilation) + +#include "tst_compilation.moc" |