diff options
Diffstat (limited to 'src/qml/qml/qqmlimport.cpp')
-rw-r--r-- | src/qml/qml/qqmlimport.cpp | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index c8d17c4b8e..8b0bd9d6ec 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -296,7 +296,9 @@ public: bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor, QQmlType *type_return, QList<QQmlError> *errors, - QQmlType::RegistrationType registrationType); + QQmlType::RegistrationType registrationType, + QQmlImport::RecursionRestriction recursionRestriction + = QQmlImport::PreventRecursion); QUrl baseUrl; QString base; @@ -634,7 +636,8 @@ QString QQmlImports::versionString(int vmaj, int vmin, ImportVersion version) bool QQmlImports::resolveType(const QHashedStringRef &type, QQmlType *type_return, int *vmaj, int *vmin, QQmlImportNamespace** ns_return, QList<QQmlError> *errors, - QQmlType::RegistrationType registrationType) const + QQmlType::RegistrationType registrationType, + QQmlImport::RecursionRestriction recursionRestriction) const { QQmlImportNamespace* ns = d->findQualifiedNamespace(type); if (ns) { @@ -643,7 +646,8 @@ bool QQmlImports::resolveType(const QHashedStringRef &type, return true; } if (type_return) { - if (d->resolveType(type, vmaj, vmin, type_return, errors, registrationType)) { + if (d->resolveType(type, vmaj, vmin, type_return, errors, registrationType, + recursionRestriction)) { if (qmlImportTrace()) { #define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \ << ')' << "::resolveType: " << type.toString() << " => " @@ -728,9 +732,10 @@ bool QQmlImports::resolveType(QQmlImportNamespace *ns, const QHashedStringRef &t } bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type, - int *vmajor, int *vminor, QQmlType* type_return, QString *base, + int *vmajor, int *vminor, QQmlType *type_return, QString *base, bool *typeRecursionDetected, - QQmlType::RegistrationType registrationType) const + QQmlType::RegistrationType registrationType, + QQmlImport::RecursionRestriction recursionRestriction) const { if (majversion >= 0 && minversion >= 0) { QQmlType t = QQmlMetaType::qmlType(type, uri, majversion, minversion); @@ -766,6 +771,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt // importing version -1 means import ALL versions if ((majversion == -1) || + (implicitlyImported && c.internal) || // allow the implicit import of internal types (c.majorVersion == majversion && c.minorVersion <= minversion)) { // Is this better than the previous candidate? if ((candidate == end) || @@ -777,7 +783,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt if (resolveLocalUrl(*base, c.fileName) != componentUrl) continue; // failed attempt to access an internal type } - if (*base == componentUrl) { + if (recursionRestriction == QQmlImport::PreventRecursion && *base == componentUrl) { if (typeRecursionDetected) *typeRecursionDetected = true; continue; // no recursion @@ -820,7 +826,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt } if (exists) { - if (base && (*base == qmlUrl)) { // no recursion + if (recursionRestriction == QQmlImport::PreventRecursion && base && (*base == qmlUrl)) { // no recursion if (typeRecursionDetected) *typeRecursionDetected = true; } else { @@ -838,7 +844,8 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor, QQmlType *type_return, QList<QQmlError> *errors, - QQmlType::RegistrationType registrationType) + QQmlType::RegistrationType registrationType, + QQmlImport::RecursionRestriction recursionRestriction) { QQmlImportNamespace *s = 0; int dot = type.indexOf(Dot); @@ -868,7 +875,7 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, QHashedStringRef unqualifiedtype = dot < 0 ? type : QHashedStringRef(type.constData()+dot+1, type.length()-dot-1); if (s) { if (s->resolveType(typeLoader, unqualifiedtype, vmajor, vminor, type_return, &base, errors, - registrationType)) + registrationType, recursionRestriction)) return true; if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && type_return && s != &unqualifiedset) { // qualified, and only 1 url @@ -892,13 +899,14 @@ QQmlImportInstance *QQmlImportNamespace::findImport(const QString &uri) const bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, int *vmajor, int *vminor, QQmlType *type_return, QString *base, QList<QQmlError> *errors, - QQmlType::RegistrationType registrationType) + QQmlType::RegistrationType registrationType, + QQmlImport::RecursionRestriction recursionRestriction) { bool typeRecursionDetected = false; for (int i=0; i<imports.count(); ++i) { const QQmlImportInstance *import = imports.at(i); - if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, - base, &typeRecursionDetected, registrationType)) { + if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, base, + &typeRecursionDetected, registrationType, recursionRestriction)) { if (qmlCheckTypes()) { // check for type clashes for (int j = i+1; j<imports.count(); ++j) { @@ -1223,10 +1231,12 @@ QString QQmlImportsPrivate::resolvedUri(const QString &dir_arg, QQmlImportDataba stableRelativePath.replace(Backslash, Slash); // remove optional versioning in dot notation from uri - int lastSlash = stableRelativePath.lastIndexOf(Slash); - if (lastSlash >= 0) { - int versionDot = stableRelativePath.indexOf(Dot, lastSlash); - if (versionDot >= 0) + int versionDot = stableRelativePath.lastIndexOf(Dot); + if (versionDot >= 0) { + int nextSlash = stableRelativePath.indexOf(Slash, versionDot); + if (nextSlash >= 0) + stableRelativePath.remove(versionDot, nextSlash - versionDot); + else stableRelativePath = stableRelativePath.left(versionDot); } @@ -1537,6 +1547,20 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix if (!url.endsWith(Slash) && !url.endsWith(Backslash)) url += Slash; + // ### For enum support, we are now adding the implicit import always (and earlier). Bail early + // if the implicit import has already been explicitly added, otherwise we can run into issues + // with duplicate imports. However remember that we attempted to add this as implicit import, to + // allow for the loading of internal types. + if (isImplicitImport) { + for (QList<QQmlImportInstance *>::const_iterator it = nameSpace->imports.constBegin(); + it != nameSpace->imports.constEnd(); ++it) { + if ((*it)->url == url) { + (*it)->implicitlyImported = true; + return true; + } + } + } + QQmlImportInstance *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QV4::CompiledData::Import::ImportFile, errors, isImplicitImport); Q_ASSERT(inserted); @@ -1738,13 +1762,13 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e) // env import paths if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QML2_IMPORT_PATH"))) { - const QByteArray envImportPath = qgetenv("QML2_IMPORT_PATH"); + const QString envImportPath = qEnvironmentVariable("QML2_IMPORT_PATH"); #if defined(Q_OS_WIN) QLatin1Char pathSep(';'); #else QLatin1Char pathSep(':'); #endif - QStringList paths = QString::fromLatin1(envImportPath).split(pathSep, QString::SkipEmptyParts); + QStringList paths = envImportPath.split(pathSep, QString::SkipEmptyParts); for (int ii = paths.count() - 1; ii >= 0; --ii) addImportPath(paths.at(ii)); } |