summaryrefslogtreecommitdiff
path: root/src/plugins/diffeditor
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2023-02-02 23:32:26 +0100
committerJarek Kobus <jaroslaw.kobus@qt.io>2023-02-03 15:31:25 +0000
commit202b696677c13079dd503d0f814aecdc64bfa00b (patch)
tree03929b572770964e07d405271c43b5dc909ab58f /src/plugins/diffeditor
parentce0f48e0f9b9e59c2c876da1eb923622730df6e4 (diff)
downloadqt-creator-202b696677c13079dd503d0f814aecdc64bfa00b.tar.gz
DiffEditor: Fix a crash when "No difference"
It may happen that async task associated with diffing one pair of files may not report any value. This happens when both file contents are the same. In this case taking a result from async task on a successful done will lead to crash. Add AsyncTask::isResultAvailable() method. Use it in client code just in case, where needed. Fix DiffFilesController, so that no result is allowed for all running tasks (i.e. make the main group optional). Collect list of optional results instead of direct results. The empty optional on the list means the result wasn't delivered by async task and it's skipped. Fixes: QTCREATORBUG-28750 Change-Id: I4ca678a187fad619bae470da3e806e8c8da61127 Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/plugins/diffeditor')
-rw-r--r--src/plugins/diffeditor/diffeditorplugin.cpp17
-rw-r--r--src/plugins/diffeditor/sidebysidediffeditorwidget.cpp2
-rw-r--r--src/plugins/diffeditor/unifieddiffeditorwidget.cpp2
3 files changed, 14 insertions, 7 deletions
diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp
index e18a0e2797..2a81320665 100644
--- a/src/plugins/diffeditor/diffeditorplugin.cpp
+++ b/src/plugins/diffeditor/diffeditorplugin.cpp
@@ -109,24 +109,25 @@ DiffFilesController::DiffFilesController(IDocument *document)
setDisplayName(Tr::tr("Diff"));
using namespace Tasking;
- const TreeStorage<QList<FileData>> storage;
+ const TreeStorage<QList<std::optional<FileData>>> storage;
const auto setupTree = [this, storage](TaskTree &taskTree) {
- QList<FileData> *outputList = storage.activeStorage();
+ QList<std::optional<FileData>> *outputList = storage.activeStorage();
const auto setupDiff = [this](AsyncTask<FileData> &async, const ReloadInput &reloadInput) {
async.setAsyncCallData(DiffFile(ignoreWhitespace(), contextLineCount()), reloadInput);
async.setFutureSynchronizer(Internal::DiffEditorPlugin::futureSynchronizer());
};
const auto onDiffDone = [outputList](const AsyncTask<FileData> &async, int i) {
- (*outputList)[i] = async.result();
+ if (async.isResultAvailable())
+ (*outputList)[i] = async.result();
};
const QList<ReloadInput> inputList = reloadInputList();
outputList->resize(inputList.size());
using namespace std::placeholders;
- QList<TaskItem> tasks {parallel, continueOnDone};
+ QList<TaskItem> tasks {parallel, optional};
for (int i = 0; i < inputList.size(); ++i) {
tasks.append(Async<FileData>(std::bind(setupDiff, _1, inputList.at(i)),
std::bind(onDiffDone, _1, i)));
@@ -134,7 +135,13 @@ DiffFilesController::DiffFilesController(IDocument *document)
taskTree.setupRoot(tasks);
};
const auto onTreeDone = [this, storage] {
- setDiffFiles(*storage.activeStorage());
+ const QList<std::optional<FileData>> &results = *storage.activeStorage();
+ QList<FileData> finalList;
+ for (const std::optional<FileData> &result : results) {
+ if (result.has_value())
+ finalList.append(*result);
+ }
+ setDiffFiles(finalList);
};
const auto onTreeError = [this, storage] {
setDiffFiles({});
diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
index 5bc887b90a..da69e60784 100644
--- a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
+++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
@@ -874,7 +874,7 @@ void SideBySideDiffEditorWidget::showDiff()
m_controller.setBusyShowing(true);
connect(m_asyncTask.get(), &AsyncTaskBase::done, this, [this] {
- if (m_asyncTask->isCanceled()) {
+ if (m_asyncTask->isCanceled() || !m_asyncTask->isResultAvailable()) {
for (SideDiffEditorWidget *editor : m_editor)
editor->clearAll(Tr::tr("Retrieving data failed."));
} else {
diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
index 8c8bee05c2..b937b919f7 100644
--- a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
+++ b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
@@ -458,7 +458,7 @@ void UnifiedDiffEditorWidget::showDiff()
m_asyncTask->setFutureSynchronizer(DiffEditorPlugin::futureSynchronizer());
m_controller.setBusyShowing(true);
connect(m_asyncTask.get(), &AsyncTaskBase::done, this, [this] {
- if (m_asyncTask->isCanceled()) {
+ if (m_asyncTask->isCanceled() || !m_asyncTask->isResultAvailable()) {
setPlainText(Tr::tr("Retrieving data failed."));
} else {
const ShowResult result = m_asyncTask->result();