diff options
author | Eike Ziller <[email protected]> | 2021-06-23 10:27:08 +0200 |
---|---|---|
committer | Eike Ziller <[email protected]> | 2021-09-07 08:16:48 +0000 |
commit | 95de5c93b1ca2944558b7c3b4666e7cb093d93b6 (patch) | |
tree | 9be022fc11cb386e613432ad0fb07d454ed4d458 /src/libs/qmljs/qmljsutils.cpp | |
parent | 481070d8080fd51f79867860a27bb0cae6600c3f (diff) |
QmlJS: Fix issues with getting modulePaths
This patch
- improves performance by removing the usage of QRegularExpression for
trivial string operations (this is called 3000 times after configuring
Qt Creator)
- fixes handling of version number like "2.-1" which are the result of
imports with only a major version number like "import QtQuick 2"
Task-number: QTCREATORBUG-25899
Fixes: QTCREATORBUG-26178
Fixes: QTCREATORBUG-26216
Change-Id: Ic792909513f4fe25ac72043645f297ee41890375
Reviewed-by: Fawzi Mohamed <[email protected]>
Reviewed-by: Jarek Kobus <[email protected]>
Diffstat (limited to 'src/libs/qmljs/qmljsutils.cpp')
-rw-r--r-- | src/libs/qmljs/qmljsutils.cpp | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/src/libs/qmljs/qmljsutils.cpp b/src/libs/qmljs/qmljsutils.cpp index d1dd0d8b1c6..db2bcc69689 100644 --- a/src/libs/qmljs/qmljsutils.cpp +++ b/src/libs/qmljs/qmljsutils.cpp @@ -213,6 +213,29 @@ bool QmlJS::maybeModuleVersion(const QString &version) { return version.isEmpty() || version == undefinedVersion || re.match(version).hasMatch(); } +const QStringList QmlJS::splitVersion(const QString &version) +{ + // Successively removing minor and major version numbers. + QStringList result; + int versionEnd = version.length(); + while (versionEnd > 0) { + result.append(version.left(versionEnd)); + // remove numbers and then potential . at the end + const int oldVersionEnd = versionEnd; + while (versionEnd > 0 && version.at(versionEnd - 1).isDigit()) + --versionEnd; + // handle e.g. -1, because an import "QtQuick 2" results in version "2.-1" + if (versionEnd > 0 && version.at(versionEnd - 1) == '-') + --versionEnd; + if (versionEnd > 0 && version.at(versionEnd - 1) == '.') + --versionEnd; + // bail out if we didn't proceed because version string contains invalid characters + if (versionEnd == oldVersionEnd) + break; + } + return result; +} + /*! * \brief Get the path of a module * \param name @@ -242,24 +265,19 @@ QStringList QmlJS::modulePaths(const QString &name, const QString &version, const QString sanitizedVersion = version == undefinedVersion ? QString() : version; const QStringList parts = name.split('.', Qt::SkipEmptyParts); - auto mkpath = [] (const QStringList &xs) -> QString { return xs.join(QLatin1Char('/')); }; - - // Regular expression for building candidates by successively removing minor and major - // version numbers. It does not match the undefined version, so it has to be applied to the - // sanitized version. - const QRegularExpression re("\\.?\\d+$"); + auto mkpath = [](const QStringList &xs) -> QString { return xs.join(QLatin1Char('/')); }; QStringList result; QString candidate; - for (QString ver = sanitizedVersion; !ver.isEmpty(); ver.remove(re)) { - for (const QString &path: importPaths) { + for (const QString &versionPart : splitVersion(sanitizedVersion)) { + for (const QString &path : importPaths) { for (int i = parts.count() - 1; i >= 0; --i) { - candidate = QDir::cleanPath( - QString::fromLatin1("%1/%2.%3/%4").arg(path, - mkpath(parts.mid(0, i + 1)), - ver, - mkpath(parts.mid(i + 1)))); + candidate = QDir::cleanPath(QString::fromLatin1("%1/%2.%3/%4") + .arg(path, + mkpath(parts.mid(0, i + 1)), + versionPart, + mkpath(parts.mid(i + 1)))); if (QDir(candidate).exists()) result << candidate; } |