forked from qt-creator/qt-creator
CppEditor: Do not use clangd < 13
We will shortly need to use a command-line option that is new in clangd 13. Rather than starting to add checks for versions that won't work as expected anyway, we simply refuse to use clangd < 13 now. Change-Id: I42ec679e0f58449a2593cf92b4be7ed3101fa787 Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
@@ -312,6 +313,11 @@ ClangdSettings &ClangdSettings::instance()
|
|||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClangdSettings::useClangd() const
|
||||||
|
{
|
||||||
|
return m_data.useClangd && clangdVersion(clangdFilePath()) >= QVersionNumber(13);
|
||||||
|
}
|
||||||
|
|
||||||
void ClangdSettings::setDefaultClangdPath(const FilePath &filePath)
|
void ClangdSettings::setDefaultClangdPath(const FilePath &filePath)
|
||||||
{
|
{
|
||||||
g_defaultClangdFilePath = 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()
|
void ClangdSettings::loadSettings()
|
||||||
{
|
{
|
||||||
m_data.fromMap(Core::ICore::settings()->value(clangdSettingsKey()).toMap());
|
m_data.fromMap(Core::ICore::settings()->value(clangdSettingsKey()).toMap());
|
||||||
|
|||||||
@@ -29,8 +29,12 @@
|
|||||||
|
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QHash>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QPair>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QVersionNumber>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QSettings;
|
class QSettings;
|
||||||
@@ -117,7 +121,7 @@ public:
|
|||||||
ClangdSettings(const Data &data) : m_data(data) {}
|
ClangdSettings(const Data &data) : m_data(data) {}
|
||||||
|
|
||||||
static ClangdSettings &instance();
|
static ClangdSettings &instance();
|
||||||
bool useClangd() const { return m_data.useClangd; }
|
bool useClangd() const;
|
||||||
|
|
||||||
static void setDefaultClangdPath(const Utils::FilePath &filePath);
|
static void setDefaultClangdPath(const Utils::FilePath &filePath);
|
||||||
Utils::FilePath clangdFilePath() const;
|
Utils::FilePath clangdFilePath() const;
|
||||||
@@ -129,6 +133,8 @@ public:
|
|||||||
void setData(const Data &data);
|
void setData(const Data &data);
|
||||||
Data data() const { return m_data; }
|
Data data() const { return m_data; }
|
||||||
|
|
||||||
|
static QVersionNumber clangdVersion(const Utils::FilePath &clangdFilePath);
|
||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
static void setUseClangd(bool use);
|
static void setUseClangd(bool use);
|
||||||
static void setClangdFilePath(const Utils::FilePath &filePath);
|
static void setClangdFilePath(const Utils::FilePath &filePath);
|
||||||
@@ -144,6 +150,7 @@ private:
|
|||||||
void saveSettings();
|
void saveSettings();
|
||||||
|
|
||||||
Data m_data;
|
Data m_data;
|
||||||
|
static inline QHash<Utils::FilePath, QPair<QDateTime, QVersionNumber>> m_versionCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)
|
inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/infolabel.h>
|
#include <utils/infolabel.h>
|
||||||
#include <utils/pathchooser.h>
|
#include <utils/pathchooser.h>
|
||||||
#include <utils/qtcprocess.h>
|
|
||||||
|
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
@@ -285,30 +284,14 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
|
|||||||
if (!d->clangdChooser.isValid())
|
if (!d->clangdChooser.isValid())
|
||||||
return;
|
return;
|
||||||
const Utils::FilePath clangdPath = d->clangdChooser.filePath();
|
const Utils::FilePath clangdPath = d->clangdChooser.filePath();
|
||||||
Utils::QtcProcess clangdProc;
|
const QVersionNumber clangdVersion = ClangdSettings::clangdVersion(clangdPath);
|
||||||
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()));
|
|
||||||
}
|
|
||||||
if (clangdVersion.isNull()) {
|
if (clangdVersion.isNull()) {
|
||||||
labelSetter.setWarning(tr("Failed to retrieve clangd version: "
|
labelSetter.setWarning(tr("Failed to retrieve clangd version: "
|
||||||
"Unexpected clangd output."));
|
"Unexpected clangd output."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (clangdVersion < QVersionNumber(13)) {
|
if (clangdVersion < QVersionNumber(13)) {
|
||||||
labelSetter.setWarning(tr("The clangd version is %1, but %2 or greater is "
|
labelSetter.setWarning(tr("The clangd version is %1, but %2 or greater is required.")
|
||||||
"recommended for full functionality.")
|
|
||||||
.arg(clangdVersion.toString()).arg(13));
|
.arg(clangdVersion.toString()).arg(13));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user