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

View File

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

View File

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

View File

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