aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2012-05-16 17:49:32 +1000
committerQt by Nokia <qt-info@nokia.com>2012-05-17 13:42:27 +0200
commit8017cf63505f7ed477c658634ec882a12d3b3ddc (patch)
tree28d023fe7e8a2b2392c564a37ef7b891d2bb41b8 /src/qml/qml
parentc556eecc25e24d6ee4f5c9965193a588c93b95fc (diff)
Optimize type resolution
Faster qmlType() and resolveType() lookup. Change-Id: I096439f23bf6071e8bfdf0cda366cc71e00293ba Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/ftw/qhashedstring.cpp21
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h1
-rw-r--r--src/qml/qml/qqmlcompiler.cpp11
-rw-r--r--src/qml/qml/qqmldirparser.cpp8
-rw-r--r--src/qml/qml/qqmldirparser_p.h7
-rw-r--r--src/qml/qml/qqmlimport.cpp61
-rw-r--r--src/qml/qml/qqmlimport_p.h4
-rw-r--r--src/qml/qml/qqmlmetatype.cpp138
-rw-r--r--src/qml/qml/qqmlmetatype_p.h15
9 files changed, 147 insertions, 119 deletions
diff --git a/src/qml/qml/ftw/qhashedstring.cpp b/src/qml/qml/ftw/qhashedstring.cpp
index 1f09d50ed3..2dc717b488 100644
--- a/src/qml/qml/ftw/qhashedstring.cpp
+++ b/src/qml/qml/ftw/qhashedstring.cpp
@@ -443,6 +443,27 @@ bool QHashedStringRef::startsWith(const QString &s) const
QHashedString::compare(s.constData(), m_data, s.length());
}
+static int findChar(const QChar *str, int len, QChar ch, int from)
+{
+ const ushort *s = (const ushort *)str;
+ ushort c = ch.unicode();
+ if (from < 0)
+ from = qMax(from + len, 0);
+ if (from < len) {
+ const ushort *n = s + from - 1;
+ const ushort *e = s + len;
+ while (++n != e)
+ if (*n == c)
+ return n - s;
+ }
+ return -1;
+}
+
+int QHashedStringRef::indexOf(const QChar &c, int from) const
+{
+ return findChar(m_data, m_length, c, from);
+}
+
QString QHashedStringRef::toString() const
{
if (m_length == 0)
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index f058f21e98..f8099d508b 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -148,6 +148,7 @@ public:
inline const QChar *constData() const;
bool startsWith(const QString &) const;
bool endsWith(const QString &) const;
+ int indexOf(const QChar &, int from=0) const;
QHashedStringRef mid(int, int) const;
inline bool isEmpty() const;
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index c423d933d0..54035fcccf 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -90,7 +90,8 @@ using namespace QQmlCompilerTypes;
static QString id_string(QLatin1String("id"));
static QString on_string(QLatin1String("on"));
static QString Changed_string(QLatin1String("Changed"));
-static QString Component_import_string(QLatin1String("QML/Component"));
+static QString Component_string(QLatin1String("Component"));
+static QString Component_module_string(QLatin1String("QML"));
static QString qsTr_string(QLatin1String("qsTr"));
static QString qsTrId_string(QLatin1String("qsTrId"));
@@ -1603,7 +1604,7 @@ bool QQmlCompiler::buildSubObject(QQmlScript::Object *obj, const BindingContext
int QQmlCompiler::componentTypeRef()
{
if (cachedComponentTypeRef == -1) {
- QQmlType *t = QQmlMetaType::qmlType(Component_import_string,1,0);
+ QQmlType *t = QQmlMetaType::qmlType(Component_string, Component_module_string, 1, 0);
for (int ii = output->types.count() - 1; ii >= 0; --ii) {
if (output->types.at(ii).type == t) {
cachedComponentTypeRef = ii;
@@ -1739,7 +1740,7 @@ bool QQmlCompiler::buildProperty(QQmlScript::Property *prop,
QQmlType *type = 0;
QQmlImportNamespace *typeNamespace = 0;
- unit->imports().resolveType(prop->name().toString(), &type, 0, 0, 0, &typeNamespace);
+ unit->imports().resolveType(prop->name(), &type, 0, 0, 0, &typeNamespace);
if (typeNamespace) {
COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj,
@@ -1861,7 +1862,7 @@ bool QQmlCompiler::buildPropertyInNamespace(QQmlImportNamespace *ns,
// Setup attached property data
QQmlType *type = 0;
- unit->imports().resolveType(ns, prop->name().toString(), &type, 0, 0, 0);
+ unit->imports().resolveType(ns, prop->name(), &type, 0, 0, 0);
if (!type || !type->attachedPropertiesType())
COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
@@ -2875,7 +2876,7 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod
QByteArray customTypeName;
QQmlType *qmltype = 0;
QString url;
- if (!unit->imports().resolveType(p->customType.toString(), &qmltype, &url, 0, 0, 0))
+ if (!unit->imports().resolveType(p->customType, &qmltype, &url, 0, 0, 0))
COMPILE_EXCEPTION(p, tr("Invalid property type"));
if (!qmltype) {
diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qml/qqmldirparser.cpp
index 2da4a3300b..2fb47cc008 100644
--- a/src/qml/qml/qqmldirparser.cpp
+++ b/src/qml/qml/qqmldirparser.cpp
@@ -156,7 +156,7 @@ bool QQmlDirParser::parse()
}
Component entry(sections[1], sections[2], -1, -1);
entry.internal = true;
- _components.append(entry);
+ _components.insertMulti(entry.typeName, entry);
} else if (sections[0] == QLatin1String("typeinfo")) {
if (sectionCount != 2) {
reportError(lineNumber, -1,
@@ -171,7 +171,7 @@ bool QQmlDirParser::parse()
} else if (sectionCount == 2) {
// No version specified (should only be used for relative qmldir files)
const Component entry(sections[0], sections[1], -1, -1);
- _components.append(entry);
+ _components.insertMulti(entry.typeName, entry);
} else if (sectionCount == 3) {
const QString &version = sections[1];
const int dotIndex = version.indexOf(QLatin1Char('.'));
@@ -196,7 +196,7 @@ bool QQmlDirParser::parse()
_scripts.append(entry);
} else {
const Component entry(sections[0], fileName, majorVersion, minorVersion);
- _components.append(entry);
+ _components.insertMulti(entry.typeName, entry);
}
}
}
@@ -250,7 +250,7 @@ QList<QQmlDirParser::Plugin> QQmlDirParser::plugins() const
return _plugins;
}
-QList<QQmlDirParser::Component> QQmlDirParser::components() const
+QHash<QHashedStringRef,QQmlDirParser::Component> QQmlDirParser::components() const
{
return _components;
}
diff --git a/src/qml/qml/qqmldirparser_p.h b/src/qml/qml/qqmldirparser_p.h
index 77fe277a7e..4de39e04d9 100644
--- a/src/qml/qml/qqmldirparser_p.h
+++ b/src/qml/qml/qqmldirparser_p.h
@@ -56,6 +56,7 @@
#include <QtCore/QUrl>
#include <QtCore/QHash>
#include <QtCore/QDebug>
+#include <private/qhashedstring_p.h>
QT_BEGIN_NAMESPACE
@@ -120,7 +121,7 @@ public:
int minorVersion;
};
- QList<Component> components() const;
+ QHash<QHashedStringRef,Component> components() const;
QList<Script> scripts() const;
QList<Plugin> plugins() const;
@@ -143,7 +144,7 @@ private:
private:
QList<QQmlError> _errors;
QString _source;
- QList<Component> _components;
+ QHash<QHashedStringRef,Component> _components; // multi hash
QList<Script> _scripts;
QList<Plugin> _plugins;
#ifdef QT_CREATOR
@@ -152,7 +153,7 @@ private:
unsigned _isParsed: 1;
};
-typedef QList<QQmlDirParser::Component> QQmlDirComponents;
+typedef QHash<QHashedStringRef,QQmlDirParser::Component> QQmlDirComponents;
typedef QList<QQmlDirParser::Script> QQmlDirScripts;
QDebug &operator<< (QDebug &, const QQmlDirParser::Component &);
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 610257de38..9bdc67a0ac 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -125,20 +125,20 @@ public:
QQmlDirComponents qmlDirComponents;
QQmlDirScripts qmlDirScripts;
- bool resolveType(QQmlTypeLoader *typeLoader, const QString& type,
+ bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
int *vmajor, int *vminor,
QQmlType** type_return, QString* url_return,
QString *base = 0, bool *typeRecursionDetected = 0) const;
};
QList<Import> imports;
- bool resolveType(QQmlTypeLoader *typeLoader, const QString& type,
+ bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
int *vmajor, int *vminor,
QQmlType** type_return, QString* url_return,
QString *base = 0, QList<QQmlError> *errors = 0);
// Prefix when used as a qualified import. Otherwise empty.
- QString prefix;
+ QHashedString prefix;
// Used by QQmlImportsPrivate::qualifiedSets
QQmlImportNamespace *nextNamespace;
@@ -156,7 +156,7 @@ public:
bool isImplicitImport, QQmlImportDatabase *database,
QString *, QList<QQmlError> *errors);
- bool resolveType(const QString& type, int *vmajor, int *vminor,
+ bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor,
QQmlType** type_return, QString* url_return,
QList<QQmlError> *errors);
@@ -166,7 +166,7 @@ public:
QQmlImportNamespace unqualifiedset;
- QQmlImportNamespace *findQualifiedNamespace(const QString &);
+ QQmlImportNamespace *findQualifiedNamespace(const QHashedStringRef &);
QFieldList<QQmlImportNamespace, &QQmlImportNamespace::nextNamespace> qualifiedSets;
QQmlTypeLoader *typeLoader;
@@ -325,7 +325,7 @@ QList<QQmlImports::ScriptReference> QQmlImports::resolvedScripts() const
\sa addImport()
*/
-bool QQmlImports::resolveType(const QString& type,
+bool QQmlImports::resolveType(const QHashedStringRef &type,
QQmlType** type_return, QString* url_return, int *vmaj, int *vmin,
QQmlImportNamespace** ns_return, QList<QQmlError> *errors) const
{
@@ -339,7 +339,7 @@ bool QQmlImports::resolveType(const QString& type,
if (d->resolveType(type,vmaj,vmin,type_return,url_return, errors)) {
if (qmlImportTrace()) {
#define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \
- << ')' << "::resolveType: " << type << " => "
+ << ')' << "::resolveType: " << type.toString() << " => "
if (type_return && *type_return && url_return && !url_return->isEmpty())
RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << ' ' << *url_return;
@@ -366,7 +366,7 @@ bool QQmlImports::resolveType(const QString& type,
If either return pointer is 0, the corresponding search is not done.
*/
-bool QQmlImports::resolveType(QQmlImportNamespace* ns, const QString& type,
+bool QQmlImports::resolveType(QQmlImportNamespace* ns, const QHashedStringRef &type,
QQmlType** type_return, QString* url_return,
int *vmaj, int *vmin) const
{
@@ -374,13 +374,12 @@ bool QQmlImports::resolveType(QQmlImportNamespace* ns, const QString& type,
}
bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
- const QString& type, int *vmajor, int *vminor,
+ const QHashedStringRef& type, int *vmajor, int *vminor,
QQmlType** type_return, QString* url_return,
QString *base, bool *typeRecursionDetected) const
{
if (majversion >= 0 && minversion >= 0) {
- QString qt = uri + QLatin1Char('/') + type;
- QQmlType *t = QQmlMetaType::qmlType(qt, majversion, minversion);
+ QQmlType *t = QQmlMetaType::qmlType(type, uri, majversion, minversion);
if (t) {
if (vmajor) *vmajor = majversion;
if (vminor) *vminor = minversion;
@@ -392,14 +391,21 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
bool typeWasDeclaredInQmldir = false;
if (!qmlDirComponents.isEmpty()) {
- foreach (const QQmlDirParser::Component &c, qmlDirComponents) {
- if (type == c.typeName) {
- typeWasDeclaredInQmldir = true;
+ QQmlDirComponents::ConstIterator it = qmlDirComponents.find(type);
+ if (it != qmlDirComponents.end()) {
+ typeWasDeclaredInQmldir = true;
+ // first found is last inserted - process in reverse
+ QQmlDirComponents::ConstIterator begin = it;
+ while (++it != qmlDirComponents.end() && it.key() == type) {}
+ do {
+ --it;
+ const QQmlDirParser::Component &c = *it;
+
// importing version -1 means import ALL versions
if ((majversion == -1) || (c.majorVersion == majversion &&
minversion >= c.minorVersion)) {
- QString candidate = resolveLocalUrl(QString(url + type + dotqml_string), c.fileName);
+ QString candidate = resolveLocalUrl(QString(url + c.typeName + dotqml_string), c.fileName);
if (c.internal && base) {
if (resolveLocalUrl(*base, c.fileName) != candidate)
continue; // failed attempt to access an internal type
@@ -413,19 +419,18 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
*url_return = candidate;
return true;
}
- }
+ } while (it != begin);
}
}
if (!typeWasDeclaredInQmldir && !isLibrary) {
- QString qmlUrl = url + type + dotqml_string;
+ QString qmlUrl = url + QString::fromRawData(type.constData(), type.length()) + dotqml_string;
bool exists = false;
if (QQmlFile::isBundle(qmlUrl)) {
exists = QQmlFile::bundleFileExists(qmlUrl, typeLoader->engine());
} else {
- QString file = QQmlFile::urlToLocalFileOrQrc(qmlUrl);
exists = !typeLoader->absoluteFilePath(QQmlFile::urlToLocalFileOrQrc(qmlUrl)).isEmpty();
}
@@ -444,19 +449,19 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
return false;
}
-bool QQmlImportsPrivate::resolveType(const QString& type, int *vmajor, int *vminor,
+bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor,
QQmlType** type_return, QString* url_return,
QList<QQmlError> *errors)
{
QQmlImportNamespace *s = 0;
int dot = type.indexOf(QLatin1Char('.'));
if (dot >= 0) {
- QString namespaceName = type.left(dot);
+ QHashedStringRef namespaceName(type.constData(), dot);
s = findQualifiedNamespace(namespaceName);
if (!s) {
if (errors) {
QQmlError error;
- error.setDescription(QQmlImportDatabase::tr("- %1 is not a namespace").arg(namespaceName));
+ error.setDescription(QQmlImportDatabase::tr("- %1 is not a namespace").arg(namespaceName.toString()));
errors->prepend(error);
}
return false;
@@ -473,13 +478,13 @@ bool QQmlImportsPrivate::resolveType(const QString& type, int *vmajor, int *vmin
} else {
s = &unqualifiedset;
}
- QString unqualifiedtype = dot < 0 ? type : type.mid(dot+1, -1);
+ QHashedStringRef unqualifiedtype = dot < 0 ? type : QHashedStringRef(type.constData()+dot+1, type.length()-dot-1);
if (s) {
if (s->resolveType(typeLoader,unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errors))
return true;
if (s->imports.count() == 1 && !s->imports.at(0).isLibrary && url_return && s != &unqualifiedset) {
// qualified, and only 1 url
- *url_return = resolveLocalUrl(s->imports.at(0).url, unqualifiedtype + QLatin1String(".qml"));
+ *url_return = resolveLocalUrl(s->imports.at(0).url, unqualifiedtype.toString() + QLatin1String(".qml"));
return true;
}
}
@@ -487,7 +492,7 @@ bool QQmlImportsPrivate::resolveType(const QString& type, int *vmajor, int *vmin
return false;
}
-bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QString& type,
+bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
int *vmajor, int *vminor, QQmlType** type_return,
QString* url_return, QString *base, QList<QQmlError> *errors)
{
@@ -560,7 +565,7 @@ QQmlImportsPrivate::~QQmlImportsPrivate()
delete ns;
}
-QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QString &prefix)
+QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QHashedStringRef &prefix)
{
for (QQmlImportNamespace *ns = qualifiedSets.first(); ns; ns = qualifiedSets.next(ns)) {
if (prefix == ns->prefix)
@@ -844,11 +849,11 @@ bool QQmlImportsPrivate::addImport(const QQmlDirComponents &qmldircomponentsnetw
} else {
int lowest_min = INT_MAX;
int highest_min = INT_MIN;
- typedef QList<QQmlDirParser::Component>::const_iterator ConstIterator;
+ typedef QQmlDirComponents::const_iterator ConstIterator;
typedef QList<QQmlDirParser::Script>::const_iterator SConstIterator;
- for (ConstIterator cit = qmldircomponents.constBegin();
- cit != qmldircomponents.constEnd(); ++cit) {
+ ConstIterator cend = qmldircomponents.end();
+ for (ConstIterator cit = qmldircomponents.begin(); cit != cend; ++cit) {
if (cit->majorVersion == vmaj) {
lowest_min = qMin(lowest_min, cit->minorVersion);
highest_min = qMax(highest_min, cit->minorVersion);
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index ad0bbc6cc6..111bf29641 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -83,13 +83,13 @@ public:
void setBaseUrl(const QUrl &url, const QString &urlString = QString());
QUrl baseUrl() const;
- bool resolveType(const QString& type,
+ bool resolveType(const QHashedStringRef &type,
QQmlType** type_return, QString* url_return,
int *version_major, int *version_minor,
QQmlImportNamespace** ns_return,
QList<QQmlError> *errors = 0) const;
bool resolveType(QQmlImportNamespace*,
- const QString& type,
+ const QHashedStringRef& type,
QQmlType** type_return, QString* url_return,
int *version_major, int *version_minor) const;
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 856f75fc16..1566d83a22 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -73,7 +73,7 @@ struct QQmlMetaTypeData
QList<QQmlType *> types;
typedef QHash<int, QQmlType *> Ids;
Ids idToType;
- typedef QHash<QString, QQmlType *> Names;
+ typedef QHash<QHashedStringRef,QQmlType *> Names;
Names nameToType;
typedef QHash<const QMetaObject *, QQmlType *> MetaObjects;
MetaObjects metaObjectToType;
@@ -83,12 +83,12 @@ struct QQmlMetaTypeData
struct VersionedUri {
VersionedUri()
: majorVersion(0) {}
- VersionedUri(const QString &uri, int majorVersion)
+ VersionedUri(const QHashedString &uri, int majorVersion)
: uri(uri), majorVersion(majorVersion) {}
bool operator==(const VersionedUri &other) const {
return other.majorVersion == majorVersion && other.uri == uri;
}
- QString uri;
+ QHashedString uri;
int majorVersion;
};
typedef QHash<VersionedUri, QQmlTypeModule *> TypeModules;
@@ -99,7 +99,7 @@ struct QQmlMetaTypeData
QList<QQmlMetaType::ModuleApi> moduleApis;
bool sorted;
};
- typedef QHash<QString, ModuleApiList> ModuleApis;
+ typedef QStringHash<ModuleApiList> ModuleApis;
ModuleApis moduleApis;
int moduleApiCount;
@@ -132,7 +132,7 @@ Q_GLOBAL_STATIC(QReadWriteLock, metaTypeDataLock)
static uint qHash(const QQmlMetaTypeData::VersionedUri &v)
{
- return qHash(v.uri) ^ qHash(v.majorVersion);
+ return v.uri.hash() ^ qHash(v.majorVersion);
}
QQmlMetaTypeData::QQmlMetaTypeData()
@@ -156,7 +156,7 @@ public:
bool m_isInterface : 1;
const char *m_iid;
- QString m_module;
+ QHashedString m_module;
QString m_name;
QString m_elementName;
int m_version_maj;
@@ -219,12 +219,14 @@ QQmlType::QQmlType(int index, const QQmlPrivate::RegisterInterface &interface)
QQmlType::QQmlType(int index, const QQmlPrivate::RegisterType &type)
: d(new QQmlTypePrivate)
{
- QString name = QString::fromUtf8(type.uri);
- if (type.uri) name += QLatin1Char('/');
- name += QString::fromUtf8(type.elementName);
-
d->m_module = QString::fromUtf8(type.uri);
- d->m_name = name;
+ d->m_elementName = QString::fromUtf8(type.elementName);
+
+ if (!d->m_module.isEmpty())
+ d->m_name = static_cast<QString>(d->m_module) + QLatin1Char('/') + d->m_elementName;
+ else
+ d->m_name = d->m_elementName;
+
d->m_version_maj = type.versionMajor;
d->m_version_min = type.versionMinor;
if (type.version >= 1) // revisions added in version 1
@@ -262,7 +264,7 @@ QQmlType::~QQmlType()
delete d;
}
-QString QQmlType::module() const
+const QHashedString &QQmlType::module() const
{
return d->m_module;
}
@@ -283,7 +285,7 @@ bool QQmlType::availableInVersion(int vmajor, int vminor) const
return vmajor == d->m_version_maj && vminor >= d->m_version_min;
}
-bool QQmlType::availableInVersion(const QString &module, int vmajor, int vminor) const
+bool QQmlType::availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const
{
Q_ASSERT(vmajor >= 0 && vminor >= 0);
return module == d->m_module && vmajor == d->m_version_maj && vminor >= d->m_version_min;
@@ -491,11 +493,6 @@ QByteArray QQmlType::typeName() const
const QString &QQmlType::elementName() const
{
- if (d->m_elementName.isEmpty()) {
- QString n = qmlTypeName();
- int idx = n.lastIndexOf(QLatin1Char('/'));
- d->m_elementName = n.mid(idx + 1);
- }
return d->m_elementName;
}
@@ -699,8 +696,6 @@ int QQmlTypeModule::maximumMinorVersion() const
void QQmlTypeModulePrivate::add(QQmlType *type)
{
- types << type;
-
minMinorVersion = qMin(minMinorVersion, type->minorVersion());
maxMinorVersion = qMax(maxMinorVersion, type->minorVersion());
@@ -714,25 +709,6 @@ void QQmlTypeModulePrivate::add(QQmlType *type)
list.append(type);
}
-QList<QQmlType *> QQmlTypeModule::types()
-{
- QList<QQmlType *> rv;
- QReadLocker lock(metaTypeDataLock());
- rv = d->types;
- return rv;
-}
-
-QList<QQmlType *> QQmlTypeModule::type(const QString &name)
-{
- QReadLocker lock(metaTypeDataLock());
- QList<QQmlType *> rv;
- for (int ii = 0; ii < d->types.count(); ++ii) {
- if (d->types.at(ii)->elementName() == name)
- rv << d->types.at(ii);
- }
- return rv;
-}
-
QQmlType *QQmlTypeModule::type(const QHashedStringRef &name, int minor)
{
QReadLocker lock(metaTypeDataLock());
@@ -835,8 +811,8 @@ int registerInterface(const QQmlPrivate::RegisterInterface &interface)
data->idToType.insert(type->typeId(), type);
data->idToType.insert(type->qListTypeId(), type);
// XXX No insertMulti, so no multi-version interfaces?
- if (!type->qmlTypeName().isEmpty())
- data->nameToType.insert(type->qmlTypeName(), type);
+ if (!type->elementName().isEmpty())
+ data->nameToType.insert(type->elementName(), type);
if (data->interfaces.size() <= interface.typeId)
data->interfaces.resize(interface.typeId + 16);
@@ -869,8 +845,8 @@ int registerType(const QQmlPrivate::RegisterType &type)
data->idToType.insert(dtype->typeId(), dtype);
if (dtype->qListTypeId()) data->idToType.insert(dtype->qListTypeId(), dtype);
- if (!dtype->qmlTypeName().isEmpty())
- data->nameToType.insertMulti(dtype->qmlTypeName(), dtype);
+ if (!dtype->elementName().isEmpty())
+ data->nameToType.insertMulti(dtype->elementName(), dtype);
data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype);
@@ -881,8 +857,8 @@ int registerType(const QQmlPrivate::RegisterType &type)
data->objects.setBit(type.typeId, true);
if (type.listId) data->lists.setBit(type.listId, true);
- if (type.uri) {
- QString mod = QString::fromUtf8(type.uri);
+ if (!dtype->module().isEmpty()) {
+ const QHashedString &mod = dtype->module();
QQmlMetaTypeData::VersionedUri versionedUri(mod, type.versionMajor);
QQmlTypeModule *module = data->uriToModule.value(versionedUri);
@@ -915,14 +891,14 @@ int registerModuleApi(const QQmlPrivate::RegisterModuleApi &api)
int index = data->moduleApiCount++;
- QQmlMetaTypeData::ModuleApis::Iterator iter = data->moduleApis.find(uri);
- if (iter == data->moduleApis.end()) {
+ QQmlMetaTypeData::ModuleApiList *apiList = data->moduleApis.value(uri);
+ if (!apiList) {
QQmlMetaTypeData::ModuleApiList apis;
apis.moduleApis << import;
data->moduleApis.insert(uri, apis);
} else {
- iter->moduleApis << import;
- iter->sorted = false;
+ apiList->moduleApis << import;
+ apiList->sorted = false;
}
return index;
@@ -985,9 +961,12 @@ bool QQmlMetaType::isModule(const QString &module, int versionMajor, int version
return true;
// then, check ModuleApis
- foreach (const QQmlMetaType::ModuleApi &mApi, data->moduleApis.value(module).moduleApis) {
- if (mApi.major == versionMajor && mApi.minor == versionMinor) // XXX is this correct?
- return true;
+ QQmlMetaTypeData::ModuleApiList *apiList = data->moduleApis.value(module);
+ if (apiList) {
+ foreach (const QQmlMetaType::ModuleApi &mApi, apiList->moduleApis) {
+ if (mApi.major == versionMajor && mApi.minor == versionMinor) // XXX is this correct?
+ return true;
+ }
}
return false;
@@ -1018,17 +997,17 @@ QQmlMetaType::moduleApi(const QString &uri, int versionMajor, int versionMinor)
QReadLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QQmlMetaTypeData::ModuleApis::Iterator iter = data->moduleApis.find(uri);
- if (iter == data->moduleApis.end())
+ QQmlMetaTypeData::ModuleApiList *apiList = data->moduleApis.value(uri);
+ if (!apiList)
return ModuleApi();
- if (iter->sorted == false) {
- qSort(iter->moduleApis.begin(), iter->moduleApis.end());
- iter->sorted = true;
+ if (apiList->sorted == false) {
+ qSort(apiList->moduleApis.begin(), apiList->moduleApis.end());
+ apiList->sorted = true;
}
- for (int ii = iter->moduleApis.count() - 1; ii >= 0; --ii) {
- const ModuleApi &import = iter->moduleApis.at(ii);
+ for (int ii = apiList->moduleApis.count() - 1; ii >= 0; --ii) {
+ const ModuleApi &import = apiList->moduleApis.at(ii);
if (import.major == versionMajor && import.minor <= versionMinor)
return import;
}
@@ -1042,11 +1021,9 @@ QHash<QString, QList<QQmlMetaType::ModuleApi> > QQmlMetaType::moduleApis()
QQmlMetaTypeData *data = metaTypeData();
QHash<QString, QList<ModuleApi> > moduleApis;
- QHashIterator<QString, QQmlMetaTypeData::ModuleApiList> it(data->moduleApis);
- while (it.hasNext()) {
- it.next();
+ QStringHash<QQmlMetaTypeData::ModuleApiList>::ConstIterator it = data->moduleApis.begin();
+ for (; it != data->moduleApis.end(); ++it)
moduleApis[it.key()] = it.value().moduleApis;
- }
return moduleApis;
}
@@ -1241,19 +1218,35 @@ QQmlMetaType::StringConverter QQmlMetaType::customStringConverter(int type)
}
/*!
- Returns the type (if any) of URI-qualified named \a name in version specified
+ Returns the type (if any) of URI-qualified named \a qualifiedName and version specified
by \a version_major and \a version_minor.
*/
-QQmlType *QQmlMetaType::qmlType(const QString &name, int version_major, int version_minor)
+QQmlType *QQmlMetaType::qmlType(const QString &qualifiedName, int version_major, int version_minor)
+{
+ int slash = qualifiedName.indexOf(QLatin1Char('/'));
+ if (slash <= 0)
+ return 0;
+
+ QHashedStringRef module(qualifiedName.constData(), slash);
+ QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.length() - slash - 1);
+
+ return qmlType(name, module, version_major, version_minor);
+}
+
+/*!
+ Returns the type (if any) of \a name in \a module and version specified
+ by \a version_major and \a version_minor.
+*/
+QQmlType *QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int version_major, int version_minor)
{
Q_ASSERT(version_major >= 0 && version_minor >= 0);
QReadLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.find(name);
- while (it != data->nameToType.end()) {
+ while (it != data->nameToType.end() && it.key() == name) {
// XXX version_major<0 just a kludge for QQmlPropertyPrivate::initProperty
- if (it.key() == name && (version_major<0 || (*it)->availableInVersion(version_major,version_minor)))
+ if (version_major < 0 || (*it)->availableInVersion(module, version_major,version_minor))
return (*it);
++it;
}
@@ -1278,7 +1271,7 @@ QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject)
by \a version_major and \a version_minor in module specified by \a uri. Returns null if no
type is registered.
*/
-QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QString &module, int version_major, int version_minor)
+QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor)
{
Q_ASSERT(version_major >= 0 && version_minor >= 0);
QReadLocker lock(metaTypeDataLock());
@@ -1319,7 +1312,14 @@ QList<QString> QQmlMetaType::qmlTypeNames()
QReadLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- return data->nameToType.keys();
+ QList<QString> names;
+ QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.begin();
+ while (it != data->nameToType.end()) {
+ names += (*it)->qmlTypeName();
+ ++it;
+ }
+
+ return names;
}
/*!
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 03017cafab..fbbc410c07 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -67,6 +67,8 @@ class QQmlType;
class QQmlCustomParser;
class QQmlTypePrivate;
class QQmlTypeModule;
+class QHashedString;
+class QHashedStringRef;
class Q_QML_PRIVATE_EXPORT QQmlMetaType
{
@@ -74,9 +76,10 @@ public:
static QList<QString> qmlTypeNames();
static QList<QQmlType*> qmlTypes();
- static QQmlType *qmlType(const QString &, int, int);
+ static QQmlType *qmlType(const QString &qualifiedName, int, int);
+ static QQmlType *qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int, int);
static QQmlType *qmlType(const QMetaObject *);
- static QQmlType *qmlType(const QMetaObject *metaObject, const QString &module, int version_major, int version_minor);
+ static QQmlType *qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor);
static QQmlType *qmlType(int);
static QMetaProperty defaultProperty(const QMetaObject *);
@@ -140,7 +143,6 @@ private:
static CompareFunction anchorLineCompareFunction;
};
-class QHashedStringRef;
class QHashedV8String;
class Q_QML_PRIVATE_EXPORT QQmlType
{
@@ -149,12 +151,12 @@ public:
const QString &qmlTypeName() const;
const QString &elementName() const;
- QString module() const;
+ const QHashedString &module() const;
int majorVersion() const;
int minorVersion() const;
bool availableInVersion(int vmajor, int vminor) const;
- bool availableInVersion(const QString &module, int vmajor, int vminor) const;
+ bool availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const;
QObject *create() const;
void create(QObject **, void **, size_t) const;
@@ -214,9 +216,6 @@ public:
int minimumMinorVersion() const;
int maximumMinorVersion() const;
- QList<QQmlType *> types();
- QList<QQmlType *> type(const QString &);
-
QQmlType *type(const QHashedStringRef &, int);
QQmlType *type(const QHashedV8String &, int);