ClangTools: Prefer .clang-tidy file by default

... and move this setting outside the diagnostic config.

Fixes: QTCREATORBUG-28852
Change-Id: Ie3b19ba7bec2bc96451f3216fa06a6941cad4c94
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2023-04-11 12:49:21 +02:00
parent de0e0fab18
commit 4028777743
16 changed files with 83 additions and 79 deletions

View File

@@ -98,15 +98,12 @@ ClangDiagnosticConfig diagnosticConfig()
return warningsConfigForProject(project); return warningsConfigForProject(project);
} }
bool isDiagnosticConfigChangable(Project *project, const ClangDiagnostic &diagnostic) static bool isDiagnosticConfigChangable(Project *project)
{ {
if (!project) if (!project)
return false; return false;
const ClangDiagnosticConfig config = diagnosticConfig(); if (diagnosticConfig().useBuildSystemWarnings())
if (config.clangTidyMode() == ClangDiagnosticConfig::TidyMode::UseConfigFile
&& diagnosticType(diagnostic) == DiagnosticType::Tidy) {
return false; return false;
}
return true; return true;
} }
@@ -308,7 +305,7 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath,
// Remove diagnostic warning action // Remove diagnostic warning action
Project *project = projectForCurrentEditor(); Project *project = projectForCurrentEditor();
if (project && isDiagnosticConfigChangable(project, diag)) { if (project && isDiagnosticConfigChangable(project)) {
action = new QAction(); action = new QAction();
action->setIcon(Icons::BROKEN.icon()); action->setIcon(Icons::BROKEN.icon());
action->setToolTip(Tr::tr("Disable Diagnostic in Current Project")); action->setToolTip(Tr::tr("Disable Diagnostic in Current Project"));

View File

@@ -858,13 +858,13 @@ static CheckResult canAnalyze()
{ {
const ClangDiagnosticConfig config = diagnosticConfig(runSettings().diagnosticConfigId()); const ClangDiagnosticConfig config = diagnosticConfig(runSettings().diagnosticConfigId());
if (config.isEnabled(ClangToolType::Tidy) if (toolEnabled(ClangToolType::Tidy, config, runSettings())
&& !toolExecutable(ClangToolType::Tidy).isExecutableFile()) { && !toolExecutable(ClangToolType::Tidy).isExecutableFile()) {
return {CheckResult::InvalidTidyExecutable, return {CheckResult::InvalidTidyExecutable,
Tr::tr("Set a valid Clang-Tidy executable.")}; Tr::tr("Set a valid Clang-Tidy executable.")};
} }
if (config.isEnabled(ClangToolType::Clazy) if (toolEnabled(ClangToolType::Clazy, config, runSettings())
&& !toolExecutable(ClangToolType::Clazy).isExecutableFile()) { && !toolExecutable(ClangToolType::Clazy).isExecutableFile()) {
return {CheckResult::InvalidClazyExecutable, return {CheckResult::InvalidClazyExecutable,
Tr::tr("Set a valid Clazy-Standalone executable.")}; Tr::tr("Set a valid Clazy-Standalone executable.")};

View File

@@ -185,7 +185,11 @@ void ClangToolRunWorker::start()
using namespace Tasking; using namespace Tasking;
QList<TaskItem> tasks{ParallelLimit(qMax(1, m_runSettings.parallelJobs()))}; QList<TaskItem> tasks{ParallelLimit(qMax(1, m_runSettings.parallelJobs()))};
for (const AnalyzeUnit &unit : std::as_const(unitsToProcess)) { for (const AnalyzeUnit &unit : std::as_const(unitsToProcess)) {
const AnalyzeInputData input{tool, m_diagnosticConfig, m_temporaryDir.path(), if (!m_diagnosticConfig.isEnabled(tool)
&& !m_runSettings.hasConfigFileForSourceFile(unit.file)) {
continue;
}
const AnalyzeInputData input{tool, m_runSettings, m_diagnosticConfig, m_temporaryDir.path(),
m_environment, unit}; m_environment, unit};
const auto setupHandler = [this, unit, tool] { const auto setupHandler = [this, unit, tool] {
const QString filePath = unit.file.toUserOutput(); const QString filePath = unit.file.toUserOutput();

View File

@@ -52,21 +52,22 @@ static bool isClMode(const QStringList &options)
return options.contains("--driver-mode=cl"); return options.contains("--driver-mode=cl");
} }
static QStringList checksArguments(ClangToolType tool, static QStringList checksArguments(const AnalyzeInputData &input)
const ClangDiagnosticConfig &diagnosticConfig)
{ {
if (tool == ClangToolType::Tidy) { if (input.tool == ClangToolType::Tidy) {
const ClangDiagnosticConfig::TidyMode tidyMode = diagnosticConfig.clangTidyMode(); if (input.runSettings.hasConfigFileForSourceFile(input.unit.file))
// The argument "-config={}" stops stating/evaluating the .clang-tidy file. return {"--warnings-as-errors=-*", "-checks=-clang-diagnostic-*"};
if (tidyMode == ClangDiagnosticConfig::TidyMode::UseDefaultChecks) switch (input.config.clangTidyMode()) {
case ClangDiagnosticConfig::TidyMode::UseDefaultChecks:
// The argument "-config={}" stops stating/evaluating the .clang-tidy file.
return {"-config={}", "-checks=-clang-diagnostic-*"}; return {"-config={}", "-checks=-clang-diagnostic-*"};
if (tidyMode == ClangDiagnosticConfig::TidyMode::UseCustomChecks) case ClangDiagnosticConfig::TidyMode::UseCustomChecks:
return {"-config=" + diagnosticConfig.clangTidyChecksAsJson()}; return {"-config=" + input.config.clangTidyChecksAsJson()};
return {"--warnings-as-errors=-*", "-checks=-clang-diagnostic-*"}; }
} }
const QString clazyChecks = diagnosticConfig.checks(ClangToolType::Clazy); const QString clazyChecks = input.config.checks(ClangToolType::Clazy);
if (!clazyChecks.isEmpty()) if (!clazyChecks.isEmpty())
return {"-checks=" + diagnosticConfig.checks(ClangToolType::Clazy)}; return {"-checks=" + input.config.checks(ClangToolType::Clazy)};
return {}; return {};
} }
@@ -148,7 +149,7 @@ TaskItem clangToolTask(const AnalyzeInputData &input,
const ClangToolStorage &data = *storage; const ClangToolStorage &data = *storage;
const QStringList args = checksArguments(input.tool, input.config) const QStringList args = checksArguments(input)
+ mainToolArguments(data) + mainToolArguments(data)
+ QStringList{"--"} + QStringList{"--"}
+ clangArguments(input.config, input.unit.arguments); + clangArguments(input.config, input.unit.arguments);

View File

@@ -4,6 +4,7 @@
#pragma once #pragma once
#include "clangfileinfo.h" #include "clangfileinfo.h"
#include "clangtoolssettings.h"
#include <cppeditor/clangdiagnosticconfig.h> #include <cppeditor/clangdiagnosticconfig.h>
@@ -28,6 +29,7 @@ using AnalyzeUnits = QList<AnalyzeUnit>;
struct AnalyzeInputData struct AnalyzeInputData
{ {
CppEditor::ClangToolType tool = CppEditor::ClangToolType::Tidy; CppEditor::ClangToolType tool = CppEditor::ClangToolType::Tidy;
RunSettings runSettings;
CppEditor::ClangDiagnosticConfig config; CppEditor::ClangDiagnosticConfig config;
Utils::FilePath outputDirPath; Utils::FilePath outputDirPath;
Utils::Environment environment; Utils::Environment environment;

View File

@@ -313,9 +313,8 @@ bool DiagnosticView::disableChecksEnabled() const
if (!activeConfig.id().isValid()) if (!activeConfig.id().isValid())
return false; return false;
// If all selected diagnostics come from clang-tidy and the active config is controlled // If all selected diagnostics come from clang-tidy and we prefer a .clang-tidy file, then we do not offer the action.
// by a .clang-tidy file, then we do not offer the action. if (!settings->runSettings().preferConfigFile())
if (activeConfig.clangTidyMode() != ClangDiagnosticConfig::TidyMode::UseConfigFile)
return true; return true;
return Utils::anyOf(indexes, [this](const QModelIndex &index) { return Utils::anyOf(indexes, [this](const QModelIndex &index) {
return model()->data(index).toString().startsWith("clazy-"); return model()->data(index).toString().startsWith("clazy-");

View File

@@ -27,6 +27,7 @@ const char clangTidyExecutableKey[] = "ClangTidyExecutable";
const char clazyStandaloneExecutableKey[] = "ClazyStandaloneExecutable"; const char clazyStandaloneExecutableKey[] = "ClazyStandaloneExecutable";
const char parallelJobsKey[] = "ParallelJobs"; const char parallelJobsKey[] = "ParallelJobs";
const char preferConfigFileKey[] = "PreferConfigFile";
const char buildBeforeAnalysisKey[] = "BuildBeforeAnalysis"; const char buildBeforeAnalysisKey[] = "BuildBeforeAnalysis";
const char analyzeOpenFilesKey[] = "AnalyzeOpenFiles"; const char analyzeOpenFilesKey[] = "AnalyzeOpenFiles";
const char oldDiagnosticConfigIdKey[] = "diagnosticConfigId"; const char oldDiagnosticConfigIdKey[] = "diagnosticConfigId";
@@ -46,6 +47,7 @@ void RunSettings::fromMap(const QVariantMap &map, const QString &prefix)
{ {
m_diagnosticConfigId = Id::fromSetting(map.value(prefix + diagnosticConfigIdKey)); m_diagnosticConfigId = Id::fromSetting(map.value(prefix + diagnosticConfigIdKey));
m_parallelJobs = map.value(prefix + parallelJobsKey).toInt(); m_parallelJobs = map.value(prefix + parallelJobsKey).toInt();
m_preferConfigFile = map.value(prefix + preferConfigFileKey).toBool();
m_buildBeforeAnalysis = map.value(prefix + buildBeforeAnalysisKey).toBool(); m_buildBeforeAnalysis = map.value(prefix + buildBeforeAnalysisKey).toBool();
m_analyzeOpenFiles = map.value(prefix + analyzeOpenFilesKey).toBool(); m_analyzeOpenFiles = map.value(prefix + analyzeOpenFilesKey).toBool();
} }
@@ -54,6 +56,7 @@ void RunSettings::toMap(QVariantMap &map, const QString &prefix) const
{ {
map.insert(prefix + diagnosticConfigIdKey, m_diagnosticConfigId.toSetting()); map.insert(prefix + diagnosticConfigIdKey, m_diagnosticConfigId.toSetting());
map.insert(prefix + parallelJobsKey, m_parallelJobs); map.insert(prefix + parallelJobsKey, m_parallelJobs);
map.insert(prefix + preferConfigFileKey, m_preferConfigFile);
map.insert(prefix + buildBeforeAnalysisKey, m_buildBeforeAnalysis); map.insert(prefix + buildBeforeAnalysisKey, m_buildBeforeAnalysis);
map.insert(prefix + analyzeOpenFilesKey, m_analyzeOpenFiles); map.insert(prefix + analyzeOpenFilesKey, m_analyzeOpenFiles);
} }
@@ -69,10 +72,23 @@ bool RunSettings::operator==(const RunSettings &other) const
{ {
return m_diagnosticConfigId == other.m_diagnosticConfigId return m_diagnosticConfigId == other.m_diagnosticConfigId
&& m_parallelJobs == other.m_parallelJobs && m_parallelJobs == other.m_parallelJobs
&& m_preferConfigFile == other.m_preferConfigFile
&& m_buildBeforeAnalysis == other.m_buildBeforeAnalysis && m_buildBeforeAnalysis == other.m_buildBeforeAnalysis
&& m_analyzeOpenFiles == other.m_analyzeOpenFiles; && m_analyzeOpenFiles == other.m_analyzeOpenFiles;
} }
bool RunSettings::hasConfigFileForSourceFile(const Utils::FilePath &sourceFile) const
{
if (!preferConfigFile())
return false;
for (FilePath parentDir = sourceFile.parentDir(); !parentDir.isEmpty();
parentDir = parentDir.parentDir()) {
if (parentDir.resolvePath(QLatin1String(".clang-tidy")).isReadableFile())
return true;
}
return false;
}
ClangToolsSettings::ClangToolsSettings() ClangToolsSettings::ClangToolsSettings()
{ {
readSettings(); readSettings();
@@ -139,6 +155,7 @@ void ClangToolsSettings::readSettings()
QVariantMap defaults; QVariantMap defaults;
defaults.insert(diagnosticConfigIdKey, defaultDiagnosticId().toSetting()); defaults.insert(diagnosticConfigIdKey, defaultDiagnosticId().toSetting());
defaults.insert(parallelJobsKey, m_runSettings.parallelJobs()); defaults.insert(parallelJobsKey, m_runSettings.parallelJobs());
defaults.insert(preferConfigFileKey, m_runSettings.preferConfigFile());
defaults.insert(buildBeforeAnalysisKey, m_runSettings.buildBeforeAnalysis()); defaults.insert(buildBeforeAnalysisKey, m_runSettings.buildBeforeAnalysis());
defaults.insert(analyzeOpenFilesKey, m_runSettings.analyzeOpenFiles()); defaults.insert(analyzeOpenFilesKey, m_runSettings.analyzeOpenFiles());
map = defaults; map = defaults;

View File

@@ -31,6 +31,9 @@ public:
Utils::Id diagnosticConfigId() const; Utils::Id diagnosticConfigId() const;
void setDiagnosticConfigId(const Utils::Id &id) { m_diagnosticConfigId = id; } void setDiagnosticConfigId(const Utils::Id &id) { m_diagnosticConfigId = id; }
bool preferConfigFile() const { return m_preferConfigFile; }
void setPreferConfigFile(bool yesno) { m_preferConfigFile = yesno; }
bool buildBeforeAnalysis() const { return m_buildBeforeAnalysis; } bool buildBeforeAnalysis() const { return m_buildBeforeAnalysis; }
void setBuildBeforeAnalysis(bool yesno) { m_buildBeforeAnalysis = yesno; } void setBuildBeforeAnalysis(bool yesno) { m_buildBeforeAnalysis = yesno; }
@@ -42,9 +45,12 @@ public:
bool operator==(const RunSettings &other) const; bool operator==(const RunSettings &other) const;
bool hasConfigFileForSourceFile(const Utils::FilePath &sourceFile) const;
private: private:
Utils::Id m_diagnosticConfigId; Utils::Id m_diagnosticConfigId;
int m_parallelJobs = -1; int m_parallelJobs = -1;
bool m_preferConfigFile = true;
bool m_buildBeforeAnalysis = true; bool m_buildBeforeAnalysis = true;
bool m_analyzeOpenFiles = true; bool m_analyzeOpenFiles = true;
}; };

View File

@@ -343,5 +343,13 @@ QString clazyDocUrl(const QString &check)
return QString::fromLatin1(urlTemplate).arg(versionString, check); return QString::fromLatin1(urlTemplate).arg(versionString, check);
} }
bool toolEnabled(CppEditor::ClangToolType type, const ClangDiagnosticConfig &config,
const RunSettings &runSettings)
{
if (type == ClangToolType::Tidy && runSettings.preferConfigFile())
return true;
return config.isEnabled(type);
}
} // namespace Internal } // namespace Internal
} // namespace ClangTools } // namespace ClangTools

View File

@@ -17,6 +17,7 @@ namespace Utils { class FilePath; }
namespace ClangTools { namespace ClangTools {
namespace Internal { namespace Internal {
class RunSettings;
QString clangTidyDocUrl(const QString &check); QString clangTidyDocUrl(const QString &check);
QString clazyDocUrl(const QString &check); QString clazyDocUrl(const QString &check);
@@ -47,6 +48,8 @@ Utils::FilePath toolShippedExecutable(CppEditor::ClangToolType tool);
Utils::FilePath toolExecutable(CppEditor::ClangToolType tool); Utils::FilePath toolExecutable(CppEditor::ClangToolType tool);
Utils::FilePath toolFallbackExecutable(CppEditor::ClangToolType tool); Utils::FilePath toolFallbackExecutable(CppEditor::ClangToolType tool);
QString clangToolName(CppEditor::ClangToolType tool); QString clangToolName(CppEditor::ClangToolType tool);
bool toolEnabled(CppEditor::ClangToolType type, const CppEditor::ClangDiagnosticConfig &config,
const RunSettings &runSettings);
bool isVFSOverlaySupported(const Utils::FilePath &executable); bool isVFSOverlaySupported(const Utils::FilePath &executable);

View File

@@ -56,7 +56,6 @@ QString removeClazyCheck(const QString &checks, const QString &check);
class TidyChecksWidget : public QWidget class TidyChecksWidget : public QWidget
{ {
public: public:
QComboBox *tidyMode;
QPushButton *plainTextEditButton; QPushButton *plainTextEditButton;
FancyLineEdit *filterLineEdit; FancyLineEdit *filterLineEdit;
QTreeView *checksPrefixesTree; QTreeView *checksPrefixesTree;
@@ -65,10 +64,6 @@ public:
TidyChecksWidget() TidyChecksWidget()
{ {
tidyMode = new QComboBox;
tidyMode->addItem(Tr::tr("Select Checks"));
tidyMode->addItem(Tr::tr("Use .clang-tidy config file"));
plainTextEditButton = new QPushButton(Tr::tr("Edit Checks as String...")); plainTextEditButton = new QPushButton(Tr::tr("Edit Checks as String..."));
filterLineEdit = new FancyLineEdit; filterLineEdit = new FancyLineEdit;
@@ -104,7 +99,7 @@ public:
}.attachTo(invalidExecutablePage, WithoutMargins); }.attachTo(invalidExecutablePage, WithoutMargins);
Column { Column {
Row { tidyMode, plainTextEditButton, filterLineEdit }, Row { plainTextEditButton, filterLineEdit },
stackedWidget, stackedWidget,
}.attachTo(this); }.attachTo(this);
} }
@@ -1107,32 +1102,18 @@ void DiagnosticConfigsWidget::syncClangTidyWidgets(const ClangDiagnosticConfig &
disconnectClangTidyItemChanged(); disconnectClangTidyItemChanged();
const ClangDiagnosticConfig::TidyMode tidyMode = config.clangTidyMode(); if (m_tidyInfo.supportedChecks.isEmpty()) {
switch (tidyMode) {
case ClangDiagnosticConfig::TidyMode::UseConfigFile:
m_tidyChecks->tidyMode->setCurrentIndex(1);
m_tidyChecks->plainTextEditButton->setVisible(false); m_tidyChecks->plainTextEditButton->setVisible(false);
m_tidyChecks->filterLineEdit->setVisible(false); m_tidyChecks->filterLineEdit->setVisible(false);
m_tidyChecks->stackedWidget->setCurrentIndex(TidyPages::EmptyPage); m_tidyChecks->stackedWidget->setCurrentIndex(TidyPages::InvalidExecutablePage);
break; } else {
case ClangDiagnosticConfig::TidyMode::UseCustomChecks: m_tidyChecks->plainTextEditButton->setVisible(true);
case ClangDiagnosticConfig::TidyMode::UseDefaultChecks: m_tidyChecks->filterLineEdit->setVisible(true);
m_tidyChecks->tidyMode->setCurrentIndex(0); m_tidyChecks->stackedWidget->setCurrentIndex(TidyPages::ChecksPage);
if (m_tidyInfo.supportedChecks.isEmpty()) { syncTidyChecksToTree(config);
m_tidyChecks->plainTextEditButton->setVisible(false);
m_tidyChecks->filterLineEdit->setVisible(false);
m_tidyChecks->stackedWidget->setCurrentIndex(TidyPages::InvalidExecutablePage);
} else {
m_tidyChecks->plainTextEditButton->setVisible(true);
m_tidyChecks->filterLineEdit->setVisible(true);
m_tidyChecks->stackedWidget->setCurrentIndex(TidyPages::ChecksPage);
syncTidyChecksToTree(config);
}
break;
} }
const bool enabled = !config.isReadOnly(); const bool enabled = !config.isReadOnly();
m_tidyChecks->tidyMode->setEnabled(enabled);
m_tidyChecks->plainTextEditButton->setText(enabled ? Tr::tr("Edit Checks as String...") m_tidyChecks->plainTextEditButton->setText(enabled ? Tr::tr("Edit Checks as String...")
: Tr::tr("View Checks as String...")); : Tr::tr("View Checks as String..."));
m_tidyTreeModel->setEnabled(enabled); m_tidyTreeModel->setEnabled(enabled);
@@ -1189,16 +1170,12 @@ void DiagnosticConfigsWidget::syncExtraWidgets(const ClangDiagnosticConfig &conf
void DiagnosticConfigsWidget::connectClangTidyItemChanged() void DiagnosticConfigsWidget::connectClangTidyItemChanged()
{ {
connect(m_tidyChecks->tidyMode, &QComboBox::currentIndexChanged,
this, &DiagnosticConfigsWidget::onClangTidyModeChanged);
connect(m_tidyTreeModel.get(), &TidyChecksTreeModel::dataChanged, connect(m_tidyTreeModel.get(), &TidyChecksTreeModel::dataChanged,
this, &DiagnosticConfigsWidget::onClangTidyTreeChanged); this, &DiagnosticConfigsWidget::onClangTidyTreeChanged);
} }
void DiagnosticConfigsWidget::disconnectClangTidyItemChanged() void DiagnosticConfigsWidget::disconnectClangTidyItemChanged()
{ {
disconnect(m_tidyChecks->tidyMode, &QComboBox::currentIndexChanged,
this, &DiagnosticConfigsWidget::onClangTidyModeChanged);
disconnect(m_tidyTreeModel.get(), &TidyChecksTreeModel::dataChanged, disconnect(m_tidyTreeModel.get(), &TidyChecksTreeModel::dataChanged,
this, &DiagnosticConfigsWidget::onClangTidyTreeChanged); this, &DiagnosticConfigsWidget::onClangTidyTreeChanged);
} }
@@ -1215,18 +1192,6 @@ void DiagnosticConfigsWidget::disconnectClazyItemChanged()
this, &DiagnosticConfigsWidget::onClazyTreeChanged); this, &DiagnosticConfigsWidget::onClazyTreeChanged);
} }
void DiagnosticConfigsWidget::onClangTidyModeChanged(int index)
{
const ClangDiagnosticConfig::TidyMode tidyMode
= index == 0 ? ClangDiagnosticConfig::TidyMode::UseCustomChecks
: ClangDiagnosticConfig::TidyMode::UseConfigFile;
ClangDiagnosticConfig config = currentConfig();
config.setClangTidyMode(tidyMode);
updateConfig(config);
syncClangTidyWidgets(config);
}
void DiagnosticConfigsWidget::onClangTidyTreeChanged() void DiagnosticConfigsWidget::onClangTidyTreeChanged()
{ {
ClangDiagnosticConfig config = currentConfig(); ClangDiagnosticConfig config = currentConfig();
@@ -1330,7 +1295,7 @@ void disableChecks(const QList<Diagnostic> &diagnostics)
} }
config.setChecks(ClangToolType::Clazy, config.setChecks(ClangToolType::Clazy,
removeClazyCheck(config.checks(ClangToolType::Clazy), diag.name)); removeClazyCheck(config.checks(ClangToolType::Clazy), diag.name));
} else if (config.clangTidyMode() != ClangDiagnosticConfig::TidyMode::UseConfigFile) { } else if (!settings->runSettings().preferConfigFile()){
if (config.clangTidyMode() == ClangDiagnosticConfig::TidyMode::UseDefaultChecks) { if (config.clangTidyMode() == ClangDiagnosticConfig::TidyMode::UseDefaultChecks) {
config.setClangTidyMode(ClangDiagnosticConfig::TidyMode::UseCustomChecks); config.setClangTidyMode(ClangDiagnosticConfig::TidyMode::UseCustomChecks);
const ClangTidyInfo tidyInfo(toolExecutable(ClangToolType::Tidy)); const ClangTidyInfo tidyInfo(toolExecutable(ClangToolType::Tidy));

View File

@@ -41,7 +41,6 @@ private:
void syncClazyWidgets(const CppEditor::ClangDiagnosticConfig &config); void syncClazyWidgets(const CppEditor::ClangDiagnosticConfig &config);
void syncClazyChecksGroupBox(); void syncClazyChecksGroupBox();
void onClangTidyModeChanged(int index);
void onClangTidyTreeChanged(); void onClangTidyTreeChanged();
void onClazyTreeChanged(); void onClazyTreeChanged();

View File

@@ -190,15 +190,17 @@ void DocumentClangToolRunner::run()
const Environment env = projectBuildEnvironment(project); const Environment env = projectBuildEnvironment(project);
using namespace Tasking; using namespace Tasking;
QList<TaskItem> tasks{parallel}; QList<TaskItem> tasks{parallel};
const auto addClangTool = [this, &config, &env, &tasks](ClangToolType tool) { const auto addClangTool = [this, &runSettings, &config, &env, &tasks](ClangToolType tool) {
if (!config.isEnabled(tool)) if (!toolEnabled(tool, config, runSettings))
return;
if (!config.isEnabled(tool) && !runSettings.hasConfigFileForSourceFile(m_fileInfo.file))
return; return;
const FilePath executable = toolExecutable(tool); const FilePath executable = toolExecutable(tool);
const auto [includeDir, clangVersion] = getClangIncludeDirAndVersion(executable); const auto [includeDir, clangVersion] = getClangIncludeDirAndVersion(executable);
if (!executable.isExecutableFile() || includeDir.isEmpty() || clangVersion.isEmpty()) if (!executable.isExecutableFile() || includeDir.isEmpty() || clangVersion.isEmpty())
return; return;
const AnalyzeUnit unit(m_fileInfo, includeDir, clangVersion); const AnalyzeUnit unit(m_fileInfo, includeDir, clangVersion);
const AnalyzeInputData input{tool, config, m_temporaryDir.path(), env, unit, const AnalyzeInputData input{tool, runSettings, config, m_temporaryDir.path(), env, unit,
vfso().overlayFilePath().toString()}; vfso().overlayFilePath().toString()};
const auto setupHandler = [this, executable] { const auto setupHandler = [this, executable] {
return !m_document->isModified() || isVFSOverlaySupported(executable); return !m_document->isModified() || isVFSOverlaySupported(executable);

View File

@@ -31,11 +31,9 @@ RunSettingsWidget::RunSettingsWidget(QWidget *parent)
resize(383, 125); resize(383, 125);
m_diagnosticWidget = new ClangDiagnosticConfigsSelectionWidget; m_diagnosticWidget = new ClangDiagnosticConfigsSelectionWidget;
m_preferConfigFile = new QCheckBox(Tr::tr("Prefer .clang-tidy file, if present"));
m_buildBeforeAnalysis = new QCheckBox(Tr::tr("Build the project before analysis")); m_buildBeforeAnalysis = new QCheckBox(Tr::tr("Build the project before analysis"));
m_analyzeOpenFiles = new QCheckBox(Tr::tr("Analyze open files")); m_analyzeOpenFiles = new QCheckBox(Tr::tr("Analyze open files"));
m_parallelJobsSpinBox = new QSpinBox; m_parallelJobsSpinBox = new QSpinBox;
m_parallelJobsSpinBox->setRange(1, 32); m_parallelJobsSpinBox->setRange(1, 32);
@@ -47,6 +45,7 @@ RunSettingsWidget::RunSettingsWidget(QWidget *parent)
title(Tr::tr("Run Options")), title(Tr::tr("Run Options")),
Column { Column {
m_diagnosticWidget, m_diagnosticWidget,
m_preferConfigFile,
m_buildBeforeAnalysis, m_buildBeforeAnalysis,
m_analyzeOpenFiles, m_analyzeOpenFiles,
Row { Tr::tr("Parallel jobs:"), m_parallelJobsSpinBox, st }, Row { Tr::tr("Parallel jobs:"), m_parallelJobsSpinBox, st },
@@ -99,6 +98,9 @@ void RunSettingsWidget::fromSettings(const RunSettings &s)
connect(m_diagnosticWidget, &ClangDiagnosticConfigsSelectionWidget::changed, connect(m_diagnosticWidget, &ClangDiagnosticConfigsSelectionWidget::changed,
this, &RunSettingsWidget::changed); this, &RunSettingsWidget::changed);
m_preferConfigFile->setChecked(s.preferConfigFile());
connect(m_preferConfigFile, &QCheckBox::toggled, this, &RunSettingsWidget::changed);
disconnect(m_buildBeforeAnalysis, 0, 0, 0); disconnect(m_buildBeforeAnalysis, 0, 0, 0);
m_buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis()); m_buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis());
m_buildBeforeAnalysis->setCheckState(s.buildBeforeAnalysis() ? Qt::Checked : Qt::Unchecked); m_buildBeforeAnalysis->setCheckState(s.buildBeforeAnalysis() ? Qt::Checked : Qt::Unchecked);
@@ -115,13 +117,13 @@ void RunSettingsWidget::fromSettings(const RunSettings &s)
connect(m_parallelJobsSpinBox, &QSpinBox::valueChanged, this, &RunSettingsWidget::changed); connect(m_parallelJobsSpinBox, &QSpinBox::valueChanged, this, &RunSettingsWidget::changed);
m_analyzeOpenFiles->setChecked(s.analyzeOpenFiles()); m_analyzeOpenFiles->setChecked(s.analyzeOpenFiles());
connect(m_analyzeOpenFiles, &QCheckBox::toggled, this, &RunSettingsWidget::changed); connect(m_analyzeOpenFiles, &QCheckBox::toggled, this, &RunSettingsWidget::changed);
} }
RunSettings RunSettingsWidget::toSettings() const RunSettings RunSettingsWidget::toSettings() const
{ {
RunSettings s; RunSettings s;
s.setDiagnosticConfigId(m_diagnosticWidget->currentConfigId()); s.setDiagnosticConfigId(m_diagnosticWidget->currentConfigId());
s.setPreferConfigFile(m_preferConfigFile->isChecked());
s.setBuildBeforeAnalysis(m_buildBeforeAnalysis->checkState() == Qt::CheckState::Checked); s.setBuildBeforeAnalysis(m_buildBeforeAnalysis->checkState() == Qt::CheckState::Checked);
s.setParallelJobs(m_parallelJobsSpinBox->value()); s.setParallelJobs(m_parallelJobsSpinBox->value());
s.setAnalyzeOpenFiles(m_analyzeOpenFiles->checkState() == Qt::CheckState::Checked); s.setAnalyzeOpenFiles(m_analyzeOpenFiles->checkState() == Qt::CheckState::Checked);

View File

@@ -37,6 +37,7 @@ signals:
private: private:
CppEditor::ClangDiagnosticConfigsSelectionWidget *m_diagnosticWidget; CppEditor::ClangDiagnosticConfigsSelectionWidget *m_diagnosticWidget;
QCheckBox *m_preferConfigFile;
QCheckBox *m_buildBeforeAnalysis; QCheckBox *m_buildBeforeAnalysis;
QCheckBox *m_analyzeOpenFiles; QCheckBox *m_analyzeOpenFiles;
QSpinBox *m_parallelJobsSpinBox; QSpinBox *m_parallelJobsSpinBox;

View File

@@ -42,10 +42,8 @@ public:
// Clang-Tidy // Clang-Tidy
enum class TidyMode enum class TidyMode
{ {
// Disabled, // Used by Qt Creator 4.10 and below.
UseCustomChecks = 1, UseCustomChecks = 1,
UseConfigFile, UseDefaultChecks = 3,
UseDefaultChecks,
}; };
TidyMode clangTidyMode() const; TidyMode clangTidyMode() const;
void setClangTidyMode(TidyMode mode); void setClangTidyMode(TidyMode mode);