aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmltypeloader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmltypeloader.cpp')
-rw-r--r--src/qml/qml/qqmltypeloader.cpp198
1 files changed, 114 insertions, 84 deletions
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 6c12de926c..1d66e756fa 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -45,12 +45,15 @@
#include <private/qqmltypedata_p.h>
#include <private/qqmltypeloaderqmldircontent_p.h>
#include <private/qqmltypeloaderthread_p.h>
+#include <private/qqmlsourcecoordinate_p.h>
#include <QtQml/qqmlabstracturlinterceptor.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlextensioninterface.h>
#include <QtQml/qqmlfile.h>
+#include <qtqml_tracepoints_p.h>
+
#include <QtCore/qdir.h>
#include <QtCore/qdiriterator.h>
#include <QtCore/qfile.h>
@@ -391,23 +394,33 @@ QQmlEngine *QQmlTypeLoader::engine() const
return m_engine;
}
-/*!
+/*! \internal
Call the initializeEngine() method on \a iface. Used by QQmlImportDatabase to ensure it
gets called in the correct thread.
*/
-void QQmlTypeLoader::initializeEngine(QQmlExtensionInterface *iface,
- const char *uri)
+template<class Interface>
+void doInitializeEngine(Interface *iface, QQmlTypeLoaderThread *thread, QQmlEngine *engine,
+ const char *uri)
{
- Q_ASSERT(m_thread->isThisThread() || engine()->thread() == QThread::currentThread());
+ Q_ASSERT(thread->isThisThread() || engine->thread() == QThread::currentThread());
- if (m_thread->isThisThread()) {
- m_thread->initializeEngine(iface, uri);
+ if (thread->isThisThread()) {
+ thread->initializeEngine(iface, uri);
} else {
- Q_ASSERT(engine()->thread() == QThread::currentThread());
- iface->initializeEngine(engine(), uri);
+ Q_ASSERT(engine->thread() == QThread::currentThread());
+ iface->initializeEngine(engine, uri);
}
}
+void QQmlTypeLoader::initializeEngine(QQmlEngineExtensionInterface *iface, const char *uri)
+{
+ doInitializeEngine(iface, m_thread, engine(), uri);
+}
+
+void QQmlTypeLoader::initializeEngine(QQmlExtensionInterface *iface, const char *uri)
+{
+ doInitializeEngine(iface, m_thread, engine(), uri);
+}
void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QByteArray &data)
{
@@ -426,6 +439,7 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QString &fileName)
void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeData &d)
{
+ Q_TRACE_SCOPE(QQmlCompiling, blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
blob->m_inCallback = true;
@@ -445,6 +459,7 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeD
void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit)
{
+ Q_TRACE_SCOPE(QQmlCompiling, blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
blob->m_inCallback = true;
@@ -563,14 +578,10 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo
QString qmldirFilePath;
QString qmldirUrl;
- if (QQmlMetaType::isLockedModule(import->uri, import->majorVersion)) {
- //Locked modules are checked first, to save on filesystem checks
- if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
- import->minorVersion, QString(), QString(), false, errors))
- return false;
-
- } else if (m_importCache.locateQmldir(importDatabase, import->uri, import->majorVersion, import->minorVersion,
- &qmldirFilePath, &qmldirUrl)) {
+ const QQmlImports::LocalQmldirResult qmldirResult = m_importCache.locateLocalQmldir(
+ importDatabase, import->uri, import->majorVersion, import->minorVersion,
+ &qmldirFilePath, &qmldirUrl);
+ if (qmldirResult == QQmlImports::QmldirFound) {
// This is a local library import
if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
import->minorVersion, qmldirFilePath, qmldirUrl, false, errors))
@@ -592,46 +603,57 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo
scriptImported(blob, import->location, script.nameSpace, import->qualifier);
}
}
+ } else if (
+ // Major version of module already registered:
+ // We believe that the registration is complete.
+ QQmlMetaType::typeModule(import->uri, import->majorVersion)
+
+ // Otherwise, try to register further module types.
+ || (qmldirResult != QQmlImports::QmldirInterceptedToRemote
+ && QQmlMetaType::qmlRegisterModuleTypes(import->uri, import->majorVersion))
+
+ // Otherwise, there is no way to register any further types.
+ // Try with any module of that name.
+ || QQmlMetaType::isAnyModule(import->uri)) {
+
+ if (!m_importCache.addLibraryImport(
+ importDatabase, import->uri, import->qualifier, import->majorVersion,
+ import->minorVersion, QString(), QString(), false, errors)) {
+ return false;
+ }
} else {
- // Is this a module?
- if (QQmlMetaType::isAnyModule(import->uri)) {
+ // We haven't yet resolved this import
+ m_unresolvedImports << import;
+
+ QQmlAbstractUrlInterceptor *interceptor = typeLoader()->engine()->urlInterceptor();
+
+ // Query any network import paths for this library.
+ // Interceptor might redirect local paths.
+ QStringList remotePathList = importDatabase->importPathList(
+ interceptor ? QQmlImportDatabase::LocalOrRemote
+ : QQmlImportDatabase::Remote);
+ if (!remotePathList.isEmpty()) {
+ // Add this library and request the possible locations for it
if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
- import->minorVersion, QString(), QString(), false, errors))
+ import->minorVersion, QString(), QString(), true, errors))
return false;
- } else {
- // We haven't yet resolved this import
- m_unresolvedImports << import;
-
- QQmlAbstractUrlInterceptor *interceptor = typeLoader()->engine()->urlInterceptor();
-
- // Query any network import paths for this library.
- // Interceptor might redirect local paths.
- QStringList remotePathList = importDatabase->importPathList(
- interceptor ? QQmlImportDatabase::LocalOrRemote
- : QQmlImportDatabase::Remote);
- if (!remotePathList.isEmpty()) {
- // Add this library and request the possible locations for it
- if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
- import->minorVersion, QString(), QString(), true, errors))
- return false;
- // Probe for all possible locations
- int priority = 0;
- const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(import->uri, remotePathList, import->majorVersion, import->minorVersion);
- for (const QString &qmldirPath : qmlDirPaths) {
- if (interceptor) {
- QUrl url = interceptor->intercept(
- QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
- QQmlAbstractUrlInterceptor::QmldirFile);
- if (!QQmlFile::isLocalFile(url)
- && !fetchQmldir(url, import, ++priority, errors)) {
- return false;
- }
- } else if (!fetchQmldir(QUrl(qmldirPath), import, ++priority, errors)) {
+ // Probe for all possible locations
+ int priority = 0;
+ const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(import->uri, remotePathList, import->majorVersion, import->minorVersion);
+ for (const QString &qmldirPath : qmlDirPaths) {
+ if (interceptor) {
+ QUrl url = interceptor->intercept(
+ QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
+ QQmlAbstractUrlInterceptor::QmldirFile);
+ if (!QQmlFile::isLocalFile(url)
+ && !fetchQmldir(url, import, ++priority, errors)) {
return false;
}
-
+ } else if (!fetchQmldir(QUrl(qmldirPath), import, ++priority, errors)) {
+ return false;
}
+
}
}
}
@@ -675,8 +697,8 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob)
Q_ASSERT(errors.size());
QQmlError error(errors.takeFirst());
error.setUrl(m_importCache.baseUrl());
- error.setLine(import->location.line);
- error.setColumn(import->location.column);
+ error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line));
+ error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column));
errors.prepend(error); // put it back on the list after filling out information.
setError(errors);
}
@@ -705,7 +727,7 @@ bool QQmlTypeLoader::Blob::isDebugging() const
bool QQmlTypeLoader::Blob::diskCacheEnabled() const
{
- return (!disableDiskCache() || forceDiskCache()) && !isDebugging();
+ return (!disableDiskCache() && !isDebugging()) || forceDiskCache();
}
bool QQmlTypeLoader::Blob::qmldirDataAvailable(const QQmlRefPointer<QQmlQmldirData> &data, QList<QQmlError> *errors)
@@ -964,48 +986,56 @@ bool QQmlTypeLoader::fileExists(const QString &path, const QString &file)
return false;
Q_ASSERT(path.endsWith(QLatin1Char('/')));
+
+ LockHolder<QQmlTypeLoader> holder(this);
+ QCache<QString, bool> *fileSet = m_importDirCache.object(path);
+ if (fileSet) {
+ if (bool *value = fileSet->object(file))
+ return *value;
+ } else if (m_importDirCache.contains(path)) {
+ // explicit nullptr in cache
+ return false;
+ }
+
+ auto addToCache = [&](const QFileInfo &fileInfo) {
+ if (!fileSet) {
+ fileSet = fileInfo.dir().exists() ? new QCache<QString, bool> : nullptr;
+ m_importDirCache.insert(path, fileSet);
+ if (!fileSet)
+ return false;
+ }
+
+ const bool exists = fileInfo.exists();
+ fileSet->insert(file, new bool(exists));
+ return exists;
+ };
+
if (path.at(0) == QLatin1Char(':')) {
// qrc resource
- QFileInfo fileInfo(path + file);
- return fileInfo.isFile();
- } else if (path.count() > 3 && path.at(3) == QLatin1Char(':') &&
- path.startsWith(QLatin1String("qrc"), Qt::CaseInsensitive)) {
+ return addToCache(QFileInfo(path + file));
+ }
+
+ if (path.count() > 3 && path.at(3) == QLatin1Char(':')
+ && path.startsWith(QLatin1String("qrc"), Qt::CaseInsensitive)) {
// qrc resource url
- QFileInfo fileInfo(QQmlFile::urlToLocalFileOrQrc(path + file));
- return fileInfo.isFile();
+ return addToCache(QFileInfo(QQmlFile::urlToLocalFileOrQrc(path + file)));
}
+
#if defined(Q_OS_ANDROID)
- else if (path.count() > 7 && path.at(6) == QLatin1Char(':') && path.at(7) == QLatin1Char('/') &&
- path.startsWith(QLatin1String("assets"), Qt::CaseInsensitive)) {
+ if (path.count() > 7 && path.at(6) == QLatin1Char(':') && path.at(7) == QLatin1Char('/')
+ && path.startsWith(QLatin1String("assets"), Qt::CaseInsensitive)) {
// assets resource url
- QFileInfo fileInfo(QQmlFile::urlToLocalFileOrQrc(path + file));
- return fileInfo.isFile();
- } else if (path.count() > 8 && path.at(7) == QLatin1Char(':') && path.at(8) == QLatin1Char('/') &&
- path.startsWith(QLatin1String("content"), Qt::CaseInsensitive)) {
- // content url
- QFileInfo fileInfo(QQmlFile::urlToLocalFileOrQrc(path + file));
- return fileInfo.isFile();
+ return addToCache(QFileInfo(QQmlFile::urlToLocalFileOrQrc(path + file)));
}
-#endif
- LockHolder<QQmlTypeLoader> holder(this);
- if (!m_importDirCache.contains(path)) {
- bool exists = QDir(path).exists();
- QCache<QString, bool> *entry = exists ? new QCache<QString, bool> : nullptr;
- m_importDirCache.insert(path, entry);
+ if (path.count() > 8 && path.at(7) == QLatin1Char(':') && path.at(8) == QLatin1Char('/')
+ && path.startsWith(QLatin1String("content"), Qt::CaseInsensitive)) {
+ // content url
+ return addToCache(QFileInfo(QQmlFile::urlToLocalFileOrQrc(path + file)));
}
- QCache<QString, bool> *fileSet = m_importDirCache.object(path);
- if (!fileSet)
- return false;
+#endif
- bool *value = fileSet->object(file);
- if (value) {
- return *value;
- } else {
- bool exists = QFile::exists(path + file);
- fileSet->insert(file, new bool(exists));
- return exists;
- }
+ return addToCache(QFileInfo(path + file));
}