ClangUtils: Get rid of GenerateCompilationDbResult struct

Replace it with expected_str<FilePath>.
Check periodically for cancel request inside
generateCompilationDB() body.

Cancel the possibly running task on ClangCodeModelPlugin
destruction.

Handle the cancellation.

Change-Id: I8bcb956bc03627b4a17a3510a76810e66c82815d
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Jarek Kobus
2024-05-23 23:41:17 +02:00
parent d3b2bc32cc
commit 63a93760d9
4 changed files with 45 additions and 38 deletions

View File

@@ -68,6 +68,7 @@ private:
ClangCodeModelPlugin::~ClangCodeModelPlugin() ClangCodeModelPlugin::~ClangCodeModelPlugin()
{ {
m_generatorWatcher.cancel();
m_generatorWatcher.waitForFinished(); m_generatorWatcher.waitForFinished();
} }
@@ -140,13 +141,18 @@ void ClangCodeModelPlugin::createCompilationDBAction()
connect(&m_generatorWatcher, &QFutureWatcher<GenerateCompilationDbResult>::finished, connect(&m_generatorWatcher, &QFutureWatcher<GenerateCompilationDbResult>::finished,
this, [this] { this, [this] {
const GenerateCompilationDbResult result = m_generatorWatcher.result();
QString message; QString message;
if (result.error.isEmpty()) { if (m_generatorWatcher.future().resultCount()) {
const GenerateCompilationDbResult result = m_generatorWatcher.result();
if (result) {
message = Tr::tr("Clang compilation database generated at \"%1\".") message = Tr::tr("Clang compilation database generated at \"%1\".")
.arg(QDir::toNativeSeparators(result.filePath)); .arg(result->toUserOutput());
} else { } else {
message = Tr::tr("Generating Clang compilation database failed: %1").arg(result.error); message
= Tr::tr("Generating Clang compilation database failed: %1").arg(result.error());
}
} else {
message = Tr::tr("Generating Clang compilation database canceled.");
} }
MessageManager::writeFlashing(message); MessageManager::writeFlashing(message);
m_generateCompilationDBAction->setEnabled(true); m_generateCompilationDBAction->setEnabled(true);

View File

@@ -540,11 +540,15 @@ void ClangModelManagerSupport::updateLanguageClient(Project *project)
generatorWatcher->deleteLater(); generatorWatcher->deleteLater();
if (!isProjectDataUpToDate(project, projectInfo, jsonDbDir)) if (!isProjectDataUpToDate(project, projectInfo, jsonDbDir))
return; return;
const GenerateCompilationDbResult result = generatorWatcher->result(); if (generatorWatcher->future().resultCount() == 0) {
if (!result.error.isEmpty()) {
MessageManager::writeDisrupting( MessageManager::writeDisrupting(
Tr::tr("Cannot use clangd: Failed to generate compilation database:\n%1") Tr::tr("Cannot use clangd: Generating compilation database canceled."));
.arg(result.error)); return;
}
const GenerateCompilationDbResult result = generatorWatcher->result();
if (!result) {
MessageManager::writeDisrupting(Tr::tr("Cannot use clangd: "
"Failed to generate compilation database:\n%1").arg(result.error()));
return; return;
} }
Id previousId; Id previousId;

View File

@@ -146,23 +146,26 @@ static QJsonObject createFileObject(const FilePath &buildDir,
return fileObject; return fileObject;
} }
GenerateCompilationDbResult generateCompilationDB(QList<ProjectInfo::ConstPtr> projectInfoList, void generateCompilationDB(
FilePath baseDir, QPromise<expected_str<FilePath>> &promise,
const QList<ProjectInfo::ConstPtr> &projectInfoList,
const FilePath &baseDir,
CompilationDbPurpose purpose, CompilationDbPurpose purpose,
ClangDiagnosticConfig warningsConfig, const ClangDiagnosticConfig &warningsConfig,
QStringList projectOptions, const QStringList &projectOptions,
FilePath clangIncludeDir) const FilePath &clangIncludeDir)
{ {
QTC_ASSERT(!baseDir.isEmpty(), return GenerateCompilationDbResult(QString(), QTC_ASSERT(!baseDir.isEmpty(),
Tr::tr("Could not retrieve build directory."))); promise.addResult(make_unexpected(Tr::tr("Could not retrieve build directory."))); return);
QTC_ASSERT(!projectInfoList.isEmpty(), QTC_ASSERT(!projectInfoList.isEmpty(),
return GenerateCompilationDbResult(QString(), "Could not retrieve project info.")); promise.addResult(make_unexpected(Tr::tr("Could not retrieve project info."))); return);
QTC_CHECK(baseDir.ensureWritableDir()); QTC_CHECK(baseDir.ensureWritableDir());
QFile compileCommandsFile(baseDir.pathAppended("compile_commands.json").toFSPathString()); QFile compileCommandsFile(baseDir.pathAppended("compile_commands.json").toFSPathString());
const bool fileOpened = compileCommandsFile.open(QIODevice::WriteOnly | QIODevice::Truncate); const bool fileOpened = compileCommandsFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
if (!fileOpened) { if (!fileOpened) {
return GenerateCompilationDbResult(QString(), Tr::tr("Could not create \"%1\": %2") promise.addResult(make_unexpected(Tr::tr("Could not create \"%1\": %2")
.arg(compileCommandsFile.fileName(), compileCommandsFile.errorString())); .arg(compileCommandsFile.fileName(), compileCommandsFile.errorString())));
return;
} }
compileCommandsFile.write("["); compileCommandsFile.write("[");
@@ -182,6 +185,8 @@ GenerateCompilationDbResult generateCompilationDB(QList<ProjectInfo::ConstPtr> p
jsonProjectOptions); jsonProjectOptions);
} }
for (const ProjectFile &projFile : projectPart->files) { for (const ProjectFile &projFile : projectPart->files) {
if (promise.isCanceled())
return;
const QJsonObject json const QJsonObject json
= createFileObject(baseDir, = createFileObject(baseDir,
args, args,
@@ -200,7 +205,7 @@ GenerateCompilationDbResult generateCompilationDB(QList<ProjectInfo::ConstPtr> p
compileCommandsFile.write("]"); compileCommandsFile.write("]");
compileCommandsFile.close(); compileCommandsFile.close();
return GenerateCompilationDbResult(compileCommandsFile.fileName(), QString()); promise.addResult(FilePath::fromUserInput(compileCommandsFile.fileName()));
} }
FilePath currentCppEditorDocumentFilePath() FilePath currentCppEditorDocumentFilePath()
@@ -262,7 +267,6 @@ QString DiagnosticTextInfo::clazyCheckName(const QString &option)
return option; return option;
} }
QJsonArray clangOptionsForFile(const ProjectFile &file, const ProjectPart &projectPart, QJsonArray clangOptionsForFile(const ProjectFile &file, const ProjectPart &projectPart,
const QJsonArray &generalOptions, UsePrecompiledHeaders usePch, const QJsonArray &generalOptions, UsePrecompiledHeaders usePch,
bool clStyle) bool clStyle)

View File

@@ -53,23 +53,16 @@ Utils::FilePath currentCppEditorDocumentFilePath();
QString diagnosticCategoryPrefixRemoved(const QString &text); QString diagnosticCategoryPrefixRemoved(const QString &text);
class GenerateCompilationDbResult using GenerateCompilationDbResult = Utils::expected_str<Utils::FilePath>;
{
public:
GenerateCompilationDbResult() = default;
GenerateCompilationDbResult(const QString &filePath, const QString &error)
: filePath(filePath), error(error)
{}
QString filePath;
QString error;
};
enum class CompilationDbPurpose { Project, CodeModel }; enum class CompilationDbPurpose { Project, CodeModel };
GenerateCompilationDbResult generateCompilationDB(QList<CppEditor::ProjectInfo::ConstPtr> projectInfo, void generateCompilationDB(
Utils::FilePath baseDir, CompilationDbPurpose purpose, QPromise<GenerateCompilationDbResult> &promise,
CppEditor::ClangDiagnosticConfig warningsConfig, QStringList projectOptions, const QList<CppEditor::ProjectInfo::ConstPtr> &projectInfoList,
Utils::FilePath clangIncludeDir); const Utils::FilePath &baseDir,
CompilationDbPurpose purpose,
const CppEditor::ClangDiagnosticConfig &warningsConfig,
const QStringList &projectOptions,
const Utils::FilePath &clangIncludeDir);
class DiagnosticTextInfo class DiagnosticTextInfo
{ {