diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index 28d00d84a28..62ef434a2e9 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -68,6 +68,7 @@ private: ClangCodeModelPlugin::~ClangCodeModelPlugin() { + m_generatorWatcher.cancel(); m_generatorWatcher.waitForFinished(); } @@ -140,13 +141,18 @@ void ClangCodeModelPlugin::createCompilationDBAction() connect(&m_generatorWatcher, &QFutureWatcher::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); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index a68f5663090..525fcc7f1ea 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -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; diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index 1b2550cbd3d..b27117f056e 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -146,23 +146,26 @@ static QJsonObject createFileObject(const FilePath &buildDir, return fileObject; } -GenerateCompilationDbResult generateCompilationDB(QList projectInfoList, - FilePath baseDir, - CompilationDbPurpose purpose, - ClangDiagnosticConfig warningsConfig, - QStringList projectOptions, - FilePath clangIncludeDir) +void generateCompilationDB( + QPromise> &promise, + const QList &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 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 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) diff --git a/src/plugins/clangcodemodel/clangutils.h b/src/plugins/clangcodemodel/clangutils.h index 6b99be52e6d..d78dab72311 100644 --- a/src/plugins/clangcodemodel/clangutils.h +++ b/src/plugins/clangcodemodel/clangutils.h @@ -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; enum class CompilationDbPurpose { Project, CodeModel }; -GenerateCompilationDbResult generateCompilationDB(QList projectInfo, - Utils::FilePath baseDir, CompilationDbPurpose purpose, - CppEditor::ClangDiagnosticConfig warningsConfig, QStringList projectOptions, - Utils::FilePath clangIncludeDir); +void generateCompilationDB( + QPromise &promise, + const QList &projectInfoList, + const Utils::FilePath &baseDir, + CompilationDbPurpose purpose, + const CppEditor::ClangDiagnosticConfig &warningsConfig, + const QStringList &projectOptions, + const Utils::FilePath &clangIncludeDir); class DiagnosticTextInfo {