diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-03-22 14:01:13 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-03-24 14:33:05 +0100 |
commit | 7dba80af8715297a7a946e11c1961c6268897171 (patch) | |
tree | f7c3d973371522b0eb656955debef9ae8f1735f2 /src/qml/qml | |
parent | 185760fa44f5b62f1ed3f10a458f4bc38072768f (diff) |
QtQml: Uncruftify QQmlImports
QQmlImports is a refcounted datastructure. Therefore, use QQmlRefPointer
for it, and avoid all the pointless indirection. Also, make the flags
type safe and document the mutability of the import namespaces.
Change-Id: I54a0db42b2b7cdfb516e9f90c2264edfa800bfe6
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlengine.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlimport.cpp | 430 | ||||
-rw-r--r-- | src/qml/qml/qqmlimport_p.h | 171 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertyvalidator.cpp | 9 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertyvalidator_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlscriptblob.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmltypecompiler.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmltypedata.cpp | 44 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 30 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 17 | ||||
-rw-r--r-- | src/qml/qml/qqmltypenamecache.cpp | 9 | ||||
-rw-r--r-- | src/qml/qml/qqmltypenamecache_p.h | 10 |
12 files changed, 323 insertions, 410 deletions
diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h index 5d8491ecac..fd741e0a04 100644 --- a/src/qml/qml/qqmlengine.h +++ b/src/qml/qml/qqmlengine.h @@ -80,7 +80,6 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlImageProviderBase::Flags) class QQmlComponent; class QQmlEnginePrivate; -class QQmlImportsPrivate; class QQmlExpression; class QQmlContext; class QQmlType; diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index f79fcaa2a1..fe957d15d8 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -54,7 +54,6 @@ #include <private/qqmlglobal_p.h> #include <private/qqmltypenamecache_p.h> #include <private/qqmlengine_p.h> -#include <private/qfieldlist_p.h> #include <private/qqmltypemodule_p.h> #include <private/qqmltypeloaderqmldircontent_p.h> #include <private/qqmlpluginimporter_p.h> @@ -233,120 +232,31 @@ bool isPathAbsolute(const QString &path) import MyFoo 1.0 as Foo */ -class QQmlImportsPrivate -{ -public: - QQmlImportsPrivate(QQmlTypeLoader *loader); - ~QQmlImportsPrivate(); - - QQmlImportNamespace *importNamespace(const QString &prefix) const; - - QTypeRevision addLibraryImport( - const QString& uri, const QString &prefix, QTypeRevision version, - const QString &qmldirIdentifier, const QString &qmldirUrl, uint flags, - QQmlImportDatabase *database, QList<QQmlError> *errors); - - QTypeRevision addFileImport( - const QString &uri, const QString &prefix, QTypeRevision version, uint flags, - QQmlImportDatabase *database, QString *localQmldir, QList<QQmlError> *errors); - - QTypeRevision updateQmldirContent(const QString &uri, const QString &prefix, - const QString &qmldirIdentifier, const QString& qmldirUrl, - QQmlImportDatabase *database, - QList<QQmlError> *errors); - - bool resolveType(const QHashedStringRef &type, QTypeRevision *version_return, - QQmlType *type_return, QList<QQmlError> *errors, - QQmlType::RegistrationType registrationType, - bool *typeRecursionDetected = nullptr); - - QUrl baseUrl; - QString base; - int ref; - - // storage of data related to imports without a namespace - mutable QQmlImportNamespace unqualifiedset; - - QQmlImportNamespace *findQualifiedNamespace(const QHashedStringRef &) const; - - // storage of data related to imports with a namespace - mutable QFieldList<QQmlImportNamespace, &QQmlImportNamespace::nextNamespace> qualifiedSets; - - QQmlTypeLoader *typeLoader; - - static QTypeRevision matchingQmldirVersion( - const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, - QTypeRevision version, QList<QQmlError> *errors); - - QTypeRevision importExtension( - const QString &uri, QTypeRevision version, QQmlImportDatabase *database, - const QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors); - - bool getQmldirContent(const QString &qmldirIdentifier, const QString &uri, - QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors); - - QString resolvedUri(const QString &dir_arg, QQmlImportDatabase *database); - - QQmlImportInstance *addImportToNamespace(QQmlImportNamespace *nameSpace, const QString &uri, - const QString &url, QTypeRevision version, - QV4::CompiledData::Import::ImportType type, - QList<QQmlError> *errors, uint flags); -}; - /*! \class QQmlImports \brief The QQmlImports class encapsulates one QML document's import statements. \internal */ -QQmlImports::QQmlImports(const QQmlImports ©) -: d(copy.d) -{ - ++d->ref; -} - -QQmlImports & -QQmlImports::operator =(const QQmlImports ©) -{ - ++copy.d->ref; - if (--d->ref == 0) - delete d; - d = copy.d; - return *this; -} - -QQmlImports::QQmlImports(QQmlTypeLoader *typeLoader) - : d(new QQmlImportsPrivate(typeLoader)) -{ -} - -QQmlImports::~QQmlImports() -{ - if (--d->ref == 0) - delete d; -} /*! Sets the base URL to be used for all relative file imports added. */ void QQmlImports::setBaseUrl(const QUrl& url, const QString &urlString) { - d->baseUrl = url; + m_baseUrl = url; - if (urlString.isEmpty()) { - d->base = url.toString(); - } else { - //Q_ASSERT(url.toString() == urlString); - d->base = urlString; - } + if (urlString.isEmpty()) + m_base = url.toString(); + else + m_base = urlString; } /*! + \fn QQmlImports::baseUrl() + \internal + Returns the base URL to be used for all relative file imports added. */ -QUrl QQmlImports::baseUrl() const -{ - return d->baseUrl; -} /* \internal @@ -360,7 +270,7 @@ QUrl QQmlImports::baseUrl() const */ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const { - const QQmlImportNamespace &set = d->unqualifiedset; + const QQmlImportNamespace &set = m_unqualifiedset; for (int ii = set.imports.count() - 1; ii >= 0; --ii) { const QQmlImportInstance *import = set.imports.at(ii); @@ -370,7 +280,7 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const } } - for (QQmlImportNamespace *ns = d->qualifiedSets.first(); ns; ns = d->qualifiedSets.next(ns)) { + for (QQmlImportNamespace *ns = m_qualifiedSets.first(); ns; ns = m_qualifiedSets.next(ns)) { const QQmlImportNamespace &set = *ns; @@ -463,10 +373,10 @@ QList<QQmlImports::CompositeSingletonReference> QQmlImports::resolvedCompositeSi { QList<QQmlImports::CompositeSingletonReference> compositeSingletons; - const QQmlImportNamespace &set = d->unqualifiedset; + const QQmlImportNamespace &set = m_unqualifiedset; findCompositeSingletons(set, compositeSingletons, baseUrl()); - for (QQmlImportNamespace *ns = d->qualifiedSets.first(); ns; ns = d->qualifiedSets.next(ns)) { + for (QQmlImportNamespace *ns = m_qualifiedSets.first(); ns; ns = m_qualifiedSets.next(ns)) { const QQmlImportNamespace &set = *ns; findCompositeSingletons(set, compositeSingletons, baseUrl()); } @@ -498,7 +408,7 @@ QList<QQmlImports::ScriptReference> QQmlImports::resolvedScripts() const { QList<QQmlImports::ScriptReference> scripts; - const QQmlImportNamespace &set = d->unqualifiedset; + const QQmlImportNamespace &set = m_unqualifiedset; for (int ii = set.imports.count() - 1; ii >= 0; --ii) { const QQmlImportInstance *import = set.imports.at(ii); @@ -511,7 +421,7 @@ QList<QQmlImports::ScriptReference> QQmlImports::resolvedScripts() const } } - for (QQmlImportNamespace *ns = d->qualifiedSets.first(); ns; ns = d->qualifiedSets.next(ns)) { + for (QQmlImportNamespace *ns = m_qualifiedSets.first(); ns; ns = m_qualifiedSets.next(ns)) { const QQmlImportNamespace &set = *ns; for (int ii = set.imports.count() - 1; ii >= 0; --ii) { @@ -574,21 +484,20 @@ QString QQmlImports::versionString(QTypeRevision version, ImportVersion versionM \sa addFileImport(), addLibraryImport */ -bool QQmlImports::resolveType(const QHashedStringRef &type, - QQmlType *type_return, QTypeRevision *version_return, - QQmlImportNamespace** ns_return, QList<QQmlError> *errors, - QQmlType::RegistrationType registrationType, - bool *typeRecursionDetected) const +bool QQmlImports::resolveType( + const QHashedStringRef &type, QQmlType *type_return, QTypeRevision *version_return, + QQmlImportNamespace **ns_return, QList<QQmlError> *errors, + QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) const { - QQmlImportNamespace* ns = d->findQualifiedNamespace(type); + QQmlImportNamespace *ns = findQualifiedNamespace(type); if (ns) { if (ns_return) *ns_return = ns; return true; } if (type_return) { - if (d->resolveType(type, version_return, type_return, errors, registrationType, - typeRecursionDetected)) { + if (resolveType(type, version_return, type_return, errors, registrationType, + typeRecursionDetected)) { if (lcQmlImport().isDebugEnabled()) { #define RESOLVE_TYPE_DEBUG qCDebug(lcQmlImport) \ << "resolveType:" << qPrintable(baseUrl().toString()) << type.toString() << " => " @@ -637,7 +546,9 @@ bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl, it != nameSpace->imports.constEnd(); ++it) { if ((*it != this) && ((*it)->uri == uri)) { QQmlError error; - error.setDescription(QQmlImportDatabase::tr("\"%1\" is ambiguous. Found in %2 and in %3").arg(uri).arg(url).arg((*it)->url)); + error.setDescription( + QQmlImportDatabase::tr("\"%1\" is ambiguous. Found in %2 and in %3") + .arg(uri, url, (*it)->url)); errors->prepend(error); return false; } @@ -673,6 +584,7 @@ QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qml } /*! + \fn QQmlImports::resolveType(QQmlImportNamespace *ns, const QHashedStringRef &type, QQmlType *type_return, QTypeRevision *version_return, QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType) const \internal Searching \e only in the namespace \a ns (previously returned in a call to @@ -682,17 +594,10 @@ QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qml If the return pointer is 0, the corresponding search is not done. */ -bool QQmlImports::resolveType(QQmlImportNamespace *ns, const QHashedStringRef &type, - QQmlType *type_return, QTypeRevision *version_return, - QQmlType::RegistrationType registrationType) const -{ - return ns->resolveType(d->typeLoader, type, version_return, type_return, nullptr, nullptr, - registrationType); -} bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type, QTypeRevision *version_return, QQmlType *type_return, - QString *base, bool *typeRecursionDetected, + const QString *base, bool *typeRecursionDetected, QQmlType::RegistrationType registrationType, QQmlImport::RecursionRestriction recursionRestriction, QList<QQmlError> *errors) const @@ -855,17 +760,23 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt return false; } -bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, QTypeRevision *version_return, - QQmlType *type_return, QList<QQmlError> *errors, - QQmlType::RegistrationType registrationType, - bool *typeRecursionDetected) +bool QQmlImports::resolveType( + const QHashedStringRef &type, QTypeRevision *version_return, QQmlType *type_return, + QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, + bool *typeRecursionDetected) const { const QVector<QHashedStringRef> splitName = type.split(Dot); - auto resolveTypeInNamespace = [&](QHashedStringRef unqualifiedtype, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors) -> bool { - if (nameSpace->resolveType(typeLoader, unqualifiedtype, version_return, type_return, &base, errors, - registrationType, typeRecursionDetected)) + auto resolveTypeInNamespace = [&]( + QHashedStringRef unqualifiedtype, QQmlImportNamespace *nameSpace, + QList<QQmlError> *errors) -> bool { + if (nameSpace->resolveType( + m_typeLoader, unqualifiedtype, version_return, type_return, &m_base, errors, + registrationType, typeRecursionDetected)) return true; - if (nameSpace->imports.count() == 1 && !nameSpace->imports.at(0)->isLibrary && type_return && nameSpace != &unqualifiedset) { + if (nameSpace->imports.count() == 1 + && !nameSpace->imports.at(0)->isLibrary + && type_return + && nameSpace != &m_unqualifiedset) { // qualified, and only 1 url *type_return = QQmlMetaType::typeForUrl( resolveLocalUrl(nameSpace->imports.at(0)->url, @@ -878,7 +789,7 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, QTypeRevision switch (splitName.size()) { case 1: { // must be a simple type - return resolveTypeInNamespace(type, &unqualifiedset, errors); + return resolveTypeInNamespace(type, &m_unqualifiedset, errors); } case 2: { // either namespace + simple type OR simple type + inline component @@ -887,7 +798,7 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, QTypeRevision // namespace + simple type return resolveTypeInNamespace(splitName.at(1), s, errors); } else { - if (resolveTypeInNamespace(splitName.at(0), &unqualifiedset, nullptr)) { + if (resolveTypeInNamespace(splitName.at(0), &m_unqualifiedset, nullptr)) { // either simple type + inline component auto const icName = splitName.at(1).toString(); auto objectIndex = type_return->lookupInlineComponentIdByName(icName); @@ -976,7 +887,7 @@ QQmlImportInstance *QQmlImportNamespace::findImport(const QString &uri) const bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, QTypeRevision *version_return, QQmlType *type_return, - QString *base, QList<QQmlError> *errors, + const QString *base, QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) { @@ -987,6 +898,7 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS if (!typeRecursionDetected) typeRecursionDetected = &localTypeRecursionDetected; + // TODO: move the sorting somewhere else and make resolveType() const. if (needsSorting()) { std::stable_partition(imports.begin(), imports.end(), [](QQmlImportInstance *import) { return import->isInlineComponent; @@ -1025,14 +937,20 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS QQmlError error; if (u1 != u2) { - error.setDescription(QQmlImportDatabase::tr("is ambiguous. Found in %1 and in %2").arg(u1).arg(u2)); + error.setDescription( + QQmlImportDatabase::tr( + "is ambiguous. Found in %1 and in %2") + .arg(u1, u2)); } else { - error.setDescription(QQmlImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5") - .arg(u1) - .arg(import->version.majorVersion()) - .arg(import->version.minorVersion()) - .arg(import2->version.majorVersion()) - .arg(import2->version.minorVersion())); + error.setDescription( + QQmlImportDatabase::tr( + "is ambiguous. Found in %1 in version " + "%2.%3 and %4.%5") + .arg(u1) + .arg(import->version.majorVersion()) + .arg(import->version.minorVersion()) + .arg(import2->version.majorVersion()) + .arg(import2->version.minorVersion())); } errors->prepend(error); } @@ -1054,30 +972,9 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS return false; } -bool QQmlImportNamespace::needsSorting() const +QQmlImportNamespace *QQmlImports::findQualifiedNamespace(const QHashedStringRef &prefix) const { - return nextNamespace == this; -} - -void QQmlImportNamespace::setNeedsSorting(bool needsSorting) -{ - Q_ASSERT(nextNamespace == this || nextNamespace == nullptr); - nextNamespace = needsSorting ? this : nullptr; -} - -QQmlImportsPrivate::QQmlImportsPrivate(QQmlTypeLoader *loader) -: ref(1), typeLoader(loader) { -} - -QQmlImportsPrivate::~QQmlImportsPrivate() -{ - while (QQmlImportNamespace *ns = qualifiedSets.takeFirst()) - delete ns; -} - -QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QHashedStringRef &prefix) const -{ - for (QQmlImportNamespace *ns = qualifiedSets.first(); ns; ns = qualifiedSets.next(ns)) { + for (QQmlImportNamespace *ns = m_qualifiedSets.first(); ns; ns = m_qualifiedSets.next(ns)) { if (prefix == ns->prefix) return ns; } @@ -1087,14 +984,14 @@ QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QHashedStr /* Import an extension defined by a qmldir file. */ -QTypeRevision QQmlImportsPrivate::importExtension( +QTypeRevision QQmlImports::importExtension( const QString &uri, QTypeRevision version, QQmlImportDatabase *database, const QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors) { Q_ASSERT(qmldir->hasContent()); qCDebug(lcQmlImport) - << "importExtension:" << qPrintable(base) << "loaded" << qmldir->qmldirLocation(); + << "importExtension:" << qPrintable(m_base) << "loaded" << qmldir->qmldirLocation(); if (designerSupportRequired && !qmldir->designerSupported()) { if (errors) { @@ -1111,17 +1008,17 @@ QTypeRevision QQmlImportsPrivate::importExtension( if (qmldir->plugins().isEmpty()) return validVersion(version); - QQmlPluginImporter importer(uri, version, database, qmldir, typeLoader, errors); + QQmlPluginImporter importer(uri, version, database, qmldir, m_typeLoader, errors); return importer.importPlugins(); } -bool QQmlImportsPrivate::getQmldirContent(const QString &qmldirIdentifier, const QString &uri, +bool QQmlImports::getQmldirContent(const QString &qmldirIdentifier, const QString &uri, QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors) { Q_ASSERT(errors); Q_ASSERT(qmldir); - *qmldir = typeLoader->qmldirContent(qmldirIdentifier); + *qmldir = m_typeLoader->qmldirContent(qmldirIdentifier); if ((*qmldir).hasContent()) { // Ensure that parsing was successful if ((*qmldir).hasError()) { @@ -1139,7 +1036,7 @@ bool QQmlImportsPrivate::getQmldirContent(const QString &qmldirIdentifier, const return true; } -QString QQmlImportsPrivate::resolvedUri(const QString &dir_arg, QQmlImportDatabase *database) +QString QQmlImports::resolvedUri(const QString &dir_arg, QQmlImportDatabase *database) { QString dir = dir_arg; if (dir.endsWith(Slash) || dir.endsWith(Backslash)) @@ -1191,7 +1088,7 @@ QString QQmlImportsPrivate::resolvedUri(const QString &dir_arg, QQmlImportDataba one, returns QmldirInterceptedToRemote. Otherwise, returns QmldirNotFound. */ -QTypeRevision QQmlImportsPrivate::matchingQmldirVersion( +QTypeRevision QQmlImports::matchingQmldirVersion( const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, QTypeRevision version, QList<QQmlError> *errors) { @@ -1278,28 +1175,28 @@ QTypeRevision QQmlImportsPrivate::matchingQmldirVersion( : highestMinorVersion); } -QQmlImportNamespace *QQmlImportsPrivate::importNamespace(const QString &prefix) const +QQmlImportNamespace *QQmlImports::importNamespace(const QString &prefix) { QQmlImportNamespace *nameSpace = nullptr; if (prefix.isEmpty()) { - nameSpace = &unqualifiedset; + nameSpace = &m_unqualifiedset; } else { nameSpace = findQualifiedNamespace(prefix); if (!nameSpace) { nameSpace = new QQmlImportNamespace; nameSpace->prefix = prefix; - qualifiedSets.append(nameSpace); + m_qualifiedSets.append(nameSpace); } } return nameSpace; } -QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace( +QQmlImportInstance *QQmlImports::addImportToNamespace( QQmlImportNamespace *nameSpace, const QString &uri, const QString &url, QTypeRevision version, - QV4::CompiledData::Import::ImportType type, QList<QQmlError> *errors, uint flags) + QV4::CompiledData::Import::ImportType type, QList<QQmlError> *errors, ImportFlags flags) { Q_ASSERT(nameSpace); Q_ASSERT(errors); @@ -1334,14 +1231,18 @@ QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace( return import; } -QTypeRevision QQmlImportsPrivate::addLibraryImport( - const QString &uri, const QString &prefix, QTypeRevision version, - const QString &qmldirIdentifier, const QString &qmldirUrl, uint flags, - QQmlImportDatabase *database, QList<QQmlError> *errors) +QTypeRevision QQmlImports::addLibraryImport( + QQmlImportDatabase *database, const QString &uri, const QString &prefix, + QTypeRevision version, const QString &qmldirIdentifier, const QString &qmldirUrl, + ImportFlags flags, QList<QQmlError> *errors) { Q_ASSERT(database); Q_ASSERT(errors); + qCDebug(lcQmlImport) + << "addLibraryImport:" << qPrintable(baseUrl().toString()) + << uri << "version '" << version << "'" << "as" << prefix; + QQmlImportNamespace *nameSpace = importNamespace(prefix); Q_ASSERT(nameSpace); @@ -1393,10 +1294,38 @@ QTypeRevision QQmlImportsPrivate::addLibraryImport( return validVersion(version); } -QTypeRevision QQmlImportsPrivate::addFileImport( - const QString& uri, const QString &prefix, QTypeRevision version, uint flags, - QQmlImportDatabase *database, QString *localQmldir, QList<QQmlError> *errors) +/*! + \internal + + Adds information to \a database such that subsequent calls to resolveType() + will resolve types qualified by \a prefix by considering types found at the given \a uri. + + The \a uri is either a directory (if importType is FileImport), or a URI resolved using paths + added via addImportPath() (if importType is LibraryImport). + + The \a prefix may be empty, in which case the import location is considered for + unqualified types. + + The base URL must already have been set with Import::setBaseUrl(). + + Optionally, the qmldir the import resolved to can be returned by providing the \a localQmldir + parameter. Not all imports will have a local qmldir. If there is none, the \a localQmldir + parameter won't be set. + + Returns a valid QTypeRevision on success, and an invalid one on failure. + In case of failure, the \a errors array will filled appropriately. +*/ +QTypeRevision QQmlImports::addFileImport( + QQmlImportDatabase *database, const QString &uri, const QString &prefix, + QTypeRevision version, ImportFlags flags, QString *localQmldir, QList<QQmlError> *errors) { + Q_ASSERT(database); + Q_ASSERT(errors); + + qCDebug(lcQmlImport) + << "addFileImport:" << qPrintable(baseUrl().toString()) + << uri << version << "as" << prefix; + if (uri.startsWith(Slash) || uri.startsWith(Colon)) { QQmlError error; const QString fix = uri.startsWith(Slash) ? QLatin1String("file:") + uri @@ -1417,10 +1346,10 @@ QTypeRevision QQmlImportsPrivate::addFileImport( // The uri for this import. For library imports this is the same as uri // specified by the user, but it may be different in the case of file imports. QString importUri = uri; - QString qmldirUrl = resolveLocalUrl(base, importUri + (importUri.endsWith(Slash) + QString qmldirUrl = resolveLocalUrl(m_base, importUri + (importUri.endsWith(Slash) ? String_qmldir : Slash_qmldir)); - qmldirUrl = typeLoader->engine()->interceptUrl( + qmldirUrl = m_typeLoader->engine()->interceptUrl( QUrl(qmldirUrl), QQmlAbstractUrlInterceptor::QmldirFile).toString(); QString qmldirIdentifier; @@ -1430,7 +1359,7 @@ QTypeRevision QQmlImportsPrivate::addFileImport( Q_ASSERT(!localFileOrQrc.isEmpty()); const QString dir = localFileOrQrc.left(localFileOrQrc.lastIndexOf(Slash) + 1); - if (!typeLoader->directoryExists(dir)) { + if (!m_typeLoader->directoryExists(dir)) { if (!(flags & QQmlImports::ImportImplicit)) { QQmlError error; error.setDescription(QQmlImportDatabase::tr("\"%1\": no such directory").arg(uri)); @@ -1446,7 +1375,7 @@ QTypeRevision QQmlImportsPrivate::addFileImport( if (importUri.endsWith(Slash)) importUri.chop(1); - if (!typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) { + if (!m_typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) { qmldirIdentifier = localFileOrQrc; if (localQmldir) *localQmldir = qmldirIdentifier; @@ -1466,7 +1395,7 @@ QTypeRevision QQmlImportsPrivate::addFileImport( } // The url for the path containing files for this import - QString url = resolveLocalUrl(base, uri); + QString url = resolveLocalUrl(m_base, uri); if (!url.endsWith(Slash) && !url.endsWith(Backslash)) url += Slash; @@ -1516,10 +1445,17 @@ QTypeRevision QQmlImportsPrivate::addFileImport( return validVersion(version); } -QTypeRevision QQmlImportsPrivate::updateQmldirContent(const QString &uri, const QString &prefix, - const QString &qmldirIdentifier, const QString& qmldirUrl, - QQmlImportDatabase *database, QList<QQmlError> *errors) +QTypeRevision QQmlImports::updateQmldirContent( + QQmlImportDatabase *database, const QString &uri, const QString &prefix, + const QString &qmldirIdentifier, const QString &qmldirUrl, QList<QQmlError> *errors) { + Q_ASSERT(database); + Q_ASSERT(errors); + + qDebug(lcQmlImport) + << "updateQmldirContent:" << qPrintable(baseUrl().toString()) + << uri << "to" << qmldirUrl << "as" << prefix; + QQmlImportNamespace *nameSpace = importNamespace(prefix); Q_ASSERT(nameSpace); @@ -1529,8 +1465,8 @@ QTypeRevision QQmlImportsPrivate::updateQmldirContent(const QString &uri, const return QTypeRevision(); if (qmldir.hasContent()) { - QTypeRevision version = importExtension(uri, import->version, database, &qmldir, - errors); + QTypeRevision version = importExtension( + uri, import->version, database, &qmldir, errors); if (!version.isValid()) return QTypeRevision(); @@ -1562,6 +1498,7 @@ QTypeRevision QQmlImportsPrivate::updateQmldirContent(const QString &uri, const } /*! + \fn QQmlImports::addImplicitImport(QQmlImportDatabase *importDb, QString *localQmldir, QList<QQmlError> *errors) \internal Adds an implicit "." file import. This is equivalent to calling addFileImport(), but error @@ -1569,17 +1506,7 @@ QTypeRevision QQmlImportsPrivate::updateQmldirContent(const QString &uri, const Additionally, this will add the import with lowest instead of highest precedence. */ -QTypeRevision QQmlImports::addImplicitImport( - QQmlImportDatabase *importDb, QString *localQmldir, QList<QQmlError> *errors) -{ - Q_ASSERT(errors); - - qCDebug(lcQmlImport) << "addImplicitImport:" << qPrintable(baseUrl().toString()); - uint flags = ImportImplicit | (!isLocal(baseUrl()) ? ImportIncomplete : 0); - return d->addFileImport(QLatin1String("."), QString(), QTypeRevision(), flags, - importDb, localQmldir, errors); -} /*! \internal @@ -1591,86 +1518,11 @@ bool QQmlImports::addInlineComponentImport(QQmlImportInstance *const importInsta importInstance->isInlineComponent = true; importInstance->version = QTypeRevision::zero(); importInstance->containingType = containingType; - d->unqualifiedset.imports.push_back(importInstance); - d->unqualifiedset.setNeedsSorting(true); + m_unqualifiedset.imports.push_back(importInstance); + m_unqualifiedset.setNeedsSorting(true); return true; } -/*! - \internal - - Adds information to \a imports such that subsequent calls to resolveType() - will resolve types qualified by \a prefix by considering types found at the given \a uri. - - The uri is either a directory (if importType is FileImport), or a URI resolved using paths - added via addImportPath() (if importType is LibraryImport). - - The \a prefix may be empty, in which case the import location is considered for - unqualified types. - - The base URL must already have been set with Import::setBaseUrl(). - - Optionally, the url the import resolved to can be returned by providing the url parameter. - Not all imports will result in an output url being generated, in which case the url will - be set to an empty string. - - Returns true on success, and false on failure. In case of failure, the errors array will - filled appropriately. -*/ -QTypeRevision QQmlImports::addFileImport( - QQmlImportDatabase *importDb, const QString& uri, const QString& prefix, - QTypeRevision version, uint flags, QList<QQmlError> *errors) -{ - Q_ASSERT(importDb); - Q_ASSERT(errors); - - qCDebug(lcQmlImport) - << "addFileImport:" << qPrintable(baseUrl().toString()) - << uri << version << "as" << prefix; - - return d->addFileImport(uri, prefix, version, flags, importDb, nullptr, errors); -} - -QTypeRevision QQmlImports::addLibraryImport( - QQmlImportDatabase *importDb, const QString &uri, const QString &prefix, - QTypeRevision version, const QString &qmldirIdentifier, const QString& qmldirUrl, - uint flags, QList<QQmlError> *errors) -{ - Q_ASSERT(importDb); - Q_ASSERT(errors); - - qCDebug(lcQmlImport) - << "addLibraryImport:" << qPrintable(baseUrl().toString()) - << uri << "version '" << version << "'" << "as" << prefix; - - return d->addLibraryImport(uri, prefix, version, qmldirIdentifier, qmldirUrl, flags, - importDb, errors); -} - -QTypeRevision QQmlImports::updateQmldirContent( - QQmlImportDatabase *importDb, const QString &uri, const QString &prefix, - const QString &qmldirIdentifier, const QString& qmldirUrl, QList<QQmlError> *errors) -{ - Q_ASSERT(importDb); - Q_ASSERT(errors); - - qDebug(lcQmlImport) - << "updateQmldirContent:" << qPrintable(baseUrl().toString()) - << uri << "to" << qmldirUrl << "as" << prefix; - - return d->updateQmldirContent(uri, prefix, qmldirIdentifier, qmldirUrl, importDb, errors); -} - -bool QQmlImports::isLocal(const QString &url) -{ - return !QQmlFile::urlToLocalFileOrQrc(url).isEmpty(); -} - -bool QQmlImports::isLocal(const QUrl &url) -{ - return !QQmlFile::urlToLocalFileOrQrc(url).isEmpty(); -} - QUrl QQmlImports::urlFromLocalFileOrQrcOrUrl(const QString &file) { QUrl url(QLatin1String(file.at(0) == Colon ? "qrc" : "") + file); @@ -1771,28 +1623,6 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e) #endif // Q_OS_DARWIN } -QQmlImportDatabase::~QQmlImportDatabase() -{ - clearDirCache(); -} - -/*! - \internal -*/ -QStringList QQmlImportDatabase::pluginPathList() const -{ - return filePluginPath; -} - -/*! - \internal -*/ -void QQmlImportDatabase::setPluginPathList(const QStringList &paths) -{ - qCDebug(lcQmlImport) << "setPluginPathList:" << paths; - filePluginPath = paths; -} - /*! \internal */ diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h index a7bb40eb2b..7f324b65aa 100644 --- a/src/qml/qml/qqmlimport_p.h +++ b/src/qml/qml/qqmlimport_p.h @@ -51,6 +51,8 @@ #include <private/qqmldirparser_p.h> #include <private/qqmltype_p.h> #include <private/qstringhash_p.h> +#include <private/qv4compileddata_p.h> +#include <private/qfieldlist_p.h> // // W A R N I N G @@ -69,7 +71,6 @@ class QQmlTypeNameCache; class QQmlEngine; class QDir; class QQmlImportNamespace; -class QQmlImportsPrivate; class QQmlImportDatabase; class QQmlTypeLoader; class QQmlTypeLoaderQmldirContent; @@ -100,7 +101,7 @@ struct QQmlImportInstance bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, QTypeRevision *version_return, QQmlType* type_return, - QString *base = nullptr, bool *typeRecursionDetected = nullptr, + const QString *base = nullptr, bool *typeRecursionDetected = nullptr, QQmlType::RegistrationType = QQmlType::AnyRegistrationType, QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion, QList<QQmlError> *errors = nullptr) const; @@ -118,62 +119,91 @@ public: bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type, QTypeRevision *version_return, QQmlType* type_return, - QString *base = nullptr, QList<QQmlError> *errors = nullptr, + const QString *base = nullptr, QList<QQmlError> *errors = nullptr, QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType, bool *typeRecursionDeteced = nullptr); // Prefix when used as a qualified import. Otherwise empty. QHashedString prefix; - // Used by QQmlImportsPrivate::qualifiedSets + // Used by QQmlImports::m_qualifiedSets // set to this in unqualifiedSet to indicate that the lists of imports needs // to be sorted when an inline component import was added // We can't use flag pointer, as that does not work with QFieldList - QQmlImportNamespace *nextNamespace; - bool needsSorting() const; - void setNeedsSorting(bool needsSorting); + QQmlImportNamespace *nextNamespace = nullptr; + bool needsSorting() const { return nextNamespace == this; } + void setNeedsSorting(bool needsSorting) + { + Q_ASSERT(nextNamespace == this || nextNamespace == nullptr); + nextNamespace = needsSorting ? this : nullptr; + } }; -class Q_QML_PRIVATE_EXPORT QQmlImports +class Q_QML_PRIVATE_EXPORT QQmlImports : public QQmlRefCount { + Q_DISABLE_COPY_MOVE(QQmlImports) public: enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned }; - enum ImportFlag { ImportIncomplete = 0x1, ImportLowPrecedence = 0x2, ImportImplicit = 0x4 }; - QQmlImports(QQmlTypeLoader *); - QQmlImports(const QQmlImports &); - ~QQmlImports(); - QQmlImports &operator=(const QQmlImports &); + enum ImportFlag { + ImportNoFlag = 0x0, + ImportIncomplete = 0x1, + ImportLowPrecedence = 0x2, + ImportImplicit = 0x4 + }; + Q_DECLARE_FLAGS(ImportFlags, ImportFlag) - void setBaseUrl(const QUrl &url, const QString &urlString = QString()); - QUrl baseUrl() const; + QQmlImports(QQmlTypeLoader *loader) : m_typeLoader(loader) {} + ~QQmlImports() + { + while (QQmlImportNamespace *ns = m_qualifiedSets.takeFirst()) + delete ns; + } - bool resolveType(const QHashedStringRef &type, - QQmlType *type_return, - QTypeRevision *version_return, - QQmlImportNamespace **ns_return, - QList<QQmlError> *errors = nullptr, - QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType, - bool *typeRecursionDetected = nullptr) const; - bool resolveType(QQmlImportNamespace *, - const QHashedStringRef& type, - QQmlType *type_return, QTypeRevision *version_return, - QQmlType::RegistrationType registrationType - = QQmlType::AnyRegistrationType) const; + void setBaseUrl(const QUrl &url, const QString &urlString = QString()); + QUrl baseUrl() const { return m_baseUrl; } + + bool resolveType( + const QHashedStringRef &type, QQmlType *type_return, QTypeRevision *version_return, + QQmlImportNamespace **ns_return, QList<QQmlError> *errors = nullptr, + QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType, + bool *typeRecursionDetected = nullptr) const; + + bool resolveType( + QQmlImportNamespace *ns, const QHashedStringRef &type, QQmlType *type_return, + QTypeRevision *version_return, + QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType) const + { + return ns->resolveType(m_typeLoader, type, version_return, type_return, nullptr, nullptr, + registrationType); + } QTypeRevision addImplicitImport( - QQmlImportDatabase *importDb, QString *localQmldir, QList<QQmlError> *errors); + QQmlImportDatabase *importDb, QString *localQmldir, QList<QQmlError> *errors) + { + Q_ASSERT(errors); + qCDebug(lcQmlImport) << "addImplicitImport:" << qPrintable(baseUrl().toString()); + + const ImportFlags flags = + ImportFlags(!isLocal(baseUrl()) ? ImportIncomplete : ImportNoFlag) | ImportImplicit; + return addFileImport( + importDb, QLatin1String("."), QString(), QTypeRevision(), + flags, localQmldir, errors); + } - bool addInlineComponentImport(QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl, QQmlType containingType); + bool addInlineComponentImport( + QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl, + QQmlType containingType); QTypeRevision addFileImport( - QQmlImportDatabase *, const QString& uri, const QString& prefix, QTypeRevision version, - uint flags, QList<QQmlError> *errors); + QQmlImportDatabase *importDb, const QString &uri, const QString &prefix, + QTypeRevision version, ImportFlags flags, QString *localQmldir, + QList<QQmlError> *errors); QTypeRevision addLibraryImport( QQmlImportDatabase *importDb, const QString &uri, const QString &prefix, QTypeRevision version, const QString &qmldirIdentifier, const QString &qmldirUrl, - uint flags, QList<QQmlError> *errors); + ImportFlags flags, QList<QQmlError> *errors); QTypeRevision updateQmldirContent( QQmlImportDatabase *importDb, const QString &uri, const QString &prefix, @@ -199,21 +229,73 @@ public: QList<CompositeSingletonReference> resolvedCompositeSingletons() const; - static QStringList completeQmldirPaths(const QString &uri, const QStringList &basePaths, - QTypeRevision version); + static QStringList completeQmldirPaths( + const QString &uri, const QStringList &basePaths, QTypeRevision version); + static QString versionString(QTypeRevision version, ImportVersion importVersion); - static bool isLocal(const QString &url); - static bool isLocal(const QUrl &url); + static bool isLocal(const QString &url) + { + return !QQmlFile::urlToLocalFileOrQrc(url).isEmpty(); + } + + static bool isLocal(const QUrl &url) + { + return !QQmlFile::urlToLocalFileOrQrc(url).isEmpty(); + } + static QUrl urlFromLocalFileOrQrcOrUrl(const QString &); static void setDesignerSupportRequired(bool b); private: friend class QQmlImportDatabase; - QQmlImportsPrivate *d; + + QQmlImportNamespace *importNamespace(const QString &prefix); + + bool resolveType( + const QHashedStringRef &type, QTypeRevision *version_return, QQmlType *type_return, + QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, + bool *typeRecursionDetected = nullptr) const; + + QQmlImportNamespace *findQualifiedNamespace(const QHashedStringRef &) const; + + static QTypeRevision matchingQmldirVersion( + const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, + QTypeRevision version, QList<QQmlError> *errors); + + QTypeRevision importExtension( + const QString &uri, QTypeRevision version, QQmlImportDatabase *database, + const QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors); + + bool getQmldirContent( + const QString &qmldirIdentifier, const QString &uri, QQmlTypeLoaderQmldirContent *qmldir, + QList<QQmlError> *errors); + + QString resolvedUri(const QString &dir_arg, QQmlImportDatabase *database); + + QQmlImportInstance *addImportToNamespace( + QQmlImportNamespace *nameSpace, const QString &uri, const QString &url, + QTypeRevision version, QV4::CompiledData::Import::ImportType type, + QList<QQmlError> *errors, ImportFlags flags); + + QUrl m_baseUrl; + QString m_base; + + // storage of data related to imports without a namespace + // TODO: This needs to be mutable because QQmlImportNamespace likes to sort itself on + // resolveType(). Therefore, QQmlImportNamespace::resolveType() is not const. + // There should be a better way to do this. + mutable QQmlImportNamespace m_unqualifiedset; + + // storage of data related to imports with a namespace + QFieldList<QQmlImportNamespace, &QQmlImportNamespace::nextNamespace> m_qualifiedSets; + + QQmlTypeLoader *m_typeLoader = nullptr; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlImports::ImportFlags) + class Q_QML_PRIVATE_EXPORT QQmlImportDatabase { Q_DECLARE_TR_FUNCTIONS(QQmlImportDatabase) @@ -233,7 +315,7 @@ public: }; QQmlImportDatabase(QQmlEngine *); - ~QQmlImportDatabase(); + ~QQmlImportDatabase() { clearDirCache(); } bool removeDynamicPlugin(const QString &pluginId); QStringList dynamicPlugins() const; @@ -242,8 +324,13 @@ public: void setImportPathList(const QStringList &paths); void addImportPath(const QString& dir); - QStringList pluginPathList() const; - void setPluginPathList(const QStringList &paths); + QStringList pluginPathList() const { return filePluginPath; } + void setPluginPathList(const QStringList &paths) + { + qCDebug(lcQmlImport) << "setPluginPathList:" << paths; + filePluginPath = paths; + } + void addPluginPath(const QString& path); template<typename Callback> @@ -255,7 +342,7 @@ public: QTypeRevision version, QList<QQmlError> *errors); private: - friend class QQmlImportsPrivate; + friend class QQmlImports; friend class QQmlPluginImporter; QString absoluteFilePath(const QString &path) const; @@ -268,7 +355,7 @@ private: QmldirCache *next; }; // Maps from an import to a linked list of qmldir info. - // Used in QQmlImportsPrivate::locateQmldir() + // Used in QQmlImports::locateQmldir() QStringHash<QmldirCache *> qmldirCache; // XXX thread diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index 1bdcfc220c..06a6acc229 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -63,7 +63,9 @@ QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(HANDLE_PRIMITIVE); } } -QQmlPropertyValidator::QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, const QQmlImports &imports, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) +QQmlPropertyValidator::QQmlPropertyValidator( + QQmlEnginePrivate *enginePrivate, const QQmlImports *imports, + const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) : enginePrivate(enginePrivate) , compilationUnit(compilationUnit) , imports(imports) @@ -223,7 +225,8 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( if (name.constData()->isUpper() && !binding->isAttachedProperty()) { QQmlType type; QQmlImportNamespace *typeNamespace = nullptr; - imports.resolveType(stringAt(binding->propertyNameIndex), &type, nullptr, &typeNamespace); + imports->resolveType( + stringAt(binding->propertyNameIndex), &type, nullptr, &typeNamespace); if (typeNamespace) return recordError(binding->location, tr("Invalid use of namespace")); return recordError(binding->location, tr("Invalid attached object assignment")); @@ -363,7 +366,7 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( customParser->clearErrors(); customParser->validator = this; customParser->engine = enginePrivate; - customParser->imports = &imports; + customParser->imports = imports; customParser->verifyBindings(compilationUnit, customBindings); customParser->validator = nullptr; customParser->engine = nullptr; diff --git a/src/qml/qml/qqmlpropertyvalidator_p.h b/src/qml/qml/qqmlpropertyvalidator_p.h index b8dc699dad..67c18b66ad 100644 --- a/src/qml/qml/qqmlpropertyvalidator_p.h +++ b/src/qml/qml/qqmlpropertyvalidator_p.h @@ -64,7 +64,7 @@ class QQmlPropertyValidator { Q_DECLARE_TR_FUNCTIONS(QQmlPropertyValidator) public: - QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, const QQmlImports &imports, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit); + QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, const QQmlImports *imports, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit); QVector<QQmlError> validate(); @@ -92,7 +92,7 @@ private: QQmlEnginePrivate *enginePrivate; QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit; - const QQmlImports &imports; + const QQmlImports *imports; const QV4::CompiledData::Unit *qmlUnit; const QQmlPropertyCacheVector &propertyCaches; diff --git a/src/qml/qml/qqmlscriptblob.cpp b/src/qml/qml/qqmlscriptblob.cpp index 7b7a842d04..02658e3f58 100644 --- a/src/qml/qml/qqmlscriptblob.cpp +++ b/src/qml/qml/qqmlscriptblob.cpp @@ -197,7 +197,7 @@ void QQmlScriptBlob::done() m_scriptData->typeNameCache->add(script.qualifier, scriptIndex, script.nameSpace); } - m_importCache.populateCache(m_scriptData->typeNameCache.data()); + m_importCache->populateCache(m_scriptData->typeNameCache.data()); } m_scripts.clear(); } @@ -226,7 +226,7 @@ void QQmlScriptBlob::initializeFromCompilationUnit(const QQmlRefPointer<QV4::Exe m_scriptData->urlString = finalUrlString(); m_scriptData->m_precompiledScript = unit; - m_importCache.setBaseUrl(finalUrl(), finalUrlString()); + m_importCache->setBaseUrl(finalUrl(), finalUrlString()); QQmlRefPointer<QV4::ExecutableCompilationUnit> script = m_scriptData->m_precompiledScript; @@ -237,7 +237,7 @@ void QQmlScriptBlob::initializeFromCompilationUnit(const QQmlRefPointer<QV4::Exe if (!addImport(import, {}, &errors)) { Q_ASSERT(errors.size()); QQmlError error(errors.takeFirst()); - error.setUrl(m_importCache.baseUrl()); + error.setUrl(m_importCache->baseUrl()); error.setLine(import->location.line); error.setColumn(import->location.column); errors.prepend(error); // put it back on the list after filling out information. diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index 617e478e57..c8f2f118a2 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -226,7 +226,7 @@ const QV4::CompiledData::Unit *QQmlTypeCompiler::qmlUnit() const const QQmlImports *QQmlTypeCompiler::imports() const { - return &typeData->imports(); + return typeData->imports(); } QVector<QmlIR::Object *> *QQmlTypeCompiler::qmlObjects() const diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index da5e5004e8..8b898db38b 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -169,7 +169,7 @@ bool QQmlTypeData::tryLoadFromDiskCache() } } - m_importCache.setBaseUrl(finalUrl(), finalUrlString()); + m_importCache->setBaseUrl(finalUrl(), finalUrlString()); // For remote URLs, we don't delay the loading of the implicit import // because the loading probably requires an asynchronous fetch of the @@ -206,7 +206,7 @@ bool QQmlTypeData::tryLoadFromDiskCache() if (!addImport(import, {}, &errors)) { Q_ASSERT(errors.size()); QQmlError error(errors.takeFirst()); - error.setUrl(m_importCache.baseUrl()); + error.setUrl(m_importCache->baseUrl()); 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. @@ -220,7 +220,7 @@ bool QQmlTypeData::tryLoadFromDiskCache() auto importUrl = finalUrl(); importUrl.setFragment(QString::number(ic.objectIndex)); auto import = new QQmlImportInstance(); - m_importCache.addInlineComponentImport(import, nameString, importUrl, QQmlType()); + m_importCache->addInlineComponentImport(import, nameString, importUrl, QQmlType()); } return true; @@ -241,7 +241,7 @@ void QQmlTypeData::createTypeAndPropertyCaches( { QQmlPropertyCacheCreator<QV4::ExecutableCompilationUnit> propertyCacheCreator( &m_compiledData->propertyCaches, &pendingGroupPropertyBindings, engine, - m_compiledData.data(), &m_importCache, typeClassName()); + m_compiledData.data(), m_importCache.data(), typeClassName()); QQmlError error = propertyCacheCreator.buildMetaObjects(); if (error.isValid()) { setError(error); @@ -460,7 +460,7 @@ void QQmlTypeData::done() m_compiledData->inlineComponentData = m_inlineComponentData; { // Sanity check property bindings - QQmlPropertyValidator validator(enginePrivate, m_importCache, m_compiledData); + QQmlPropertyValidator validator(enginePrivate, m_importCache.data(), m_compiledData); QVector<QQmlError> errors = validator.validate(); if (!errors.isEmpty()) { setError(errors); @@ -551,7 +551,7 @@ bool QQmlTypeData::loadImplicitImport() { m_implicitImportLoaded = true; // Even if we hit an error, count as loaded (we'd just keep hitting the error) - m_importCache.setBaseUrl(finalUrl(), finalUrlString()); + m_importCache->setBaseUrl(finalUrl(), finalUrlString()); QQmlImportDatabase *importDatabase = typeLoader()->importDatabase(); // For local urls, add an implicit import "." as most overridden lookup. @@ -559,7 +559,7 @@ bool QQmlTypeData::loadImplicitImport() // types from available plugins. QList<QQmlError> implicitImportErrors; QString localQmldir; - m_importCache.addImplicitImport(importDatabase, &localQmldir, &implicitImportErrors); + m_importCache->addImplicitImport(importDatabase, &localQmldir, &implicitImportErrors); // When loading with QQmlImports::ImportImplicit, the imports are _appended_ to the namespace // in the order they are loaded. Therefore, the addImplicitImport above gets the highest @@ -667,19 +667,19 @@ void QQmlTypeData::continueLoadFromIR() auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first(); QTypeRevision version; QQmlImportNamespace *ns = nullptr; - m_importCache.resolveType(containingTypeName, &containingType, &version, &ns); + m_importCache->resolveType(containingTypeName, &containingType, &version, &ns); for (auto const& object: m_document->objects) { for (auto it = object->inlineComponentsBegin(); it != object->inlineComponentsEnd(); ++it) { QString const nameString = m_document->stringAt(it->nameIndex); auto importUrl = finalUrl(); importUrl.setFragment(QString::number(it->objectIndex)); auto import = new QQmlImportInstance(); // Note: The cache takes ownership of the QQmlImportInstance - m_importCache.addInlineComponentImport(import, nameString, importUrl, containingType); + m_importCache->addInlineComponentImport(import, nameString, importUrl, containingType); } } m_typeReferences.collectFromObjects(m_document->objects.constBegin(), m_document->objects.constEnd()); - m_importCache.setBaseUrl(finalUrl(), finalUrlString()); + m_importCache->setBaseUrl(finalUrl(), finalUrlString()); // For remote URLs, we don't delay the loading of the implicit import // because the loading probably requires an asynchronous fetch of the @@ -712,7 +712,7 @@ void QQmlTypeData::continueLoadFromIR() // errors might be from unsuccessfully trying to load a module from the // resource file system. QQmlError error = errors.first(); - error.setUrl(m_importCache.baseUrl()); + error.setUrl(m_importCache->baseUrl()); error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line)); error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column)); setError(error); @@ -738,7 +738,7 @@ void QQmlTypeData::allDependenciesDone() PendingImportPtr import = *keyIt; QQmlError error; error.setDescription(QQmlTypeLoader::tr("module \"%1\" is not installed").arg(import->uri)); - error.setUrl(m_importCache.baseUrl()); + error.setUrl(m_importCache->baseUrl()); error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line)); error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column)); errors.prepend(error); @@ -806,7 +806,7 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach void QQmlTypeData::resolveTypes() { // Add any imported scripts to our resolved set - const auto resolvedScripts = m_importCache.resolvedScripts(); + const auto resolvedScripts = m_importCache->resolvedScripts(); for (const QQmlImports::ScriptReference &script : resolvedScripts) { QQmlRefPointer<QQmlScriptBlob> blob = typeLoader()->getScript(script.location); addDependency(blob.data()); @@ -827,7 +827,7 @@ void QQmlTypeData::resolveTypes() } // Lets handle resolved composite singleton types - const auto resolvedCompositeSingletons = m_importCache.resolvedCompositeSingletons(); + const auto resolvedCompositeSingletons = m_importCache->resolvedCompositeSingletons(); for (const QQmlImports::CompositeSingletonReference &csRef : resolvedCompositeSingletons) { TypeReference ref; QString typeName; @@ -917,7 +917,7 @@ QQmlError QQmlTypeData::buildTypeResolutionCaches( for (const QQmlTypeData::TypeReference &singleton: m_compositeSingletons) (*typeNameCache)->add(singleton.type.qmlTypeName(), singleton.type.sourceUrl(), singleton.prefix); - m_importCache.populateCache(typeNameCache->data()); + m_importCache->populateCache(typeNameCache->data()); for (auto resolvedType = m_resolvedTypes.constBegin(), end = m_resolvedTypes.constEnd(); resolvedType != end; ++resolvedType) { auto ref = std::make_unique<QV4::ResolvedTypeReference>(); @@ -989,17 +989,17 @@ bool QQmlTypeData::resolveType(const QString &typeName, QTypeRevision &version, QQmlImportNamespace *typeNamespace = nullptr; QList<QQmlError> errors; - bool typeFound = m_importCache.resolveType(typeName, &ref.type, &version, - &typeNamespace, &errors, registrationType, - typeRecursionDetected); + bool typeFound = m_importCache->resolveType(typeName, &ref.type, &version, + &typeNamespace, &errors, registrationType, + typeRecursionDetected); if (!typeNamespace && !typeFound && !m_implicitImportLoaded) { // Lazy loading of implicit import if (loadImplicitImport()) { // Try again to find the type errors.clear(); - typeFound = m_importCache.resolveType(typeName, &ref.type, &version, - &typeNamespace, &errors, registrationType, - typeRecursionDetected); + typeFound = m_importCache->resolveType(typeName, &ref.type, &version, + &typeNamespace, &errors, registrationType, + typeRecursionDetected); } else { return false; //loadImplicitImport() hit an error, and called setError already } @@ -1020,7 +1020,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, QTypeRevision &version, // Description should come from error provided by addImport() function. error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database")); } - error.setUrl(m_importCache.baseUrl()); + error.setUrl(m_importCache->baseUrl()); error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(typeName).arg(error.description())); } diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index d458a622c9..652f03aae5 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -482,7 +482,8 @@ void QQmlTypeLoader::shutdownThread() } QQmlTypeLoader::Blob::PendingImport::PendingImport( - QQmlTypeLoader::Blob *blob, const QV4::CompiledData::Import *import, uint flags) + QQmlTypeLoader::Blob *blob, const QV4::CompiledData::Import *import, + QQmlImports::ImportFlags flags) : uri(blob->stringAt(import->uriIndex)) , qualifier(blob->stringAt(import->qualifierIndex)) , type(static_cast<QV4::CompiledData::Import::ImportType>(quint32(import->type))) @@ -493,7 +494,8 @@ QQmlTypeLoader::Blob::PendingImport::PendingImport( } QQmlTypeLoader::Blob::Blob(const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader) - : QQmlDataBlob(url, type, loader), m_importCache(loader) + : QQmlDataBlob(url, type, loader) + , m_importCache(new QQmlImports(loader), QQmlRefPointer<QQmlImports>::Adopt) { } @@ -527,7 +529,7 @@ bool QQmlTypeLoader::Blob::updateQmldir(const QQmlRefPointer<QQmlQmldirData> &da typeLoader()->setQmldirContent(qmldirIdentifier, data->content()); - const QTypeRevision version = m_importCache.updateQmldirContent( + const QTypeRevision version = m_importCache->updateQmldirContent( typeLoader()->importDatabase(), import->uri, import->qualifier, qmldirIdentifier, qmldirUrl, errors); if (!version.isValid()) @@ -562,8 +564,8 @@ bool QQmlTypeLoader::Blob::updateQmldir(const QQmlRefPointer<QQmlQmldirData> &da return true; } -bool QQmlTypeLoader::Blob::addImport(const QV4::CompiledData::Import *import, uint flags, - QList<QQmlError> *errors) +bool QQmlTypeLoader::Blob::addImport(const QV4::CompiledData::Import *import, + QQmlImports::ImportFlags flags, QList<QQmlError> *errors) { return addImport(std::make_shared<PendingImport>(this, import, flags), errors); } @@ -592,7 +594,7 @@ bool QQmlTypeLoader::Blob::addImport( import->uri, import->version, searchMode, [&](const QString &qmldirFilePath, const QString &qmldirUrl) { // This is a local library import - const QTypeRevision actualVersion = m_importCache.addLibraryImport( + const QTypeRevision actualVersion = m_importCache->addLibraryImport( importDatabase, import->uri, import->qualifier, import->version, qmldirFilePath, qmldirUrl, import->flags, errors); if (!actualVersion.isValid()) @@ -657,7 +659,7 @@ bool QQmlTypeLoader::Blob::addImport( // Try with any module of that name. || QQmlMetaType::latestModuleVersion(import->uri).isValid()) { - if (!m_importCache.addLibraryImport( + if (!m_importCache->addLibraryImport( importDatabase, import->uri, import->qualifier, import->version, QString(), QString(), import->flags, errors).isValid()) { return false; @@ -677,7 +679,7 @@ bool QQmlTypeLoader::Blob::addImport( : QQmlImportDatabase::Remote); if (!remotePathList.isEmpty()) { // Add this library and request the possible locations for it - const QTypeRevision version = m_importCache.addLibraryImport( + const QTypeRevision version = m_importCache->addLibraryImport( importDatabase, import->uri, import->qualifier, import->version, QString(), QString(), import->flags | QQmlImports::ImportIncomplete, errors); @@ -712,7 +714,7 @@ bool QQmlTypeLoader::Blob::addImport( } else { Q_ASSERT(import->type == QV4::CompiledData::Import::ImportFile); - uint flags = 0; + QQmlImports::ImportFlags flags; QUrl importUrl(import->uri); QString path = importUrl.path(); @@ -724,9 +726,9 @@ bool QQmlTypeLoader::Blob::addImport( flags = QQmlImports::ImportIncomplete; } - const QTypeRevision version = m_importCache.addFileImport( + const QTypeRevision version = m_importCache->addFileImport( importDatabase, import->uri, import->qualifier, import->version, flags, - errors); + nullptr, errors); if (!version.isValid()) return false; @@ -751,7 +753,7 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob) if (!qmldirDataAvailable(data, &errors)) { Q_ASSERT(errors.size()); QQmlError error(errors.takeFirst()); - error.setUrl(m_importCache.baseUrl()); + error.setUrl(m_importCache->baseUrl()); const QV4::CompiledData::Location importLocation = data->importLocation(this); error.setLine(qmlConvertSourceCoordinate<quint32, int>(importLocation.line)); error.setColumn(qmlConvertSourceCoordinate<quint32, int>(importLocation.column)); @@ -763,7 +765,7 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob) bool QQmlTypeLoader::Blob::loadDependentImports( const QList<QQmlDirParser::Import> &imports, const QString &qualifier, - QTypeRevision version, uint flags, QList<QQmlError> *errors) + QTypeRevision version, QQmlImports::ImportFlags flags, QList<QQmlError> *errors) { for (const auto &import : imports) { if (import.flags & QQmlDirParser::Import::Optional) @@ -796,7 +798,7 @@ bool QQmlTypeLoader::Blob::loadDependentImports( } bool QQmlTypeLoader::Blob::loadImportDependencies( - PendingImportPtr currentImport, const QString &qmldirUri, uint flags, + PendingImportPtr currentImport, const QString &qmldirUri, QQmlImports::ImportFlags flags, QList<QQmlError> *errors) { const QQmlTypeLoaderQmldirContent qmldir = typeLoader()->qmldirContent(qmldirUri); diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index c5e84446d7..8fe818c96d 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -87,7 +87,7 @@ public: Blob(const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader); ~Blob() override; - const QQmlImports &imports() const { return m_importCache; } + const QQmlImports *imports() const { return m_importCache.data(); } void setCachedUnitStatus(QQmlMetaType::CachedUnitLookupError status) { m_cachedUnitStatus = status; } @@ -100,18 +100,19 @@ public: = QV4::CompiledData::Import::ImportType::ImportLibrary; QV4::CompiledData::Location location; - uint flags = 0; + QQmlImports::ImportFlags flags; int priority = 0; QTypeRevision version; PendingImport() = default; - PendingImport(Blob *blob, const QV4::CompiledData::Import *import, uint flags); + PendingImport(Blob *blob, const QV4::CompiledData::Import *import, + QQmlImports::ImportFlags flags); }; using PendingImportPtr = std::shared_ptr<PendingImport>; protected: - bool addImport(const QV4::CompiledData::Import *import, uint flags, + bool addImport(const QV4::CompiledData::Import *import, QQmlImports::ImportFlags, QList<QQmlError> *errors); bool addImport(PendingImportPtr import, QList<QQmlError> *errors); @@ -126,19 +127,19 @@ public: void dependencyComplete(QQmlDataBlob *) override; bool loadImportDependencies( - PendingImportPtr currentImport, const QString &qmldirUri, uint flags, - QList<QQmlError> *errors); + PendingImportPtr currentImport, const QString &qmldirUri, + QQmlImports::ImportFlags flags, QList<QQmlError> *errors); protected: bool loadDependentImports( const QList<QQmlDirParser::Import> &imports, const QString &qualifier, - QTypeRevision version, uint flags, QList<QQmlError> *errors); + QTypeRevision version, QQmlImports::ImportFlags flags, QList<QQmlError> *errors); virtual QString stringAt(int) const { return QString(); } bool isDebugging() const; bool diskCacheEnabled() const; - QQmlImports m_importCache; + QQmlRefPointer<QQmlImports> m_importCache; QVector<PendingImportPtr> m_unresolvedImports; QVector<QQmlRefPointer<QQmlQmldirData>> m_qmldirs; QQmlMetaType::CachedUnitLookupError m_cachedUnitStatus = QQmlMetaType::CachedUnitLookupError::NoError; diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp index 0f23b3190e..0ae5b84195 100644 --- a/src/qml/qml/qqmltypenamecache.cpp +++ b/src/qml/qml/qqmltypenamecache.cpp @@ -43,15 +43,6 @@ QT_BEGIN_NAMESPACE -QQmlTypeNameCache::QQmlTypeNameCache(const QQmlImports &importCache) - : m_imports(importCache) -{ -} - -QQmlTypeNameCache::~QQmlTypeNameCache() -{ -} - void QQmlTypeNameCache::add(const QHashedString &name, const QUrl &url, const QHashedString &nameSpace) { if (nameSpace.length() != 0) { diff --git a/src/qml/qml/qqmltypenamecache_p.h b/src/qml/qml/qqmltypenamecache_p.h index 5e1a88b2a5..a44ac2ed2d 100644 --- a/src/qml/qml/qqmltypenamecache_p.h +++ b/src/qml/qml/qqmltypenamecache_p.h @@ -84,8 +84,8 @@ class QQmlEngine; class Q_QML_PRIVATE_EXPORT QQmlTypeNameCache : public QQmlRefCount { public: - QQmlTypeNameCache(const QQmlImports &imports); - ~QQmlTypeNameCache() override; + QQmlTypeNameCache(const QQmlRefPointer<QQmlImports> &imports) : m_imports(imports) {} + ~QQmlTypeNameCache() {} inline bool isEmpty() const; @@ -176,7 +176,7 @@ private: QList<QQmlError> errors; QQmlType t; bool typeRecursionDetected = false; - const bool typeFound = m_imports.resolveType( + const bool typeFound = m_imports->resolveType( toHashedStringRef(name), &t, nullptr, &typeNamespace, &errors, QQmlType::AnyRegistrationType, recursionRestriction == QQmlImport::AllowRecursion @@ -218,7 +218,7 @@ private: QQmlImportNamespace *typeNamespace = nullptr; QList<QQmlError> errors; QQmlType t; - bool typeFound = m_imports.resolveType( + bool typeFound = m_imports->resolveType( qualifiedTypeName, &t, nullptr, &typeNamespace, &errors); if (typeFound) return Result(t); @@ -272,7 +272,7 @@ private: QMap<const QQmlImportRef *, QStringHash<QQmlImportRef> > m_namespacedImports; QVector<QQmlTypeModuleVersion> m_anonymousImports; QStringHash<QUrl> m_anonymousCompositeSingletons; - QQmlImports m_imports; + QQmlRefPointer<QQmlImports> m_imports; }; QQmlTypeNameCache::Result::Result() |