diff --git a/src/plugins/cppeditor/cppcodemodelsettings.cpp b/src/plugins/cppeditor/cppcodemodelsettings.cpp index f6c4629d0c7..cf57ee39730 100644 --- a/src/plugins/cppeditor/cppcodemodelsettings.cpp +++ b/src/plugins/cppeditor/cppcodemodelsettings.cpp @@ -34,6 +34,7 @@ #include #include +#include #include @@ -312,6 +313,11 @@ ClangdSettings &ClangdSettings::instance() return settings; } +bool ClangdSettings::useClangd() const +{ + return m_data.useClangd && clangdVersion(clangdFilePath()) >= QVersionNumber(13); +} + void ClangdSettings::setDefaultClangdPath(const FilePath &filePath) { g_defaultClangdFilePath = filePath; @@ -333,6 +339,37 @@ void ClangdSettings::setData(const Data &data) } } +static QVersionNumber getClangdVersion(const FilePath &clangdFilePath) +{ + Utils::QtcProcess clangdProc; + clangdProc.setCommand({clangdFilePath, {"--version"}}); + clangdProc.start(); + if (!clangdProc.waitForStarted() || !clangdProc.waitForFinished()) + return{}; + const QString output = clangdProc.allOutput(); + static const QString versionPrefix = "clangd version "; + const int prefixOffset = output.indexOf(versionPrefix); + if (prefixOffset == -1) + return {}; + return QVersionNumber::fromString(output.mid(prefixOffset + versionPrefix.length())); +} + +QVersionNumber ClangdSettings::clangdVersion(const FilePath &clangdFilePath) +{ + const QDateTime timeStamp = clangdFilePath.lastModified(); + const auto it = m_versionCache.find(clangdFilePath); + if (it == m_versionCache.end()) { + const QVersionNumber version = getClangdVersion(clangdFilePath); + m_versionCache.insert(clangdFilePath, qMakePair(timeStamp, version)); + return version; + } + if (it->first != timeStamp) { + it->first = timeStamp; + it->second = getClangdVersion(clangdFilePath); + } + return it->second; +} + void ClangdSettings::loadSettings() { m_data.fromMap(Core::ICore::settings()->value(clangdSettingsKey()).toMap()); diff --git a/src/plugins/cppeditor/cppcodemodelsettings.h b/src/plugins/cppeditor/cppcodemodelsettings.h index 5f4f4622c7a..2f3de7dd6bc 100644 --- a/src/plugins/cppeditor/cppcodemodelsettings.h +++ b/src/plugins/cppeditor/cppcodemodelsettings.h @@ -29,8 +29,12 @@ #include +#include +#include #include +#include #include +#include QT_BEGIN_NAMESPACE class QSettings; @@ -117,7 +121,7 @@ public: ClangdSettings(const Data &data) : m_data(data) {} static ClangdSettings &instance(); - bool useClangd() const { return m_data.useClangd; } + bool useClangd() const; static void setDefaultClangdPath(const Utils::FilePath &filePath); Utils::FilePath clangdFilePath() const; @@ -129,6 +133,8 @@ public: void setData(const Data &data); Data data() const { return m_data; } + static QVersionNumber clangdVersion(const Utils::FilePath &clangdFilePath); + #ifdef WITH_TESTS static void setUseClangd(bool use); static void setClangdFilePath(const Utils::FilePath &filePath); @@ -144,6 +150,7 @@ private: void saveSettings(); Data m_data; + static inline QHash> m_versionCache; }; inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2) diff --git a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp index 7a850df329f..3e899ae01f6 100644 --- a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp +++ b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -285,30 +284,14 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD if (!d->clangdChooser.isValid()) return; const Utils::FilePath clangdPath = d->clangdChooser.filePath(); - Utils::QtcProcess clangdProc; - clangdProc.setCommand({clangdPath, {"--version"}}); - clangdProc.start(); - if (!clangdProc.waitForStarted() || !clangdProc.waitForFinished()) { - labelSetter.setWarning(tr("Failed to retrieve clangd version: %1") - .arg(clangdProc.exitMessage())); - return; - } - const QString output = clangdProc.allOutput(); - static const QString versionPrefix = "clangd version "; - const int prefixOffset = output.indexOf(versionPrefix); - QVersionNumber clangdVersion; - if (prefixOffset != -1) { - clangdVersion = QVersionNumber::fromString(output.mid(prefixOffset - + versionPrefix.length())); - } + const QVersionNumber clangdVersion = ClangdSettings::clangdVersion(clangdPath); if (clangdVersion.isNull()) { labelSetter.setWarning(tr("Failed to retrieve clangd version: " "Unexpected clangd output.")); return; } if (clangdVersion < QVersionNumber(13)) { - labelSetter.setWarning(tr("The clangd version is %1, but %2 or greater is " - "recommended for full functionality.") + labelSetter.setWarning(tr("The clangd version is %1, but %2 or greater is required.") .arg(clangdVersion.toString()).arg(13)); return; }