diff options
Diffstat (limited to 'src/qml/qml/qqmlimport.cpp')
-rw-r--r-- | src/qml/qml/qqmlimport.cpp | 310 |
1 files changed, 113 insertions, 197 deletions
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 98d9aee61b..86380294ba 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -85,12 +85,6 @@ QTypeRevision relevantVersion(const QString &uri, QTypeRevision version) return QQmlMetaType::latestModuleVersion(uri).isValid() ? version : QTypeRevision(); } -QTypeRevision validVersion(QTypeRevision version = QTypeRevision()) -{ - // If the given version is invalid, return a valid but useless version to signal "It's OK". - return version.isValid() ? version : QTypeRevision::fromMinorVersion(0); -} - QQmlError moduleNotFoundError(const QString &uri, QTypeRevision version) { QQmlError error; @@ -203,6 +197,12 @@ bool isPathAbsolute(const QString &path) \internal */ +QTypeRevision QQmlImports::validVersion(QTypeRevision version) +{ + // If the given version is invalid, return a valid but useless version to signal "It's OK". + return version.isValid() ? version : QTypeRevision::fromMinorVersion(0); +} + /*! Sets the base URL to be used for all relative file imports added. */ @@ -450,8 +450,8 @@ 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, + QQmlTypeLoader *typeLoader, const QHashedStringRef &type, QQmlType *type_return, + QTypeRevision *version_return, QQmlImportNamespace **ns_return, QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) const { QQmlImportNamespace *ns = findQualifiedNamespace(type); @@ -461,7 +461,7 @@ bool QQmlImports::resolveType( return true; } if (type_return) { - if (resolveType(type, version_return, type_return, errors, registrationType, + if (resolveType(typeLoader, type, version_return, type_return, errors, registrationType, typeRecursionDetected)) { if (lcQmlImport().isDebugEnabled()) { #define RESOLVE_TYPE_DEBUG qCDebug(lcQmlImport) \ @@ -489,18 +489,8 @@ bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoaderQmldirContent &qmldir, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors) { - - const QString preferredPath = qmldir.preferredPath(); - if (preferredPath.isEmpty()) { - Q_ASSERT(resolvedUrl.endsWith(Slash)); - url = resolvedUrl; - } else { - Q_ASSERT(preferredPath.endsWith(Slash)); - if (preferredPath.startsWith(u':')) - url = QStringLiteral("qrc") + preferredPath; - else - url = QUrl::fromLocalFile(preferredPath).toString(); - } + Q_ASSERT(resolvedUrl.endsWith(Slash)); + url = resolvedUrl; qmlDirComponents = qmldir.components(); @@ -537,8 +527,8 @@ QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qml && (!version.hasMinorVersion() || (sit->version.minorVersion() <= version.minorVersion()))) { // Load the highest version that matches - QMap<QString, QQmlDirParser::Script>::iterator vit = versioned.find(sit->nameSpace); - if (vit == versioned.end() + const auto vit = versioned.constFind(sit->nameSpace); + if (vit == versioned.cend() || (vit->version.minorVersion() < sit->version.minorVersion())) { versioned.insert(sit->nameSpace, *sit); } @@ -582,37 +572,14 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt bool ret = uri == typeStr; if (ret) { Q_ASSERT(!type_return->isValid()); - auto createICType = [&]() { - auto typePriv = new QQmlTypePrivate {QQmlType::RegistrationType::InlineComponentType}; - bool ok = false; - typePriv->extraData.id->objectId = QUrl(this->url).fragment().toInt(&ok); - Q_ASSERT(ok); - typePriv->extraData.id->url = QUrl(this->url); - auto icType = QQmlType(typePriv); - typePriv->release(); - return icType; - }; - if (containingType.isValid()) { - // we currently cannot reference a Singleton inside itself - // in that case, containingType is still invalid - if (int icID = containingType.lookupInlineComponentIdByName(typeStr); icID != -1) { - *type_return = containingType.lookupInlineComponentById(icID); - } else { - auto icType = createICType(); - int placeholderId = containingType.generatePlaceHolderICId(); - const_cast<QQmlImportInstance*>(this)->containingType.associateInlineComponent(typeStr, placeholderId, CompositeMetaTypeIds {}, icType); - *type_return = QQmlType(icType); - } - } else { - *type_return = createICType(); - } + *type_return = QQmlMetaType::fetchOrCreateInlineComponentTypeForUrl(QUrl(url)); } return ret; } QQmlDirComponents::ConstIterator it = qmlDirComponents.find(typeStr), end = qmlDirComponents.end(); if (it != end) { QString componentUrl; - bool isCompositeSingleton = false; + QQmlMetaType::CompositeTypeLookupMode lookupMode = QQmlMetaType::NonSingleton; QQmlDirComponents::ConstIterator candidate = end; for ( ; it != end && it.key() == typeStr; ++it) { const QQmlDirParser::Component &c = *it; @@ -657,7 +624,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt // This is our best candidate so far candidate = it; - isCompositeSingleton = c.singleton; + lookupMode = c.singleton ? QQmlMetaType::Singleton : QQmlMetaType::NonSingleton; } } } @@ -665,7 +632,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt if (candidate != end) { if (!base) // ensure we have a componentUrl componentUrl = resolveLocalUrl(QString(url + candidate->typeName + dotqml_string), candidate->fileName); - QQmlType returnType = QQmlMetaType::typeForUrl(componentUrl, type, isCompositeSingleton, + QQmlType returnType = QQmlMetaType::typeForUrl(componentUrl, type, lookupMode, nullptr, candidate->version); if (version_return) *version_return = candidate->version; @@ -714,7 +681,10 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt *typeRecursionDetected = recursion; if (recursionRestriction == QQmlImport::AllowRecursion || !recursion) { QQmlType returnType = QQmlMetaType::typeForUrl( - qmlUrl, type, registrationType == QQmlType::CompositeSingletonType, errors); + qmlUrl, type, registrationType == QQmlType::CompositeSingletonType + ? QQmlMetaType::Singleton + : QQmlMetaType::NonSingleton, + errors); if (type_return) *type_return = returnType; return returnType.isValid(); @@ -726,16 +696,16 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt } bool QQmlImports::resolveType( - const QHashedStringRef &type, QTypeRevision *version_return, QQmlType *type_return, - QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, - bool *typeRecursionDetected) const + QQmlTypeLoader *typeLoader, 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( - m_typeLoader, unqualifiedtype, version_return, type_return, &m_base, errors, + typeLoader, unqualifiedtype, version_return, type_return, &m_base, errors, registrationType, typeRecursionDetected)) return true; if (nameSpace->imports.size() == 1 @@ -746,7 +716,7 @@ bool QQmlImports::resolveType( *type_return = QQmlMetaType::typeForUrl( resolveLocalUrl(nameSpace->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml")), - type, false, errors); + type, QQmlMetaType::NonSingleton, errors); return type_return->isValid(); } return false; @@ -765,23 +735,8 @@ bool QQmlImports::resolveType( } else { 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); - if (objectIndex != -1) { - *type_return = type_return->lookupInlineComponentById(objectIndex); - } else { - auto icTypePriv = new QQmlTypePrivate(QQmlType::RegistrationType::InlineComponentType); - icTypePriv->setContainingType(type_return); - icTypePriv->extraData.id->url = type_return->sourceUrl(); - int placeholderId = type_return->generatePlaceHolderICId(); - icTypePriv->extraData.id->url.setFragment(QString::number(placeholderId)); - auto icType = QQmlType(icTypePriv); - icTypePriv->release(); - type_return->associateInlineComponent(icName, placeholderId, CompositeMetaTypeIds {}, icType); - *type_return = icType; - } - Q_ASSERT(type_return->containingType().isValid()); - type_return->setPendingResolutionName(icName); + *type_return = QQmlMetaType::inlineComponentType( + *type_return, splitName.at(1).toString()); return true; } else { // or a failure @@ -802,22 +757,8 @@ bool QQmlImports::resolveType( error.setDescription(QQmlImportDatabase::tr("- %1 is not a namespace").arg(splitName.at(0).toString())); } else { if (resolveTypeInNamespace(splitName.at(1), s, nullptr)) { - auto const icName = splitName.at(2).toString(); - auto objectIndex = type_return->lookupInlineComponentIdByName(icName); - if (objectIndex != -1) - *type_return = type_return->lookupInlineComponentById(objectIndex); - else { - auto icTypePriv = new QQmlTypePrivate(QQmlType::RegistrationType::InlineComponentType); - icTypePriv->setContainingType(type_return); - icTypePriv->extraData.id->url = type_return->sourceUrl(); - int placeholderId = type_return->generatePlaceHolderICId(); - icTypePriv->extraData.id->url.setFragment(QString::number(placeholderId)); - auto icType = QQmlType(icTypePriv); - icTypePriv->release(); - type_return->associateInlineComponent(icName, placeholderId, CompositeMetaTypeIds {}, icType); - *type_return = icType; - } - type_return->setPendingResolutionName(icName); + *type_return = QQmlMetaType::inlineComponentType( + *type_return, splitName.at(2).toString()); return true; } else { error.setDescription(QQmlImportDatabase::tr("- %1 is not a type").arg(splitName.at(1).toString())); @@ -950,7 +891,7 @@ QQmlImportNamespace *QQmlImports::findQualifiedNamespace(const QHashedStringRef Import an extension defined by a qmldir file. */ QTypeRevision QQmlImports::importExtension( - const QString &uri, QTypeRevision version, QQmlImportDatabase *database, + QQmlTypeLoader *typeLoader, const QString &uri, QTypeRevision version, const QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors) { Q_ASSERT(qmldir->hasContent()); @@ -970,35 +911,49 @@ QTypeRevision QQmlImports::importExtension( return QTypeRevision(); } - if (qmldir->plugins().isEmpty()) + if (qmldir->plugins().isEmpty()) { + // If the qmldir does not register a plugin, we might still have declaratively + // registered types (if we are dealing with an application instead of a library) + if (!QQmlMetaType::typeModule(uri, version)) + QQmlMetaType::qmlRegisterModuleTypes(uri); return validVersion(version); + } - QQmlPluginImporter importer(uri, version, database, qmldir, m_typeLoader, errors); + QQmlPluginImporter importer( + uri, version, typeLoader->importDatabase(), qmldir, typeLoader, errors); return importer.importPlugins(); } -bool QQmlImports::getQmldirContent(const QString &qmldirIdentifier, const QString &uri, - QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors) +QString QQmlImports::redirectQmldirContent( + QQmlTypeLoader *typeLoader, QQmlTypeLoaderQmldirContent *qmldir) +{ + const QString preferredPath = qmldir->preferredPath(); + const QString url = preferredPath.startsWith(u':') + ? QStringLiteral("qrc") + preferredPath + : QUrl::fromLocalFile(preferredPath).toString(); + + QQmlTypeLoaderQmldirContent redirected + = typeLoader->qmldirContent(url + QLatin1String("qmldir")); + + // Ignore errors: If the qmldir doesn't exist, stick to the old one. + if (redirected.hasContent() && !redirected.hasError()) + *qmldir = std::move(redirected); + return url; +} + +bool QQmlImports::getQmldirContent( + QQmlTypeLoader *typeLoader, const QString &qmldirIdentifier, const QString &uri, + QQmlTypeLoaderQmldirContent *qmldir, QList<QQmlError> *errors) { Q_ASSERT(errors); Q_ASSERT(qmldir); - *qmldir = m_typeLoader->qmldirContent(qmldirIdentifier); - if ((*qmldir).hasContent()) { - // Ensure that parsing was successful - if ((*qmldir).hasError()) { - QUrl url = QUrl::fromLocalFile(qmldirIdentifier); - const QList<QQmlError> qmldirErrors = (*qmldir).errors(uri); - for (int i = 0; i < qmldirErrors.size(); ++i) { - QQmlError error = qmldirErrors.at(i); - error.setUrl(url); - errors->append(error); - } - return false; - } - } + *qmldir = typeLoader->qmldirContent(qmldirIdentifier); + if (!qmldir->hasContent() || !qmldir->hasError()) + return true; - return true; + errors->append(qmldir->errors(uri, QUrl::fromLocalFile(qmldirIdentifier))); + return false; } QString QQmlImports::resolvedUri(const QString &dir_arg, QQmlImportDatabase *database) @@ -1036,26 +991,6 @@ QString QQmlImports::resolvedUri(const QString &dir_arg, QQmlImportDatabase *dat return stableRelativePath; } -/* removes all file selector occurrences in path - firstPlus is the position of the initial '+' in the path - which we always have as we check for '+' to decide whether - we need to do some work at all -*/ -static QString pathWithoutFileSelectors(QString path, // we want a copy of path - qsizetype firstPlus) -{ - do { - Q_ASSERT(path.at(firstPlus) == u'+'); - const auto eos = path.size(); - qsizetype terminatingSlashPos = firstPlus + 1; - while (terminatingSlashPos != eos && path.at(terminatingSlashPos) != u'/') - ++terminatingSlashPos; - path.remove(firstPlus, terminatingSlashPos - firstPlus + 1); - firstPlus = path.indexOf(u'+', firstPlus); - } while (firstPlus != -1); - return path; -} - /*! \internal @@ -1102,47 +1037,17 @@ QTypeRevision QQmlImports::matchingQmldirVersion( typedef QQmlDirComponents::const_iterator ConstIterator; const QQmlDirComponents &components = qmldir.components(); - QMultiHash<QString, ConstIterator> baseFileName2ConflictingComponents; - ConstIterator cend = components.constEnd(); for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) { for (ConstIterator cit2 = components.constBegin(); cit2 != cit; ++cit2) { if (cit2->typeName == cit->typeName && cit2->version == cit->version) { - // ugly heuristic to deal with file selectors - const auto comp2PotentialFileSelectorPos = cit2->fileName.indexOf(u'+'); - const bool comp2MightHaveFileSelector = comp2PotentialFileSelectorPos != -1; - /* If we detect conflicting paths, we check if they agree when we remove anything looking like a - file selector. - We need to create copies of the filenames, otherwise QString::replace would modify the - existing file-names - */ - QString compFileName1 = cit->fileName; - QString compFileName2 = cit2->fileName; - if (auto fileSelectorPos1 = compFileName1.indexOf(u'+'); fileSelectorPos1 != -1) { - // existing entry was file selector entry, fix it up - // it could also be the case that _both_ are using file selectors - QString baseName = comp2MightHaveFileSelector ? pathWithoutFileSelectors(compFileName2, - comp2PotentialFileSelectorPos) - : compFileName2; - if (pathWithoutFileSelectors(compFileName1, fileSelectorPos1) == baseName) { - baseFileName2ConflictingComponents.insert(baseName, cit); - baseFileName2ConflictingComponents.insert(baseName, cit2); - continue; - } - // fall through to error case - } else if (comp2MightHaveFileSelector) { - // new entry contains file selector (and we now that cit did not) - if (pathWithoutFileSelectors(compFileName2, comp2PotentialFileSelectorPos) == compFileName1) { - baseFileName2ConflictingComponents.insert(compFileName1, cit2); - continue; - } - // fall through to error case - } // This entry clashes with a predecessor QQmlError error; - error.setDescription(QQmlImportDatabase::tr("\"%1\" version %2.%3 is defined more than once in module \"%4\"") - .arg(cit->typeName).arg(cit->version.majorVersion()) - .arg(cit->version.minorVersion()).arg(uri)); + error.setDescription( + QQmlImportDatabase::tr( + "\"%1\" version %2.%3 is defined more than once in module \"%4\"") + .arg(cit->typeName).arg(cit->version.majorVersion()) + .arg(cit->version.minorVersion()).arg(uri)); errors->prepend(error); return QTypeRevision(); } @@ -1151,14 +1056,6 @@ QTypeRevision QQmlImports::matchingQmldirVersion( addVersion(cit->version); } - // ensure that all components point to the actual base URL, and let the file selectors resolve them correctly during URL resolution - for (auto keyIt = baseFileName2ConflictingComponents.keyBegin(); keyIt != baseFileName2ConflictingComponents.keyEnd(); ++keyIt) { - const QString& baseFileName = *keyIt; - const auto conflictingComponents = baseFileName2ConflictingComponents.values(baseFileName); - for (ConstIterator component: conflictingComponents) - component->fileName = baseFileName; - } - typedef QList<QQmlDirParser::Script>::const_iterator SConstIterator; const QQmlDirScripts &scripts = qmldir.scripts(); @@ -1219,7 +1116,7 @@ QQmlImportNamespace *QQmlImports::importNamespace(const QString &prefix) return nameSpace; } -QQmlImportInstance *QQmlImports::addImportToNamespace( +static QQmlImportInstance *addImportToNamespace( QQmlImportNamespace *nameSpace, const QString &uri, const QString &url, QTypeRevision version, QV4::CompiledData::Import::ImportType type, QList<QQmlError> *errors, quint16 precedence) { @@ -1249,11 +1146,11 @@ QQmlImportInstance *QQmlImports::addImportToNamespace( } QTypeRevision QQmlImports::addLibraryImport( - QQmlImportDatabase *database, const QString &uri, const QString &prefix, + QQmlTypeLoader *typeLoader, const QString &uri, const QString &prefix, QTypeRevision version, const QString &qmldirIdentifier, const QString &qmldirUrl, ImportFlags flags, quint16 precedence, QList<QQmlError> *errors) { - Q_ASSERT(database); + Q_ASSERT(typeLoader); Q_ASSERT(errors); qCDebug(lcQmlImport) @@ -1273,15 +1170,19 @@ QTypeRevision QQmlImports::addLibraryImport( QQmlTypeLoaderQmldirContent qmldir; if (!qmldirIdentifier.isEmpty()) { - if (!getQmldirContent(qmldirIdentifier, uri, &qmldir, errors)) + if (!getQmldirContent(typeLoader, qmldirIdentifier, uri, &qmldir, errors)) return QTypeRevision(); if (qmldir.hasContent()) { - version = importExtension(uri, version, database, &qmldir, errors); + version = importExtension(typeLoader, uri, version, &qmldir, errors); if (!version.isValid()) return QTypeRevision(); - if (!inserted->setQmldirContent(qmldirUrl, qmldir, nameSpace, errors)) + const QString resolvedUrl = qmldir.hasRedirection() + ? redirectQmldirContent(typeLoader, &qmldir) + : qmldirUrl; + + if (!inserted->setQmldirContent(resolvedUrl, qmldir, nameSpace, errors)) return QTypeRevision(); } } @@ -1333,11 +1234,11 @@ QTypeRevision QQmlImports::addLibraryImport( 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, quint16 precedence, - QString *localQmldir, QList<QQmlError> *errors) + QQmlTypeLoader *typeLoader, const QString &uri, const QString &prefix, + QTypeRevision version, ImportFlags flags, quint16 precedence, QString *localQmldir, + QList<QQmlError> *errors) { - Q_ASSERT(database); + Q_ASSERT(typeLoader); Q_ASSERT(errors); qCDebug(lcQmlImport) @@ -1367,7 +1268,7 @@ QTypeRevision QQmlImports::addFileImport( QString qmldirUrl = resolveLocalUrl(m_base, importUri + (importUri.endsWith(Slash) ? String_qmldir : Slash_qmldir)); - qmldirUrl = m_typeLoader->engine()->interceptUrl( + qmldirUrl = typeLoader->engine()->interceptUrl( QUrl(qmldirUrl), QQmlAbstractUrlInterceptor::QmldirFile).toString(); QString qmldirIdentifier; @@ -1377,7 +1278,7 @@ QTypeRevision QQmlImports::addFileImport( Q_ASSERT(!localFileOrQrc.isEmpty()); const QString dir = localFileOrQrc.left(localFileOrQrc.lastIndexOf(Slash) + 1); - if (!m_typeLoader->directoryExists(dir)) { + if (!typeLoader->directoryExists(dir)) { if (precedence < QQmlImportInstance::Implicit) { QQmlError error; error.setDescription(QQmlImportDatabase::tr("\"%1\": no such directory").arg(uri)); @@ -1389,12 +1290,12 @@ QTypeRevision QQmlImports::addFileImport( // Transforms the (possible relative) uri into our best guess relative to the // import paths. - importUri = resolvedUri(dir, database); + importUri = resolvedUri(dir, typeLoader->importDatabase()); if (importUri.endsWith(Slash)) importUri.chop(1); - if (!m_typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) { - qmldirIdentifier = localFileOrQrc; + if (!typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) { + qmldirIdentifier = std::move(localFileOrQrc); if (localQmldir) *localQmldir = qmldirIdentifier; } @@ -1414,6 +1315,15 @@ QTypeRevision QQmlImports::addFileImport( // The url for the path containing files for this import QString url = resolveLocalUrl(m_base, uri); + if (url.isEmpty()) { + QQmlError error; + error.setDescription( + QQmlImportDatabase::tr("Cannot resolve URL for import \"%1\"").arg(uri)); + error.setUrl(m_baseUrl); + errors->prepend(error); + return QTypeRevision(); + } + if (!url.endsWith(Slash) && !url.endsWith(Backslash)) url += Slash; @@ -1433,7 +1343,7 @@ QTypeRevision QQmlImports::addFileImport( if (!(flags & QQmlImports::ImportIncomplete) && !qmldirIdentifier.isEmpty()) { QQmlTypeLoaderQmldirContent qmldir; - if (!getQmldirContent(qmldirIdentifier, importUri, &qmldir, errors)) + if (!getQmldirContent(typeLoader, qmldirIdentifier, importUri, &qmldir, errors)) return QTypeRevision(); if (qmldir.hasContent()) { @@ -1447,10 +1357,13 @@ QTypeRevision QQmlImports::addFileImport( errors, precedence); Q_ASSERT(inserted); - version = importExtension(importUri, version, database, &qmldir, errors); + version = importExtension(typeLoader, importUri, version, &qmldir, errors); if (!version.isValid()) return QTypeRevision(); + if (qmldir.hasRedirection()) + url = redirectQmldirContent(typeLoader, &qmldir); + if (!inserted->setQmldirContent(url, qmldir, nameSpace, errors)) return QTypeRevision(); @@ -1466,10 +1379,10 @@ QTypeRevision QQmlImports::addFileImport( } QTypeRevision QQmlImports::updateQmldirContent( - QQmlImportDatabase *database, const QString &uri, const QString &prefix, + QQmlTypeLoader *typeLoader, const QString &uri, const QString &prefix, const QString &qmldirIdentifier, const QString &qmldirUrl, QList<QQmlError> *errors) { - Q_ASSERT(database); + Q_ASSERT(typeLoader); Q_ASSERT(errors); qDebug(lcQmlImport) @@ -1481,16 +1394,20 @@ QTypeRevision QQmlImports::updateQmldirContent( if (QQmlImportInstance *import = nameSpace->findImport(uri)) { QQmlTypeLoaderQmldirContent qmldir; - if (!getQmldirContent(qmldirIdentifier, uri, &qmldir, errors)) + if (!getQmldirContent(typeLoader, qmldirIdentifier, uri, &qmldir, errors)) return QTypeRevision(); if (qmldir.hasContent()) { QTypeRevision version = importExtension( - uri, import->version, database, &qmldir, errors); + typeLoader, uri, import->version, &qmldir, errors); if (!version.isValid()) return QTypeRevision(); - if (import->setQmldirContent(qmldirUrl, qmldir, nameSpace, errors)) { + const QString resolvedUrl = qmldir.hasRedirection() + ? redirectQmldirContent(typeLoader, &qmldir) + : qmldirUrl; + + if (import->setQmldirContent(resolvedUrl, qmldir, nameSpace, errors)) { if (import->qmlDirComponents.isEmpty() && import->qmlDirScripts.isEmpty()) { // The implicit import qmldir can be empty, and plugins have no extra versions if (uri != QLatin1String(".") && !QQmlMetaType::matchingModuleVersion(uri, version).isValid()) { @@ -1518,7 +1435,7 @@ QTypeRevision QQmlImports::updateQmldirContent( } /*! - \fn QQmlImports::addImplicitImport(QQmlImportDatabase *importDb, QString *localQmldir, QList<QQmlError> *errors) + \fn QQmlImports::addImplicitImport(QQmlTypeLoader *typeLoader, QString *localQmldir, QList<QQmlError> *errors) \internal Adds an implicit "." file import. This is equivalent to calling addFileImport(), but error @@ -1531,13 +1448,12 @@ QTypeRevision QQmlImports::updateQmldirContent( /*! \internal */ -bool QQmlImports::addInlineComponentImport(QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl, QQmlType containingType) +bool QQmlImports::addInlineComponentImport(QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl) { importInstance->url = importUrl.toString(); importInstance->uri = name; importInstance->isInlineComponent = true; importInstance->version = QTypeRevision::zero(); - importInstance->containingType = containingType; m_unqualifiedset.imports.push_back(importInstance); m_unqualifiedset.setNeedsSorting(true); return true; |