forked from qt-creator/qt-creator
QmlJS: Fix handling multiple import paths into same module
It is possible to import components of different paths to fill a module. Take further paths into account when looking up types. Fixes: QTCREATORBUG-24405 Change-Id: I8d6bf0a324ea9c0d1fe9d91b40857f91f00dd662 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Fawzi Mohamed <fawzi.mohamed@qt.io>
This commit is contained in:
@@ -410,8 +410,13 @@ Import LinkPrivate::importNonFile(const Document::Ptr &doc, const ImportInfo &im
|
||||
const QString packageName = importInfo.name();
|
||||
const ComponentVersion version = importInfo.version();
|
||||
|
||||
QString libraryPath = modulePath(packageName, version.toString(), m_importPaths);
|
||||
bool importFound = !libraryPath.isEmpty() && importLibrary(doc, libraryPath, &import, import.object);
|
||||
QStringList libraryPaths = modulePaths(packageName, version.toString(), m_importPaths);
|
||||
bool importFound = false;
|
||||
for (const QString &libPath : libraryPaths) {
|
||||
importFound = !libPath.isEmpty() && importLibrary(doc, libPath, &import, import.object);
|
||||
if (importFound)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!importFound) {
|
||||
for (const QString &dir : qAsConst(m_applicationDirectories)) {
|
||||
@@ -501,7 +506,10 @@ bool LinkPrivate::importLibrary(const Document::Ptr &doc,
|
||||
Import subImport;
|
||||
subImport.valid = true;
|
||||
subImport.info = ImportInfo::moduleImport(importName, vNow, importInfo.as(), importInfo.ast());
|
||||
subImport.libraryPath = modulePath(importName, vNow.toString(), m_importPaths);
|
||||
|
||||
const QStringList libraryPaths = modulePaths(importName, vNow.toString(), m_importPaths);
|
||||
subImport.libraryPath = libraryPaths.value(0); // first is the best match
|
||||
|
||||
bool subImportFound = importLibrary(doc, subImport.libraryPath, &subImport, targetObject, importPath, true);
|
||||
|
||||
if (!subImportFound && errorLoc.isValid()) {
|
||||
|
||||
@@ -869,7 +869,9 @@ static QString modulePath(const ImportInfo &import, const QStringList &paths)
|
||||
{
|
||||
if (!import.version().isValid())
|
||||
return QString();
|
||||
return modulePath(import.name(), import.version().toString(), paths);
|
||||
|
||||
const QStringList modPaths = modulePaths(import.name(), import.version().toString(), paths);
|
||||
return modPaths.value(0); // first is best match
|
||||
}
|
||||
|
||||
static void findNewLibraryImports(const Document::Ptr &doc, const Snapshot &snapshot,
|
||||
|
||||
@@ -421,16 +421,17 @@ QString PluginDumper::buildQmltypesPath(const QString &name) const
|
||||
version = m.captured("major") + QLatin1Char('.') + m.captured("minor");
|
||||
}
|
||||
|
||||
const QString path = modulePath(qualifiedName, version, m_modelManager->importPathsNames());
|
||||
const QStringList paths = modulePaths(qualifiedName, version, m_modelManager->importPathsNames());
|
||||
|
||||
if (path.isEmpty())
|
||||
if (paths.isEmpty())
|
||||
return QString();
|
||||
|
||||
QDirIterator it(path, QStringList { "*.qmltypes" }, QDir::Files);
|
||||
|
||||
if (it.hasNext())
|
||||
return it.next();
|
||||
for (const QString &path : paths) {
|
||||
QDirIterator it(path, QStringList { "*.qmltypes" }, QDir::Files);
|
||||
|
||||
if (it.hasNext())
|
||||
return it.next();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
@@ -233,12 +233,12 @@ bool QmlJS::maybeModuleVersion(const QString &version) {
|
||||
* \return The module paths if found, an empty string otherwise
|
||||
* \see qmlimportscanner in qtdeclarative/tools
|
||||
*/
|
||||
QString QmlJS::modulePath(const QString &name, const QString &version,
|
||||
const QStringList &importPaths)
|
||||
QStringList QmlJS::modulePaths(const QString &name, const QString &version,
|
||||
const QStringList &importPaths)
|
||||
{
|
||||
Q_ASSERT(maybeModuleVersion(version));
|
||||
if (importPaths.isEmpty())
|
||||
return QString();
|
||||
return {};
|
||||
|
||||
const QString sanitizedVersion = version == undefinedVersion ? QString() : version;
|
||||
const QStringList parts = name.split('.', Qt::SkipEmptyParts);
|
||||
@@ -249,6 +249,7 @@ QString QmlJS::modulePath(const QString &name, const QString &version,
|
||||
// sanitized version.
|
||||
const QRegularExpression re("\\.?\\d+$");
|
||||
|
||||
QStringList result;
|
||||
QString candidate;
|
||||
|
||||
for (QString ver = sanitizedVersion; !ver.isEmpty(); ver.remove(re)) {
|
||||
@@ -260,7 +261,7 @@ QString QmlJS::modulePath(const QString &name, const QString &version,
|
||||
ver,
|
||||
mkpath(parts.mid(i + 1))));
|
||||
if (QDir(candidate).exists())
|
||||
return candidate;
|
||||
result << candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,10 +270,10 @@ QString QmlJS::modulePath(const QString &name, const QString &version,
|
||||
for (const QString &path: importPaths) {
|
||||
candidate = QDir::cleanPath(QString::fromLatin1("%1/%2").arg(path, mkpath(parts)));
|
||||
if (QDir(candidate).exists())
|
||||
return candidate;
|
||||
result << candidate;
|
||||
}
|
||||
|
||||
return QString();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QmlJS::isValidBuiltinPropertyType(const QString &name)
|
||||
|
||||
@@ -57,8 +57,8 @@ QMLJS_EXPORT DiagnosticMessage errorMessage(const SourceLocation &loc,
|
||||
|
||||
QMLJS_EXPORT bool maybeModuleVersion(const QString &version);
|
||||
|
||||
QMLJS_EXPORT QString modulePath(const QString &moduleImportName, const QString &version,
|
||||
const QStringList &importPaths);
|
||||
QMLJS_EXPORT QStringList modulePaths(const QString &moduleImportName, const QString &version,
|
||||
const QStringList &importPaths);
|
||||
|
||||
template <class T>
|
||||
SourceLocation locationFromRange(const T *node)
|
||||
|
||||
Reference in New Issue
Block a user