From f873ad1cf05a0c14c233c787b32f597e2267bcef Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 16 Jun 2022 10:12:23 +0200 Subject: [PATCH 001/100] Debugger: Ensure termination of lldb.exe LLDB 12.0.8, which is included in NDK 23.1, hesitates to termiate when being told to. Calling QtcProcess::stop() and using CtrlCStub on Windows helps with that. Amends: 17ff9317cdc3de1773b62e46c1ec9b6958fa1035 Fixes: QTCREATORBUG-27723 Change-Id: Ie9d4ed23a833019f445c1517983c90ae899fbf39 Reviewed-by: Jarek Kobus Reviewed-by: Cristian Adam --- src/plugins/debugger/lldb/lldbengine.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index f870ba78f40..8bcd5112305 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -189,16 +189,13 @@ void LldbEngine::shutdownInferior() void LldbEngine::shutdownEngine() { QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); - if (m_lldbProc.isRunning()) - m_lldbProc.terminate(); - else - notifyEngineShutdownFinished(); + abortDebuggerProcess(); } void LldbEngine::abortDebuggerProcess() { if (m_lldbProc.isRunning()) - m_lldbProc.kill(); + m_lldbProc.stop(); else notifyEngineShutdownFinished(); } @@ -799,7 +796,7 @@ void LldbEngine::handleLldbError(QProcess::ProcessError error) case QProcess::Timedout: default: //setState(EngineShutdownRequested, true); - m_lldbProc.kill(); + m_lldbProc.stop(); AsynchronousMessageBox::critical(tr("LLDB I/O Error"), errorMessage(error)); break; } From f1ff0a90e0e8656ecc97ed898a7552cd86b79d9f Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 16 Jun 2022 17:27:47 +0200 Subject: [PATCH 002/100] DocumentClangToolRunner: Delete later the old runner on runNext() Don't delete the old ClangToolRunner directly from its signal handler when calling runNext(). Change-Id: I55e72c1cced9ecbce492d00896d6fa161df02fd0 Reviewed-by: David Schulz --- src/plugins/clangtools/documentclangtoolrunner.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/clangtools/documentclangtoolrunner.cpp b/src/plugins/clangtools/documentclangtoolrunner.cpp index 28a4d0df29b..cebd508ed10 100644 --- a/src/plugins/clangtools/documentclangtoolrunner.cpp +++ b/src/plugins/clangtools/documentclangtoolrunner.cpp @@ -251,6 +251,8 @@ QPair getClangIncludeDirAndVersion(ClangToolRunner *runner) void DocumentClangToolRunner::runNext() { + if (m_currentRunner) + m_currentRunner.release()->deleteLater(); m_currentRunner.reset(m_runnerCreators.isEmpty() ? nullptr : m_runnerCreators.takeFirst()()); if (m_currentRunner) { auto [clangIncludeDir, clangVersion] = getClangIncludeDirAndVersion(m_currentRunner.get()); From 8295714ff6e8e91d9c2327d735b63572235e5f16 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Dec 2021 11:07:33 +0100 Subject: [PATCH 003/100] Utils: Shuffle PathChooser expansion responsibility around Change-Id: Iaee0c21e8e1c99cc034bee5b892587d3137b5508 Reviewed-by: Qt CI Bot Reviewed-by: Eike Ziller --- src/libs/utils/pathchooser.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp index 27d08acb803..7a31cf8318d 100644 --- a/src/libs/utils/pathchooser.cpp +++ b/src/libs/utils/pathchooser.cpp @@ -178,7 +178,7 @@ class PathChooserPrivate public: PathChooserPrivate(); - FilePath expandedPath(const QString &path) const; + FilePath expandedPath(const FilePath &path) const; QHBoxLayout *m_hLayout = nullptr; FancyLineEdit *m_lineEdit = nullptr; @@ -202,12 +202,12 @@ PathChooserPrivate::PathChooserPrivate() { } -FilePath PathChooserPrivate::expandedPath(const QString &input) const +FilePath PathChooserPrivate::expandedPath(const FilePath &input) const { if (input.isEmpty()) return {}; - FilePath path = FilePath::fromUserInput(input); + FilePath path = input; Environment env = path.deviceEnvironment(); m_environmentChange.applyToEnvironment(env); @@ -353,7 +353,7 @@ FilePath PathChooser::rawFilePath() const FilePath PathChooser::filePath() const { - return d->expandedPath(rawFilePath().toString()); + return d->expandedPath(rawFilePath()); } FilePath PathChooser::absoluteFilePath() const @@ -529,11 +529,11 @@ FancyLineEdit::ValidationFunction PathChooser::defaultValidationFunction() const bool PathChooser::validatePath(FancyLineEdit *edit, QString *errorMessage) const { - QString path = edit->text(); + QString input = edit->text(); - if (path.isEmpty()) { + if (input.isEmpty()) { if (!d->m_defaultValue.isEmpty()) { - path = d->m_defaultValue; + input = d->m_defaultValue; } else { if (errorMessage) *errorMessage = tr("The path must not be empty."); @@ -541,10 +541,10 @@ bool PathChooser::validatePath(FancyLineEdit *edit, QString *errorMessage) const } } - const FilePath filePath = d->expandedPath(path); + const FilePath filePath = d->expandedPath(FilePath::fromUserInput(input)); if (filePath.isEmpty()) { if (errorMessage) - *errorMessage = tr("The path \"%1\" expanded to an empty string.").arg(QDir::toNativeSeparators(path)); + *errorMessage = tr("The path \"%1\" expanded to an empty string.").arg(input); return false; } From 5f4806632826e9e7c9c47efd8dbe937cd9d24462 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 17 Jun 2022 13:03:16 +0200 Subject: [PATCH 004/100] Bump version to 8.0.0-beta2 Change-Id: I02a09e916d11c7ce28b2d58ba7517e582e14be06 Reviewed-by: David Schulz --- cmake/QtCreatorIDEBranding.cmake | 6 +++--- qbs/modules/qtc/qtc.qbs | 6 +++--- qtcreator_ide_branding.pri | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake index 3ca492689c7..92a3d31689c 100644 --- a/cmake/QtCreatorIDEBranding.cmake +++ b/cmake/QtCreatorIDEBranding.cmake @@ -1,6 +1,6 @@ -set(IDE_VERSION "7.82.0") # The IDE version. -set(IDE_VERSION_COMPAT "7.82.0") # The IDE Compatibility version. -set(IDE_VERSION_DISPLAY "8.0.0-beta1") # The IDE display version. +set(IDE_VERSION "7.83.0") # The IDE version. +set(IDE_VERSION_COMPAT "7.83.0") # The IDE Compatibility version. +set(IDE_VERSION_DISPLAY "8.0.0-beta2") # The IDE display version. set(IDE_COPYRIGHT_YEAR "2022") # The IDE current copyright year. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index 4d231e7063b..8578403fcc5 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -3,15 +3,15 @@ import qbs.Environment import qbs.FileInfo Module { - property string qtcreator_display_version: '8.0.0-beta1' + property string qtcreator_display_version: '8.0.0-beta2' property string ide_version_major: '7' - property string ide_version_minor: '82' + property string ide_version_minor: '83' property string ide_version_release: '0' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release property string ide_compat_version_major: '7' - property string ide_compat_version_minor: '82' + property string ide_compat_version_minor: '83' property string ide_compat_version_release: '0' property string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release diff --git a/qtcreator_ide_branding.pri b/qtcreator_ide_branding.pri index bb1f7131f26..5f55cb9ead2 100644 --- a/qtcreator_ide_branding.pri +++ b/qtcreator_ide_branding.pri @@ -1,6 +1,6 @@ -QTCREATOR_VERSION = 7.82.0 -QTCREATOR_COMPAT_VERSION = 7.82.0 -QTCREATOR_DISPLAY_VERSION = 8.0.0-beta1 +QTCREATOR_VERSION = 7.83.0 +QTCREATOR_COMPAT_VERSION = 7.83.0 +QTCREATOR_DISPLAY_VERSION = 8.0.0-beta2 QTCREATOR_COPYRIGHT_YEAR = 2022 IDE_DISPLAY_NAME = Qt Creator From 6767b9b7375dc8148fa3434051aad0d531aed933 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 15 Jun 2022 08:27:06 +0200 Subject: [PATCH 005/100] COIN/GitHub: Use Qt 6.3.1 Change-Id: I2485ef1ec0414d503a907d69fcc277f80d569286 Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: David Schulz --- .github/workflows/build_cmake.yml | 2 +- coin/instructions/common_environment.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 7e7c91d6a21..ed0a3958f3e 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -7,7 +7,7 @@ on: - 'doc/**' env: - QT_VERSION: 6.3.0 + QT_VERSION: 6.3.1 CLANG_VERSION: 14.0.3 ELFUTILS_VERSION: 0.175 CMAKE_VERSION: 3.21.1 diff --git a/coin/instructions/common_environment.yaml b/coin/instructions/common_environment.yaml index 3b1faa00981..6141d447915 100644 --- a/coin/instructions/common_environment.yaml +++ b/coin/instructions/common_environment.yaml @@ -13,7 +13,7 @@ instructions: instructions: - type: EnvironmentVariable variableName: QTC_QT_BASE_URL - variableValue: "http://ci-files02-hki.intra.qt.io/packages/jenkins/archive/qt/6.3/6.3.0-final-released/Qt6.3.0" + variableValue: "http://ci-files02-hki.intra.qt.io/packages/jenkins/archive/qt/6.3/6.3.1-final-released/Qt6.3.1" - type: EnvironmentVariable variableName: QTC_QT_MODULES variableValue: "qt5compat qtbase qtdeclarative qtimageformats qtquick3d qtquickcontrols2 qtquicktimeline qtserialport qtshadertools qtsvg qttools qttranslations" From 7d69b5b2080a7e98b4d30a2fa5b087850889d2b8 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 17 Jun 2022 09:22:37 +0200 Subject: [PATCH 006/100] Tests: Provide valgrind testapps in cmake build Change-Id: I4ec94504e3d2265d066434e118ab2eae6279a42f Reviewed-by: hjk Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: Eike Ziller --- tests/auto/valgrind/CMakeLists.txt | 4 +++- tests/auto/valgrind/memcheck/CMakeLists.txt | 1 + tests/auto/valgrind/memcheck/testapps/CMakeLists.txt | 12 ++++++++++++ .../valgrind/memcheck/testapps/free1/CMakeLists.txt | 3 +++ .../valgrind/memcheck/testapps/free2/CMakeLists.txt | 3 +++ .../memcheck/testapps/invalidjump/CMakeLists.txt | 3 +++ .../valgrind/memcheck/testapps/leak1/CMakeLists.txt | 5 +++++ .../valgrind/memcheck/testapps/leak2/CMakeLists.txt | 3 +++ .../valgrind/memcheck/testapps/leak3/CMakeLists.txt | 3 +++ .../valgrind/memcheck/testapps/leak4/CMakeLists.txt | 4 ++++ .../memcheck/testapps/overlap/CMakeLists.txt | 3 +++ .../memcheck/testapps/syscall/CMakeLists.txt | 3 +++ tests/auto/valgrind/memcheck/testapps/testapp.cmake | 4 ++++ .../memcheck/testapps/uninit1/CMakeLists.txt | 3 +++ .../memcheck/testapps/uninit2/CMakeLists.txt | 3 +++ .../memcheck/testapps/uninit3/CMakeLists.txt | 3 +++ 16 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/auto/valgrind/memcheck/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/free1/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/free2/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/invalidjump/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/leak1/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/leak2/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/leak3/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/leak4/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/overlap/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/syscall/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/testapp.cmake create mode 100644 tests/auto/valgrind/memcheck/testapps/uninit1/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/uninit2/CMakeLists.txt create mode 100644 tests/auto/valgrind/memcheck/testapps/uninit3/CMakeLists.txt diff --git a/tests/auto/valgrind/CMakeLists.txt b/tests/auto/valgrind/CMakeLists.txt index 4091dd61268..9a19241b2a0 100644 --- a/tests/auto/valgrind/CMakeLists.txt +++ b/tests/auto/valgrind/CMakeLists.txt @@ -1,2 +1,4 @@ add_subdirectory(callgrind) -# add_subdirectory(memcheck) +if (UNIX) + add_subdirectory(memcheck) +endif() diff --git a/tests/auto/valgrind/memcheck/CMakeLists.txt b/tests/auto/valgrind/memcheck/CMakeLists.txt new file mode 100644 index 00000000000..8ea0f41a15b --- /dev/null +++ b/tests/auto/valgrind/memcheck/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(testapps) diff --git a/tests/auto/valgrind/memcheck/testapps/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/CMakeLists.txt new file mode 100644 index 00000000000..89149fc5309 --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/CMakeLists.txt @@ -0,0 +1,12 @@ +add_subdirectory(free1) +add_subdirectory(free2) +add_subdirectory(invalidjump) +add_subdirectory(leak1) +add_subdirectory(leak2) +add_subdirectory(leak3) +add_subdirectory(leak4) +add_subdirectory(overlap) +add_subdirectory(syscall) +add_subdirectory(uninit1) +add_subdirectory(uninit2) +add_subdirectory(uninit3) diff --git a/tests/auto/valgrind/memcheck/testapps/free1/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/free1/CMakeLists.txt new file mode 100644 index 00000000000..99ca11c06c2 --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/free1/CMakeLists.txt @@ -0,0 +1,3 @@ +include(../testapp.cmake) + +add_valgrind_testapp(free1) diff --git a/tests/auto/valgrind/memcheck/testapps/free2/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/free2/CMakeLists.txt new file mode 100644 index 00000000000..798be2b8122 --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/free2/CMakeLists.txt @@ -0,0 +1,3 @@ +include(../testapp.cmake) + +add_valgrind_testapp(free2) diff --git a/tests/auto/valgrind/memcheck/testapps/invalidjump/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/invalidjump/CMakeLists.txt new file mode 100644 index 00000000000..17ab08a4e44 --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/invalidjump/CMakeLists.txt @@ -0,0 +1,3 @@ +include(../testapp.cmake) + +add_valgrind_testapp(invalidjump) diff --git a/tests/auto/valgrind/memcheck/testapps/leak1/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/leak1/CMakeLists.txt new file mode 100644 index 00000000000..cd05f350fda --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/leak1/CMakeLists.txt @@ -0,0 +1,5 @@ +include(../testapp.cmake) + +add_valgrind_testapp(leak1) +target_link_libraries(leak1 PRIVATE Qt5::Core) + diff --git a/tests/auto/valgrind/memcheck/testapps/leak2/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/leak2/CMakeLists.txt new file mode 100644 index 00000000000..a1134baf9c9 --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/leak2/CMakeLists.txt @@ -0,0 +1,3 @@ +include(../testapp.cmake) + +add_valgrind_testapp(leak2) diff --git a/tests/auto/valgrind/memcheck/testapps/leak3/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/leak3/CMakeLists.txt new file mode 100644 index 00000000000..d825d1ac82d --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/leak3/CMakeLists.txt @@ -0,0 +1,3 @@ +include(../testapp.cmake) + +add_valgrind_testapp(leak3) diff --git a/tests/auto/valgrind/memcheck/testapps/leak4/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/leak4/CMakeLists.txt new file mode 100644 index 00000000000..112d8b2e9df --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/leak4/CMakeLists.txt @@ -0,0 +1,4 @@ +include(../testapp.cmake) + +add_valgrind_testapp(leak4) +target_link_libraries(leak4 PRIVATE Qt5::Core) diff --git a/tests/auto/valgrind/memcheck/testapps/overlap/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/overlap/CMakeLists.txt new file mode 100644 index 00000000000..149f26e3bdf --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/overlap/CMakeLists.txt @@ -0,0 +1,3 @@ +include(../testapp.cmake) + +add_valgrind_testapp(overlap) diff --git a/tests/auto/valgrind/memcheck/testapps/syscall/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/syscall/CMakeLists.txt new file mode 100644 index 00000000000..639996072b3 --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/syscall/CMakeLists.txt @@ -0,0 +1,3 @@ +include(../testapp.cmake) + +add_valgrind_testapp(syscall) diff --git a/tests/auto/valgrind/memcheck/testapps/testapp.cmake b/tests/auto/valgrind/memcheck/testapps/testapp.cmake new file mode 100644 index 00000000000..25d8a154b7e --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/testapp.cmake @@ -0,0 +1,4 @@ +function(add_valgrind_testapp name) + add_executable("${name}" + ${CMAKE_CURRENT_LIST_DIR}/main.cpp) +endfunction() diff --git a/tests/auto/valgrind/memcheck/testapps/uninit1/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/uninit1/CMakeLists.txt new file mode 100644 index 00000000000..99296862d5f --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/uninit1/CMakeLists.txt @@ -0,0 +1,3 @@ +include(../testapp.cmake) + +add_valgrind_testapp(uninit1) diff --git a/tests/auto/valgrind/memcheck/testapps/uninit2/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/uninit2/CMakeLists.txt new file mode 100644 index 00000000000..32f279703cc --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/uninit2/CMakeLists.txt @@ -0,0 +1,3 @@ +include(../testapp.cmake) + +add_valgrind_testapp(uninit2) diff --git a/tests/auto/valgrind/memcheck/testapps/uninit3/CMakeLists.txt b/tests/auto/valgrind/memcheck/testapps/uninit3/CMakeLists.txt new file mode 100644 index 00000000000..def23876926 --- /dev/null +++ b/tests/auto/valgrind/memcheck/testapps/uninit3/CMakeLists.txt @@ -0,0 +1,3 @@ +include(../testapp.cmake) + +add_valgrind_testapp(uninit3) From 120f3872d23933d8bcdae209b270b9a0af47dc6d Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 15 Jun 2022 15:01:46 +0200 Subject: [PATCH 007/100] CppEditor: Add an enum to the code style preview for braces settings So the user gets feedback for all the checkboxes by default. Fixes: QTCREATORBUG-27268 Change-Id: I3518a7693bf31ce6c48a12905b77713c591e1853 Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: Christian Stenger --- src/plugins/cppeditor/cppcodestylesnippets.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/cppeditor/cppcodestylesnippets.h b/src/plugins/cppeditor/cppcodestylesnippets.h index d58a728f233..83cb3555d54 100644 --- a/src/plugins/cppeditor/cppcodestylesnippets.h +++ b/src/plugins/cppeditor/cppcodestylesnippets.h @@ -135,6 +135,12 @@ static const char *DEFAULT_CODE_STYLE_SNIPPETS[] "private:\n" " int _a;\n" " };\n" + "enum class E\n" + "{\n" + " V1,\n" + " V2,\n" + " V3\n" + "};\n" "}\n" "}\n", "#include \"bar.h\"\n" From 6517e3bbe30ca92d0fb99d78c6ac5fd295e95944 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Jun 2022 13:31:25 +0200 Subject: [PATCH 008/100] Valgrind: Simplify connection setup It's static 1:1 nowadays. Change-Id: I0bdc62bda4aade6753b04c42d95fbbdf70c37386 Reviewed-by: Jarek Kobus Reviewed-by: --- src/plugins/valgrind/valgrindengine.cpp | 27 ++++++++++--------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp index a6a21e7dcb5..a1b2b9cd35e 100644 --- a/src/plugins/valgrind/valgrindengine.cpp +++ b/src/plugins/valgrind/valgrindengine.cpp @@ -61,6 +61,17 @@ ValgrindToolRunner::ValgrindToolRunner(RunControl *runControl) setSupportsReRunning(false); m_settings.fromMap(runControl->settingsData(ANALYZER_VALGRIND_SETTINGS)); + + connect(&m_runner, &ValgrindRunner::processOutputReceived, + this, &ValgrindToolRunner::receiveProcessOutput); + connect(&m_runner, &ValgrindRunner::valgrindExecuted, + this, [this](const QString &commandLine) { + appendMessage(commandLine, NormalMessageFormat); + }); + connect(&m_runner, &ValgrindRunner::processErrorReceived, + this, &ValgrindToolRunner::receiveProcessError); + connect(&m_runner, &ValgrindRunner::finished, + this, &ValgrindToolRunner::runnerFinished); } void ValgrindToolRunner::start() @@ -96,17 +107,6 @@ void ValgrindToolRunner::start() if (auto aspect = runControl()->aspect()) m_runner.setUseTerminal(aspect->useTerminal); - connect(&m_runner, &ValgrindRunner::processOutputReceived, - this, &ValgrindToolRunner::receiveProcessOutput); - connect(&m_runner, &ValgrindRunner::valgrindExecuted, - this, [this](const QString &commandLine) { - appendMessage(commandLine, NormalMessageFormat); - }); - connect(&m_runner, &ValgrindRunner::processErrorReceived, - this, &ValgrindToolRunner::receiveProcessError); - connect(&m_runner, &ValgrindRunner::finished, - this, &ValgrindToolRunner::runnerFinished); - if (!m_runner.start()) { m_progress.cancel(); reportFailure(); @@ -161,11 +161,6 @@ void ValgrindToolRunner::runnerFinished() m_progress.reportFinished(); - disconnect(&m_runner, &ValgrindRunner::processOutputReceived, - this, &ValgrindToolRunner::receiveProcessOutput); - disconnect(&m_runner, &ValgrindRunner::finished, - this, &ValgrindToolRunner::runnerFinished); - reportStopped(); } From eb411dfeb01e4ce9d824728bae9a483fe354c329 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Jun 2022 13:11:56 +0200 Subject: [PATCH 009/100] RemoteLinux: Fix rscync deploystep with multiple dirs This was quoting them into a single argument, failing if there was more than one. Change-Id: Idc099970f3b747918adf7559b95e749940aad11a Reviewed-by: Christian Kandeler --- src/plugins/remotelinux/rsyncdeploystep.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/remotelinux/rsyncdeploystep.cpp b/src/plugins/remotelinux/rsyncdeploystep.cpp index b4d9929d76b..bd17c575f7d 100644 --- a/src/plugins/remotelinux/rsyncdeploystep.cpp +++ b/src/plugins/remotelinux/rsyncdeploystep.cpp @@ -140,8 +140,8 @@ void RsyncDeployService::createRemoteDirectories() remoteDirs << file.m_target.parentDir().path(); remoteDirs.sort(); remoteDirs.removeDuplicates(); - m_mkdir.setCommand({deviceConfiguration()->filePath("mkdir"), - {"-p", ProcessArgs::createUnixArgs(remoteDirs).toString()}}); + + m_mkdir.setCommand({deviceConfiguration()->filePath("mkdir"), QStringList("-p") + remoteDirs}); m_mkdir.start(); } From 644b51a699c98fbcd47d89c59404e3b4f12d8a92 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Jun 2022 14:29:11 +0200 Subject: [PATCH 010/100] Utils: Add more correct comment to QtcProcess::cleanedStd{Out,Err} Change-Id: I50202db7d8455372c3697087d9571db6706b45a1 Reviewed-by: David Schulz Reviewed-by: Jarek Kobus --- src/libs/utils/qtcprocess.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h index 42c981a3431..8763bc14e26 100644 --- a/src/libs/utils/qtcprocess.h +++ b/src/libs/utils/qtcprocess.h @@ -189,8 +189,8 @@ public: QString stdOut() const; // possibly with CR QString stdErr() const; // possibly with CR - QString cleanedStdOut() const; // with CR removed - QString cleanedStdErr() const; // with CR removed + QString cleanedStdOut() const; // with sequences of CR squashed and CR LF replaced by LF + QString cleanedStdErr() const; // with sequences of CR squashed and CR LF replaced by LF const QStringList stdOutLines() const; // split, CR removed const QStringList stdErrLines() const; // split, CR removed From dcd3d9e71788953af3ee7cb4495805da19c62c34 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Jun 2022 15:49:36 +0200 Subject: [PATCH 011/100] Docker: Simplify (unused) settings page code Change-Id: I57496f1f3150b91681724878772227ef25b65789 Reviewed-by: Jarek Kobus Reviewed-by: --- src/plugins/docker/dockersettings.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/plugins/docker/dockersettings.cpp b/src/plugins/docker/dockersettings.cpp index fc28988e3ed..f9c615ed0ea 100644 --- a/src/plugins/docker/dockersettings.cpp +++ b/src/plugins/docker/dockersettings.cpp @@ -82,14 +82,9 @@ void DockerSettings::updateImageList() { QtcProcess process; process.setCommand({"docker", {"search", imageListFilter.value()}}); - - connect(&process, &QtcProcess::finished, this, [&process, this] { - const QString data = QString::fromUtf8(process.readAllStandardOutput()); - imageList.setValue(data); - }); - process.start(); process.waitForFinished(); + imageList.setValue(process.cleanedStdOut()); } void DockerSettings::readSettings(const QSettings *settings) From 153ff77a6b4f9b1a36d4c56d6349cde76664e754 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 17 Jun 2022 14:17:14 +0200 Subject: [PATCH 012/100] Utils: use cleaned stdout all over the place again Amends 5ee880ce5e6998170823e6fc9afb6b6c36c6170a Change-Id: Ie0202db7d8455372c3697087d9571db6706b45a1 Reviewed-by: hjk --- src/libs/utils/buildablehelperlibrary.cpp | 2 +- src/libs/utils/qtcprocess.cpp | 24 ++--- src/libs/utils/shellcommand.cpp | 8 +- src/plugins/android/androidbuildapkstep.cpp | 2 +- src/plugins/android/androidmanager.cpp | 4 +- src/plugins/android/androidsdkmanager.cpp | 2 +- src/plugins/bazaar/bazaarclient.cpp | 2 +- .../artisticstyle/artisticstylesettings.cpp | 6 +- src/plugins/boot2qt/qdbdevice.cpp | 4 +- src/plugins/clangtools/clangtoolrunner.cpp | 4 +- src/plugins/clangtools/executableinfo.cpp | 2 +- src/plugins/clearcase/clearcaseplugin.cpp | 4 +- src/plugins/cmakeprojectmanager/cmaketool.cpp | 10 +- src/plugins/cvs/cvsplugin.cpp | 4 +- src/plugins/debugger/gdb/gdbengine.cpp | 2 +- src/plugins/docker/dockerdevice.cpp | 8 +- src/plugins/git/changeselectiondialog.cpp | 2 +- src/plugins/git/gerrit/gerritserver.cpp | 8 +- src/plugins/git/gitclient.cpp | 98 +++++++++---------- src/plugins/ios/iosconfigurations.cpp | 2 +- src/plugins/ios/iosprobe.cpp | 2 +- src/plugins/ios/simulatorcontrol.cpp | 2 +- src/plugins/mercurial/mercurialclient.cpp | 14 +-- .../exewrappers/toolwrapper.cpp | 2 +- src/plugins/nim/project/nimblebuildsystem.cpp | 4 +- src/plugins/perforce/perforcechecker.cpp | 4 +- src/plugins/perforce/perforceplugin.cpp | 4 +- .../customwizardscriptgenerator.cpp | 4 +- .../devicesupport/sshdeviceprocesslist.cpp | 4 +- src/plugins/projectexplorer/gcctoolchain.cpp | 2 +- src/plugins/projectexplorer/msvctoolchain.cpp | 10 +- src/plugins/python/pythonsettings.cpp | 2 +- src/plugins/qnx/qnxutils.cpp | 2 +- src/plugins/qtsupport/baseqtversion.cpp | 2 +- .../genericdirectuploadservice.cpp | 2 +- src/plugins/remotelinux/linuxdevice.cpp | 2 +- src/plugins/remotelinux/linuxdevicetester.cpp | 2 +- .../remotelinux/publickeydeploymentdialog.cpp | 2 +- src/plugins/remotelinux/rsyncdeploystep.cpp | 2 +- .../findinfilessilversearcher.cpp | 4 +- src/plugins/subversion/subversionclient.cpp | 2 +- src/plugins/subversion/subversionplugin.cpp | 4 +- src/plugins/texteditor/formattexteditor.cpp | 2 +- .../texteditor/highlightersettings.cpp | 2 +- src/plugins/updateinfo/updateinfoplugin.cpp | 4 +- src/plugins/valgrind/valgrindrunner.cpp | 2 +- src/plugins/vcsbase/vcsbaseclient.cpp | 2 +- src/plugins/webassembly/webassemblyemsdk.cpp | 2 +- 48 files changed, 145 insertions(+), 145 deletions(-) diff --git a/src/libs/utils/buildablehelperlibrary.cpp b/src/libs/utils/buildablehelperlibrary.cpp index c1030fd5e78..a23ba678dcb 100644 --- a/src/libs/utils/buildablehelperlibrary.cpp +++ b/src/libs/utils/buildablehelperlibrary.cpp @@ -50,7 +50,7 @@ FilePath BuildableHelperLibrary::qtChooserToQmakePath(const FilePath &qtChooser) proc.runBlocking(); if (proc.result() != ProcessResult::FinishedWithSuccess) return {}; - const QString output = proc.stdOut(); + const QString output = proc.cleanedStdOut(); int pos = output.indexOf(toolDir); if (pos == -1) return {}; diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 925038086f4..5612b2c8197 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -1051,17 +1051,17 @@ QtcProcess::QtcProcess(QObject *parent) qCDebug(processLog).nospace() << "Process " << number << " finished: " << "result=" << int(result()) << ", ex=" << exitCode() - << ", " << stdOut().size() << " bytes stdout: " - << stdOut().left(20) - << ", " << stdErr().size() << " bytes stderr: " - << stdErr().left(1000) + << ", " << cleanedStdOut().size() << " bytes stdout: " + << cleanedStdOut().left(20) + << ", " << cleanedStdErr().size() << " bytes stderr: " + << cleanedStdErr().left(1000) << ", " << msElapsed << " ms elapsed"; - if (processStdoutLog().isDebugEnabled() && !stdOut().isEmpty()) + if (processStdoutLog().isDebugEnabled() && !cleanedStdOut().isEmpty()) qCDebug(processStdoutLog).nospace() - << "Process " << number << " sdout: " << stdOut(); - if (processStderrLog().isDebugEnabled() && !stdErr().isEmpty()) + << "Process " << number << " sdout: " << cleanedStdOut(); + if (processStderrLog().isDebugEnabled() && !cleanedStdErr().isEmpty()) qCDebug(processStderrLog).nospace() - << "Process " << number << " stderr: " << stdErr(); + << "Process " << number << " stderr: " << cleanedStdErr(); }); } } @@ -1691,8 +1691,8 @@ QString QtcProcess::allOutput() const { QTC_CHECK(d->m_stdOut.keepRawData); QTC_CHECK(d->m_stdErr.keepRawData); - const QString out = stdOut(); - const QString err = stdErr(); + const QString out = cleanedStdOut(); + const QString err = cleanedStdErr(); if (!out.isEmpty() && !err.isEmpty()) { QString result = out; @@ -1748,12 +1748,12 @@ static QStringList splitLines(const QString &text) const QStringList QtcProcess::stdOutLines() const { - return splitLines(stdOut()); + return splitLines(cleanedStdOut()); } const QStringList QtcProcess::stdErrLines() const { - return splitLines(stdErr()); + return splitLines(cleanedStdErr()); } QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug str, const QtcProcess &r) diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp index 6f8a49de019..81c293c8d99 100644 --- a/src/libs/utils/shellcommand.cpp +++ b/src/libs/utils/shellcommand.cpp @@ -271,8 +271,8 @@ void ShellCommand::run(QFutureInterface &future) proc.setExitCodeInterpreter(job.exitCodeInterpreter); proc.setTimeoutS(job.timeoutS); runCommand(proc, job.command, job.workingDirectory); - stdOut += proc.stdOut(); - stdErr += proc.stdErr(); + stdOut += proc.cleanedStdOut(); + stdErr += proc.cleanedStdErr(); d->m_lastExecExitCode = proc.exitCode(); d->m_lastExecSuccess = proc.result() == ProcessResult::FinishedWithSuccess; if (!d->m_lastExecSuccess) @@ -352,11 +352,11 @@ void ShellCommand::runFullySynchronous(QtcProcess &process, const FilePath &work process.runBlocking(); if (!d->m_aborted) { - const QString stdErr = process.stdErr(); + const QString stdErr = process.cleanedStdErr(); if (!stdErr.isEmpty() && !(d->m_flags & SuppressStdErr)) emit append(stdErr); - const QString stdOut = process.stdOut(); + const QString stdOut = process.cleanedStdOut(); if (!stdOut.isEmpty() && d->m_flags & ShowStdOut) { if (d->m_flags & SilentOutput) emit appendSilently(stdOut); diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index b53cf3b6f7a..17342ba9fb2 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -1065,7 +1065,7 @@ QAbstractItemModel *AndroidBuildApkStep::keystoreCertificates() if (keytoolProc.result() > ProcessResult::FinishedWithError) QMessageBox::critical(nullptr, tr("Error"), tr("Failed to run keytool.")); else - model = new CertificatesModel(keytoolProc.stdOut(), this); + model = new CertificatesModel(keytoolProc.cleanedStdOut(), this); return model; } diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 3dbee9e59a1..974e6c11638 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -787,8 +787,8 @@ SdkToolResult AndroidManager::runCommand(const CommandLine &command, qCDebug(androidManagerLog) << "Running command (sync):" << command.toUserOutput(); cmdProc.setCommand(command); cmdProc.runBlocking(EventLoopMode::On); - cmdResult.m_stdOut = cmdProc.stdOut().trimmed(); - cmdResult.m_stdErr = cmdProc.stdErr().trimmed(); + cmdResult.m_stdOut = cmdProc.cleanedStdOut().trimmed(); + cmdResult.m_stdErr = cmdProc.cleanedStdErr().trimmed(); cmdResult.m_success = cmdProc.result() == ProcessResult::FinishedWithSuccess; qCDebug(androidManagerLog) << "Command finshed (sync):" << command.toUserOutput() << "Success:" << cmdResult.m_success diff --git a/src/plugins/android/androidsdkmanager.cpp b/src/plugins/android/androidsdkmanager.cpp index 628f245c349..960509e827c 100644 --- a/src/plugins/android/androidsdkmanager.cpp +++ b/src/plugins/android/androidsdkmanager.cpp @@ -186,7 +186,7 @@ static void sdkManagerCommand(const AndroidConfig &config, const QStringList &ar proc.runBlocking(EventLoopMode::On); if (assertionFound) { output.success = false; - output.stdOutput = proc.stdOut(); + output.stdOutput = proc.cleanedStdOut(); output.stdError = QCoreApplication::translate("Android::Internal::AndroidSdkManager", "The operation requires user interaction. " "Use the \"sdkmanager\" command-line tool."); diff --git a/src/plugins/bazaar/bazaarclient.cpp b/src/plugins/bazaar/bazaarclient.cpp index 3265905531f..ccd91a236f2 100644 --- a/src/plugins/bazaar/bazaarclient.cpp +++ b/src/plugins/bazaar/bazaarclient.cpp @@ -153,7 +153,7 @@ bool BazaarClient::synchronousUncommit(const FilePath &workingDir, QtcProcess proc; vcsFullySynchronousExec(proc, workingDir, args); - VcsOutputWindow::append(proc.stdOut()); + VcsOutputWindow::append(proc.cleanedStdOut()); return proc.result() == ProcessResult::FinishedWithSuccess; } diff --git a/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp b/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp index ed6d0b91590..a47fdda1011 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp +++ b/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp @@ -92,10 +92,10 @@ static int updateVersionHelper(const FilePath &command) return 0; // Astyle prints the version on stdout or stderr, depending on platform - const int version = parseVersion(process.stdOut().trimmed()); + const int version = parseVersion(process.cleanedStdOut().trimmed()); if (version != 0) return version; - return parseVersion(process.stdErr().trimmed()); + return parseVersion(process.cleanedStdErr().trimmed()); } void ArtisticStyleSettings::updateVersion() @@ -204,7 +204,7 @@ void ArtisticStyleSettings::createDocumentationFile() const stream.writeStartElement(Constants::DOCUMENTATION_XMLROOT); // astyle writes its output to 'error'... - const QStringList lines = process.stdErr().split(QLatin1Char('\n')); + const QStringList lines = process.cleanedStdErr().split(QLatin1Char('\n')); QStringList keys; QStringList docu; for (QString line : lines) { diff --git a/src/plugins/boot2qt/qdbdevice.cpp b/src/plugins/boot2qt/qdbdevice.cpp index f6c3f6312d7..8017a39a1e6 100644 --- a/src/plugins/boot2qt/qdbdevice.cpp +++ b/src/plugins/boot2qt/qdbdevice.cpp @@ -88,8 +88,8 @@ public: private: void handleDone() { - const QString stdOut = m_appRunner.stdOut(); - const QString stdErr = m_appRunner.stdErr(); + const QString stdOut = m_appRunner.cleanedStdOut(); + const QString stdErr = m_appRunner.cleanedStdErr(); // FIXME: Needed in a post-adb world? // adb does not forward exit codes and all stderr goes to stdout. diff --git a/src/plugins/clangtools/clangtoolrunner.cpp b/src/plugins/clangtools/clangtoolrunner.cpp index c602203a24d..12fe0aede06 100644 --- a/src/plugins/clangtools/clangtoolrunner.cpp +++ b/src/plugins/clangtools/clangtoolrunner.cpp @@ -132,7 +132,7 @@ void ClangToolRunner::onProcessDone() if (m_process.result() == ProcessResult::StartFailed) { emit finishedWithFailure(generalProcessError(m_name), commandlineAndOutput()); } else if (m_process.result() == ProcessResult::FinishedWithSuccess) { - qCDebug(LOG).noquote() << "Output:\n" << m_process.stdOut(); + qCDebug(LOG).noquote() << "Output:\n" << m_process.cleanedStdOut(); emit finishedWithSuccess(m_fileToAnalyze); } else if (m_process.result() == ProcessResult::FinishedWithError) { emit finishedWithFailure(finishedWithBadExitCode(m_name, m_process.exitCode()), @@ -149,7 +149,7 @@ QString ClangToolRunner::commandlineAndOutput() const "Output:\n%3") .arg(m_commandLine.toUserOutput()) .arg(m_process.error()) - .arg(m_process.stdOut()); + .arg(m_process.cleanedStdOut()); } } // namespace Internal diff --git a/src/plugins/clangtools/executableinfo.cpp b/src/plugins/clangtools/executableinfo.cpp index 9277e54df9f..f27d4aef8b5 100644 --- a/src/plugins/clangtools/executableinfo.cpp +++ b/src/plugins/clangtools/executableinfo.cpp @@ -63,7 +63,7 @@ static QString runExecutable(const Utils::CommandLine &commandLine, QueryFailMod return {}; } - return cpp.stdOut(); + return cpp.cleanedStdOut(); } static QStringList queryClangTidyChecks(const FilePath &executable, diff --git a/src/plugins/clearcase/clearcaseplugin.cpp b/src/plugins/clearcase/clearcaseplugin.cpp index bd6786ed49c..7450ad9ff76 100644 --- a/src/plugins/clearcase/clearcaseplugin.cpp +++ b/src/plugins/clearcase/clearcaseplugin.cpp @@ -1676,8 +1676,8 @@ ClearCasePluginPrivate::runCleartool(const FilePath &workingDir, response.error = proc.result() != ProcessResult::FinishedWithSuccess; if (response.error) response.message = proc.exitMessage(); - response.stdErr = proc.stdErr(); - response.stdOut = proc.stdOut(); + response.stdErr = proc.cleanedStdErr(); + response.stdOut = proc.cleanedStdOut(); return response; } diff --git a/src/plugins/cmakeprojectmanager/cmaketool.cpp b/src/plugins/cmakeprojectmanager/cmaketool.cpp index 482c2d05a38..c5804f039b8 100644 --- a/src/plugins/cmakeprojectmanager/cmaketool.cpp +++ b/src/plugins/cmakeprojectmanager/cmaketool.cpp @@ -280,19 +280,19 @@ TextEditor::Keywords CMakeTool::keywords() QtcProcess proc; runCMake(proc, {"--help-command-list"}, 5); if (proc.result() == ProcessResult::FinishedWithSuccess) - m_introspection->m_functions = proc.stdOut().split('\n'); + m_introspection->m_functions = proc.cleanedStdOut().split('\n'); runCMake(proc, {"--help-commands"}, 5); if (proc.result() == ProcessResult::FinishedWithSuccess) - parseFunctionDetailsOutput(proc.stdOut()); + parseFunctionDetailsOutput(proc.cleanedStdOut()); runCMake(proc, {"--help-property-list"}, 5); if (proc.result() == ProcessResult::FinishedWithSuccess) - m_introspection->m_variables = parseVariableOutput(proc.stdOut()); + m_introspection->m_variables = parseVariableOutput(proc.cleanedStdOut()); runCMake(proc, {"--help-variable-list"}, 5); if (proc.result() == ProcessResult::FinishedWithSuccess) { - m_introspection->m_variables.append(parseVariableOutput(proc.stdOut())); + m_introspection->m_variables.append(parseVariableOutput(proc.cleanedStdOut())); m_introspection->m_variables = Utils::filteredUnique(m_introspection->m_variables); Utils::sort(m_introspection->m_variables); } @@ -523,7 +523,7 @@ void CMakeTool::fetchFromCapabilities() const if (cmake.result() == ProcessResult::FinishedWithSuccess) { m_introspection->m_didRun = true; - parseFromCapabilities(cmake.stdOut()); + parseFromCapabilities(cmake.cleanedStdOut()); } else { qCCritical(cmakeToolLog) << "Fetching capabilities failed: " << cmake.allOutput() << cmake.error(); m_introspection->m_didRun = false; diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 8b3210a9e0a..e004f6cd886 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -1449,8 +1449,8 @@ CvsResponse CvsPluginPrivate::runCvs(const FilePath &workingDirectory, command.runCommand(proc, {executable, m_settings.addOptions(arguments)}); response.result = CvsResponse::OtherError; - response.stdErr = proc.stdErr(); - response.stdOut = proc.stdOut(); + response.stdErr = proc.cleanedStdErr(); + response.stdOut = proc.cleanedStdOut(); switch (proc.result()) { case ProcessResult::FinishedWithSuccess: response.result = CvsResponse::Ok; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index bf62f52c829..1fd3aef4aad 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -5004,7 +5004,7 @@ CoreInfo CoreInfo::readExecutableNameFromCore(const Runnable &debugger, const Fi proc.runBlocking(); if (proc.result() == ProcessResult::FinishedWithSuccess) { - QString output = proc.stdOut(); + QString output = proc.cleanedStdOut(); // Core was generated by `/data/dev/creator-2.6/bin/qtcreator'. // Program terminated with signal 11, Segmentation fault. int pos1 = output.indexOf("Core was generated by"); diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index ca6d87e36fb..888884b3a19 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -444,7 +444,7 @@ void DockerDevicePrivate::startContainer() if (createProcess.result() != ProcessResult::FinishedWithSuccess) return; - m_container = createProcess.stdOut().trimmed(); + m_container = createProcess.cleanedStdOut().trimmed(); if (m_container.isEmpty()) return; LOG("Container via process: " << m_container); @@ -988,11 +988,11 @@ void DockerDevicePrivate::fetchSystemEnviroment() proc.setCommand(q->withDockerExecCmd({"env", {}})); proc.start(); proc.waitForFinished(); - const QString remoteOutput = proc.stdOut(); + const QString remoteOutput = proc.cleanedStdOut(); m_cachedEnviroment = Environment(remoteOutput.split('\n', Qt::SkipEmptyParts), q->osType()); - const QString remoteError = proc.stdErr(); + const QString remoteError = proc.cleanedStdErr(); if (!remoteError.isEmpty()) qWarning("Cannot read container environment: %s\n", qPrintable(remoteError)); } @@ -1126,7 +1126,7 @@ public: }); connect(m_process, &Utils::QtcProcess::readyReadStandardError, this, [this] { - const QString out = DockerDevice::tr("Error: %1").arg(m_process->stdErr()); + const QString out = DockerDevice::tr("Error: %1").arg(m_process->cleanedStdErr()); m_log->append(DockerDevice::tr("Error: %1").arg(out)); }); diff --git a/src/plugins/git/changeselectiondialog.cpp b/src/plugins/git/changeselectiondialog.cpp index a32047d7f87..57bd97c1d98 100644 --- a/src/plugins/git/changeselectiondialog.cpp +++ b/src/plugins/git/changeselectiondialog.cpp @@ -162,7 +162,7 @@ void ChangeSelectionDialog::setDetails() QPalette palette; if (m_process->result() == ProcessResult::FinishedWithSuccess) { - m_ui->detailsText->setPlainText(m_process->stdOut()); + m_ui->detailsText->setPlainText(m_process->cleanedStdOut()); palette.setColor(QPalette::Text, theme->color(Theme::TextColorNormal)); m_ui->changeNumberEdit->setPalette(palette); } else { diff --git a/src/plugins/git/gerrit/gerritserver.cpp b/src/plugins/git/gerrit/gerritserver.cpp index 4ddbcfd1363..7fc9ae4c7ef 100644 --- a/src/plugins/git/gerrit/gerritserver.cpp +++ b/src/plugins/git/gerrit/gerritserver.cpp @@ -247,7 +247,7 @@ int GerritServer::testConnection() client->vcsFullySynchronousExec(proc, {}, {curlBinary, arguments}, Core::ShellCommand::NoOutput); if (proc.result() == ProcessResult::FinishedWithSuccess) { - QString output = proc.stdOut(); + QString output = proc.cleanedStdOut(); // Gerrit returns an empty response for /p/qt-creator/a/accounts/self // so consider this as 404. if (output.isEmpty()) @@ -266,7 +266,7 @@ int GerritServer::testConnection() if (proc.exitCode() == CertificateError) return CertificateError; const QRegularExpression errorRegexp("returned error: (\\d+)"); - QRegularExpressionMatch match = errorRegexp.match(proc.stdErr()); + QRegularExpressionMatch match = errorRegexp.match(proc.cleanedStdErr()); if (match.hasMatch()) return match.captured(1).toInt(); return UnknownError; @@ -346,7 +346,7 @@ bool GerritServer::resolveVersion(const GerritParameters &p, bool forceReload) arguments << p.portFlag << QString::number(port); arguments << hostArgument() << "gerrit" << "version"; client->vcsFullySynchronousExec(proc, {}, {p.ssh, arguments}, Core::ShellCommand::NoOutput); - QString stdOut = proc.stdOut().trimmed(); + QString stdOut = proc.cleanedStdOut().trimmed(); stdOut.remove("gerrit version "); version = stdOut; if (version.isEmpty()) @@ -359,7 +359,7 @@ bool GerritServer::resolveVersion(const GerritParameters &p, bool forceReload) // REST endpoint for version is only available from 2.8 and up. Do not consider invalid // if it fails. if (proc.result() == ProcessResult::FinishedWithSuccess) { - QString output = proc.stdOut(); + QString output = proc.cleanedStdOut(); if (output.isEmpty()) return false; output.remove(0, output.indexOf('\n')); // Strip first line diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 4d42372c72b..4b3b59a06d6 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -761,8 +761,8 @@ public: // No conflicts => do nothing if (proc.result() == ProcessResult::FinishedWithSuccess) return; - handler.readStdOut(proc.stdOut()); - handler.readStdErr(proc.stdErr()); + handler.readStdOut(proc.cleanedStdOut()); + handler.readStdErr(proc.cleanedStdErr()); } private: @@ -944,7 +944,7 @@ FilePaths GitClient::unmanagedFiles(const FilePaths &filePaths) const if (proc.result() != ProcessResult::FinishedWithSuccess) return filePaths; const QStringList managedFilePaths - = transform(proc.stdOut().split('\0', Qt::SkipEmptyParts), + = transform(proc.cleanedStdOut().split('\0', Qt::SkipEmptyParts), [&wd](const QString &fp) { return wd.absoluteFilePath(fp); }); const QStringList filtered = Utils::filtered(it.value(), [&managedFilePaths, &wd](const QString &fp) { return !managedFilePaths.contains(wd.absoluteFilePath(fp)); @@ -1515,7 +1515,7 @@ void GitClient::recoverDeletedFiles(const FilePath &workingDirectory) vcsFullySynchronousExec(proc, workingDirectory, {"ls-files", "--deleted"}, VcsCommand::SuppressCommandLogging); if (proc.result() == ProcessResult::FinishedWithSuccess) { - const QString stdOut = proc.stdOut().trimmed(); + const QString stdOut = proc.cleanedStdOut().trimmed(); if (stdOut.isEmpty()) { VcsOutputWindow::appendError(tr("Nothing to recover")); return; @@ -1542,11 +1542,11 @@ bool GitClient::synchronousLog(const FilePath &workingDirectory, const QStringLi vcsFullySynchronousExec(proc, workingDirectory, allArguments, flags, vcsTimeoutS(), encoding(workingDirectory, "i18n.logOutputEncoding")); if (proc.result() == ProcessResult::FinishedWithSuccess) { - *output = proc.stdOut(); + *output = proc.cleanedStdOut(); return true; } else { msgCannotRun(tr("Cannot obtain log of \"%1\": %2") - .arg(workingDirectory.toUserOutput(), proc.stdErr()), errorMessageIn); + .arg(workingDirectory.toUserOutput(), proc.cleanedStdErr()), errorMessageIn); return false; } } @@ -1596,7 +1596,7 @@ bool GitClient::synchronousReset(const FilePath &workingDirectory, QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, arguments); - const QString stdOut = proc.stdOut(); + const QString stdOut = proc.cleanedStdOut(); VcsOutputWindow::append(stdOut); // Note that git exits with 1 even if the operation is successful // Assume real failure if the output does not contain "foo.cpp modified" @@ -1604,10 +1604,10 @@ bool GitClient::synchronousReset(const FilePath &workingDirectory, if (proc.result() != ProcessResult::FinishedWithSuccess && (!stdOut.contains("modified") && !stdOut.contains("Unstaged changes after reset"))) { if (files.isEmpty()) { - msgCannotRun(arguments, workingDirectory, proc.stdErr(), errorMessage); + msgCannotRun(arguments, workingDirectory, proc.cleanedStdErr(), errorMessage); } else { msgCannotRun(tr("Cannot reset %n files in \"%1\": %2", nullptr, files.size()) - .arg(workingDirectory.toUserOutput(), proc.stdErr()), + .arg(workingDirectory.toUserOutput(), proc.cleanedStdErr()), errorMessage); } return false; @@ -1621,7 +1621,7 @@ bool GitClient::synchronousInit(const FilePath &workingDirectory) QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, QStringList{"init"}); // '[Re]Initialized...' - VcsOutputWindow::append(proc.stdOut()); + VcsOutputWindow::append(proc.cleanedStdOut()); if (proc.result() == ProcessResult::FinishedWithSuccess) { resetCachedVcsInfo(workingDirectory); return true; @@ -1653,7 +1653,7 @@ bool GitClient::synchronousCheckoutFiles(const FilePath &workingDirectory, QStri //: Meaning of the arguments: %1: revision, %2: files, %3: repository, //: %4: Error message msgCannotRun(tr("Cannot checkout \"%1\" of %2 in \"%3\": %4") - .arg(revision, fileArg, workingDirectory.toUserOutput(), proc.stdErr()), + .arg(revision, fileArg, workingDirectory.toUserOutput(), proc.cleanedStdErr()), errorMessage); return false; } @@ -1701,10 +1701,10 @@ bool GitClient::synchronousRevListCmd(const FilePath &workingDirectory, const QS QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, arguments, silentFlags); if (proc.result() != ProcessResult::FinishedWithSuccess) { - msgCannotRun(arguments, workingDirectory, proc.stdErr(), errorMessage); + msgCannotRun(arguments, workingDirectory, proc.cleanedStdErr(), errorMessage); return false; } - *output = proc.stdOut(); + *output = proc.cleanedStdOut(); return true; } @@ -1765,7 +1765,7 @@ QString GitClient::synchronousCurrentLocalBranch(const FilePath &workingDirector QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, {"symbolic-ref", HEAD}, silentFlags); if (proc.result() == ProcessResult::FinishedWithSuccess) { - branch = proc.stdOut().trimmed(); + branch = proc.cleanedStdOut().trimmed(); } else { const QString gitDir = findGitDirForRepository(workingDirectory); const QString rebaseHead = gitDir + "/rebase-merge/head-name"; @@ -1790,11 +1790,11 @@ bool GitClient::synchronousHeadRefs(const FilePath &workingDirectory, QStringLis QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, arguments, silentFlags); if (proc.result() != ProcessResult::FinishedWithSuccess) { - msgCannotRun(arguments, workingDirectory, proc.stdErr(), errorMessage); + msgCannotRun(arguments, workingDirectory, proc.cleanedStdErr(), errorMessage); return false; } - const QString stdOut = proc.stdOut(); + const QString stdOut = proc.cleanedStdOut(); const QString headSha = stdOut.left(10); QString rest = stdOut.mid(15); @@ -1839,7 +1839,7 @@ QString GitClient::synchronousTopic(const FilePath &workingDirectory) const QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, QStringList{"describe"}, VcsCommand::NoOutput); if (proc.result() == ProcessResult::FinishedWithSuccess) { - const QString stdOut = proc.stdOut().trimmed(); + const QString stdOut = proc.cleanedStdOut().trimmed(); if (!stdOut.isEmpty()) return stdOut; } @@ -1852,9 +1852,9 @@ bool GitClient::synchronousRevParseCmd(const FilePath &workingDirectory, const Q const QStringList arguments = {"rev-parse", ref}; QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, arguments, silentFlags); - *output = proc.stdOut().trimmed(); + *output = proc.cleanedStdOut().trimmed(); if (proc.result() != ProcessResult::FinishedWithSuccess) { - msgCannotRun(arguments, workingDirectory, proc.stdErr(), errorMessage); + msgCannotRun(arguments, workingDirectory, proc.cleanedStdErr(), errorMessage); return false; } @@ -1869,7 +1869,7 @@ QString GitClient::synchronousTopRevision(const FilePath &workingDirectory, QDat vcsFullySynchronousExec(proc, workingDirectory, arguments, silentFlags); if (proc.result() != ProcessResult::FinishedWithSuccess) return QString(); - const QStringList output = proc.stdOut().trimmed().split(':'); + const QStringList output = proc.cleanedStdOut().trimmed().split(':'); if (dateTime && output.size() > 1) { bool ok = false; const qint64 timeT = output.at(1).toLongLong(&ok); @@ -1889,7 +1889,7 @@ bool GitClient::isFastForwardMerge(const FilePath &workingDirectory, const QStri { QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, {"merge-base", HEAD, branch}, silentFlags); - return proc.stdOut().trimmed() == synchronousTopRevision(workingDirectory); + return proc.cleanedStdOut().trimmed() == synchronousTopRevision(workingDirectory); } // Format an entry in a one-liner for selection list using git log. @@ -1902,10 +1902,10 @@ QString GitClient::synchronousShortDescription(const FilePath &workingDirectory, vcsFullySynchronousExec(proc, workingDirectory, arguments, silentFlags); if (proc.result() != ProcessResult::FinishedWithSuccess) { VcsOutputWindow::appendSilently(tr("Cannot describe revision \"%1\" in \"%2\": %3") - .arg(revision, workingDirectory.toUserOutput(), proc.stdErr())); + .arg(revision, workingDirectory.toUserOutput(), proc.cleanedStdErr())); return revision; } - return stripLastNewline(proc.stdOut()); + return stripLastNewline(proc.cleanedStdOut()); } // Create a default message to be used for describing stashes @@ -1982,7 +1982,7 @@ bool GitClient::executeSynchronousStash(const FilePath &workingDirectory, QtcProcess proc; vcsSynchronousExec(proc, workingDirectory, arguments, flags); if (proc.result() != ProcessResult::FinishedWithSuccess) { - msgCannotRun(arguments, workingDirectory, proc.stdErr(), errorMessage); + msgCannotRun(arguments, workingDirectory, proc.cleanedStdErr(), errorMessage); return false; } @@ -2021,9 +2021,9 @@ bool GitClient::synchronousBranchCmd(const FilePath &workingDirectory, QStringLi branchArgs.push_front("branch"); QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, branchArgs); - *output = proc.stdOut(); + *output = proc.cleanedStdOut(); if (proc.result() != ProcessResult::FinishedWithSuccess) { - msgCannotRun(branchArgs, workingDirectory, proc.stdErr(), errorMessage); + msgCannotRun(branchArgs, workingDirectory, proc.cleanedStdErr(), errorMessage); return false; } return true; @@ -2035,9 +2035,9 @@ bool GitClient::synchronousTagCmd(const FilePath &workingDirectory, QStringList tagArgs.push_front("tag"); QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, tagArgs); - *output = proc.stdOut(); + *output = proc.cleanedStdOut(); if (proc.result() != ProcessResult::FinishedWithSuccess) { - msgCannotRun(tagArgs, workingDirectory, proc.stdErr(), errorMessage); + msgCannotRun(tagArgs, workingDirectory, proc.cleanedStdErr(), errorMessage); return false; } return true; @@ -2049,9 +2049,9 @@ bool GitClient::synchronousForEachRefCmd(const FilePath &workingDirectory, QStri args.push_front("for-each-ref"); QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, args, silentFlags); - *output = proc.stdOut(); + *output = proc.cleanedStdOut(); if (proc.result() != ProcessResult::FinishedWithSuccess) { - msgCannotRun(args, workingDirectory, proc.stdErr(), errorMessage); + msgCannotRun(args, workingDirectory, proc.cleanedStdErr(), errorMessage); return false; } return true; @@ -2070,9 +2070,9 @@ bool GitClient::synchronousRemoteCmd(const FilePath &workingDirectory, QStringLi QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, remoteArgs, silent ? silentFlags : 0); - const QString stdErr = proc.stdErr(); + const QString stdErr = proc.cleanedStdErr(); *errorMessage = stdErr; - *output = proc.stdOut(); + *output = proc.cleanedStdOut(); if (proc.result() != ProcessResult::FinishedWithSuccess) { msgCannotRun(remoteArgs, workingDirectory, stdErr, errorMessage); @@ -2116,10 +2116,10 @@ QStringList GitClient::synchronousSubmoduleStatus(const FilePath &workingDirecto if (proc.result() != ProcessResult::FinishedWithSuccess) { msgCannotRun(tr("Cannot retrieve submodule status of \"%1\": %2") - .arg(workingDirectory.toUserOutput(), proc.stdErr()), errorMessage); + .arg(workingDirectory.toUserOutput(), proc.cleanedStdErr()), errorMessage); return QStringList(); } - return splitLines(proc.stdOut()); + return splitLines(proc.cleanedStdOut()); } SubmoduleDataMap GitClient::submoduleList(const FilePath &workingDirectory) const @@ -2195,7 +2195,7 @@ QByteArray GitClient::synchronousShow(const FilePath &workingDirectory, const QS QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, arguments, flags); if (proc.result() != ProcessResult::FinishedWithSuccess) { - msgCannotRun(arguments, workingDirectory, proc.stdErr(), nullptr); + msgCannotRun(arguments, workingDirectory, proc.cleanedStdErr(), nullptr); return {}; } return proc.rawStdOut(); @@ -2211,7 +2211,7 @@ bool GitClient::cleanList(const FilePath &workingDirectory, const QString &modul QtcProcess proc; vcsFullySynchronousExec(proc, directory, arguments, VcsCommand::ForceCLocale); if (proc.result() != ProcessResult::FinishedWithSuccess) { - msgCannotRun(arguments, directory, proc.stdErr(), errorMessage); + msgCannotRun(arguments, directory, proc.cleanedStdErr(), errorMessage); return false; } @@ -2219,7 +2219,7 @@ bool GitClient::cleanList(const FilePath &workingDirectory, const QString &modul const QString relativeBase = modulePath.isEmpty() ? QString() : modulePath + '/'; const QString prefix = "Would remove "; const QStringList removeLines = Utils::filtered( - splitLines(proc.stdOut()), [](const QString &s) { + splitLines(proc.cleanedStdOut()), [](const QString &s) { return s.startsWith("Would remove "); }); *files = Utils::transform(removeLines, [&relativeBase, &prefix](const QString &s) -> QString { @@ -2257,7 +2257,7 @@ bool GitClient::synchronousApplyPatch(const FilePath &workingDirectory, QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, arguments); - const QString stdErr = proc.stdErr(); + const QString stdErr = proc.cleanedStdErr(); if (proc.result() == ProcessResult::FinishedWithSuccess) { if (!stdErr.isEmpty()) *errorMessage = tr("There were warnings while applying \"%1\" to \"%2\":\n%3") @@ -2394,7 +2394,7 @@ GitClient::StatusResult GitClient::gitStatus(const FilePath &workingDirectory, S QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, arguments, silentFlags); - const QString stdOut = proc.stdOut(); + const QString stdOut = proc.cleanedStdOut(); if (output) *output = stdOut; @@ -2404,7 +2404,7 @@ GitClient::StatusResult GitClient::gitStatus(const FilePath &workingDirectory, S // Is it something really fatal? if (!statusRc && !branchKnown) { if (errorMessage) { - *errorMessage = tr("Cannot obtain status: %1").arg(proc.stdErr()); + *errorMessage = tr("Cannot obtain status: %1").arg(proc.cleanedStdErr()); } return StatusFailed; } @@ -2547,7 +2547,7 @@ QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryUR // split "82bfad2f51d34e98b18982211c82220b8db049brefs/heads/master" bool headFound = false; bool branchFound = false; - const QStringList lines = proc.stdOut().split('\n'); + const QStringList lines = proc.cleanedStdOut().split('\n'); for (const QString &line : lines) { if (line.endsWith("\tHEAD")) { QTC_CHECK(headSha.isNull()); @@ -3179,7 +3179,7 @@ void GitClient::synchronousAbortCommand(const FilePath &workingDir, const QStrin QtcProcess proc; vcsFullySynchronousExec(proc, workingDir, {abortCommand, "--abort"}, VcsCommand::ExpectRepoChanges | VcsCommand::ShowSuccessMessage); - VcsOutputWindow::append(proc.stdOut()); + VcsOutputWindow::append(proc.cleanedStdOut()); } QString GitClient::synchronousTrackingBranch(const FilePath &workingDirectory, const QString &branch) @@ -3529,12 +3529,12 @@ bool GitClient::synchronousStashRemove(const FilePath &workingDirectory, const Q QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, arguments); if (proc.result() == ProcessResult::FinishedWithSuccess) { - const QString output = proc.stdOut(); + const QString output = proc.cleanedStdOut(); if (!output.isEmpty()) VcsOutputWindow::append(output); return true; } else { - msgCannotRun(arguments, workingDirectory, proc.stdErr(), errorMessage); + msgCannotRun(arguments, workingDirectory, proc.cleanedStdErr(), errorMessage); return false; } } @@ -3548,11 +3548,11 @@ bool GitClient::synchronousStashList(const FilePath &workingDirectory, QListpush_back(stash); @@ -3589,7 +3589,7 @@ QString GitClient::readOneLine(const FilePath &workingDirectory, const QStringLi vcsFullySynchronousExec(proc, workingDirectory, arguments, silentFlags, vcsTimeoutS(), codec); if (proc.result() != ProcessResult::FinishedWithSuccess) return QString(); - return proc.stdOut().trimmed(); + return proc.cleanedStdOut().trimmed(); } // determine version as '(major << 16) + (minor << 8) + patch' or 0. @@ -3615,13 +3615,13 @@ unsigned GitClient::synchronousGitVersion(QString *errorMessage) const QtcProcess proc; vcsSynchronousExec(proc, {}, {"--version"}, silentFlags); if (proc.result() != ProcessResult::FinishedWithSuccess) { - msgCannotRun(tr("Cannot determine Git version: %1").arg(proc.stdErr()), errorMessage); + msgCannotRun(tr("Cannot determine Git version: %1").arg(proc.cleanedStdErr()), errorMessage); return 0; } // cut 'git version 1.6.5.1.sha' // another form: 'git version 1.9.rc1' - const QString output = proc.stdOut(); + const QString output = proc.cleanedStdOut(); const QRegularExpression versionPattern("^[^\\d]+(\\d+)\\.(\\d+)\\.(\\d+|rc\\d).*$"); QTC_ASSERT(versionPattern.isValid(), return 0); const QRegularExpressionMatch match = versionPattern.match(output); diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index 13942365ccd..41af86aa03e 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -238,7 +238,7 @@ static QByteArray decodeProvisioningProfile(const QString &path) p.runBlocking(); if (p.result() != ProcessResult::FinishedWithSuccess) qCDebug(iosCommonLog) << "Reading signed provisioning file failed" << path; - return p.stdOut().toLatin1(); + return p.cleanedStdOut().toLatin1(); } void IosConfigurations::updateAutomaticKitList() diff --git a/src/plugins/ios/iosprobe.cpp b/src/plugins/ios/iosprobe.cpp index 49ae0a7cd20..4f09f556a07 100644 --- a/src/plugins/ios/iosprobe.cpp +++ b/src/plugins/ios/iosprobe.cpp @@ -72,7 +72,7 @@ void XcodeProbe::detectDeveloperPaths() qCWarning(probeLog) << QString::fromLatin1("Could not detect selected Xcode using xcode-select"); else - addDeveloperPath(selectedXcode.stdOut().trimmed()); + addDeveloperPath(selectedXcode.cleanedStdOut().trimmed()); addDeveloperPath(defaultDeveloperPath); } diff --git a/src/plugins/ios/simulatorcontrol.cpp b/src/plugins/ios/simulatorcontrol.cpp index 0334e11218c..d4b154a0c9e 100644 --- a/src/plugins/ios/simulatorcontrol.cpp +++ b/src/plugins/ios/simulatorcontrol.cpp @@ -85,7 +85,7 @@ static bool runCommand(const CommandLine &command, QString *stdOutput, QString * p.setCommand(command); p.runBlocking(); if (stdOutput) - *stdOutput = p.stdOut(); + *stdOutput = p.cleanedStdOut(); if (allOutput) *allOutput = p.allOutput(); return p.result() == ProcessResult::FinishedWithSuccess; diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index c4d7f89abb3..ddf930ba1c6 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -103,7 +103,7 @@ bool MercurialClient::manifestSync(const FilePath &repository, const QString &re const QDir repositoryDir(repository.toString()); const QFileInfo needle = QFileInfo(repositoryDir, relativeFilename); - const QStringList files = proc.stdOut().split(QLatin1Char('\n')); + const QStringList files = proc.cleanedStdOut().split(QLatin1Char('\n')); for (const QString &fileName : files) { const QFileInfo managedFile(repositoryDir, fileName); if (needle == managedFile) @@ -186,7 +186,7 @@ bool MercurialClient::synchronousPull(const FilePath &workingDir, const QString const bool ok = proc.result() == ProcessResult::FinishedWithSuccess; - parsePullOutput(proc.stdOut().trimmed()); + parsePullOutput(proc.cleanedStdOut().trimmed()); return ok; } @@ -232,16 +232,16 @@ changeset: 0:031a48610fba user: ... \endcode */ // Obtain first line and split by blank-delimited tokens - const QStringList lines = proc.stdOut().split(QLatin1Char('\n')); + const QStringList lines = proc.cleanedStdOut().split(QLatin1Char('\n')); if (lines.size() < 1) { VcsOutputWindow::appendSilently( - msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(proc.stdOut()))); + msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(proc.cleanedStdOut()))); return QStringList(); } QStringList changeSets = lines.front().simplified().split(QLatin1Char(' ')); if (changeSets.size() < 2) { VcsOutputWindow::appendSilently( - msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(proc.stdOut()))); + msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(proc.cleanedStdOut()))); return QStringList(); } // Remove revision numbers @@ -270,7 +270,7 @@ QString MercurialClient::shortDescriptionSync(const FilePath &workingDirectory, vcsFullySynchronousExec(proc, workingDirectory, args); if (proc.result() != ProcessResult::FinishedWithSuccess) return revision; - return stripLastNewline(proc.stdOut()); + return stripLastNewline(proc.cleanedStdOut()); } // Default format: "SHA1 (author summmary)" @@ -288,7 +288,7 @@ bool MercurialClient::managesFile(const FilePath &workingDirectory, const QStrin args << QLatin1String("status") << QLatin1String("--unknown") << fileName; QtcProcess proc; vcsFullySynchronousExec(proc, workingDirectory, args); - return proc.stdOut().isEmpty(); + return proc.cleanedStdOut().isEmpty(); } void MercurialClient::incoming(const FilePath &repositoryRoot, const QString &repository) diff --git a/src/plugins/mesonprojectmanager/exewrappers/toolwrapper.cpp b/src/plugins/mesonprojectmanager/exewrappers/toolwrapper.cpp index d13175f5f4f..48579c8d074 100644 --- a/src/plugins/mesonprojectmanager/exewrappers/toolwrapper.cpp +++ b/src/plugins/mesonprojectmanager/exewrappers/toolwrapper.cpp @@ -66,7 +66,7 @@ Version ToolWrapper::read_version(const Utils::FilePath &toolPath) process.setCommand({ toolPath, { "--version" } }); process.start(); if (process.waitForFinished()) - return Version::fromString(process.stdOut()); + return Version::fromString(process.cleanedStdOut()); } return {}; } diff --git a/src/plugins/nim/project/nimblebuildsystem.cpp b/src/plugins/nim/project/nimblebuildsystem.cpp index 7a2a642eebc..634012cb42f 100644 --- a/src/plugins/nim/project/nimblebuildsystem.cpp +++ b/src/plugins/nim/project/nimblebuildsystem.cpp @@ -63,7 +63,7 @@ static std::vector parseTasks(const FilePath &nimblePath, const File std::vector result; if (process.exitCode() != 0) { - TaskHub::addTask(Task(Task::Error, process.stdOut(), {}, -1, Constants::C_NIMPARSE_ID)); + TaskHub::addTask(Task(Task::Error, process.cleanedStdOut(), {}, -1, Constants::C_NIMPARSE_ID)); return result; } @@ -91,7 +91,7 @@ static NimbleMetadata parseMetadata(const FilePath &nimblePath, const FilePath & NimbleMetadata result = {}; if (process.exitCode() != 0) { - TaskHub::addTask(Task(Task::Error, process.stdOut(), {}, -1, Constants::C_NIMPARSE_ID)); + TaskHub::addTask(Task(Task::Error, process.cleanedStdOut(), {}, -1, Constants::C_NIMPARSE_ID)); return result; } const QList &lines = linesFromProcessOutput(&process); diff --git a/src/plugins/perforce/perforcechecker.cpp b/src/plugins/perforce/perforcechecker.cpp index 3dc7f73d504..8ce4f04d395 100644 --- a/src/plugins/perforce/perforcechecker.cpp +++ b/src/plugins/perforce/perforcechecker.cpp @@ -127,11 +127,11 @@ void PerforceChecker::slotDone() break; case QProcess::NormalExit: if (m_process.exitCode()) { - const QString stdErr = m_process.stdErr(); + const QString stdErr = m_process.cleanedStdErr(); emitFailed(tr("\"%1\" terminated with exit code %2: %3"). arg(m_binary.toUserOutput()).arg(m_process.exitCode()).arg(stdErr)); } else { - parseOutput(m_process.stdOut()); + parseOutput(m_process.cleanedStdOut()); } break; } diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index 4c7039d2606..84ecf557214 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -1277,8 +1277,8 @@ PerforceResponse PerforcePluginPrivate::synchronousProcess(const FilePath &worki PerforceResponse response; response.error = true; response.exitCode = process.exitCode(); - response.stdErr = process.stdErr(); - response.stdOut = process.stdOut(); + response.stdErr = process.cleanedStdErr(); + response.stdOut = process.cleanedStdOut(); switch (process.result()) { case ProcessResult::FinishedWithSuccess: response.error = false; diff --git a/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp b/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp index 0b834009493..c5f801cc8e4 100644 --- a/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp +++ b/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp @@ -118,7 +118,7 @@ static bool process.runBlocking(EventLoopMode::On); if (process.result() != Utils::ProcessResult::FinishedWithSuccess) { *errorMessage = QString("Generator script failed: %1").arg(process.exitMessage()); - const QString stdErr = process.stdErr(); + const QString stdErr = process.cleanedStdErr(); if (!stdErr.isEmpty()) { errorMessage->append(QLatin1Char('\n')); errorMessage->append(stdErr); @@ -126,7 +126,7 @@ static bool return false; } if (stdOut) { - *stdOut = process.stdOut(); + *stdOut = process.cleanedStdOut(); if (CustomWizard::verbose()) qDebug("Output: '%s'\n", qPrintable(*stdOut)); } diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.cpp index a9ab24c39b8..da69611151f 100644 --- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.cpp +++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.cpp @@ -68,12 +68,12 @@ void SshDeviceProcessList::doKillProcess(const ProcessInfo &process) void SshDeviceProcessList::handleProcessDone() { if (d->m_process.result() == ProcessResult::FinishedWithSuccess) { - reportProcessListUpdated(buildProcessList(d->m_process.stdOut())); + reportProcessListUpdated(buildProcessList(d->m_process.cleanedStdOut())); } else { const QString errorMessage = d->m_process.exitStatus() == QProcess::NormalExit ? tr("Process listing command failed with exit code %1.").arg(d->m_process.exitCode()) : d->m_process.errorString(); - const QString stdErr = d->m_process.stdErr(); + const QString stdErr = d->m_process.cleanedStdErr(); const QString fullMessage = stdErr.isEmpty() ? errorMessage : errorMessage + '\n' + tr("Remote stderr was: %1").arg(stdErr); reportError(fullMessage); diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 355ff2d7fc6..8a3ffe5b53b 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -1590,7 +1590,7 @@ bool ClangToolChain::matchesCompilerCommand(const Utils::FilePath &command, std::unique_ptr xcrun(new QtcProcess); xcrun->setCommand({"/usr/bin/xcrun", {"-f", compilerCommand().fileName()}}); xcrun->runBlocking(); - const FilePath output = FilePath::fromString(xcrun->stdOut().trimmed()); + const FilePath output = FilePath::fromString(xcrun->cleanedStdOut().trimmed()); if (output.isExecutableFile() && output != compilerCommand()) m_resolvedCompilerCommand = output; } diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 9f456a8b06c..99b1e0bad06 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -296,7 +296,7 @@ static QVector detectVisualStudioFromVsWhere(const QSt return installations; } - QByteArray output = vsWhereProcess.stdOut().toUtf8(); + QByteArray output = vsWhereProcess.cleanedStdOut().toUtf8(); QJsonParseError error; const QJsonDocument doc = QJsonDocument::fromJson(output, &error); if (error.error != QJsonParseError::NoError || doc.isNull()) { @@ -667,7 +667,7 @@ Macros MsvcToolChain::msvcPredefinedMacros(const QStringList &cxxflags, if (cpp.result() != ProcessResult::FinishedWithSuccess) return predefinedMacros; - const QStringList output = Utils::filtered(cpp.stdOut().split('\n'), + const QStringList output = Utils::filtered(cpp.cleanedStdOut().split('\n'), [](const QString &s) { return s.startsWith('V'); }); for (const QString &line : output) predefinedMacros.append(Macro::fromKeyValue(line.mid(1))); @@ -1555,7 +1555,7 @@ static QVersionNumber clangClVersion(const FilePath &clangClPath) return {}; const QRegularExpressionMatch match = QRegularExpression( QStringLiteral("clang version (\\d+(\\.\\d+)+)")) - .match(clangClProcess.stdOut()); + .match(clangClProcess.cleanedStdOut()); if (!match.hasMatch()) return {}; return QVersionNumber::fromString(match.captured(1)); @@ -2127,7 +2127,7 @@ Utils::optional MsvcToolChain::generateEnvironmentSettings(const Utils: run.runBlocking(); if (run.result() != ProcessResult::FinishedWithSuccess) { - const QString message = !run.stdErr().isEmpty() ? run.stdErr() : run.exitMessage(); + const QString message = !run.cleanedStdErr().isEmpty() ? run.cleanedStdErr() : run.exitMessage(); qWarning().noquote() << message; QString command = QDir::toNativeSeparators(batchFile); if (!batchArgs.isEmpty()) @@ -2139,7 +2139,7 @@ Utils::optional MsvcToolChain::generateEnvironmentSettings(const Utils: } // The SDK/MSVC scripts do not return exit codes != 0. Check on stdout. - const QString stdOut = run.stdOut(); + const QString stdOut = run.cleanedStdOut(); // // Now parse the file to get the environment settings diff --git a/src/plugins/python/pythonsettings.cpp b/src/plugins/python/pythonsettings.cpp index e861e4c46b8..c8e77b0e538 100644 --- a/src/plugins/python/pythonsettings.cpp +++ b/src/plugins/python/pythonsettings.cpp @@ -78,7 +78,7 @@ static Interpreter createInterpreter(const FilePath &python, pythonProcess.setCommand({python, {"--version"}}); pythonProcess.runBlocking(); if (pythonProcess.result() == ProcessResult::FinishedWithSuccess) - result.name = pythonProcess.stdOut().trimmed(); + result.name = pythonProcess.cleanedStdOut().trimmed(); if (result.name.isEmpty()) result.name = defaultName; if (windowedSuffix) diff --git a/src/plugins/qnx/qnxutils.cpp b/src/plugins/qnx/qnxutils.cpp index e46b5cec8e0..1670419a432 100644 --- a/src/plugins/qnx/qnxutils.cpp +++ b/src/plugins/qnx/qnxutils.cpp @@ -125,7 +125,7 @@ EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const FilePath &filePath) return items; // parsing process output - const QString output = process.stdOut(); + const QString output = process.cleanedStdOut(); for (const QString &line : output.split('\n')) { int equalIndex = line.indexOf('='); if (equalIndex < 0) diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 4298c74590e..8b51cdaa6d9 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -1822,7 +1822,7 @@ static QByteArray runQmakeQuery(const FilePath &binary, const Environment &env, const QByteArray out = process.readAllStandardOutput(); if (out.isEmpty()) { *error = QCoreApplication::translate("QtVersion", "\"%1\" produced no output: %2.") - .arg(binary.displayName(), process.stdErr()); + .arg(binary.displayName(), process.cleanedStdErr()); return {}; } diff --git a/src/plugins/remotelinux/genericdirectuploadservice.cpp b/src/plugins/remotelinux/genericdirectuploadservice.cpp index f4aed62bfd6..6842eb43311 100644 --- a/src/plugins/remotelinux/genericdirectuploadservice.cpp +++ b/src/plugins/remotelinux/genericdirectuploadservice.cpp @@ -146,7 +146,7 @@ QDateTime GenericDirectUploadService::timestampFromStat(const DeployableFile &fi error = tr("\"stat\" crashed."); } else if (statProc->exitCode() != 0) { error = tr("\"stat\" failed with exit code %1: %2") - .arg(statProc->exitCode()).arg(statProc->stdErr()); + .arg(statProc->exitCode()).arg(statProc->cleanedStdErr()); } else { succeeded = true; } diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index edc6a624562..f011d8c563f 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -260,7 +260,7 @@ QString SshSharedConnection::fullProcessError() const { const QString errorString = m_masterProcess->exitStatus() == QProcess::CrashExit ? m_masterProcess->errorString() : QString(); - const QString standardError = m_masterProcess->stdErr(); + const QString standardError = m_masterProcess->cleanedStdErr(); const QString errorPrefix = errorString.isEmpty() && standardError.isEmpty() ? tr("SSH connection failure.") : tr("SSH connection failure:"); QStringList allErrors {errorPrefix, errorString, standardError}; diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index 796b9c87d4e..6d0028fb800 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -183,7 +183,7 @@ void GenericLinuxDeviceTester::handleEchoDone() return; } - const QString reply = d->echoProcess.stdOut().chopped(1); // Remove trailing \n + const QString reply = d->echoProcess.cleanedStdOut().chopped(1); // Remove trailing \n if (reply != s_echoContents) emit errorMessage(tr("Device replied to echo with unexpected contents.") + '\n'); else diff --git a/src/plugins/remotelinux/publickeydeploymentdialog.cpp b/src/plugins/remotelinux/publickeydeploymentdialog.cpp index e8c0c3b6ce2..3ba3f011d70 100644 --- a/src/plugins/remotelinux/publickeydeploymentdialog.cpp +++ b/src/plugins/remotelinux/publickeydeploymentdialog.cpp @@ -80,7 +80,7 @@ PublicKeyDeploymentDialog::PublicKeyDeploymentDialog(const IDevice::ConstPtr &de if (!succeeded) { QString errorMessage = d->m_process.errorString(); if (errorMessage.isEmpty()) - errorMessage = d->m_process.stdErr(); + errorMessage = d->m_process.cleanedStdErr(); if (errorMessage.endsWith('\n')) errorMessage.chop(1); finalMessage = tr("Key deployment failed."); diff --git a/src/plugins/remotelinux/rsyncdeploystep.cpp b/src/plugins/remotelinux/rsyncdeploystep.cpp index bd17c575f7d..7b8cf858f19 100644 --- a/src/plugins/remotelinux/rsyncdeploystep.cpp +++ b/src/plugins/remotelinux/rsyncdeploystep.cpp @@ -52,7 +52,7 @@ public: connect(&m_mkdir, &QtcProcess::done, this, [this] { if (m_mkdir.result() != ProcessResult::FinishedWithSuccess) { QString finalMessage = m_mkdir.errorString(); - const QString stdErr = m_mkdir.stdErr(); + const QString stdErr = m_mkdir.cleanedStdErr(); if (!stdErr.isEmpty()) { if (!finalMessage.isEmpty()) finalMessage += '\n'; diff --git a/src/plugins/silversearcher/findinfilessilversearcher.cpp b/src/plugins/silversearcher/findinfilessilversearcher.cpp index d32bbdc22b7..fa9c0a20c29 100644 --- a/src/plugins/silversearcher/findinfilessilversearcher.cpp +++ b/src/plugins/silversearcher/findinfilessilversearcher.cpp @@ -90,7 +90,7 @@ bool isSilverSearcherAvailable() silverSearcherProcess.setCommand({"ag", {"--version"}}); silverSearcherProcess.start(); if (silverSearcherProcess.waitForFinished(1000)) { - if (silverSearcherProcess.stdOut().contains("ag version")) + if (silverSearcherProcess.cleanedStdOut().contains("ag version")) return true; } @@ -145,7 +145,7 @@ void runSilverSeacher(FutureInterfaceType &fi, FileFindParameters parameters) regexp.setPattern(parameters.text); regexp.setPatternOptions(patternOptions); } - SilverSearcher::SilverSearcherOutputParser parser(process.stdOut(), regexp); + SilverSearcher::SilverSearcherOutputParser parser(process.cleanedStdOut(), regexp); FileSearchResultList items = parser.parse(); if (!items.isEmpty()) fi.reportResult(items); diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index 3083672d54d..99f13476586 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -157,7 +157,7 @@ QString SubversionClient::synchronousTopic(const FilePath &repository) const if (proc.result() != ProcessResult::FinishedWithSuccess) return QString(); - return proc.stdOut().trimmed(); + return proc.cleanedStdOut().trimmed(); } QString SubversionClient::escapeFile(const QString &file) diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 97e5ee6649f..46231e4052d 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -1034,8 +1034,8 @@ SubversionResponse SubversionPluginPrivate::runSvn(const FilePath &workingDir, response.error = proc.result() != ProcessResult::FinishedWithSuccess; if (response.error) response.message = proc.exitMessage(); - response.stdErr = proc.stdErr(); - response.stdOut = proc.stdOut(); + response.stdErr = proc.cleanedStdErr(); + response.stdOut = proc.cleanedStdOut(); return response; } diff --git a/src/plugins/texteditor/formattexteditor.cpp b/src/plugins/texteditor/formattexteditor.cpp index 58f48a0bf86..a01f543f1a1 100644 --- a/src/plugins/texteditor/formattexteditor.cpp +++ b/src/plugins/texteditor/formattexteditor.cpp @@ -97,7 +97,7 @@ static FormatTask format(FormatTask task) .arg(process.exitMessage()); return task; } - const QString output = process.stdErr(); + const QString output = process.cleanedStdErr(); if (!output.isEmpty()) task.error = executable + QLatin1String(": ") + output; diff --git a/src/plugins/texteditor/highlightersettings.cpp b/src/plugins/texteditor/highlightersettings.cpp index 7691f39cbed..d4755948084 100644 --- a/src/plugins/texteditor/highlightersettings.cpp +++ b/src/plugins/texteditor/highlightersettings.cpp @@ -71,7 +71,7 @@ FilePath findFallbackDefinitionsLocation() process.setCommand({program, {"--prefix"}}); process.runBlocking(); if (process.result() == ProcessResult::FinishedWithSuccess) { - QString output = process.stdOut(); + QString output = process.cleanedStdOut(); output.remove('\n'); const FilePath dir = FilePath::fromString(output); for (auto &kateSyntaxPath : kateSyntaxPaths) { diff --git a/src/plugins/updateinfo/updateinfoplugin.cpp b/src/plugins/updateinfo/updateinfoplugin.cpp index a0617df3a09..78d31e72910 100644 --- a/src/plugins/updateinfo/updateinfoplugin.cpp +++ b/src/plugins/updateinfo/updateinfoplugin.cpp @@ -167,7 +167,7 @@ void UpdateInfoPlugin::startCheckForUpdates() this, [this, futureIf]() mutable { if (d->m_maintenanceToolProcess->result() == ProcessResult::FinishedWithSuccess) { - d->m_updateOutput = d->m_maintenanceToolProcess->stdOut(); + d->m_updateOutput = d->m_maintenanceToolProcess->cleanedStdOut(); if (d->m_settings.checkForQtVersions) { d->m_maintenanceToolProcess.reset(new QtcProcess); d->m_maintenanceToolProcess->setCommand( @@ -181,7 +181,7 @@ void UpdateInfoPlugin::startCheckForUpdates() [this, futureIf]() mutable { if (d->m_maintenanceToolProcess->result() == ProcessResult::FinishedWithSuccess) { - d->m_packagesOutput = d->m_maintenanceToolProcess->stdOut(); + d->m_packagesOutput = d->m_maintenanceToolProcess->cleanedStdOut(); d->m_maintenanceToolProcess.reset(); futureIf.reportFinished(); checkForUpdatesFinished(); diff --git a/src/plugins/valgrind/valgrindrunner.cpp b/src/plugins/valgrind/valgrindrunner.cpp index b547edc802a..7b1b2fdc8e3 100644 --- a/src/plugins/valgrind/valgrindrunner.cpp +++ b/src/plugins/valgrind/valgrindrunner.cpp @@ -211,7 +211,7 @@ void ValgrindRunner::Private::findPidProcessDone() emit q->processOutputReceived(m_findPID.allOutput(), StdErrFormat); return; } - QString out = m_findPID.stdOut(); + QString out = m_findPID.cleanedStdOut(); if (out.isEmpty()) return; bool ok; diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 35e61845028..ea43dca0046 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -277,7 +277,7 @@ bool VcsBaseClient::synchronousCreateRepository(const FilePath &workingDirectory vcsFullySynchronousExec(proc, workingDirectory, args); if (proc.result() != ProcessResult::FinishedWithSuccess) return false; - VcsOutputWindow::append(proc.stdOut()); + VcsOutputWindow::append(proc.cleanedStdOut()); resetCachedVcsInfo(workingDirectory); diff --git a/src/plugins/webassembly/webassemblyemsdk.cpp b/src/plugins/webassembly/webassemblyemsdk.cpp index c5da7d13570..351bda3062e 100644 --- a/src/plugins/webassembly/webassemblyemsdk.cpp +++ b/src/plugins/webassembly/webassemblyemsdk.cpp @@ -118,7 +118,7 @@ QVersionNumber WebAssemblyEmSdk::version(const FilePath &sdkRoot) emcc.setCommand(command); emcc.setEnvironment(env); emcc.runBlocking(); - const QString version = emcc.stdOut(); + const QString version = emcc.cleanedStdOut(); emSdkVersionCache()->insert(cacheKey, new QVersionNumber(QVersionNumber::fromString(version))); } From cdedc711825162c44e451deddbcecd47989acf14 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Tue, 14 Jun 2022 18:21:17 +0200 Subject: [PATCH 013/100] scripts: Do not deploly clang and clang-cl executables They were used in debugging of the libclang code model, and having only the compiler is not very useful. Users can install complete LLVM toolchains from llvm.org Change-Id: If19a0b75c8505ba7589b377292bd96f855e91c00 Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: Christian Kandeler Reviewed-by: Eike Ziller --- scripts/deployqt.py | 4 ++-- scripts/deployqtHelper_mac.sh | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/scripts/deployqt.py b/scripts/deployqt.py index 33d216751fd..bfbc9ebf30a 100755 --- a/scripts/deployqt.py +++ b/scripts/deployqt.py @@ -238,7 +238,7 @@ def deploy_clang(install_dir, llvm_install_dir, chrpath_bin): clanglibdirtarget = os.path.join(install_dir, 'bin', 'clang', 'lib') if not os.path.exists(clanglibdirtarget): os.makedirs(clanglibdirtarget) - for binary in ['clang', 'clang-cl', 'clangd', 'clang-tidy', 'clazy-standalone']: + for binary in ['clangd', 'clang-tidy', 'clazy-standalone']: binary_filepath = os.path.join(llvm_install_dir, 'bin', binary + '.exe') if os.path.exists(binary_filepath): deployinfo.append((binary_filepath, clangbindirtarget)) @@ -248,7 +248,7 @@ def deploy_clang(install_dir, llvm_install_dir, chrpath_bin): clangbinary_targetdir = os.path.join(install_dir, 'libexec', 'qtcreator', 'clang', 'bin') if not os.path.exists(clangbinary_targetdir): os.makedirs(clangbinary_targetdir) - for binary in ['clang', 'clangd', 'clang-tidy', 'clazy-standalone']: + for binary in ['clangd', 'clang-tidy', 'clazy-standalone']: binary_filepath = os.path.join(llvm_install_dir, 'bin', binary) if os.path.exists(binary_filepath): deployinfo.append((binary_filepath, clangbinary_targetdir)) diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh index 8e6880f7d99..e3a0871d4d6 100755 --- a/scripts/deployqtHelper_mac.sh +++ b/scripts/deployqtHelper_mac.sh @@ -120,12 +120,6 @@ if [ $LLVM_INSTALL_DIR ]; then cp -Rf "$LLVM_INSTALL_DIR"/lib/clang "$libexec_path/clang/lib/" || exit 1 cp -Rf "$LLVM_INSTALL_DIR"/lib/libclang-cpp.dylib "$libexec_path/clang/lib/" || exit 1 cp -Rf "$LLVM_INSTALL_DIR"/lib/ClazyPlugin.dylib "$libexec_path/clang/lib/" || exit 1 - clangsource="$LLVM_INSTALL_DIR"/bin/clang - clanglinktarget="$(readlink "$clangsource")" - cp -Rf "$clangsource" "$libexec_path/clang/bin/" || exit 1 - if [ $clanglinktarget ]; then - cp -Rf "$(dirname "$clangsource")/$clanglinktarget" "$libexec_path/clang/bin/$clanglinktarget" || exit 1 - fi clangdsource="$LLVM_INSTALL_DIR"/bin/clangd cp -Rf "$clangdsource" "$libexec_path/clang/bin/" || exit 1 clangtidysource="$LLVM_INSTALL_DIR"/bin/clang-tidy From d4b8739653de90e9dbbe03b8d6a3a08be5f5e9ac Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 13 Jun 2022 17:28:17 +0200 Subject: [PATCH 014/100] qbs build: Fix building with MSVC and Qt >= 6.3 Change-Id: I59439217575bdcc170f38382129fa5f13edb23e2 Reviewed-by: Christian Stenger --- qbs/modules/qtc/qtc.qbs | 11 +++++++++++ tests/manual/debugger/gui/gui.qbs | 1 + tests/manual/debugger/simple/simple_test_app.qbs | 1 + tests/manual/debugger/simple/simple_test_plugin.qbs | 1 + tests/manual/widgets/crumblepath/crumblepath.qbs | 1 + tests/manual/widgets/infolabel/infolabel.qbs | 1 + .../manual/widgets/manhattanstyle/manhattanstyle.qbs | 1 + tests/manual/widgets/tracing/tracing.qbs | 1 + 8 files changed, 18 insertions(+) diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index 8578403fcc5..717ebe1d9fa 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -1,8 +1,11 @@ import qbs import qbs.Environment import qbs.FileInfo +import qbs.Utilities Module { + Depends { name: "cpp"; required: false } + property string qtcreator_display_version: '8.0.0-beta2' property string ide_version_major: '7' property string ide_version_minor: '83' @@ -92,4 +95,12 @@ Module { "QT_USE_QSTRINGBUILDER", ].concat(testsEnabled ? ["WITH_TESTS"] : []) .concat(qbs.toolchain.contains("msvc") ? ["_CRT_SECURE_NO_WARNINGS"] : []) + + Properties { + condition: cpp.present && qbs.toolchain.contains("msvc") && product.Qt + && Utilities.versionCompare(Qt.core.version, "6.3") >= 0 + && Utilities.versionCompare(cpp.compilerVersion, "19.10") >= 0 + && Utilities.versionCompare(qbs.version, "1.23") < 0 + cpp.cxxFlags: "/permissive-" + } } diff --git a/tests/manual/debugger/gui/gui.qbs b/tests/manual/debugger/gui/gui.qbs index 7a464f77c17..88e9bd53071 100644 --- a/tests/manual/debugger/gui/gui.qbs +++ b/tests/manual/debugger/gui/gui.qbs @@ -1,5 +1,6 @@ QtApplication { name: "Manual debugger gui test" + Depends { name: "qtc" } Depends { name: "Qt.widgets" } files: [ diff --git a/tests/manual/debugger/simple/simple_test_app.qbs b/tests/manual/debugger/simple/simple_test_app.qbs index 59cf3fe3074..ca2c56229e4 100644 --- a/tests/manual/debugger/simple/simple_test_app.qbs +++ b/tests/manual/debugger/simple/simple_test_app.qbs @@ -5,6 +5,7 @@ CppApplication { name: "Manual Test Simple Application" targetName: "simple_test_app" + Depends { name: "qtc" } Depends { name: "Qt.core" } Depends { name: "Qt.core-private"; required: false; condition: Qt.core.versionMajor > 4 } Depends { name: "Qt.core5compat"; condition: Qt.core.versionMajor > 5 } diff --git a/tests/manual/debugger/simple/simple_test_plugin.qbs b/tests/manual/debugger/simple/simple_test_plugin.qbs index 33f257c449b..eca6791c02c 100644 --- a/tests/manual/debugger/simple/simple_test_plugin.qbs +++ b/tests/manual/debugger/simple/simple_test_plugin.qbs @@ -4,6 +4,7 @@ DynamicLibrary { name: "Manual Test Simple Plugin" targetName: "simple_test_plugin" + Depends { name: "qtc" } Depends { name: "Qt.core" } files: [ "simple_test_plugin.cpp" ] diff --git a/tests/manual/widgets/crumblepath/crumblepath.qbs b/tests/manual/widgets/crumblepath/crumblepath.qbs index af1860a52ec..c9b32a0810f 100644 --- a/tests/manual/widgets/crumblepath/crumblepath.qbs +++ b/tests/manual/widgets/crumblepath/crumblepath.qbs @@ -3,6 +3,7 @@ import "../common/common.qbs" as Common CppApplication { name: "Manual Test Utils CrumblePath" + Depends { name: "qtc" } Depends { name: "Core" } Depends { name: "Utils" } diff --git a/tests/manual/widgets/infolabel/infolabel.qbs b/tests/manual/widgets/infolabel/infolabel.qbs index ce00065c7cf..dfba3bd9ef7 100644 --- a/tests/manual/widgets/infolabel/infolabel.qbs +++ b/tests/manual/widgets/infolabel/infolabel.qbs @@ -3,6 +3,7 @@ import "../common/common.qbs" as Common CppApplication { name: "Manual Test Utils InfoLabel" + Depends { name: "qtc" } Depends { name: "Core" } Depends { name: "Utils" } diff --git a/tests/manual/widgets/manhattanstyle/manhattanstyle.qbs b/tests/manual/widgets/manhattanstyle/manhattanstyle.qbs index 97a728a6f63..c04bd03e89f 100644 --- a/tests/manual/widgets/manhattanstyle/manhattanstyle.qbs +++ b/tests/manual/widgets/manhattanstyle/manhattanstyle.qbs @@ -3,6 +3,7 @@ import "../common/common.qbs" as Common CppApplication { name: "Manual Test Utils ManhattanStyle" + Depends { name: "qtc" } Depends { name: "Core" } Depends { name: "Utils" } diff --git a/tests/manual/widgets/tracing/tracing.qbs b/tests/manual/widgets/tracing/tracing.qbs index 06bbc4edd4a..95e661910ce 100644 --- a/tests/manual/widgets/tracing/tracing.qbs +++ b/tests/manual/widgets/tracing/tracing.qbs @@ -3,6 +3,7 @@ import "../common/common.qbs" as Common CppApplication { name: "Manual Test Tracing" + Depends { name: "qtc" } Depends { name: "Qt.quick" } Depends { name: "Tracing" } Depends { name: "Utils" } From 91d1ed25c2081d619b60ed9585e61f15a2a353aa Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 17 Jun 2022 12:59:27 +0200 Subject: [PATCH 015/100] LldbEngine: Connect to done() signal Instead of connecting to errorOccurred() and finished() signals. Change-Id: If82a7c79bba9bd3457d07fbc212f6b007699b0f0 Reviewed-by: hjk --- src/plugins/debugger/lldb/lldbengine.cpp | 39 ++++++++---------------- src/plugins/debugger/lldb/lldbengine.h | 4 +-- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 8bcd5112305..cb8f0909d3d 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -92,21 +92,14 @@ LldbEngine::LldbEngine() setDebuggerName("LLDB"); DebuggerSettings &ds = *debuggerSettings(); - connect(&ds.autoDerefPointers, &BaseAspect::changed, - this, &LldbEngine::updateLocals); + connect(&ds.autoDerefPointers, &BaseAspect::changed, this, &LldbEngine::updateLocals); connect(ds.createFullBacktrace.action(), &QAction::triggered, this, &LldbEngine::fetchFullBacktrace); - connect(&ds.useDebuggingHelpers, &BaseAspect::changed, - this, &LldbEngine::updateLocals); - connect(&ds.useDynamicType, &BaseAspect::changed, - this, &LldbEngine::updateLocals); - connect(&ds.intelFlavor, &BaseAspect::changed, - this, &LldbEngine::updateAll); + connect(&ds.useDebuggingHelpers, &BaseAspect::changed, this, &LldbEngine::updateLocals); + connect(&ds.useDynamicType, &BaseAspect::changed, this, &LldbEngine::updateLocals); + connect(&ds.intelFlavor, &BaseAspect::changed, this, &LldbEngine::updateAll); - connect(&m_lldbProc, &QtcProcess::errorOccurred, - this, &LldbEngine::handleLldbError); - connect(&m_lldbProc, &QtcProcess::finished, - this, &LldbEngine::handleLldbFinished); + connect(&m_lldbProc, &QtcProcess::done, this, &LldbEngine::handleLldbDone); connect(&m_lldbProc, &QtcProcess::readyReadStandardOutput, this, &LldbEngine::readLldbStandardOutput); connect(&m_lldbProc, &QtcProcess::readyReadStandardError, @@ -116,11 +109,6 @@ LldbEngine::LldbEngine() this, &LldbEngine::handleResponse, Qt::QueuedConnection); } -LldbEngine::~LldbEngine() -{ - m_lldbProc.disconnect(); -} - void LldbEngine::executeDebuggerCommand(const QString &command) { DebuggerCommand cmd("executeDebuggerCommand"); @@ -782,12 +770,17 @@ void LldbEngine::doUpdateLocals(const UpdateParameters ¶ms) runCommand(cmd); } -void LldbEngine::handleLldbError(QProcess::ProcessError error) +void LldbEngine::handleLldbDone() { + if (m_lldbProc.error() == QProcess::UnknownError) { + notifyDebuggerProcessFinished(m_lldbProc.resultData(), "LLDB"); + return; + } + + const QProcess::ProcessError error = m_lldbProc.error(); showMessage(QString("LLDB PROCESS ERROR: %1").arg(error)); switch (error) { case QProcess::Crashed: - m_lldbProc.disconnect(); notifyEngineShutdownFinished(); break; // will get a processExited() as well // impossible case QProcess::FailedToStart: @@ -796,7 +789,6 @@ void LldbEngine::handleLldbError(QProcess::ProcessError error) case QProcess::Timedout: default: //setState(EngineShutdownRequested, true); - m_lldbProc.stop(); AsynchronousMessageBox::critical(tr("LLDB I/O Error"), errorMessage(error)); break; } @@ -829,11 +821,6 @@ QString LldbEngine::errorMessage(QProcess::ProcessError error) const } } -void LldbEngine::handleLldbFinished() -{ - notifyDebuggerProcessFinished(m_lldbProc.resultData(), "LLDB"); -} - void LldbEngine::readLldbStandardError() { QString err = QString::fromUtf8(m_lldbProc.readAllStandardError()); @@ -921,7 +908,7 @@ void LldbEngine::handleStateNotification(const GdbMi &item) void LldbEngine::handleLocationNotification(const GdbMi &reportedLocation) { qulonglong address = reportedLocation["address"].toAddress(); - Utils::FilePath fileName = FilePath::fromUserInput(reportedLocation["file"].data()); + FilePath fileName = FilePath::fromUserInput(reportedLocation["file"].data()); QString function = reportedLocation["function"].data(); int lineNumber = reportedLocation["line"].toInt(); Location loc = Location(fileName, lineNumber); diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index 0e7e60bb713..7562eb98e24 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -53,7 +53,6 @@ class LldbEngine : public CppDebuggerEngine public: LldbEngine(); - ~LldbEngine() override; signals: void outputReady(const QString &data); @@ -111,8 +110,7 @@ private: QString errorMessage(QProcess::ProcessError error) const; bool hasCapability(unsigned cap) const override; - void handleLldbFinished(); - void handleLldbError(QProcess::ProcessError error); + void handleLldbDone(); void readLldbStandardOutput(); void readLldbStandardError(); From 498418bbc9a73e7cace534fa237479a08901ccd9 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Thu, 16 Jun 2022 20:20:54 +0200 Subject: [PATCH 016/100] CMakePM: Treat .h files as compile group language header types CMake splits sources files into groups "Source Files" and "Header Files". CMake also has compiler groups when source files are compiled differently. Qt Creator is mapping the compiler groups as RawProjectParts. In order to get the header files as part of a RawProjectPart the target sources (which contains all sources) is mapping the header files that match the mime type of the compiler group language type. .h header files were considered ambigous headers, and in this commit we treat them as the compile group language header. Fixes: QTCREATORBUG-27117 Change-Id: If68e847846cc270f06fc2231ec44a29ea6a987c1 Reviewed-by: Reviewed-by: Eike Ziller --- .../fileapidataextractor.cpp | 24 ++++++++++++------- .../cppeditor/cppprojectinfogenerator.cpp | 3 ++- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index 21d056f6083..9970fc019c4 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -402,18 +402,18 @@ RawProjectParts generateRawProjectParts(const PreprocessedData &input, const bool hasPchSource = anyOf(sources, [buildDirectory](const QString &path) { return isPchFile(buildDirectory, FilePath::fromString(path)); }); - if (!hasPchSource) { - QString headerMimeType; - if (ci.language == "C") - headerMimeType = CppEditor::Constants::C_HEADER_MIMETYPE; - else if (ci.language == "CXX") - headerMimeType = CppEditor::Constants::CPP_HEADER_MIMETYPE; + QString headerMimeType; + if (ci.language == "C") + headerMimeType = CppEditor::Constants::C_HEADER_MIMETYPE; + else if (ci.language == "CXX") + headerMimeType = CppEditor::Constants::CPP_HEADER_MIMETYPE; + if (!hasPchSource) { for (const SourceInfo &si : t.sources) { if (si.isGenerated) continue; const auto mimeTypes = Utils::mimeTypesForFileName(si.path); - for (auto mime : mimeTypes) + for (const auto &mime : mimeTypes) if (mime.name() == headerMimeType) sources.push_back(sourceDir.absoluteFilePath(si.path)); } @@ -421,8 +421,14 @@ RawProjectParts generateRawProjectParts(const PreprocessedData &input, // Set project files except pch files rpp.setFiles(Utils::filtered(sources, [buildDirectory](const QString &path) { - return !isPchFile(buildDirectory, FilePath::fromString(path)); - })); + return !isPchFile(buildDirectory, FilePath::fromString(path)); + }), {}, [headerMimeType](const QString &path) { + // Similar to ProjectFile::classify but classify headers with language + // of compile group instead of ambiguous header + if (path.endsWith(".h")) + return headerMimeType; + return Utils::mimeTypeForFile(path).name(); + }); FilePath precompiled_header = FilePath::fromString(findOrDefault(t.sources, [&ending](const SourceInfo &si) { diff --git a/src/plugins/cppeditor/cppprojectinfogenerator.cpp b/src/plugins/cppeditor/cppprojectinfogenerator.cpp index 67ebd19f6d5..55bbf3d3560 100644 --- a/src/plugins/cppeditor/cppprojectinfogenerator.cpp +++ b/src/plugins/cppeditor/cppprojectinfogenerator.cpp @@ -87,7 +87,8 @@ const QVector ProjectInfoGenerator::createProjectParts( QVector result; ProjectFileCategorizer cat(rawProjectPart.displayName, rawProjectPart.files, - rawProjectPart.fileIsActive); + rawProjectPart.fileIsActive, + rawProjectPart.getMimeType); if (!cat.hasParts()) return result; From 3b8b247f88f3a97bdd69f6ea058ed439f9b8648b Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 16 Jun 2022 15:09:39 +0200 Subject: [PATCH 017/100] Python: ignore windows store redirectors Change-Id: Ife5c13549d73156550a7ce4b5436f1e5a19503fa Reviewed-by: Christian Stenger --- src/plugins/python/pythonutils.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/plugins/python/pythonutils.cpp b/src/plugins/python/pythonutils.cpp index 08c8750c21f..ebc2a695f7b 100644 --- a/src/plugins/python/pythonutils.cpp +++ b/src/plugins/python/pythonutils.cpp @@ -74,13 +74,22 @@ FilePath detectPython(const FilePath &documentPath) if (defaultInterpreter.exists()) return defaultInterpreter; - const FilePath python3FromPath = env.searchInPath("python3"); - if (python3FromPath.exists()) - return python3FromPath; + auto pythonFromPath = [=](const QString toCheck) { + for (const FilePath &python : env.findAllInPath(toCheck)) { + // Windows creates empty redirector files that may interfere + if (python.exists() && python.osType() == OsTypeWindows && python.fileSize() != 0) + return python; + } + return FilePath(); + }; - const FilePath pythonFromPath = env.searchInPath("python"); - if (pythonFromPath.exists()) - return pythonFromPath; + const FilePath fromPath3 = pythonFromPath("python3"); + if (fromPath3.exists()) + return fromPath3; + + const FilePath fromPath = pythonFromPath("python"); + if (fromPath.exists()) + return fromPath; return PythonSettings::interpreters().value(0).command; } From e980d87b5004351ff63e573f0f2c035abe60b6d2 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Jun 2022 17:10:38 +0200 Subject: [PATCH 018/100] Debugger: Fix LLDB start on Ubuntu 22.04 The LLDB (14) installation on Ubuntu 22.04 is broken, see https://bugs.launchpad.net/ubuntu/+source/llvm-defaults/+bug/1972855 Work around by using a corrected PYTHONPATH when starting LLDB. Change-Id: I9bede8f146c32f60247ca3416a14cf9ccf4b0fb6 Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/debugger/lldb/lldbengine.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index cb8f0909d3d..62009240f55 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -203,6 +203,22 @@ void LldbEngine::setupEngine() Environment environment = runParameters().debugger.environment; environment.appendOrSet("PYTHONUNBUFFERED", "1"); // avoid flushing problem on macOS DebuggerItem::addAndroidLldbPythonEnv(lldbCmd, environment); + + if (lldbCmd.osType() == OsTypeLinux) { + // LLDB 14 installation on Ubuntu 22.04 is broken: + // https://bugs.launchpad.net/ubuntu/+source/llvm-defaults/+bug/1972855 + // Brush over it: + QtcProcess lldbPythonPathFinder; + lldbPythonPathFinder.setCommand({lldbCmd, {"-P"}}); + lldbPythonPathFinder.start(); + lldbPythonPathFinder.waitForFinished(); + QString lldbPythonPath = lldbPythonPathFinder.cleanedStdOut(); + if (lldbPythonPath.endsWith('\n')) + lldbPythonPath.chop(1); + if (lldbPythonPath == "/usr/lib/local/lib/python3.10/dist-packages") + environment.appendOrSet("PYTHONPATH", "/usr/lib/llvm-14/lib/python3.10/dist-packages"); + } + m_lldbProc.setEnvironment(environment); if (runParameters().debugger.workingDirectory.isDir()) From fd5bcea5f64001ad03794a0468fbb3dcdebba0fe Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 15 Jun 2022 14:57:51 +0200 Subject: [PATCH 019/100] QmlJS: Enhance member lookup Check for the alias when performing a member lookup on an import. Fixes: QTCREATORBUG-26714 Change-Id: If3febb7d6de9fa2663cdda0143d4aa3590312ca5 Reviewed-by: Ulf Hermann --- src/libs/qmljs/qmljsinterpreter.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index 74526295813..9412406fdc4 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -2378,8 +2378,12 @@ const Value *TypeScope::lookupMember(const QString &name, const Context *context continue; if (const Value *v = import->lookupMember(name, context, foundInObject)) { - i.used = true; - return v; + // FIXME if we have multiple non-aliased imports containing this object we'd have to + // disambiguate (and inform the user) about this issue + if (info.as().isEmpty()) { + i.used = true; + return v; + } } } if (foundInObject) From 1d67bf597f6426e5a8419587ef52304647743c1d Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 17 Jun 2022 11:45:59 +0200 Subject: [PATCH 020/100] DocumentClangToolRunner: Remove no-op call to disconnect A call to disconnect() prior to object destruction is no-op. Change-Id: I719d84d5fde43038c80bd2fc164ffe5e0aab1fec Reviewed-by: Reviewed-by: David Schulz --- src/plugins/clangtools/documentclangtoolrunner.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/clangtools/documentclangtoolrunner.cpp b/src/plugins/clangtools/documentclangtoolrunner.cpp index cebd508ed10..9b8b206f2cc 100644 --- a/src/plugins/clangtools/documentclangtoolrunner.cpp +++ b/src/plugins/clangtools/documentclangtoolrunner.cpp @@ -364,10 +364,7 @@ void DocumentClangToolRunner::cancel() if (m_projectSettingsUpdate) disconnect(m_projectSettingsUpdate); m_runnerCreators.clear(); - if (m_currentRunner) { - m_currentRunner->disconnect(this); - m_currentRunner.reset(nullptr); - } + m_currentRunner.reset(nullptr); } bool DocumentClangToolRunner::isSuppressed(const Diagnostic &diagnostic) const From 13c7513024df4a3007afe6ac47b4e3e2fa569e27 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 16 Jun 2022 16:00:49 +0200 Subject: [PATCH 021/100] QueryRunner: Connect to done() signal Instead of connecting to errorOccurred() and finished() signals. Change-Id: I57adabc52b38be6b22a4d7380e6fbaaae3192201 Reviewed-by: Christian Stenger --- src/plugins/gitlab/queryrunner.cpp | 84 ++++++++---------------------- src/plugins/gitlab/queryrunner.h | 10 ---- 2 files changed, 23 insertions(+), 71 deletions(-) diff --git a/src/plugins/gitlab/queryrunner.cpp b/src/plugins/gitlab/queryrunner.cpp index fe46db842e0..55d1572bd32 100644 --- a/src/plugins/gitlab/queryrunner.cpp +++ b/src/plugins/gitlab/queryrunner.cpp @@ -37,6 +37,8 @@ #include +using namespace Utils; + namespace GitLab { const char API_PREFIX[] = "/api/v4"; @@ -100,15 +102,13 @@ QString Query::toString() const return query; } -QueryRunner::QueryRunner(const Query &query, const Utils::Id &id, QObject *parent) +QueryRunner::QueryRunner(const Query &query, const Id &id, QObject *parent) : QObject(parent) - , m_serverId(id) { const GitLabParameters *p = GitLabPlugin::globalParameters(); - const auto server = p->serverForId(m_serverId); + const auto server = p->serverForId(id); QStringList args = server.curlArguments(); - m_paginated = query.hasPaginatedResults(); - if (m_paginated) + if (query.hasPaginatedResults()) args << "-i"; if (!server.token.isEmpty()) args << "--header" << "PRIVATE-TOKEN: " + server.token; @@ -118,69 +118,31 @@ QueryRunner::QueryRunner(const Query &query, const Utils::Id &id, QObject *paren url += query.toString(); args << url; m_process.setCommand({p->curl, args}); - connect(&m_process, &Utils::QtcProcess::finished, this, &QueryRunner::processFinished); - connect(&m_process, &Utils::QtcProcess::errorOccurred, this, &QueryRunner::processError); -} - -QueryRunner::~QueryRunner() -{ - m_process.disconnect(); - terminate(); -} - -void QueryRunner::start() -{ - QTC_ASSERT(!m_running, return); - m_running = true; - m_process.start(); -} - -void QueryRunner::terminate() -{ - m_process.stop(); - m_process.waitForFinished(); -} - -void QueryRunner::errorTermination(const QString &msg) -{ - if (!m_running) - return; - VcsBase::VcsOutputWindow::appendError(msg); - m_running = false; - emit finished(); -} - -void QueryRunner::processError(QProcess::ProcessError /*error*/) -{ - const QString msg = tr("Error running %1: %2") - .arg(m_process.commandLine().executable().toUserOutput(), - m_process.errorString()); - errorTermination(msg); -} -void QueryRunner::processFinished() -{ - const QString executable = m_process.commandLine().executable().toUserOutput(); - if (m_process.exitStatus() != QProcess::NormalExit) { - errorTermination(tr("%1 crashed.").arg(executable)); - return; - } else if (int exitCode = m_process.exitCode()) { - if (exitCode == 35 || exitCode == 60) { // common ssl certificate issues - if (GitLabPlugin::handleCertificateIssue(m_serverId)) { - m_running = false; + connect(&m_process, &QtcProcess::done, this, [this, id] { + if (m_process.result() != ProcessResult::FinishedWithSuccess) { + const int exitCode = m_process.exitCode(); + if (m_process.exitStatus() == QProcess::NormalExit + && (exitCode == 35 || exitCode == 60) // common ssl certificate issues + && GitLabPlugin::handleCertificateIssue(id)) { // prepend -k for re-requesting the same query - Utils::CommandLine cmdline = m_process.commandLine(); + CommandLine cmdline = m_process.commandLine(); cmdline.prependArgs({"-k"}); m_process.setCommand(cmdline); start(); return; } + VcsBase::VcsOutputWindow::appendError(m_process.exitMessage()); + } else { + emit resultRetrieved(m_process.readAllStandardOutput()); } - errorTermination(tr("%1 returned %2.").arg(executable).arg(m_process.exitCode())); - return; - } - m_running = false; - emit resultRetrieved(m_process.readAllStandardOutput()); - emit finished(); + emit finished(); + }); +} + +void QueryRunner::start() +{ + QTC_ASSERT(!m_process.isRunning(), return); + m_process.start(); } } // namespace GitLab diff --git a/src/plugins/gitlab/queryrunner.h b/src/plugins/gitlab/queryrunner.h index c002f9a5611..a60eb470ac7 100644 --- a/src/plugins/gitlab/queryrunner.h +++ b/src/plugins/gitlab/queryrunner.h @@ -62,24 +62,14 @@ class QueryRunner : public QObject Q_OBJECT public: QueryRunner(const Query &query, const Utils::Id &id, QObject *parent = nullptr); - ~QueryRunner(); - void start(); - void terminate(); signals: void finished(); void resultRetrieved(const QByteArray &json); private: - void errorTermination(const QString &msg); - void processError(QProcess::ProcessError error); - void processFinished(); - Utils::QtcProcess m_process; - Utils::Id m_serverId; - bool m_running = false; - bool m_paginated = false; }; } // namespace GitLab From d783b4d5ff14ce346ec4c13272d2b2583c3b2d6c Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Jun 2022 10:56:05 +0200 Subject: [PATCH 022/100] ValgrindRunner: Remove ValgrindRunner::setDevice The device can now be determined from the debuggee's file path. Change-Id: I2b24d6e325f74826a644d02a9e418576c4e9b436 Reviewed-by: Jarek Kobus Reviewed-by: --- src/plugins/valgrind/valgrindengine.cpp | 2 -- .../valgrind/valgrindmemcheckparsertest.cpp | 7 ----- src/plugins/valgrind/valgrindrunner.cpp | 29 +++++++++---------- src/plugins/valgrind/valgrindrunner.h | 1 - .../valgrind/valgrindtestrunnertest.cpp | 2 -- 5 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp index a1b2b9cd35e..fc914a1d9f8 100644 --- a/src/plugins/valgrind/valgrindengine.cpp +++ b/src/plugins/valgrind/valgrindengine.cpp @@ -26,7 +26,6 @@ #include "valgrindengine.h" #include "valgrindsettings.h" -#include "valgrindplugin.h" #include @@ -101,7 +100,6 @@ void ValgrindToolRunner::start() valgrind.addArgs(toolArguments()); m_runner.setValgrindCommand(valgrind); - m_runner.setDevice(device()); m_runner.setDebuggee(runControl()->runnable()); if (auto aspect = runControl()->aspect()) diff --git a/src/plugins/valgrind/valgrindmemcheckparsertest.cpp b/src/plugins/valgrind/valgrindmemcheckparsertest.cpp index 4ca3d768126..4218f75b211 100644 --- a/src/plugins/valgrind/valgrindmemcheckparsertest.cpp +++ b/src/plugins/valgrind/valgrindmemcheckparsertest.cpp @@ -31,7 +31,6 @@ #include "xmlprotocol/stack.h" #include "xmlprotocol/suppression.h" -#include #include #include @@ -483,8 +482,6 @@ void ValgrindMemcheckParserTest::testParserStop() "-i", dataFile("memcheck-output-sample1.xml"), "--wait", "5" }}); runner.setProcessChannelMode(QProcess::ForwardedChannels); - runner.setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice( - ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)); runner.start(); QTest::qWait(500); runner.stop(); @@ -505,8 +502,6 @@ void ValgrindMemcheckParserTest::testRealValgrind() ValgrindRunner runner; runner.setValgrindCommand({"valgrind", {}}); runner.setDebuggee(debuggee); - runner.setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice( - ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)); RunnerDumper dumper(&runner); runner.start(); runner.waitForFinished(); @@ -544,8 +539,6 @@ void ValgrindMemcheckParserTest::testValgrindStartError() ValgrindRunner runner; runner.setValgrindCommand({FilePath::fromString(valgrindExe), valgrindArgs}); runner.setDebuggee(debuggeeExecutable); - runner.setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice( - ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)); RunnerDumper dumper(&runner); runner.start(); runner.waitForFinished(); diff --git a/src/plugins/valgrind/valgrindrunner.cpp b/src/plugins/valgrind/valgrindrunner.cpp index 7b1b2fdc8e3..76d6b72f118 100644 --- a/src/plugins/valgrind/valgrindrunner.cpp +++ b/src/plugins/valgrind/valgrindrunner.cpp @@ -28,7 +28,6 @@ #include "xmlprotocol/threadedparser.h" -#include #include #include #include @@ -58,7 +57,6 @@ public: ValgrindRunner *q; Runnable m_debuggee; QtcProcess m_valgrindProcess; - IDevice::ConstPtr m_device; QtcProcess m_findPID; @@ -187,15 +185,19 @@ void ValgrindRunner::Private::remoteProcessStarted() QString procEscaped = proc; procEscaped.replace("/", "\\\\/"); - CommandLine cmd(m_device->filePath("/bin/sh"), {}); - // sleep required since otherwise we might only match "bash -c..." and not the actual - // valgrind run - cmd.setArguments(QString("-c \"" - "sleep 1; ps ax" // list all processes with aliased name - " | grep '%1.*%2'" // find valgrind process that runs with our exec - " | awk '\\$5 ~ /^%3/" // 5th column must start with valgrind process - " {print \\$1;}'" // print 1st then (with PID) - "\"").arg(proc, m_debuggee.command.executable().fileName(), procEscaped)); + const FilePath debuggee = m_debuggee.command.executable(); + const CommandLine cmd( + debuggee.withNewPath("/bin/sh"), + // sleep required since otherwise we might only match "bash -c..." and not the actual + // valgrind run + QString("-c \"" + "sleep 1; ps ax" // list all processes with aliased name + " | grep '%1.*%2'" // find valgrind process that runs with our exec + " | awk '\\$5 ~ /^%3/" // 5th column must start with valgrind process + " {print \\$1;}'" // print 1st then (with PID) + "\"").arg(proc, debuggee.fileName(), procEscaped), + CommandLine::Raw + ); m_findPID.setCommand(cmd); @@ -264,11 +266,6 @@ void ValgrindRunner::setLocalServerAddress(const QHostAddress &localServerAddres d->localServerAddress = localServerAddress; } -void ValgrindRunner::setDevice(const IDevice::ConstPtr &device) -{ - d->m_device = device; -} - void ValgrindRunner::setUseTerminal(bool on) { d->m_valgrindProcess.setTerminalMode(on ? TerminalMode::On : TerminalMode::Off); diff --git a/src/plugins/valgrind/valgrindrunner.h b/src/plugins/valgrind/valgrindrunner.h index 3350792b51f..a522820c058 100644 --- a/src/plugins/valgrind/valgrindrunner.h +++ b/src/plugins/valgrind/valgrindrunner.h @@ -52,7 +52,6 @@ public: void setDebuggee(const ProjectExplorer::Runnable &debuggee); void setProcessChannelMode(QProcess::ProcessChannelMode mode); void setLocalServerAddress(const QHostAddress &localServerAddress); - void setDevice(const ProjectExplorer::IDeviceConstPtr &device); void setUseTerminal(bool on); void waitForFinished() const; diff --git a/src/plugins/valgrind/valgrindtestrunnertest.cpp b/src/plugins/valgrind/valgrindtestrunnertest.cpp index 4dde3013628..889422b6189 100644 --- a/src/plugins/valgrind/valgrindtestrunnertest.cpp +++ b/src/plugins/valgrind/valgrindtestrunnertest.cpp @@ -91,8 +91,6 @@ QString ValgrindTestRunnerTest::runTestBinary(const QString &binary, const QStri m_runner->setLocalServerAddress(QHostAddress::LocalHost); m_runner->setValgrindCommand(valgrind); m_runner->setDebuggee(debuggee); - m_runner->setDevice(DeviceManager::instance()->defaultDevice( - ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)); m_runner->start(); m_runner->waitForFinished(); return binPath; From 1bea5708b48429b50223d56d0f6c8384b38df3e7 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Jun 2022 10:11:42 +0200 Subject: [PATCH 023/100] Debugger: Make one manual test deployable to remote linux Change-Id: Ia61926353e93ae394d3eb2082bb92769967cd958 Reviewed-by: Eike Ziller --- tests/manual/debugger/gui/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/manual/debugger/gui/CMakeLists.txt b/tests/manual/debugger/gui/CMakeLists.txt index 59e45b3804d..21c89f291cb 100644 --- a/tests/manual/debugger/gui/CMakeLists.txt +++ b/tests/manual/debugger/gui/CMakeLists.txt @@ -16,3 +16,10 @@ add_executable(manual_test_debugger_gui tst_gui.cpp ) target_link_libraries(manual_test_debugger_gui PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) + +if (NOT QT_CREATOR_API_DEFINED) + if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set (CMAKE_INSTALL_PREFIX "/tmp/manual_test_debugger_gui" CACHE PATH "default install path" FORCE) + endif() + install(TARGETS manual_test_debugger_gui) + endif() From 27ce8d6177be8d292158e607a9a93f37d6c303ab Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Jun 2022 15:57:15 +0200 Subject: [PATCH 024/100] FakeVim: Simplify calling external processes Change-Id: I5157e2e73654df8bef65d72b7209c487e8b0c881 Reviewed-by: Jarek Kobus Reviewed-by: --- src/plugins/fakevim/fakevimhandler.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 79e8153c01b..56980bfb2c6 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -864,15 +864,6 @@ static QByteArray toLocalEncoding(const QString &text) #endif } -static QString fromLocalEncoding(const QByteArray &data) -{ -#if defined(Q_OS_WIN) - return QString::fromLocal8Bit(data).replace("\n", "\r\n"); -#else - return QString::fromLocal8Bit(data); -#endif -} - static QString getProcessOutput(const QString &command, const QString &input) { Utils::QtcProcess proc; @@ -884,7 +875,7 @@ static QString getProcessOutput(const QString &command, const QString &input) // Solution is to create a QObject for each process and emit finished state. proc.waitForFinished(); - return fromLocalEncoding(proc.readAllStandardOutput()); + return proc.cleanedStdOut(); } static const QMap &vimKeyNames() From 917f0d151bfde32fc231822357622e644517a5c6 Mon Sep 17 00:00:00 2001 From: Bartlomiej Moskal Date: Mon, 20 Jun 2022 10:25:25 +0200 Subject: [PATCH 025/100] Android: set release flag when signing apk Currently, signing a package by androiddeployqt automatically implies the --release option, but there is a fix that removes it from being set by default. To prepare QtCreator for the upcoming change and not to change its behavior, we need to manually add the --release option to the argument list. Change-Id: I31df1b8252a4444afde95a043848391590f4db82 Reviewed-by: Alessandro Portale --- src/plugins/android/androidbuildapkstep.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index 17342ba9fb2..0746a6b9be2 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -611,9 +611,11 @@ bool AndroidBuildApkStep::init() QStringList argumentsPasswordConcealed = arguments; if (m_signPackage) { - arguments << "--sign" << m_keystorePath.toString() << m_certificateAlias + arguments << "--release" + << "--sign" << m_keystorePath.toString() << m_certificateAlias << "--storepass" << m_keystorePasswd; - argumentsPasswordConcealed << "--sign" << "******" + argumentsPasswordConcealed << "--release" + << "--sign" << "******" << "--storepass" << "******"; if (!m_certificatePasswd.isEmpty()) { arguments << "--keypass" << m_certificatePasswd; From b6adaab3ea7c318af2ca52eaa6770661dae6fd01 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 15 Jun 2022 17:18:01 +0200 Subject: [PATCH 026/100] CompilationDatabaseProjectManager: Fix flags extraction The code would blindly remove all "options" starting with /, which meant that all file paths arguments got lost on Unix-like hosts. Fixes: QTCREATORBUG-22949 Change-Id: I43e2b1e57ed0e9ced9da8fa46d98d9ac25f83d13 Reviewed-by: Qt CI Bot Reviewed-by: Christian Stenger --- .../compilationdatabasetests.cpp | 17 ++++++++++------- .../compilationdatabaseutils.cpp | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp index 113e60ad740..17840e92544 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -239,13 +240,15 @@ void CompilationDatabaseTests::testFilterCommand() "SemaCodeComplete"); testData.getFilteredFlags(); - QCOMPARE(testData.flags, - (QStringList{"/Zc:inline", "/Zc:strictStrings", "/Zc:rvalueCast", "/Zi"})); - QCOMPARE(testData.headerPaths, - toUserHeaderPaths(QStringList{"C:/build-qt_llvm-msvc2017_64bit-Debug/tools\\clang\\lib\\Sema"})); - QCOMPARE(testData.macros, (Macros{{"UNICODE", "1"}, {"_HAS_EXCEPTIONS", "0"}, {"WIN32", "1"}, - {"_WINDOWS", "1"}})); - QCOMPARE(testData.fileKind, CppEditor::ProjectFile::Kind::CXXSource); + if (Utils::HostOsInfo::isWindowsHost()) { + QCOMPARE(testData.flags, + (QStringList{"/Zc:inline", "/Zc:strictStrings", "/Zc:rvalueCast", "/Zi"})); + QCOMPARE(testData.headerPaths, + toUserHeaderPaths(QStringList{"C:/build-qt_llvm-msvc2017_64bit-Debug/tools\\clang\\lib\\Sema"})); + QCOMPARE(testData.macros, (Macros{{"UNICODE", "1"}, {"_HAS_EXCEPTIONS", "0"}, {"WIN32", "1"}, + {"_WINDOWS", "1"}})); + QCOMPARE(testData.fileKind, CppEditor::ProjectFile::Kind::CXXSource); + } } void CompilationDatabaseTests::testFileKindDifferentFromExtension() diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp index b17b2c3a0e5..632db825562 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp @@ -206,7 +206,7 @@ void filteredFlags(const QString &fileName, } // Skip all remaining Windows flags except feature flags. - if (flag.startsWith("/") && !flag.startsWith("/Z")) + if (Utils::HostOsInfo::isWindowsHost() && flag.startsWith("/") && !flag.startsWith("/Z")) continue; filtered.push_back(flag); From 6fee34887b2774d0484160cc12474118df8e4df2 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 20 Jun 2022 12:09:16 +0200 Subject: [PATCH 027/100] Valgrind: Fix test build Amends 25b1c59f744716d0f206663485ca582bfcd20d4. Change-Id: Ibbc2ab6aca74e8bffa97bca53909daf2240a3eab Reviewed-by: hjk --- src/plugins/valgrind/valgrindrunner.cpp | 5 +++++ src/plugins/valgrind/valgrindrunner.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/plugins/valgrind/valgrindrunner.cpp b/src/plugins/valgrind/valgrindrunner.cpp index 76d6b72f118..ce43ea5b41b 100644 --- a/src/plugins/valgrind/valgrindrunner.cpp +++ b/src/plugins/valgrind/valgrindrunner.cpp @@ -281,6 +281,11 @@ void ValgrindRunner::waitForFinished() const loop.exec(); } +QString ValgrindRunner::errorString() const +{ + return d->m_valgrindProcess.errorString(); +} + bool ValgrindRunner::start() { return d->run(); diff --git a/src/plugins/valgrind/valgrindrunner.h b/src/plugins/valgrind/valgrindrunner.h index a522820c058..e79dc1bbf42 100644 --- a/src/plugins/valgrind/valgrindrunner.h +++ b/src/plugins/valgrind/valgrindrunner.h @@ -56,6 +56,8 @@ public: void waitForFinished() const; + QString errorString() const; + bool start(); void stop(); From a13a83b65ddef15ee1d683c7eb5760ff7313862d Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Jun 2022 13:01:09 +0200 Subject: [PATCH 028/100] ExecuteFilter: Connect to done() signal instead of finished() Change-Id: I36e8ed92fc57f67da51acc7712a939bf8d7a78c6 Reviewed-by: Eike Ziller --- .../coreplugin/locator/executefilter.cpp | 20 ++++--------------- .../coreplugin/locator/executefilter.h | 2 +- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/plugins/coreplugin/locator/executefilter.cpp b/src/plugins/coreplugin/locator/executefilter.cpp index 59d6d7a3212..fe54059efc8 100644 --- a/src/plugins/coreplugin/locator/executefilter.cpp +++ b/src/plugins/coreplugin/locator/executefilter.cpp @@ -132,16 +132,10 @@ void ExecuteFilter::accept(const LocatorFilterEntry &selection, p->runHeadCommand(); } -void ExecuteFilter::finished() +void ExecuteFilter::done() { QTC_ASSERT(m_process, return); - const QString commandName = headCommand(); - QString message; - if (m_process->result() == ProcessResult::FinishedWithSuccess) - message = tr("Command \"%1\" finished.").arg(commandName); - else - message = tr("Command \"%1\" failed.").arg(commandName); - MessageManager::writeFlashing(message); + MessageManager::writeFlashing(m_process->exitMessage()); removeProcess(); runHeadCommand(); @@ -180,12 +174,6 @@ void ExecuteFilter::runHeadCommand() m_process->setWorkingDirectory(d.workingDirectory); m_process->setCommand(d.command); m_process->start(); - if (!m_process->waitForStarted(1000)) { - MessageManager::writeFlashing( - tr("Could not start process: %1.").arg(m_process->errorString())); - removeProcess(); - runHeadCommand(); - } } } @@ -196,7 +184,7 @@ void ExecuteFilter::createProcess() m_process = new Utils::QtcProcess; m_process->setEnvironment(Utils::Environment::systemEnvironment()); - connect(m_process, &QtcProcess::finished, this, &ExecuteFilter::finished); + connect(m_process, &QtcProcess::done, this, &ExecuteFilter::done); connect(m_process, &QtcProcess::readyReadStandardOutput, this, &ExecuteFilter::readStandardOutput); connect(m_process, &QtcProcess::readyReadStandardError, this, &ExecuteFilter::readStandardError); } @@ -207,7 +195,7 @@ void ExecuteFilter::removeProcess() return; m_taskQueue.dequeue(); - delete m_process; + m_process->deleteLater(); m_process = nullptr; } diff --git a/src/plugins/coreplugin/locator/executefilter.h b/src/plugins/coreplugin/locator/executefilter.h index 588bdad6ecd..7da5c086753 100644 --- a/src/plugins/coreplugin/locator/executefilter.h +++ b/src/plugins/coreplugin/locator/executefilter.h @@ -57,7 +57,7 @@ public: QString *newText, int *selectionStart, int *selectionLength) const override; private: - void finished(); + void done(); void readStandardOutput(); void readStandardError(); void runHeadCommand(); From 74e35d68a86636c51e55470602fa88776a96c3ea Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Jun 2022 13:53:26 +0200 Subject: [PATCH 029/100] Utils: Add a convenience function to fill clipboard and selection Relieves the user code side from repeated code which then tends to get forgotten. Change-Id: I079f97a658b55f3c79111df1946b8d72863ce513 Reviewed-by: Eike Ziller --- src/libs/utils/stringutils.cpp | 17 +++++++++++++++++ src/libs/utils/stringutils.h | 8 ++++++++ 2 files changed, 25 insertions(+) diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp index 75c37bd49f9..30f5c805aa8 100644 --- a/src/libs/utils/stringutils.cpp +++ b/src/libs/utils/stringutils.cpp @@ -29,6 +29,11 @@ #include "hostosinfo.h" #include "qtcassert.h" +#ifdef QT_WIDGETS_LIB +#include +#include +#endif + #include #include #include @@ -469,4 +474,16 @@ QTCREATOR_UTILS_EXPORT QString languageNameFromLanguageCode(const QString &langu return languageName; } +#ifdef QT_WIDGETS_LIB + +QTCREATOR_UTILS_EXPORT void setClipboardAndSelection(const QString &text) +{ + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(text); + if (clipboard->supportsSelection()) + clipboard->setText(text, QClipboard::Selection); +} + +#endif + } // namespace Utils diff --git a/src/libs/utils/stringutils.h b/src/libs/utils/stringutils.h index 70cf6738950..fd29223967b 100644 --- a/src/libs/utils/stringutils.h +++ b/src/libs/utils/stringutils.h @@ -122,4 +122,12 @@ QTCREATOR_UTILS_EXPORT QString wildcardToRegularExpression(const QString &origin QTCREATOR_UTILS_EXPORT QString languageNameFromLanguageCode(const QString &languageCode); + +#ifdef QT_WIDGETS_LIB + +// Feeds the global clipboard and, when present, the primary selection +QTCREATOR_UTILS_EXPORT void setClipboardAndSelection(const QString &text); + +#endif + } // namespace Utils From 2f54c9a364844cf29ae0a6c0bac384346a2fa44b Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Jun 2022 11:32:05 +0200 Subject: [PATCH 030/100] Use new convenience function for clipboard contents Change-Id: I4a856fa53e66d42bc5f08ee79c40ad071d2841bf Reviewed-by: Eike Ziller --- src/plugins/clangcodemodel/clangtextmark.cpp | 6 ++---- src/plugins/clangtools/diagnosticmark.cpp | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/plugins/clangcodemodel/clangtextmark.cpp b/src/plugins/clangcodemodel/clangtextmark.cpp index 6120e90e917..c9c33dc5959 100644 --- a/src/plugins/clangcodemodel/clangtextmark.cpp +++ b/src/plugins/clangcodemodel/clangtextmark.cpp @@ -29,7 +29,6 @@ #include "clangdclient.h" #include "clangdiagnostictooltipwidget.h" #include "clangeditordocumentprocessor.h" -#include "clangmodelmanagersupport.h" #include "clangutils.h" #include @@ -42,12 +41,11 @@ #include #include +#include #include #include #include -#include -#include #include #include #include @@ -319,7 +317,7 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath, QObject::connect(action, &QAction::triggered, [diag = m_diagnostic]() { const QString text = ClangDiagnosticWidget::createText({diag}, ClangDiagnosticWidget::InfoBar); - QApplication::clipboard()->setText(text, QClipboard::Clipboard); + setClipboardAndSelection(text); }); actions << action; diff --git a/src/plugins/clangtools/diagnosticmark.cpp b/src/plugins/clangtools/diagnosticmark.cpp index 632781c7127..37dd7693921 100644 --- a/src/plugins/clangtools/diagnosticmark.cpp +++ b/src/plugins/clangtools/diagnosticmark.cpp @@ -30,10 +30,9 @@ #include "diagnosticconfigswidget.h" #include +#include #include -#include -#include namespace ClangTools { namespace Internal { @@ -65,7 +64,7 @@ DiagnosticMark::DiagnosticMark(const Diagnostic &diagnostic) const QString text = createFullLocationString(diagnostic.location) + ": " + diagnostic.description; - QApplication::clipboard()->setText(text); + Utils::setClipboardAndSelection(text); }); actions << action; From c3dcc1ee38e496a6720a7c43a776ef9ed35a20be Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Jun 2022 11:42:24 +0200 Subject: [PATCH 031/100] Debugger: Use new clipboard setting convenience Change-Id: I4bbbff708287a0999c8009b6c2bd91967ee63808 Reviewed-by: Eike Ziller --- .../debugger/analyzer/detailederrorview.cpp | 8 ++++---- src/plugins/debugger/console/consoleview.cpp | 6 +++--- src/plugins/debugger/debuggertooltipmanager.cpp | 10 +++------- src/plugins/debugger/stackhandler.cpp | 15 +++------------ 4 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/plugins/debugger/analyzer/detailederrorview.cpp b/src/plugins/debugger/analyzer/detailederrorview.cpp index a5fad37821f..b1ac155afb2 100644 --- a/src/plugins/debugger/analyzer/detailederrorview.cpp +++ b/src/plugins/debugger/analyzer/detailederrorview.cpp @@ -30,12 +30,12 @@ #include #include +#include #include +#include #include #include -#include -#include #include #include #include @@ -54,12 +54,12 @@ DetailedErrorView::DetailedErrorView(QWidget *parent) : m_copyAction->setIcon(Utils::Icons::COPY.icon()); m_copyAction->setShortcut(QKeySequence::Copy); m_copyAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); - connect(m_copyAction, &QAction::triggered, [this] { + connect(m_copyAction, &QAction::triggered, this, [this] { const QModelIndexList selectedRows = selectionModel()->selectedRows(); QStringList data; for (const QModelIndex &index : selectedRows) data << model()->data(index, FullTextRole).toString(); - QApplication::clipboard()->setText(data.join('\n')); + Utils::setClipboardAndSelection(data.join('\n')); }); connect(this, &QAbstractItemView::clicked, [](const QModelIndex &index) { if (index.column() == LocationColumn) { diff --git a/src/plugins/debugger/console/consoleview.cpp b/src/plugins/debugger/console/consoleview.cpp index 93fec5b73e6..72ff8cedef8 100644 --- a/src/plugins/debugger/console/consoleview.cpp +++ b/src/plugins/debugger/console/consoleview.cpp @@ -30,14 +30,15 @@ #include #include #include + #include +#include #include #include #include #include #include -#include #include #include #include @@ -204,8 +205,7 @@ void ConsoleView::copyToClipboard(const QModelIndex &index) contents = QString::fromLatin1("%1 %2: %3").arg(contents).arg(filePath).arg( model()->data(index, ConsoleItem::LineRole).toString()); } - QClipboard *cb = QApplication::clipboard(); - cb->setText(contents); + Utils::setClipboardAndSelection(contents); } bool ConsoleView::canShowItemInTextEditor(const QModelIndex &index) diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index 8a6eab069a1..4177879653c 100644 --- a/src/plugins/debugger/debuggertooltipmanager.cpp +++ b/src/plugins/debugger/debuggertooltipmanager.cpp @@ -26,7 +26,6 @@ #include "debuggertooltipmanager.h" #include "debuggeractions.h" -#include "debuggercore.h" #include "debuggerengine.h" #include "debuggerinternalconstants.h" #include "debuggermainwindow.h" @@ -34,7 +33,6 @@ #include "sourceutils.h" #include "stackhandler.h" #include "watchhandler.h" -#include "watchwindow.h" #include #include @@ -53,6 +51,7 @@ #include #include #include +#include #include #include @@ -577,17 +576,14 @@ DebuggerToolTipWidget::DebuggerToolTipWidget() mainLayout->addWidget(toolBar); mainLayout->addWidget(treeView); - connect(copyButton, &QAbstractButton::clicked, [this] { + connect(copyButton, &QAbstractButton::clicked, this, [this] { QString text; QTextStream str(&text); model.forAllItems([&str](ToolTipWatchItem *item) { str << QString(item->level(), '\t') << item->name << '\t' << item->value << '\t' << item->type << '\n'; }); - QClipboard *clipboard = QApplication::clipboard(); - if (clipboard->supportsSelection()) - clipboard->setText(text, QClipboard::Selection); - clipboard->setText(text, QClipboard::Clipboard); + setClipboardAndSelection(text); }); connect(treeView, &QTreeView::expanded, &model, &ToolTipModel::expandNode); diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index c42c196b09f..4001b854486 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -40,9 +40,8 @@ #include #include #include +#include -#include -#include #include #include #include @@ -410,14 +409,6 @@ static QString selectedText(QWidget *widget, bool useAll) return str; } -static void copyTextToClipboard(const QString &str) -{ - QClipboard *clipboard = QApplication::clipboard(); - if (clipboard->supportsSelection()) - clipboard->setText(str, QClipboard::Selection); - clipboard->setText(str, QClipboard::Clipboard); -} - // Write stack frames as task file for displaying it in the build issues pane. void StackHandler::saveTaskFile() { @@ -458,11 +449,11 @@ bool StackHandler::contextMenuEvent(const ItemViewEvent &ev) menu->addAction(debuggerSettings()->expandStack.action()); addAction(this, menu, tr("Copy Contents to Clipboard"), true, [ev] { - copyTextToClipboard(selectedText(ev.view(), true)); + setClipboardAndSelection(selectedText(ev.view(), true)); }); addAction(this, menu, tr("Copy Selection to Clipboard"), true, [ev] { - copyTextToClipboard(selectedText(ev.view(), false)); + setClipboardAndSelection(selectedText(ev.view(), false)); }); addAction(this, menu, tr("Save as Task File..."), true, [this] { saveTaskFile(); }); From 0ae2e48ff132e6761803061f71a4ba0931de4020 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Jun 2022 12:01:33 +0200 Subject: [PATCH 032/100] FakeVim: Fix crash with debug build of Qt 6 915be6606ead2 in Qt base introduced an assert that triggers occasionally. This here moves the original check to the fakevim side, without changing (possibly wrong) functionality. Change-Id: I435ea53ecc0ba1a905dee2f4e3f8feb3c6dc7db3 Reviewed-by: Eike Ziller --- src/plugins/fakevim/fakevimhandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 56980bfb2c6..812bb994d0a 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -1237,7 +1237,7 @@ public: return '\n'; if (m_key == Key_Escape) return QChar(27); - return QChar(m_xkey); + return QChar(m_xkey & 0xffff); // FIXME } QString toString() const @@ -1254,7 +1254,7 @@ public: else if (m_xkey == '>') key = ""; else - key = QChar(m_xkey); + key = QChar(m_xkey & 0xffff); // FIXME } bool shift = isShift(); From 79b8e5397d340d70ad755c7bd8301846d89cafab Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 16 Jun 2022 15:21:34 +0200 Subject: [PATCH 033/100] ClangCodeModel: Prevent surprisingly late "follow symbol" reactions It can happen under certain circumstances (high system load, overworked clangd, ...) that "follow symbol" requests get replied to very late, with the user having manually navigated to the target document in the mean time or started doing something else entirely. In such a situation, it would be disruptive if we were to jump to a symbol suddenly, stealing the cursor from the unsuspecting user. We now prevent this by aborting the "follow symbol" procedure if the user does something else with the document. Fixes: QTCREATORBUG-20878 Change-Id: Iea52db661e8ba634951b18654a94e4b90580f001 Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdfollowsymbol.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/clangcodemodel/clangdfollowsymbol.cpp b/src/plugins/clangcodemodel/clangdfollowsymbol.cpp index 53ec97342f4..64993a03ba0 100644 --- a/src/plugins/clangcodemodel/clangdfollowsymbol.cpp +++ b/src/plugins/clangcodemodel/clangdfollowsymbol.cpp @@ -38,6 +38,7 @@ #include #include +#include #include using namespace CppEditor; @@ -143,6 +144,16 @@ ClangdFollowSymbol::ClangdFollowSymbol(ClangdClient *client, const QTextCursor & d(new Private(this, client, cursor, editorWidget, document->filePath(), callback, openInSplit)) { + // Abort if the user does something else with the document in the meantime. + connect(document, &TextDocument::contentsChanged, this, &ClangdFollowSymbol::done, + Qt::QueuedConnection); + if (editorWidget) { + connect(editorWidget, &CppEditorWidget::cursorPositionChanged, + this, &ClangdFollowSymbol::done, Qt::QueuedConnection); + } + connect(qApp, &QApplication::focusChanged, + this, &ClangdFollowSymbol::done, Qt::QueuedConnection); + // Step 1: Follow the symbol via "Go to Definition". At the same time, request the // AST node corresponding to the cursor position, so we can find out whether // we have to look for overrides. From 0fa349237daccfe64d63d6cff0ba236ac8555168 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Jun 2022 09:48:54 +0200 Subject: [PATCH 034/100] ClangCodeModel: Special rendering for deprecated completion items We add the attribute textually and show a warning icon. Fixes: QTCREATORBUG-2325 Change-Id: Icc0305a703e26c84095167087b30fa3456f97614 Reviewed-by: David Schulz --- .../languageserverprotocol/completion.cpp | 10 +++++++++ src/libs/languageserverprotocol/completion.h | 21 +++++++++++++++++++ src/libs/languageserverprotocol/jsonkeys.h | 1 + src/plugins/clangcodemodel/clangdclient.cpp | 11 ++++++++++ .../languageclientcompletionassist.cpp | 9 ++++++++ .../languageclientcompletionassist.h | 1 + 6 files changed, 53 insertions(+) diff --git a/src/libs/languageserverprotocol/completion.cpp b/src/libs/languageserverprotocol/completion.cpp index 9f04338e87e..10d38c71178 100644 --- a/src/libs/languageserverprotocol/completion.cpp +++ b/src/libs/languageserverprotocol/completion.cpp @@ -49,6 +49,16 @@ Utils::optional CompletionItem::insertTextForm return Utils::nullopt; } +Utils::optional> CompletionItem::tags() const +{ + if (const auto value = optionalValue(tagsKey)) { + QList tags; + for (auto it = value->cbegin(); it != value->cend(); ++it) + tags << static_cast(it->toInt()); + return tags; + } + return {}; +} CompletionItemResolveRequest::CompletionItemResolveRequest(const CompletionItem ¶ms) : Request(methodName, params) diff --git a/src/libs/languageserverprotocol/completion.h b/src/libs/languageserverprotocol/completion.h index ab5e43ac220..b635e121e42 100644 --- a/src/libs/languageserverprotocol/completion.h +++ b/src/libs/languageserverprotocol/completion.h @@ -214,6 +214,27 @@ public: void setData(const QJsonValue &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } + /** + * Completion item tags are extra annotations that tweak the rendering of a + * completion item. + * @since 3.15.0 + */ + enum CompletionItemTag { + Deprecated = 1, + }; + + /** + * Tags for this completion item. + * @since 3.15.0 + */ + Utils::optional> tags() const; + + /** + * Indicates if this item is deprecated. + * @deprecated Use `tags` instead if supported. + */ + Utils::optional deprecated() const { return optionalValue(deprecatedKey); } + bool isValid() const override { return contains(labelKey); } }; diff --git a/src/libs/languageserverprotocol/jsonkeys.h b/src/libs/languageserverprotocol/jsonkeys.h index f5c10a0b5d6..3c520ebad93 100644 --- a/src/libs/languageserverprotocol/jsonkeys.h +++ b/src/libs/languageserverprotocol/jsonkeys.h @@ -209,6 +209,7 @@ constexpr char symbolKindKey[] = "symbolKind"; constexpr char syncKindKey[] = "syncKind"; constexpr char synchronizationKey[] = "synchronization"; constexpr char tabSizeKey[] = "tabSize"; +constexpr char tagsKey[] = "tags"; constexpr char targetKey[] = "target"; constexpr char textDocumentKey[] = "textDocument"; constexpr char textDocumentSyncKey[] = "textDocumentSync"; diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 326539e5619..771ce6a44bd 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -741,6 +741,7 @@ public: private: QIcon icon() const override; + QString text() const override; }; class ClangdClient::ClangdCompletionAssistProcessor : public LanguageClientCompletionAssistProcessor @@ -2551,6 +2552,8 @@ ClangdCompletionItem::SpecialQtType ClangdCompletionItem::getQtType(const Comple QIcon ClangdCompletionItem::icon() const { + if (isDeprecated()) + return Utils::Icons::WARNING.icon(); const SpecialQtType qtType = getQtType(item()); switch (qtType) { case SpecialQtType::Signal: @@ -2566,6 +2569,14 @@ QIcon ClangdCompletionItem::icon() const return LanguageClientCompletionItem::icon(); } +QString ClangdCompletionItem::text() const +{ + const QString clangdValue = LanguageClientCompletionItem::text(); + if (isDeprecated()) + return "[[deprecated]]" + clangdValue; + return clangdValue; +} + MessageId ClangdClient::Private::getAndHandleAst(const TextDocOrFile &doc, const AstHandler &astHandler, AstCallbackMode callbackMode, const Range &range) diff --git a/src/plugins/languageclient/languageclientcompletionassist.cpp b/src/plugins/languageclient/languageclientcompletionassist.cpp index e10729987ce..0ab76a10c07 100644 --- a/src/plugins/languageclient/languageclientcompletionassist.cpp +++ b/src/plugins/languageclient/languageclientcompletionassist.cpp @@ -227,6 +227,15 @@ bool LanguageClientCompletionItem::isPerfectMatch(int pos, QTextDocument *doc) c return textToInsert == textAt(QTextCursor(doc), pos - length, length); } +bool LanguageClientCompletionItem::isDeprecated() const +{ + if (const auto tags = m_item.tags(); tags && tags->contains(CompletionItem::Deprecated)) + return true; + if (const auto deprecated = m_item.deprecated()) + return *deprecated; + return false; +} + class LanguageClientCompletionModel : public GenericProposalModel { public: diff --git a/src/plugins/languageclient/languageclientcompletionassist.h b/src/plugins/languageclient/languageclientcompletionassist.h index 2f5ba014fab..19a8ec93063 100644 --- a/src/plugins/languageclient/languageclientcompletionassist.h +++ b/src/plugins/languageclient/languageclientcompletionassist.h @@ -135,6 +135,7 @@ public: bool operator <(const LanguageClientCompletionItem &other) const; bool isPerfectMatch(int pos, QTextDocument *doc) const; + bool isDeprecated() const; private: LanguageServerProtocol::CompletionItem m_item; From fcb2807efaa8c8fbdc01776289300a3542ee2ba5 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 20 Jun 2022 14:04:04 +0200 Subject: [PATCH 035/100] Wizards: Make PySide6 default Change-Id: I6d84261e56dafcd55b7842e140d9c09935df70a8 Reviewed-by: David Schulz Reviewed-by: Christian Stenger --- .../projects/qtforpythonapplication/empty/wizard.json | 6 +++++- .../projects/qtforpythonapplication/mainwindow/wizard.json | 6 +++++- .../qtforpythonapplication/qtquickapplication/wizard.json | 2 +- .../projects/qtforpythonapplication/widget/wizard.json | 6 +++++- .../projects/qtforpythonapplication/widget_gen/wizard.json | 6 +++++- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json index 7a032fc0f11..fecabd09428 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json @@ -33,7 +33,11 @@ "name": "PySideVersion", "trDisplayName": "PySide version:", "type": "ComboBox", - "data": { "items": [ "PySide2", "PySide6" ] } + "data": + { + "index": 1, + "items": [ "PySide2", "PySide6" ] + } } ] }, diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json index 1e19a607f71..d9f575ecd9b 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json @@ -34,7 +34,11 @@ "name": "PySideVersion", "trDisplayName": "PySide version:", "type": "ComboBox", - "data": { "items": [ "PySide2", "PySide6" ] } + "data": + { + "index": 1, + "items": [ "PySide2", "PySide6" ] + } }, { "name": "Class", diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/qtquickapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/qtquickapplication/wizard.json index 68051e52f78..7ab73b917f4 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/qtquickapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/qtquickapplication/wizard.json @@ -39,7 +39,7 @@ "type": "ComboBox", "data": { - "index": 2, + "index": 0, "items": [ { diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget/wizard.json index 6b2bd45565f..b9c96c97886 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget/wizard.json @@ -34,7 +34,11 @@ "name": "PySideVersion", "trDisplayName": "PySide version:", "type": "ComboBox", - "data": { "items": [ "PySide2", "PySide6" ] } + "data": + { + "index": 1, + "items": [ "PySide2", "PySide6" ] + } }, { "name": "Class", diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget_gen/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget_gen/wizard.json index 1a2bcec74b4..91572c2bdd2 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget_gen/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget_gen/wizard.json @@ -34,7 +34,11 @@ "name": "PySideVersion", "trDisplayName": "PySide version:", "type": "ComboBox", - "data": { "items": [ "PySide2", "PySide6" ] } + "data": + { + "index": 1, + "items": [ "PySide2", "PySide6" ] + } }, { "name": "Class", From 9db4587db5739594a9b9c35877d9da525b8359c0 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 17 Jun 2022 12:33:07 +0200 Subject: [PATCH 036/100] CdbEngine: Connect to done() signal Instead of connecting to errorOccurred() and finished() signals. Change-Id: Id5e92fbccd361c7bce7718704f33e221649ab47b Reviewed-by: Reviewed-by: David Schulz --- src/plugins/debugger/cdb/cdbengine.cpp | 28 ++++++++++++-------------- src/plugins/debugger/cdb/cdbengine.h | 3 +-- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index e3602fba712..b8566b78740 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -211,8 +211,7 @@ CdbEngine::CdbEngine() : DebuggerSettings *s = debuggerSettings(); connect(s->createFullBacktrace.action(), &QAction::triggered, this, &CdbEngine::createFullBacktrace); - connect(&m_process, &QtcProcess::finished, this, &CdbEngine::processFinished); - connect(&m_process, &QtcProcess::errorOccurred, this, &CdbEngine::processError); + connect(&m_process, &QtcProcess::done, this, &CdbEngine::processDone); connect(&m_process, &QtcProcess::readyReadStandardOutput, this, &CdbEngine::readyReadStandardOut); connect(&m_process, &QtcProcess::readyReadStandardError, @@ -354,7 +353,7 @@ void CdbEngine::setupEngine() return; } - bool cdbIs64Bit = Utils::is64BitWindowsBinary(sp.debugger.command.executable()); + bool cdbIs64Bit = is64BitWindowsBinary(sp.debugger.command.executable()); if (!cdbIs64Bit) m_wow64State = noWow64Stack; const QFileInfo extensionFi(CdbEngine::extensionLibraryName(cdbIs64Bit)); @@ -702,12 +701,16 @@ void CdbEngine::abortDebuggerProcess() m_process.kill(); } -void CdbEngine::processFinished() +void CdbEngine::processDone() { - if (debug) + if (m_process.error() != QProcess::UnknownError) + showMessage(m_process.errorString(), LogError); + + if (debug) { qDebug("CdbEngine::processFinished %dms '%s' (exit state=%d, ex=%d)", elapsedLogTime(), qPrintable(stateName(state())), m_process.exitStatus(), m_process.exitCode()); + } notifyDebuggerProcessFinished(m_process.resultData(), "CDB"); } @@ -1039,7 +1042,7 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd) QList splittedArguments; int maxArgumentSize = maxCommandLength - prefix.length() - maxTokenLength; while (argumentSplitPos < arguments.size()) { - splittedArguments << Utils::midView(arguments, argumentSplitPos, maxArgumentSize); + splittedArguments << midView(arguments, argumentSplitPos, maxArgumentSize); argumentSplitPos += splittedArguments.last().length(); } QTC_CHECK(argumentSplitPos == arguments.size()); @@ -2446,11 +2449,6 @@ void CdbEngine::readyReadStandardError() showMessage(QString::fromLocal8Bit(m_process.readAllStandardError()), LogError); } -void CdbEngine::processError() -{ - showMessage(m_process.errorString(), LogError); -} - #if 0 // Join breakpoint ids for a multi-breakpoint id commands like 'bc', 'be', 'bd' static QByteArray multiBreakpointCommand(const char *cmdC, const Breakpoints &bps) @@ -2498,14 +2496,14 @@ public: const CppEditor::WorkingCopy &workingCopy) : m_snapshot(s), m_workingCopy(workingCopy) {} - unsigned fixLineNumber(const Utils::FilePath &filePath, unsigned lineNumber) const; + unsigned fixLineNumber(const FilePath &filePath, unsigned lineNumber) const; private: const CPlusPlus::Snapshot m_snapshot; CppEditor::WorkingCopy m_workingCopy; }; -static CPlusPlus::Document::Ptr getParsedDocument(const Utils::FilePath &filePath, +static CPlusPlus::Document::Ptr getParsedDocument(const FilePath &filePath, const CppEditor::WorkingCopy &workingCopy, const CPlusPlus::Snapshot &snapshot) { @@ -2520,7 +2518,7 @@ static CPlusPlus::Document::Ptr getParsedDocument(const Utils::FilePath &filePat return doc; } -unsigned BreakpointCorrectionContext::fixLineNumber(const Utils::FilePath &filePath, +unsigned BreakpointCorrectionContext::fixLineNumber(const FilePath &filePath, unsigned lineNumber) const { const CPlusPlus::Document::Ptr doc = getParsedDocument(filePath, @@ -2677,7 +2675,7 @@ static StackFrames parseFrames(const GdbMi &gdbmi, bool *incomplete = nullptr) frame.level = QString::number(i); const GdbMi fullName = frameMi["fullname"]; if (fullName.isValid()) { - frame.file = Utils::FilePath::fromString(fullName.data()).normalizedPathName(); + frame.file = FilePath::fromString(fullName.data()).normalizedPathName(); frame.line = frameMi["line"].data().toInt(); frame.usable = false; // To be decided after source path mapping. const GdbMi languageMi = frameMi["language"]; diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 811b539c000..4fdc5f957cd 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -106,8 +106,7 @@ public: private: void readyReadStandardOut(); void readyReadStandardError(); - void processError(); - void processFinished(); + void processDone(); void runCommand(const DebuggerCommand &cmd) override; void adjustOperateByInstruction(bool); From c3f55f6b5074e3c349b958636b67647647393712 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 20 Jun 2022 13:25:01 +0200 Subject: [PATCH 037/100] ClangCodeModel: Fix "switch decl/def" for free functions Fixes: QTCREATORBUG-27731 Change-Id: Ibab872b9d4ecedba097c91ca44d279a1bb8208b6 Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdclient.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 771ce6a44bd..6441202bb6a 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -326,7 +326,8 @@ public: for (auto it = path.rbegin(); it != path.rend(); ++it) { if (it->role() == "declaration" && (it->kind() == "CXXMethod" || it->kind() == "CXXConversion" - || it->kind() == "CXXConstructor" || it->kind() == "CXXDestructor")) { + || it->kind() == "CXXConstructor" || it->kind() == "CXXDestructor" + || it->kind() == "Function")) { return *it; } } From 178d555151ec8820e19ca33eb2a13f49d846b611 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 8 Jun 2022 09:23:24 +0200 Subject: [PATCH 038/100] LanguageClient: prevent assert in semantic highlighter Do not send messages to server that are not reachable, but queue the highlighting requests until the client is fully initialized. Change-Id: I7da140ec33fb1974d3eaed03110ed85dc3a87594 Reviewed-by: Qt CI Bot Reviewed-by: Christian Kandeler --- .../semantichighlightsupport.cpp | 27 +++++++++++++++++-- .../languageclient/semantichighlightsupport.h | 3 +++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/plugins/languageclient/semantichighlightsupport.cpp b/src/plugins/languageclient/semantichighlightsupport.cpp index 4cef4cd5cc8..a7aca308643 100644 --- a/src/plugins/languageclient/semantichighlightsupport.cpp +++ b/src/plugins/languageclient/semantichighlightsupport.cpp @@ -68,12 +68,16 @@ void SemanticTokenSupport::refresh() void SemanticTokenSupport::reloadSemanticTokens(TextDocument *textDocument) { - reloadSemanticTokensImpl(textDocument); + if (m_client->reachable()) + reloadSemanticTokensImpl(textDocument); + else + queueDocumentReload(textDocument); } void SemanticTokenSupport::reloadSemanticTokensImpl(TextDocument *textDocument, int remainingRerequests) { + m_docReloadQueue.remove(textDocument); const SemanticRequestTypes supportedRequests = supportedSemanticRequests(textDocument); if (supportedRequests.testFlag(SemanticRequestType::None)) return; @@ -122,7 +126,10 @@ void SemanticTokenSupport::reloadSemanticTokensImpl(TextDocument *textDocument, void SemanticTokenSupport::updateSemanticTokens(TextDocument *textDocument) { - updateSemanticTokensImpl(textDocument); + if (m_client->reachable()) + updateSemanticTokensImpl(textDocument); + else + queueDocumentReload(textDocument); } void SemanticTokenSupport::updateSemanticTokensImpl(TextDocument *textDocument, @@ -168,6 +175,22 @@ void SemanticTokenSupport::updateSemanticTokensImpl(TextDocument *textDocument, reloadSemanticTokens(textDocument); } +void SemanticTokenSupport::queueDocumentReload(TextEditor::TextDocument *doc) +{ + if (m_docReloadQueue.contains(doc)) + return; + m_docReloadQueue << doc; + connect( + m_client, + &Client::initialized, + this, + [this, doc = QPointer(doc)]() { + if (doc) + reloadSemanticTokensImpl(doc); + }, + Qt::QueuedConnection); +} + void SemanticTokenSupport::clearHighlight(TextEditor::TextDocument *doc) { if (m_tokens.contains(doc->filePath())){ diff --git a/src/plugins/languageclient/semantichighlightsupport.h b/src/plugins/languageclient/semantichighlightsupport.h index e903fe58f94..a03947c9153 100644 --- a/src/plugins/languageclient/semantichighlightsupport.h +++ b/src/plugins/languageclient/semantichighlightsupport.h @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -86,6 +87,7 @@ public: private: void reloadSemanticTokensImpl(TextEditor::TextDocument *doc, int remainingRerequests = 3); void updateSemanticTokensImpl(TextEditor::TextDocument *doc, int remainingRerequests = 3); + void queueDocumentReload(TextEditor::TextDocument *doc); LanguageServerProtocol::SemanticRequestTypes supportedSemanticRequests( TextEditor::TextDocument *document) const; void handleSemanticTokens(const Utils::FilePath &filePath, @@ -117,6 +119,7 @@ private: SemanticTokensHandler m_tokensHandler; QStringList m_tokenTypeStrings; QStringList m_tokenModifierStrings; + QSet m_docReloadQueue; }; } // namespace LanguageClient From ff6f3dc65d6f70f0e4a0ce96c9c07ea33f3d9fe1 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Jun 2022 13:53:26 +0200 Subject: [PATCH 039/100] Valgrind: Consolidate message production and consumption Change-Id: I779f97a658b55f3c79111df1946b8d72863ce513 Reviewed-by: Jarek Kobus --- src/plugins/valgrind/valgrindengine.cpp | 9 ++------- src/plugins/valgrind/valgrindengine.h | 1 - src/plugins/valgrind/valgrindrunner.cpp | 10 +++++----- src/plugins/valgrind/valgrindrunner.h | 3 ++- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp index fc914a1d9f8..fdb147e1c74 100644 --- a/src/plugins/valgrind/valgrindengine.cpp +++ b/src/plugins/valgrind/valgrindengine.cpp @@ -61,8 +61,8 @@ ValgrindToolRunner::ValgrindToolRunner(RunControl *runControl) m_settings.fromMap(runControl->settingsData(ANALYZER_VALGRIND_SETTINGS)); - connect(&m_runner, &ValgrindRunner::processOutputReceived, - this, &ValgrindToolRunner::receiveProcessOutput); + connect(&m_runner, &ValgrindRunner::appendMessage, + this, &ValgrindToolRunner::appendMessage); connect(&m_runner, &ValgrindRunner::valgrindExecuted, this, [this](const QString &commandLine) { appendMessage(commandLine, NormalMessageFormat); @@ -162,11 +162,6 @@ void ValgrindToolRunner::runnerFinished() reportStopped(); } -void ValgrindToolRunner::receiveProcessOutput(const QString &output, OutputFormat format) -{ - appendMessage(output, format); -} - void ValgrindToolRunner::receiveProcessError(const QString &message, QProcess::ProcessError error) { if (error == QProcess::FailedToStart) { diff --git a/src/plugins/valgrind/valgrindengine.h b/src/plugins/valgrind/valgrindengine.h index 06e767b7629..8bb050405af 100644 --- a/src/plugins/valgrind/valgrindengine.h +++ b/src/plugins/valgrind/valgrindengine.h @@ -60,7 +60,6 @@ private: void handleProgressFinished(); void runnerFinished(); - void receiveProcessOutput(const QString &output, Utils::OutputFormat format); void receiveProcessError(const QString &message, QProcess::ProcessError error); QStringList genericToolArguments() const; diff --git a/src/plugins/valgrind/valgrindrunner.cpp b/src/plugins/valgrind/valgrindrunner.cpp index ce43ea5b41b..376cc30927e 100644 --- a/src/plugins/valgrind/valgrindrunner.cpp +++ b/src/plugins/valgrind/valgrindrunner.cpp @@ -120,12 +120,12 @@ bool ValgrindRunner::Private::run() this, &ValgrindRunner::Private::processDone); connect(&m_valgrindProcess, &QtcProcess::readyReadStandardOutput, q, [this] { - q->processOutputReceived(QString::fromUtf8(m_valgrindProcess.readAllStandardOutput()), - Utils::StdOutFormat); + emit q->appendMessage(QString::fromUtf8(m_valgrindProcess.readAllStandardOutput()), + StdOutFormat); }); connect(&m_valgrindProcess, &QtcProcess::readyReadStandardError, q, [this] { - q->processOutputReceived(QString::fromUtf8(m_valgrindProcess.readAllStandardError()), - Utils::StdErrFormat); + emit q->appendMessage(QString::fromUtf8(m_valgrindProcess.readAllStandardError()), + StdErrFormat); }); if (cmd.executable().osType() == OsTypeMac) { @@ -210,7 +210,7 @@ void ValgrindRunner::Private::remoteProcessStarted() void ValgrindRunner::Private::findPidProcessDone() { if (m_findPID.result() != ProcessResult::FinishedWithSuccess) { - emit q->processOutputReceived(m_findPID.allOutput(), StdErrFormat); + emit q->appendMessage(m_findPID.allOutput(), StdErrFormat); return; } QString out = m_findPID.cleanedStdOut(); diff --git a/src/plugins/valgrind/valgrindrunner.h b/src/plugins/valgrind/valgrindrunner.h index e79dc1bbf42..f6182a895a7 100644 --- a/src/plugins/valgrind/valgrindrunner.h +++ b/src/plugins/valgrind/valgrindrunner.h @@ -64,8 +64,9 @@ public: XmlProtocol::ThreadedParser *parser() const; signals: + void appendMessage(const QString &, Utils::OutputFormat); + void logMessageReceived(const QByteArray &); - void processOutputReceived(const QString &, Utils::OutputFormat); void processErrorReceived(const QString &, QProcess::ProcessError); void valgrindExecuted(const QString &); void valgrindStarted(qint64 pid); From 5f53b983ffc2b0169681b8dd49171777fb8fe456 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Jun 2022 15:59:58 +0200 Subject: [PATCH 040/100] Valgrind: Simplify pid search in remote setup We have first-hand information nowadays from the process itself. Change-Id: I99cc61b9c8534740b0eb59a8fabed7e648eb2146 Reviewed-by: Reviewed-by: Jarek Kobus --- src/plugins/valgrind/valgrindrunner.cpp | 77 +------------------------ 1 file changed, 3 insertions(+), 74 deletions(-) diff --git a/src/plugins/valgrind/valgrindrunner.cpp b/src/plugins/valgrind/valgrindrunner.cpp index 376cc30927e..73ade61a18f 100644 --- a/src/plugins/valgrind/valgrindrunner.cpp +++ b/src/plugins/valgrind/valgrindrunner.cpp @@ -50,16 +50,11 @@ public: void processStarted(); void processDone(); - void localProcessStarted(); - void remoteProcessStarted(); - void findPidProcessDone(); ValgrindRunner *q; Runnable m_debuggee; QtcProcess m_valgrindProcess; - QtcProcess m_findPID; - CommandLine m_valgrindCommand; QHostAddress localServerAddress; @@ -146,10 +141,8 @@ bool ValgrindRunner::Private::run() void ValgrindRunner::Private::processStarted() { - if (!m_valgrindProcess.commandLine().executable().needsDevice()) - localProcessStarted(); - else - remoteProcessStarted(); + const qint64 pid = m_valgrindProcess.processId(); + emit q->valgrindStarted(pid); } void ValgrindRunner::Private::processDone() @@ -163,70 +156,6 @@ void ValgrindRunner::Private::processDone() emit q->finished(); } -void ValgrindRunner::Private::localProcessStarted() -{ - qint64 pid = m_valgrindProcess.processId(); - emit q->valgrindStarted(pid); -} - -void ValgrindRunner::Private::remoteProcessStarted() -{ - // find out what PID our process has - - // NOTE: valgrind cloaks its name, - // e.g.: valgrind --tool=memcheck foobar - // => ps aux, pidof will see valgrind.bin - // => pkill/killall/top... will see memcheck-amd64-linux or similar - // hence we need to do something more complex... - - // plain path to exe, m_valgrindExe contains e.g. env vars etc. pp. - // FIXME: Really? - const QString proc = m_valgrindCommand.executable().toString().split(' ').last(); - QString procEscaped = proc; - procEscaped.replace("/", "\\\\/"); - - const FilePath debuggee = m_debuggee.command.executable(); - const CommandLine cmd( - debuggee.withNewPath("/bin/sh"), - // sleep required since otherwise we might only match "bash -c..." and not the actual - // valgrind run - QString("-c \"" - "sleep 1; ps ax" // list all processes with aliased name - " | grep '%1.*%2'" // find valgrind process that runs with our exec - " | awk '\\$5 ~ /^%3/" // 5th column must start with valgrind process - " {print \\$1;}'" // print 1st then (with PID) - "\"").arg(proc, debuggee.fileName(), procEscaped), - CommandLine::Raw - ); - - m_findPID.setCommand(cmd); - - connect(&m_findPID, &QtcProcess::done, - this, &ValgrindRunner::Private::findPidProcessDone); - - m_findPID.start(); -} - -void ValgrindRunner::Private::findPidProcessDone() -{ - if (m_findPID.result() != ProcessResult::FinishedWithSuccess) { - emit q->appendMessage(m_findPID.allOutput(), StdErrFormat); - return; - } - QString out = m_findPID.cleanedStdOut(); - if (out.isEmpty()) - return; - bool ok; - const qint64 pid = out.trimmed().toLongLong(&ok); - if (!ok) { -// m_remote.m_errorString = tr("Could not determine remote PID."); -// emit ValgrindRunner::Private::error(QProcess::FailedToStart); -// close(); - } else { - emit q->valgrindStarted(pid); - } -} - ValgrindRunner::ValgrindRunner(QObject *parent) : QObject(parent), d(new Private(this)) { @@ -246,7 +175,7 @@ ValgrindRunner::~ValgrindRunner() d = nullptr; } -void ValgrindRunner::setValgrindCommand(const Utils::CommandLine &command) +void ValgrindRunner::setValgrindCommand(const CommandLine &command) { d->m_valgrindCommand = command; } From 425a0c8835243c93b6c68300fa76160337d83a78 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Jun 2022 11:45:36 +0200 Subject: [PATCH 041/100] AutoTest: Connect to done() signal instead of finished() QtcProcess::done() is also emitted when process failed to start. Change-Id: I08f6f104014d1c90c0f761de352dada620207d86 Reviewed-by: Christian Stenger --- .../autotest/boost/boosttestoutputreader.cpp | 8 +++----- .../autotest/boost/boosttestoutputreader.h | 2 +- src/plugins/autotest/gtest/gtestoutputreader.cpp | 5 ++--- src/plugins/autotest/testrunner.cpp | 15 +++++++-------- src/plugins/autotest/testrunner.h | 2 +- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/plugins/autotest/boost/boosttestoutputreader.cpp b/src/plugins/autotest/boost/boosttestoutputreader.cpp index a9668fc8e80..b87f9ab764b 100644 --- a/src/plugins/autotest/boost/boosttestoutputreader.cpp +++ b/src/plugins/autotest/boost/boosttestoutputreader.cpp @@ -51,10 +51,8 @@ BoostTestOutputReader::BoostTestOutputReader(const QFutureInterfaceexitCode(); if (m_reportLevel == ReportLevel::No && m_testCaseCount != -1) { int reportedFailsAndSkips = m_summary[ResultType::Fail] + m_summary[ResultType::Skip]; diff --git a/src/plugins/autotest/boost/boosttestoutputreader.h b/src/plugins/autotest/boost/boosttestoutputreader.h index b5cab378a7c..2bfd9af3f94 100644 --- a/src/plugins/autotest/boost/boosttestoutputreader.h +++ b/src/plugins/autotest/boost/boosttestoutputreader.h @@ -47,7 +47,7 @@ protected: TestResultPtr createDefaultResult() const override; private: - void onFinished(); + void onDone(); void sendCompleteInformation(); void handleMessageMatch(const QRegularExpressionMatch &match); void reportNoOutputFinish(const QString &description, ResultType type); diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp index 0c9f0b87334..4935b6599b3 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.cpp +++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp @@ -45,9 +45,8 @@ GTestOutputReader::GTestOutputReader(const QFutureInterface &futu , m_projectFile(projectFile) { if (m_testApplication) { - connect(m_testApplication, &Utils::QtcProcess::finished, - this, [this]() { - int exitCode = m_testApplication->exitCode(); + connect(m_testApplication, &Utils::QtcProcess::done, this, [this] { + const int exitCode = m_testApplication->exitCode(); if (exitCode == 1 && !m_description.isEmpty()) { createAndReportResult(tr("Running tests failed.\n %1\nExecutable: %2") .arg(m_description).arg(id()), ResultType::MessageFatal); diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 942730ba9d8..90c4f72a1d0 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -197,7 +197,7 @@ bool TestRunner::currentConfigValid() m_fakeFutureInterface->reportFinished(); onFinished(); } else { - onProcessFinished(); + onProcessDone(); } return false; } @@ -263,21 +263,20 @@ void TestRunner::scheduleNext() return; if (!m_currentConfig->project()) - onProcessFinished(); + onProcessDone(); setUpProcess(); - QTC_ASSERT(m_currentProcess, onProcessFinished(); return); + QTC_ASSERT(m_currentProcess, onProcessDone(); return); QTC_ASSERT(!m_currentOutputReader, delete m_currentOutputReader); m_currentOutputReader = m_currentConfig->outputReader(*m_fakeFutureInterface, m_currentProcess); - QTC_ASSERT(m_currentOutputReader, onProcessFinished();return); + QTC_ASSERT(m_currentOutputReader, onProcessDone();return); connect(m_currentOutputReader, &TestOutputReader::newOutputLineAvailable, TestResultsPane::instance(), &TestResultsPane::addOutputLine); setUpProcessEnv(); - connect(m_currentProcess, &Utils::QtcProcess::finished, - this, &TestRunner::onProcessFinished); + connect(m_currentProcess, &Utils::QtcProcess::done, this, &TestRunner::onProcessDone); const int timeout = AutotestPlugin::settings()->timeout; m_cancelTimer.setInterval(timeout); m_cancelTimer.start(); @@ -292,7 +291,7 @@ void TestRunner::scheduleNext() reportResult(ResultType::MessageFatal, tr("Failed to start test for project \"%1\".").arg(m_currentConfig->displayName()) + processInformation(m_currentProcess) + rcInfo(m_currentConfig)); - onProcessFinished(); + onProcessDone(); } } @@ -315,7 +314,7 @@ void TestRunner::cancelCurrent(TestRunner::CancelReason reason) } } -void TestRunner::onProcessFinished() +void TestRunner::onProcessDone() { if (m_executingTests && m_currentConfig) { QTC_CHECK(m_fakeFutureInterface); diff --git a/src/plugins/autotest/testrunner.h b/src/plugins/autotest/testrunner.h index 961312b6410..0d41f7d161c 100644 --- a/src/plugins/autotest/testrunner.h +++ b/src/plugins/autotest/testrunner.h @@ -90,7 +90,7 @@ private: void setUpProcessEnv(); void scheduleNext(); void cancelCurrent(CancelReason reason); - void onProcessFinished(); + void onProcessDone(); void resetInternalPointers(); void runTests(); From 44bb33012809d238138037b3ac9382215c0233aa Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Jun 2022 13:50:03 +0200 Subject: [PATCH 042/100] ProjectExplorer: Split RunWorker::appendMessage overloads ... into separate functions. Makes the use of the parameter clearer and is easier to connect too. Change-Id: I061b0b5c847ae1e695afc75332e634ddf2576d6c Reviewed-by: David Schulz --- src/plugins/projectexplorer/runcontrol.cpp | 13 +++++++++---- src/plugins/projectexplorer/runcontrol.h | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp index b826b215698..f8da814b7a6 100644 --- a/src/plugins/projectexplorer/runcontrol.cpp +++ b/src/plugins/projectexplorer/runcontrol.cpp @@ -1379,7 +1379,7 @@ void SimpleTargetRunnerPrivate::handleStandardOutput() const QByteArray data = m_process.readAllStandardOutput(); const QString msg = m_outputCodec->toUnicode( data.constData(), data.length(), &m_outputCodecState); - q->appendMessage(msg, StdOutFormat, false); + q->appendMessageChunk(msg, StdOutFormat); } void SimpleTargetRunnerPrivate::handleStandardError() @@ -1387,7 +1387,7 @@ void SimpleTargetRunnerPrivate::handleStandardError() const QByteArray data = m_process.readAllStandardError(); const QString msg = m_outputCodec->toUnicode( data.constData(), data.length(), &m_errorCodecState); - q->appendMessage(msg, StdErrFormat, false); + q->appendMessageChunk(msg, StdErrFormat); } void SimpleTargetRunnerPrivate::start() @@ -1766,14 +1766,19 @@ void RunWorker::reportFailure(const QString &msg) * Appends a message in the specified \a format to * the owning RunControl's \uicontrol{Application Output} pane. */ -void RunWorker::appendMessage(const QString &msg, OutputFormat format, bool appendNewLine) +void RunWorker::appendMessage(const QString &msg, OutputFormat format) { - if (!appendNewLine || msg.endsWith('\n')) + if (msg.endsWith('\n')) emit d->runControl->appendMessage(msg, format); else emit d->runControl->appendMessage(msg + '\n', format); } +void RunWorker::appendMessageChunk(const QString &msg, OutputFormat format) +{ + emit d->runControl->appendMessage(msg, format); +} + IDevice::ConstPtr RunWorker::device() const { return d->runControl->device(); diff --git a/src/plugins/projectexplorer/runcontrol.h b/src/plugins/projectexplorer/runcontrol.h index ebb0ec54a0b..0ff9b8778e9 100644 --- a/src/plugins/projectexplorer/runcontrol.h +++ b/src/plugins/projectexplorer/runcontrol.h @@ -92,7 +92,8 @@ public: QVariant recordedData(const QString &channel) const; // Part of read-only interface of RunControl for convenience. - void appendMessage(const QString &msg, Utils::OutputFormat format, bool appendNewLine = true); + void appendMessage(const QString &msg, Utils::OutputFormat format); + void appendMessageChunk(const QString &msg, Utils::OutputFormat format); IDeviceConstPtr device() const; // States From 3b0add4b16bc3c634f9063c5db735d1552e7388e Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 17 Jun 2022 13:11:08 +0200 Subject: [PATCH 043/100] DeviceShell: Merge done() and errorOccurred() signals into one Don't connect to QtcProcess::errorOccurred() signal, as it's going to be removed soon. Rely on done() signal instead. Change-Id: I28260f8eb77911a23de80512881cf7220f1bc1fc Reviewed-by: hjk --- src/libs/utils/deviceshell.cpp | 4 ++-- src/libs/utils/deviceshell.h | 4 ++-- src/plugins/docker/dockerdevice.cpp | 7 +++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/libs/utils/deviceshell.cpp b/src/libs/utils/deviceshell.cpp index 807ac2c4bd5..7256b9cb3a9 100644 --- a/src/libs/utils/deviceshell.cpp +++ b/src/libs/utils/deviceshell.cpp @@ -277,8 +277,8 @@ void DeviceShell::startupFailed(const CommandLine &cmdLine) bool DeviceShell::start() { m_shellProcess = new QtcProcess(); - connect(m_shellProcess, &QtcProcess::done, this, [this] { emit done(); }); - connect(m_shellProcess, &QtcProcess::errorOccurred, this, &DeviceShell::errorOccurred); + connect(m_shellProcess, &QtcProcess::done, m_shellProcess, + [this] { emit done(m_shellProcess->resultData()); }); connect(m_shellProcess, &QObject::destroyed, this, [this] { m_shellProcess = nullptr; }); connect(&m_thread, &QThread::finished, m_shellProcess, [this] { closeShellProcess(); }); diff --git a/src/libs/utils/deviceshell.h b/src/libs/utils/deviceshell.h index 8def78f6d3c..d25746ddf12 100644 --- a/src/libs/utils/deviceshell.h +++ b/src/libs/utils/deviceshell.h @@ -36,6 +36,7 @@ namespace Utils { class CommandLine; +class ProcessResultData; class QtcProcess; class DeviceShellImpl; @@ -69,8 +70,7 @@ public: State state() const; signals: - void done(); - void errorOccurred(QProcess::ProcessError error); + void done(const ProcessResultData &resultData); protected: virtual void startupFailed(const CommandLine &cmdLine); diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 888884b3a19..04f1a1ab043 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -450,8 +450,11 @@ void DockerDevicePrivate::startContainer() LOG("Container via process: " << m_container); m_shell = std::make_unique(m_container); - connect(m_shell.get(), &DeviceShell::errorOccurred, this, [this] (QProcess::ProcessError error) { - qCWarning(dockerDeviceLog) << "Container shell encountered error:" << error; + connect(m_shell.get(), &DeviceShell::done, this, [this] (const ProcessResultData &resultData) { + if (resultData.m_error != QProcess::UnknownError) + return; + + qCWarning(dockerDeviceLog) << "Container shell encountered error:" << resultData.m_error; m_shell.reset(); DockerApi::recheckDockerDaemon(); From ca47064020d9f07d4dfa7a203fe7834fc7fa1562 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 20 Jun 2022 13:55:25 +0200 Subject: [PATCH 044/100] Python: Fix scripts path to global/venv pyside installations ... when checking for pyside tools. Change-Id: I1aaac9dd9da76f08ada031cc88761dba36c4e3b6 Reviewed-by: Christian Stenger --- src/plugins/python/pythonrunconfiguration.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp index a04d2b723a7..9882cfb5fb0 100644 --- a/src/plugins/python/pythonrunconfiguration.cpp +++ b/src/plugins/python/pythonrunconfiguration.cpp @@ -236,7 +236,12 @@ void PythonRunConfiguration::currentInterpreterChanged() // Workaround that pip might return an incomplete file list on windows if (HostOsInfo::isWindowsHost() && !python.needsDevice() && !info.location.isEmpty() && m_pySideUicPath.isEmpty()) { - const FilePath scripts = info.location.parentDir().pathAppended("Scripts"); + // Scripts is next to the site-packages install dir for user installations + FilePath scripts = info.location.parentDir().pathAppended("Scripts"); + if (!scripts.exists()) { + // in global/venv installations Scripts is next to Lib/site-packages + scripts = info.location.parentDir().parentDir().pathAppended("Scripts"); + } auto userInstalledPySideTool = [&](const QString &toolName) { const FilePath tool = scripts.pathAppended(HostOsInfo::withExecutableSuffix(toolName)); return tool.isExecutableFile() ? tool : FilePath(); From e74999ccedd6ea529ca4f21fe4e881bede57bcb0 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 16 Jun 2022 15:33:32 +0200 Subject: [PATCH 045/100] Python: check for pyside tools after installation Change-Id: Icf9ae0ec08a78efc51216daa3304e76f8e812d5f Reviewed-by: Christian Stenger --- src/plugins/python/pyside.cpp | 4 ++++ src/plugins/python/pyside.h | 6 +++++- src/plugins/python/pythonrunconfiguration.cpp | 15 +++++++++++++-- src/plugins/python/pythonrunconfiguration.h | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/plugins/python/pyside.cpp b/src/plugins/python/pyside.cpp index 6965305f2e6..2bdfebc2783 100644 --- a/src/plugins/python/pyside.cpp +++ b/src/plugins/python/pyside.cpp @@ -106,6 +106,10 @@ void PySideInstaller::installPyside(const Utils::FilePath &python, auto install = new PipInstallTask(python); connect(install, &PipInstallTask::finished, install, &QObject::deleteLater); + connect(install, &PipInstallTask::finished, this, [=](bool success){ + if (success) + emit pySideInstalled(python, pySide); + }); install->setPackage(PipPackage(pySide)); install->run(); } diff --git a/src/plugins/python/pyside.h b/src/plugins/python/pyside.h index f749399903f..d396c726b4a 100644 --- a/src/plugins/python/pyside.h +++ b/src/plugins/python/pyside.h @@ -40,13 +40,17 @@ namespace Internal { class PySideInstaller : public QObject { - Q_DECLARE_TR_FUNCTIONS(Python::Internal::PySideInstaller) + Q_OBJECT public: static PySideInstaller *instance(); static void checkPySideInstallation(const Utils::FilePath &python, TextEditor::TextDocument *document); + +signals: + void pySideInstalled(const Utils::FilePath &python, const QString &pySide); + private: PySideInstaller(); diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp index 9882cfb5fb0..5f63c19091f 100644 --- a/src/plugins/python/pythonrunconfiguration.cpp +++ b/src/plugins/python/pythonrunconfiguration.cpp @@ -202,6 +202,12 @@ PythonRunConfiguration::PythonRunConfiguration(Target *target, Id id) setRunnableModifier([](Runnable &r) { r.workingDirectory = r.workingDirectory.onDevice(r.command.executable()); }); + + connect(PySideInstaller::instance(), &PySideInstaller::pySideInstalled, this, + [this](const FilePath &python) { + if (python == aspect()->currentInterpreter().command) + checkForPySide(python); + }); } PythonRunConfiguration::~PythonRunConfiguration() @@ -209,9 +215,8 @@ PythonRunConfiguration::~PythonRunConfiguration() qDeleteAll(m_extraCompilers); } -void PythonRunConfiguration::currentInterpreterChanged() +void PythonRunConfiguration::checkForPySide(const FilePath &python) { - const FilePath python = aspect()->currentInterpreter().command; BuildStepList *buildSteps = target()->activeBuildConfiguration()->buildSteps(); Utils::FilePath pySideProjectPath; @@ -255,6 +260,12 @@ void PythonRunConfiguration::currentInterpreterChanged() if (auto pySideBuildStep = buildSteps->firstOfType()) pySideBuildStep->updatePySideProjectPath(pySideProjectPath); +} + +void PythonRunConfiguration::currentInterpreterChanged() +{ + const FilePath python = aspect()->currentInterpreter().command; + checkForPySide(python); for (FilePath &file : project()->files(Project::AllFiles)) { if (auto document = TextEditor::TextDocument::textDocumentForFilePath(file)) { diff --git a/src/plugins/python/pythonrunconfiguration.h b/src/plugins/python/pythonrunconfiguration.h index 5394896b948..89bddac83e2 100644 --- a/src/plugins/python/pythonrunconfiguration.h +++ b/src/plugins/python/pythonrunconfiguration.h @@ -43,6 +43,7 @@ public: QList extraCompilers() const; private: + void checkForPySide(const Utils::FilePath &python); void updateExtraCompilers(); Utils::FilePath m_pySideUicPath; From 591fc12ffa094e1da419abc0b0acf1931e504608 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 15 Jun 2022 12:44:44 +0200 Subject: [PATCH 046/100] Python: remove static cast of client interface in client constructor Change-Id: I475a2b79438b8392085f1d9bf2cdb8b7369efa68 Reviewed-by: Christian Stenger --- src/plugins/python/pythonlanguageclient.cpp | 4 ++-- src/plugins/python/pythonlanguageclient.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/python/pythonlanguageclient.cpp b/src/plugins/python/pythonlanguageclient.cpp index b129a069049..2a4ea8c7d97 100644 --- a/src/plugins/python/pythonlanguageclient.cpp +++ b/src/plugins/python/pythonlanguageclient.cpp @@ -181,9 +181,9 @@ PyLSClient *clientForPython(const FilePath &python) return client; } -PyLSClient::PyLSClient(BaseClientInterface *interface) +PyLSClient::PyLSClient(PyLSInterface *interface) : Client(interface) - , m_extraCompilerOutputDir(static_cast(interface)->m_extraPythonPath.path()) + , m_extraCompilerOutputDir(interface->m_extraPythonPath.path()) { connect(this, &Client::initialized, this, &PyLSClient::updateConfiguration); connect(PythonSettings::instance(), &PythonSettings::pylsConfigurationChanged, diff --git a/src/plugins/python/pythonlanguageclient.h b/src/plugins/python/pythonlanguageclient.h index ed0c16b5893..c58103c5fbf 100644 --- a/src/plugins/python/pythonlanguageclient.h +++ b/src/plugins/python/pythonlanguageclient.h @@ -40,12 +40,13 @@ namespace Internal { class PySideUicExtraCompiler; class PythonLanguageServerState; +class PyLSInterface; class PyLSClient : public LanguageClient::Client { Q_OBJECT public: - explicit PyLSClient(LanguageClient::BaseClientInterface *interface); + explicit PyLSClient(PyLSInterface *interface); ~PyLSClient(); void openDocument(TextEditor::TextDocument *document) override; From 3156c33d12561337a3ad7ab9cdb7157330e2fba5 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Jun 2022 15:03:39 +0200 Subject: [PATCH 047/100] CallgrindToolRunner: Connect to done() signal instead of finished() This should also handle a failed to start case. Change-Id: I120a342cb9ec0ec980eae00d357905ca08bac5ed Reviewed-by: hjk --- src/plugins/valgrind/callgrindengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/valgrind/callgrindengine.cpp b/src/plugins/valgrind/callgrindengine.cpp index aa9b3fad546..da6d214d000 100644 --- a/src/plugins/valgrind/callgrindengine.cpp +++ b/src/plugins/valgrind/callgrindengine.cpp @@ -224,7 +224,7 @@ void CallgrindToolRunner::run(Option option) #if CALLGRIND_CONTROL_DEBUG m_controllerProcess->setProcessChannelMode(QProcess::ForwardedChannels); #endif - connect(m_controllerProcess.get(), &QtcProcess::finished, + connect(m_controllerProcess.get(), &QtcProcess::done, this, &CallgrindToolRunner::controllerProcessDone); const FilePath control = From f7e9623369a189442063e2a1e6e257901c583f61 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Jun 2022 16:50:14 +0200 Subject: [PATCH 048/100] Utils: Remove one spurious static function from QtcProcess The next one could probably be merged into FilePath::searchInPath Change-Id: If32fe77fb19b628a44d212bb8420443bd4f04899 Reviewed-by: Jarek Kobus Reviewed-by: --- src/libs/utils/qtcprocess.cpp | 6 ------ src/libs/utils/qtcprocess.h | 4 ++-- src/plugins/qmakeprojectmanager/externaleditors.cpp | 7 +++++-- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 5612b2c8197..6c00b1d291c 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -1617,12 +1617,6 @@ void QtcProcess::stop() d->m_killTimer.start(d->m_process->m_setup.m_reaperTimeout); } -QString QtcProcess::locateBinary(const QString &binary) -{ - const QByteArray path = qgetenv("PATH"); - return locateBinary(QString::fromLocal8Bit(path), binary); -} - /*! \class Utils::SynchronousProcess diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h index 8763bc14e26..8169e926b45 100644 --- a/src/libs/utils/qtcprocess.h +++ b/src/libs/utils/qtcprocess.h @@ -144,10 +144,10 @@ public: // These (or some of them) may be potentially moved outside of the class. // For some we may aggregate in another public utils class (or subclass of QtcProcess)? - // TODO: How below 3 methods relate to QtcProcess? Action: move them somewhere else. + // TODO: How below 2 methods relate to QtcProcess? + // Action: move/merge them somewhere else, FilePath::searchInPath() ? // Helpers to find binaries. Do not use it for other path variables // and file types. - static QString locateBinary(const QString &binary); static QString locateBinary(const QString &path, const QString &binary); static QString normalizeNewlines(const QString &text); diff --git a/src/plugins/qmakeprojectmanager/externaleditors.cpp b/src/plugins/qmakeprojectmanager/externaleditors.cpp index 3d43bd45418..9d22c2ad0cf 100644 --- a/src/plugins/qmakeprojectmanager/externaleditors.cpp +++ b/src/plugins/qmakeprojectmanager/externaleditors.cpp @@ -170,8 +170,11 @@ bool ExternalQtEditor::getEditorLaunchData(const Utils::FilePath &filePath, qtVersionsToCheck = Utils::filteredUnique(qtVersionsToCheck); // can still contain nullptr data->binary = findFirstCommand(qtVersionsToCheck, m_commandForQtVersion); // fallback - if (data->binary.isEmpty()) - data->binary = Utils::QtcProcess::locateBinary(m_commandForQtVersion(nullptr)); + if (data->binary.isEmpty()) { + const QString path = qEnvironmentVariable("PATH"); + data->binary = Utils::QtcProcess::locateBinary(path, m_commandForQtVersion(nullptr)); + } + if (data->binary.isEmpty()) { *errorMessage = msgAppNotFound(id().toString()); return false; From d1b7e90b7dab46c6314fc71519f5248255801992 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Jun 2022 14:21:12 +0200 Subject: [PATCH 049/100] Use Utils::setClipboardAndSelection() more often Change-Id: I094f07cdb1e5e8c8026bb36d0a486719567641b9 Reviewed-by: Eike Ziller --- src/plugins/debugger/watchhandler.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index b4656da8f2e..3663daa5296 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -60,7 +60,6 @@ #include #include -#include #include #include #include @@ -1663,14 +1662,6 @@ static QString removeWatchActionText(QString exp) return WatchModel::tr("Remove Expression Evaluator for \"%1\"").arg(Utils::quoteAmpersands(exp)); } -static void copyToClipboard(const QString &clipboardText) -{ - QClipboard *clipboard = QApplication::clipboard(); - if (clipboard->supportsSelection()) - clipboard->setText(clipboardText, QClipboard::Selection); - clipboard->setText(clipboardText, QClipboard::Clipboard); -} - void WatchModel::inputNewExpression() { QDialog dlg; @@ -1788,19 +1779,19 @@ bool WatchModel::contextMenuEvent(const ItemViewEvent &ev) addAction(this, menu, tr("Copy View Contents to Clipboard"), true, - [this] { copyToClipboard(editorContents()); }); + [this] { setClipboardAndSelection(editorContents()); }); addAction(this, menu, tr("Copy Current Value to Clipboard"), item, [this, name = item ? item->iname : QString()] { if (auto item = findItem(name)) - copyToClipboard(item->value); + setClipboardAndSelection(item->value); }); // addAction(menu, tr("Copy Selected Rows to Clipboard"), // selectionModel()->hasSelection(), - // [this] { copyToClipboard(editorContents(selectionModel()->selectedRows())); }); + // [this] { setClipboardAndSelection(editorContents(selectionModel()->selectedRows())); }); addAction(this, menu, tr("Open View Contents in Editor"), m_engine->debuggerActionsEnabled(), From 3151ae48452550dc51802c1828587a2630eb5c8d Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Jun 2022 15:58:48 +0200 Subject: [PATCH 050/100] NimSuggestServer: Connect to done() signal instead of finished() Get rid of crashed() signal, since the handler of this signal was doing the same as the handler for finished() signal. Change-Id: I7cb2d53bbf0bdcea58c2101efe97a82505333740 Reviewed-by: hjk --- src/plugins/nim/suggest/nimsuggest.cpp | 15 +++--------- src/plugins/nim/suggest/nimsuggest.h | 3 +-- src/plugins/nim/suggest/server.cpp | 34 ++++++-------------------- src/plugins/nim/suggest/server.h | 10 +++----- 4 files changed, 16 insertions(+), 46 deletions(-) diff --git a/src/plugins/nim/suggest/nimsuggest.cpp b/src/plugins/nim/suggest/nimsuggest.cpp index e51efea0545..fc12c160233 100644 --- a/src/plugins/nim/suggest/nimsuggest.cpp +++ b/src/plugins/nim/suggest/nimsuggest.cpp @@ -32,8 +32,7 @@ NimSuggest::NimSuggest(QObject *parent) : QObject(parent) { connect(&m_server, &NimSuggestServer::started, this, &NimSuggest::onServerStarted); - connect(&m_server, &NimSuggestServer::crashed, this, &NimSuggest::onServerCrashed); - connect(&m_server, &NimSuggestServer::finished, this, &NimSuggest::onServerFinished); + connect(&m_server, &NimSuggestServer::done, this, &NimSuggest::onServerDone); connect(&m_client, &NimSuggestClient::disconnected, this, &NimSuggest::onClientDisconnected); connect(&m_client, &NimSuggestClient::connected, this, &NimSuggest::onClientConnected); @@ -134,14 +133,13 @@ void NimSuggest::disconnectClient() void NimSuggest::stopServer() { - m_server.kill(); + m_server.stop(); } void NimSuggest::startServer() { - if (!m_projectFile.isEmpty() && !m_executablePath.isEmpty()) { + if (!m_projectFile.isEmpty() && !m_executablePath.isEmpty()) m_server.start(m_executablePath, m_projectFile); - } } void NimSuggest::onServerStarted() @@ -150,18 +148,13 @@ void NimSuggest::onServerStarted() connectClient(); } -void NimSuggest::onServerCrashed() +void NimSuggest::onServerDone() { setServerReady(false); disconnectClient(); restart(); } -void NimSuggest::onServerFinished() -{ - onServerCrashed(); -} - void NimSuggest::onClientConnected() { setClientReady(true); diff --git a/src/plugins/nim/suggest/nimsuggest.h b/src/plugins/nim/suggest/nimsuggest.h index 5043455cec3..48190496ab2 100644 --- a/src/plugins/nim/suggest/nimsuggest.h +++ b/src/plugins/nim/suggest/nimsuggest.h @@ -75,8 +75,7 @@ private: void startServer(); void onServerStarted(); - void onServerCrashed(); - void onServerFinished(); + void onServerDone(); void onClientConnected(); void onClientDisconnected(); diff --git a/src/plugins/nim/suggest/server.cpp b/src/plugins/nim/suggest/server.cpp index 48e29d1ceb7..e55151afbe8 100644 --- a/src/plugins/nim/suggest/server.cpp +++ b/src/plugins/nim/suggest/server.cpp @@ -32,17 +32,11 @@ namespace Suggest { NimSuggestServer::NimSuggestServer(QObject *parent) : QObject(parent) { - connect(&m_process, &QtcProcess::finished, this, &NimSuggestServer::onFinished); - connect(&m_process, &QtcProcess::started, this, &NimSuggestServer::onStarted); + connect(&m_process, &QtcProcess::done, this, &NimSuggestServer::onDone); connect(&m_process, &QtcProcess::readyReadStandardOutput, this, &NimSuggestServer::onStandardOutputAvailable); } -NimSuggestServer::~NimSuggestServer() -{ - kill(); -} - QString NimSuggestServer::executablePath() const { return m_executablePath; @@ -61,7 +55,7 @@ bool NimSuggestServer::start(const QString &executablePath, return false; } - m_port = 0; + stop(); m_executablePath = executablePath; m_projectFilePath = projectFilePath; m_process.setCommand({FilePath::fromString(executablePath), {"--epc", m_projectFilePath}}); @@ -69,11 +63,9 @@ bool NimSuggestServer::start(const QString &executablePath, return true; } -void NimSuggestServer::kill() +void NimSuggestServer::stop() { - disconnect(&m_process, &QtcProcess::finished, this, &NimSuggestServer::onFinished); - m_process.kill(); - m_process.waitForFinished(); + m_process.close(); clearState(); } @@ -87,15 +79,10 @@ QString NimSuggestServer::projectFilePath() const return m_projectFilePath; } -void NimSuggestServer::onStarted() -{ - m_started = true; -} - void NimSuggestServer::onStandardOutputAvailable() { - if (m_started && !m_portAvailable) { - auto output = QString::fromUtf8(m_process.readAllStandardOutput()); + if (!m_portAvailable) { + const QString output = QString::fromUtf8(m_process.readAllStandardOutput()); m_port = static_cast(output.toUInt()); m_portAvailable = true; emit started(); @@ -104,19 +91,14 @@ void NimSuggestServer::onStandardOutputAvailable() } } -void NimSuggestServer::onFinished() +void NimSuggestServer::onDone() { clearState(); - - if (m_process.exitStatus() == QProcess::CrashExit) - emit crashed(); - else - emit finished(); + emit done(); } void NimSuggestServer::clearState() { - m_started = false; m_portAvailable = false; m_port = 0; } diff --git a/src/plugins/nim/suggest/server.h b/src/plugins/nim/suggest/server.h index 53f0590288a..4d3a5857ef0 100644 --- a/src/plugins/nim/suggest/server.h +++ b/src/plugins/nim/suggest/server.h @@ -40,10 +40,9 @@ class NimSuggestServer : public QObject public: NimSuggestServer(QObject *parent = nullptr); - ~NimSuggestServer(); bool start(const QString &executablePath, const QString &projectFilePath); - void kill(); + void stop(); quint16 port() const; QString executablePath() const; @@ -51,16 +50,13 @@ public: signals: void started(); - void finished(); - void crashed(); + void done(); private: - void onStarted(); void onStandardOutputAvailable(); - void onFinished(); + void onDone(); void clearState(); - bool m_started = false; bool m_portAvailable = false; Utils::QtcProcess m_process; quint16 m_port = 0; From 7ef6a455cd23e8e2fc7a616e73bf608ca38a4f5e Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 17 Jun 2022 23:31:54 +0200 Subject: [PATCH 051/100] Valgrind: Simplify internals Change-Id: Ice10c1bf96f3102c6525d37ee7ec25b10604ebb9 Reviewed-by: hjk --- src/plugins/valgrind/callgrindengine.cpp | 17 +- src/plugins/valgrind/callgrindengine.h | 1 - src/plugins/valgrind/valgrindrunner.cpp | 207 ++++++++++------------- src/plugins/valgrind/valgrindrunner.h | 7 - 4 files changed, 96 insertions(+), 136 deletions(-) diff --git a/src/plugins/valgrind/callgrindengine.cpp b/src/plugins/valgrind/callgrindengine.cpp index da6d214d000..974a4848440 100644 --- a/src/plugins/valgrind/callgrindengine.cpp +++ b/src/plugins/valgrind/callgrindengine.cpp @@ -57,17 +57,15 @@ CallgrindToolRunner::CallgrindToolRunner(RunControl *runControl) { setId("CallgrindToolRunner"); - connect(&m_runner, &ValgrindRunner::finished, - this, &CallgrindToolRunner::slotFinished); - connect(&m_parser, &Callgrind::Parser::parserDataReady, - this, &CallgrindToolRunner::slotFinished); - connect(&m_runner, &ValgrindRunner::valgrindStarted, this, [this](qint64 pid) { m_pid = pid; }); - - connect(&m_runner, &ValgrindRunner::extraProcessFinished, this, [this] { + connect(&m_runner, &ValgrindRunner::finished, this, [this] { triggerParse(); + emit parserDataReady(this); + }); + connect(&m_parser, &Callgrind::Parser::parserDataReady, this, [this] { + emit parserDataReady(this); }); m_valgrindRunnable = runControl->runnable(); @@ -152,11 +150,6 @@ Callgrind::ParseData *CallgrindToolRunner::takeParserData() return m_parser.takeData(); } -void CallgrindToolRunner::slotFinished() -{ - emit parserDataReady(this); -} - void CallgrindToolRunner::showStatusMessage(const QString &message) { Debugger::showPermanentStatusMessage(message); diff --git a/src/plugins/valgrind/callgrindengine.h b/src/plugins/valgrind/callgrindengine.h index 21f7abcce0a..1037b234167 100644 --- a/src/plugins/valgrind/callgrindengine.h +++ b/src/plugins/valgrind/callgrindengine.h @@ -77,7 +77,6 @@ signals: void parserDataReady(CallgrindToolRunner *engine); private: - void slotFinished(); void showStatusMessage(const QString &message); /** diff --git a/src/plugins/valgrind/valgrindrunner.cpp b/src/plugins/valgrind/valgrindrunner.cpp index 73ade61a18f..f606789cf11 100644 --- a/src/plugins/valgrind/valgrindrunner.cpp +++ b/src/plugins/valgrind/valgrindrunner.cpp @@ -44,44 +44,98 @@ namespace Valgrind { class ValgrindRunner::Private : public QObject { public: - Private(ValgrindRunner *owner) : q(owner) {} + Private(ValgrindRunner *owner) : q(owner) { + connect(&m_process, &QtcProcess::started, this, [this] { + emit q->valgrindStarted(m_process.processId()); + }); + connect(&m_process, &QtcProcess::done, this, [this] { + if (m_process.result() != ProcessResult::FinishedWithSuccess) + emit q->processErrorReceived(m_process.errorString(), m_process.error()); + emit q->finished(); + }); + connect(&m_process, &QtcProcess::readyReadStandardOutput, this, [this] { + emit q->appendMessage(QString::fromUtf8(m_process.readAllStandardOutput()), + StdOutFormat); + }); + connect(&m_process, &QtcProcess::readyReadStandardError, this, [this] { + emit q->appendMessage(QString::fromUtf8(m_process.readAllStandardError()), + StdErrFormat); + }); + connect(&m_xmlServer, &QTcpServer::newConnection, this, &Private::xmlSocketConnected); + connect(&m_logServer, &QTcpServer::newConnection, this, &Private::logSocketConnected); + } + + void xmlSocketConnected(); + void logSocketConnected(); + bool startServers(); bool run(); - void processStarted(); - void processDone(); - ValgrindRunner *q; Runnable m_debuggee; - QtcProcess m_valgrindProcess; - CommandLine m_valgrindCommand; + CommandLine m_command; + QtcProcess m_process; - QHostAddress localServerAddress; - QProcess::ProcessChannelMode channelMode = QProcess::SeparateChannels; + QHostAddress m_localServerAddress; - QTcpServer xmlServer; - XmlProtocol::ThreadedParser parser; - QTcpServer logServer; - QTcpSocket *logSocket = nullptr; - - // Workaround for valgrind bug when running vgdb with xml output - // https://bugs.kde.org/show_bug.cgi?id=343902 - bool disableXml = false; + QTcpServer m_xmlServer; + XmlProtocol::ThreadedParser m_parser; + QTcpServer m_logServer; }; +void ValgrindRunner::Private::xmlSocketConnected() +{ + QTcpSocket *socket = m_xmlServer.nextPendingConnection(); + QTC_ASSERT(socket, return); + m_xmlServer.close(); + m_parser.parse(socket); +} + +void ValgrindRunner::Private::logSocketConnected() +{ + QTcpSocket *logSocket = m_logServer.nextPendingConnection(); + QTC_ASSERT(logSocket, return); + connect(logSocket, &QIODevice::readyRead, this, [this, logSocket] { + emit q->logMessageReceived(logSocket->readAll()); + }); + m_logServer.close(); +} + +bool ValgrindRunner::Private::startServers() +{ + const bool xmlOK = m_xmlServer.listen(m_localServerAddress); + const QString ip = m_localServerAddress.toString(); + if (!xmlOK) { + emit q->processErrorReceived(tr("XmlServer on %1:").arg(ip) + ' ' + + m_xmlServer.errorString(), QProcess::FailedToStart ); + return false; + } + m_xmlServer.setMaxPendingConnections(1); + const bool logOK = m_logServer.listen(m_localServerAddress); + if (!logOK) { + emit q->processErrorReceived(tr("LogServer on %1:").arg(ip) + ' ' + + m_logServer.errorString(), QProcess::FailedToStart ); + return false; + } + m_logServer.setMaxPendingConnections(1); + return true; +} + bool ValgrindRunner::Private::run() { CommandLine cmd; - cmd.setExecutable(m_valgrindCommand.executable()); + cmd.setExecutable(m_command.executable()); - if (!localServerAddress.isNull()) { - if (!q->startServers()) + if (!m_localServerAddress.isNull()) { + if (!startServers()) return false; cmd.addArg("--child-silent-after-fork=yes"); - bool enableXml = !disableXml; + // Workaround for valgrind bug when running vgdb with xml output + // https://bugs.kde.org/show_bug.cgi?id=343902 + bool enableXml = true; auto handleSocketParameter = [&enableXml, &cmd](const QString &prefix, const QTcpServer &tcpServer) { @@ -97,32 +151,17 @@ bool ValgrindRunner::Private::run() } }; - handleSocketParameter("--xml-socket", xmlServer); - handleSocketParameter("--log-socket", logServer); + handleSocketParameter("--xml-socket", m_xmlServer); + handleSocketParameter("--log-socket", m_logServer); if (enableXml) cmd.addArg("--xml=yes"); } - cmd.addArgs(m_valgrindCommand.arguments(), CommandLine::Raw); + cmd.addArgs(m_command.arguments(), CommandLine::Raw); - m_valgrindProcess.setProcessChannelMode(channelMode); // consider appending our options last so they override any interfering user-supplied options // -q as suggested by valgrind manual - connect(&m_valgrindProcess, &QtcProcess::started, - this, &ValgrindRunner::Private::processStarted); - connect(&m_valgrindProcess, &QtcProcess::done, - this, &ValgrindRunner::Private::processDone); - - connect(&m_valgrindProcess, &QtcProcess::readyReadStandardOutput, q, [this] { - emit q->appendMessage(QString::fromUtf8(m_valgrindProcess.readAllStandardOutput()), - StdOutFormat); - }); - connect(&m_valgrindProcess, &QtcProcess::readyReadStandardError, q, [this] { - emit q->appendMessage(QString::fromUtf8(m_valgrindProcess.readAllStandardError()), - StdErrFormat); - }); - if (cmd.executable().osType() == OsTypeMac) { // May be slower to start but without it we get no filenames for symbols. cmd.addArg("--dsymutil=yes"); @@ -132,30 +171,13 @@ bool ValgrindRunner::Private::run() emit q->valgrindExecuted(cmd.toUserOutput()); - m_valgrindProcess.setCommand(cmd); - m_valgrindProcess.setWorkingDirectory(m_debuggee.workingDirectory); - m_valgrindProcess.setEnvironment(m_debuggee.environment); - m_valgrindProcess.start(); + m_process.setCommand(cmd); + m_process.setWorkingDirectory(m_debuggee.workingDirectory); + m_process.setEnvironment(m_debuggee.environment); + m_process.start(); return true; } -void ValgrindRunner::Private::processStarted() -{ - const qint64 pid = m_valgrindProcess.processId(); - emit q->valgrindStarted(pid); -} - -void ValgrindRunner::Private::processDone() -{ - emit q->extraProcessFinished(); - - if (m_valgrindProcess.result() != ProcessResult::FinishedWithSuccess) - emit q->processErrorReceived(m_valgrindProcess.errorString(), m_valgrindProcess.error()); - - // make sure we don't wait for the connection anymore - emit q->finished(); -} - ValgrindRunner::ValgrindRunner(QObject *parent) : QObject(parent), d(new Private(this)) { @@ -163,11 +185,11 @@ ValgrindRunner::ValgrindRunner(QObject *parent) ValgrindRunner::~ValgrindRunner() { - if (d->m_valgrindProcess.isRunning()) { + if (d->m_process.isRunning()) { // make sure we don't delete the thread while it's still running waitForFinished(); } - if (d->parser.isRunning()) { + if (d->m_parser.isRunning()) { // make sure we don't delete the thread while it's still running waitForFinished(); } @@ -177,7 +199,7 @@ ValgrindRunner::~ValgrindRunner() void ValgrindRunner::setValgrindCommand(const CommandLine &command) { - d->m_valgrindCommand = command; + d->m_command = command; } void ValgrindRunner::setDebuggee(const Runnable &debuggee) @@ -187,22 +209,22 @@ void ValgrindRunner::setDebuggee(const Runnable &debuggee) void ValgrindRunner::setProcessChannelMode(QProcess::ProcessChannelMode mode) { - d->channelMode = mode; + d->m_process.setProcessChannelMode(mode); } void ValgrindRunner::setLocalServerAddress(const QHostAddress &localServerAddress) { - d->localServerAddress = localServerAddress; + d->m_localServerAddress = localServerAddress; } void ValgrindRunner::setUseTerminal(bool on) { - d->m_valgrindProcess.setTerminalMode(on ? TerminalMode::On : TerminalMode::Off); + d->m_process.setTerminalMode(on ? TerminalMode::On : TerminalMode::Off); } void ValgrindRunner::waitForFinished() const { - if (d->m_valgrindProcess.state() == QProcess::NotRunning) + if (d->m_process.state() == QProcess::NotRunning) return; QEventLoop loop; @@ -212,7 +234,7 @@ void ValgrindRunner::waitForFinished() const QString ValgrindRunner::errorString() const { - return d->m_valgrindProcess.errorString(); + return d->m_process.errorString(); } bool ValgrindRunner::start() @@ -222,59 +244,12 @@ bool ValgrindRunner::start() void ValgrindRunner::stop() { - d->m_valgrindProcess.stop(); + d->m_process.stop(); } XmlProtocol::ThreadedParser *ValgrindRunner::parser() const { - return &d->parser; -} - -void ValgrindRunner::xmlSocketConnected() -{ - QTcpSocket *socket = d->xmlServer.nextPendingConnection(); - QTC_ASSERT(socket, return); - d->xmlServer.close(); - d->parser.parse(socket); -} - -void ValgrindRunner::logSocketConnected() -{ - d->logSocket = d->logServer.nextPendingConnection(); - QTC_ASSERT(d->logSocket, return); - connect(d->logSocket, &QIODevice::readyRead, - this, &ValgrindRunner::readLogSocket); - d->logServer.close(); -} - -void ValgrindRunner::readLogSocket() -{ - QTC_ASSERT(d->logSocket, return); - emit logMessageReceived(d->logSocket->readAll()); -} - -bool ValgrindRunner::startServers() -{ - bool check = d->xmlServer.listen(d->localServerAddress); - const QString ip = d->localServerAddress.toString(); - if (!check) { - emit processErrorReceived(tr("XmlServer on %1:").arg(ip) + ' ' - + d->xmlServer.errorString(), QProcess::FailedToStart ); - return false; - } - d->xmlServer.setMaxPendingConnections(1); - connect(&d->xmlServer, &QTcpServer::newConnection, - this, &ValgrindRunner::xmlSocketConnected); - check = d->logServer.listen(d->localServerAddress); - if (!check) { - emit processErrorReceived(tr("LogServer on %1:").arg(ip) + ' ' - + d->logServer.errorString(), QProcess::FailedToStart ); - return false; - } - d->logServer.setMaxPendingConnections(1); - connect(&d->logServer, &QTcpServer::newConnection, - this, &ValgrindRunner::logSocketConnected); - return true; + return &d->m_parser; } } // namespace Valgrind diff --git a/src/plugins/valgrind/valgrindrunner.h b/src/plugins/valgrind/valgrindrunner.h index f6182a895a7..c8701b6e89a 100644 --- a/src/plugins/valgrind/valgrindrunner.h +++ b/src/plugins/valgrind/valgrindrunner.h @@ -71,15 +71,8 @@ signals: void valgrindExecuted(const QString &); void valgrindStarted(qint64 pid); void finished(); - void extraProcessFinished(); private: - bool startServers(); - - void xmlSocketConnected(); - void logSocketConnected(); - void readLogSocket(); - class Private; Private *d; }; From 01398fb1d46d8c1483b362773444de9a7f12e2d0 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Jun 2022 15:29:34 +0200 Subject: [PATCH 052/100] BareMetal: Use upcoming-standard process exit message Change-Id: Id90b01eaa3afcf768ae07821c435b1db1680d3cb Reviewed-by: Jarek Kobus --- .../debugservers/uvsc/uvscserverprovider.cpp | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp index ed0c419e87e..1fddaada16c 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp @@ -91,12 +91,12 @@ UvscServerProvider::UvscServerProvider(const UvscServerProvider &other) setEngineType(UvscEngineType); } -void UvscServerProvider::setToolsIniFile(const Utils::FilePath &toolsIniFile) +void UvscServerProvider::setToolsIniFile(const FilePath &toolsIniFile) { m_toolsIniFile = toolsIniFile; } -Utils::FilePath UvscServerProvider::toolsIniFile() const +FilePath UvscServerProvider::toolsIniFile() const { return m_toolsIniFile; } @@ -251,8 +251,7 @@ bool UvscServerProvider::fromMap(const QVariantMap &data) return true; } -Utils::FilePath UvscServerProvider::projectFilePath(DebuggerRunTool *runTool, - QString &errorMessage) const +FilePath UvscServerProvider::projectFilePath(DebuggerRunTool *runTool, QString &errorMessage) const { const FilePath projectPath = buildProjectFilePath(runTool); std::ofstream ofs(projectPath.toString().toStdString(), std::ofstream::out); @@ -332,12 +331,12 @@ void UvscServerProviderConfigWidget::discard() IDebugServerProviderConfigWidget::discard(); } -void UvscServerProviderConfigWidget::setToolsIniFile(const Utils::FilePath &toolsIniFile) +void UvscServerProviderConfigWidget::setToolsIniFile(const FilePath &toolsIniFile) { m_toolsIniChooser->setFilePath(toolsIniFile); } -Utils::FilePath UvscServerProviderConfigWidget::toolsIniFile() const +FilePath UvscServerProviderConfigWidget::toolsIniFile() const { return m_toolsIniChooser->filePath(); } @@ -386,21 +385,16 @@ UvscServerProviderRunner::UvscServerProviderRunner(ProjectExplorer::RunControl * this->runControl()->setApplicationProcessHandle(pid); reportStarted(); }); - connect(&m_process, &QtcProcess::finished, this, [this] { - const QProcess::ProcessError error = m_process.error(); - const QString message = (error == QProcess::UnknownError) - ? m_process.exitMessage() - : userMessageForProcessError(error, m_process.commandLine().executable()); - appendMessage(message, Utils::NormalMessageFormat); + connect(&m_process, &QtcProcess::done, this, [this] { + appendMessage(m_process.exitMessage(), NormalMessageFormat); reportStopped(); }); } void UvscServerProviderRunner::start() { - const QString msg = RunControl::tr("Starting %1 ...") - .arg(m_process.commandLine().toUserOutput()); - appendMessage(msg, Utils::NormalMessageFormat); + const QString msg = RunControl::tr("Starting %1 ...").arg(m_process.commandLine().displayName()); + appendMessage(msg, NormalMessageFormat); m_process.start(); } From d7b1e87fac17b609ff07e3a9d278926ffa3b48ee Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Jun 2022 17:38:32 +0200 Subject: [PATCH 053/100] ChangeSelectionDialog: Connect to done() signal instead of finished() Don't call blocking waitForStarted() and handle failed to start case inside done() handler. Change-Id: I6f88703c4ddc2c26af27b449eaa5be9ef087b1a2 Reviewed-by: Orgad Shaneh --- src/plugins/git/changeselectiondialog.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/plugins/git/changeselectiondialog.cpp b/src/plugins/git/changeselectiondialog.cpp index 57bd97c1d98..5dd3e199b91 100644 --- a/src/plugins/git/changeselectiondialog.cpp +++ b/src/plugins/git/changeselectiondialog.cpp @@ -165,6 +165,8 @@ void ChangeSelectionDialog::setDetails() m_ui->detailsText->setPlainText(m_process->cleanedStdOut()); palette.setColor(QPalette::Text, theme->color(Theme::TextColorNormal)); m_ui->changeNumberEdit->setPalette(palette); + } else if (m_process->result() == ProcessResult::StartFailed) { + m_ui->detailsText->setPlainText(tr("Error: Could not start Git.")); } else { m_ui->detailsText->setPlainText(tr("Error: Unknown reference")); palette.setColor(QPalette::Text, theme->color(Theme::TextColorError)); @@ -218,17 +220,12 @@ void ChangeSelectionDialog::recalculateDetails() } m_process.reset(new QtcProcess); + connect(m_process.get(), &QtcProcess::done, this, &ChangeSelectionDialog::setDetails); m_process->setWorkingDirectory(workingDir); m_process->setEnvironment(m_gitEnvironment); m_process->setCommand({m_gitExecutable, {"show", "--decorate", "--stat=80", ref}}); - - connect(m_process.get(), &QtcProcess::finished, this, &ChangeSelectionDialog::setDetails); - m_process->start(); - if (!m_process->waitForStarted()) - m_ui->detailsText->setPlainText(tr("Error: Could not start Git.")); - else - m_ui->detailsText->setPlainText(tr("Fetching commit data...")); + m_ui->detailsText->setPlainText(tr("Fetching commit data...")); } void ChangeSelectionDialog::changeTextChanged(const QString &text) From a4c0014b88fa06bff865815bdc69b0b34a50a18b Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 21 Jun 2022 08:16:38 +0200 Subject: [PATCH 054/100] Utils: Fix qbs build on macOS using Qt6 Change-Id: I5e8df475fbf1520831cd3ae04f2baa7b81f78fe4 Reviewed-by: Christian Kandeler --- src/libs/utils/utils.qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index b3e5adcf013..71fadc6bcf3 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -34,7 +34,7 @@ Project { } Depends { name: "Qt"; submodules: ["concurrent", "network", "qml", "widgets", "xml"] } - Depends { name: "Qt.macextras"; condition: qbs.targetOS.contains("macos") } + Depends { name: "Qt.macextras"; condition: Qt.core.versionMajor < 6 && qbs.targetOS.contains("macos") } Depends { name: "app_version_header" } files: [ From fc16aad2b430602810c9f66991098b85f5823f31 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Jun 2022 18:07:25 +0200 Subject: [PATCH 055/100] QdbDeviceInferiorRunner: Connect to done() signal Instead of connecting to finished(). Change-Id: I714c980f558cda3b330e03bb83b30dc7328699a5 Reviewed-by: Reviewed-by: hjk --- src/plugins/boot2qt/qdbdevicedebugsupport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/boot2qt/qdbdevicedebugsupport.cpp b/src/plugins/boot2qt/qdbdevicedebugsupport.cpp index 44e70d01922..e09b134e74f 100644 --- a/src/plugins/boot2qt/qdbdevicedebugsupport.cpp +++ b/src/plugins/boot2qt/qdbdevicedebugsupport.cpp @@ -55,7 +55,7 @@ public: setId("QdbDebuggeeRunner"); connect(&m_launcher, &QtcProcess::started, this, &RunWorker::reportStarted); - connect(&m_launcher, &QtcProcess::finished, this, &RunWorker::reportStopped); + connect(&m_launcher, &QtcProcess::done, this, &RunWorker::reportStopped); connect(&m_launcher, &QtcProcess::readyReadStandardOutput, [this] { appendMessage(QString::fromUtf8(m_launcher.readAllStandardOutput()), StdOutFormat); From a613caa234a41512718054e72289a958bed45411 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Jun 2022 16:32:36 +0200 Subject: [PATCH 056/100] PipInstallTask: Connect to done() signal instead of finished() Change-Id: I7a712791a440668c7efb8282d7f035a120c7d719 Reviewed-by: hjk Reviewed-by: David Schulz --- src/plugins/python/pipsupport.cpp | 22 ++++++++++------------ src/plugins/python/pipsupport.h | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/plugins/python/pipsupport.cpp b/src/plugins/python/pipsupport.cpp index 44ee82727c0..b290f75d2ee 100644 --- a/src/plugins/python/pipsupport.cpp +++ b/src/plugins/python/pipsupport.cpp @@ -47,10 +47,16 @@ namespace Internal { static constexpr char pipInstallTaskId[] = "Python::pipInstallTask"; -PipInstallTask::PipInstallTask(const Utils::FilePath &python) +PipInstallTask::PipInstallTask(const FilePath &python) : m_python(python) { m_watcher.setFuture(m_future.future()); + + connect(&m_process, &QtcProcess::done, this, &PipInstallTask::handleDone); + connect(&m_process, &QtcProcess::readyReadStandardError, this, &PipInstallTask::handleError); + connect(&m_process, &QtcProcess::readyReadStandardOutput, this, &PipInstallTask::handleOutput); + connect(&m_killTimer, &QTimer::timeout, this, &PipInstallTask::cancel); + connect(&m_watcher, &QFutureWatcher::canceled, this, &PipInstallTask::cancel); } void PipInstallTask::setPackage(const PipPackage &package) @@ -66,13 +72,6 @@ void PipInstallTask::run() } const QString taskTitle = tr("Install %1").arg(m_package.displayName); Core::ProgressManager::addTask(m_future.future(), taskTitle, pipInstallTaskId); - connect(&m_process, &QtcProcess::finished, this, &PipInstallTask::installFinished); - connect(&m_process, &QtcProcess::readyReadStandardError, this, &PipInstallTask::handleError); - connect(&m_process, &QtcProcess::readyReadStandardOutput, this, &PipInstallTask::handleOutput); - - connect(&m_killTimer, &QTimer::timeout, this, &PipInstallTask::cancel); - connect(&m_watcher, &QFutureWatcher::canceled, this, &PipInstallTask::cancel); - QString package = m_package.packageName; if (!m_package.version.isEmpty()) package += "==" + m_package.version; @@ -102,13 +101,12 @@ void PipInstallTask::cancel() .arg(m_package.displayName, m_killTimer.isActive() ? tr("user") : tr("time out"))); } -void PipInstallTask::installFinished() +void PipInstallTask::handleDone() { m_future.reportFinished(); const bool success = m_process.result() == ProcessResult::FinishedWithSuccess; if (!success) { - Core::MessageManager::writeFlashing( - tr("Installing the %1 failed with exit code %2") + Core::MessageManager::writeFlashing(tr("Installing the %1 failed with exit code %2") .arg(m_package.displayName).arg(m_process.exitCode())); } emit finished(success); @@ -128,7 +126,7 @@ void PipInstallTask::handleError() Core::MessageManager::writeSilently(stdErr); } -PipPackageInfo PipPackage::info(const Utils::FilePath &python) const +PipPackageInfo PipPackage::info(const FilePath &python) const { PipPackageInfo result; diff --git a/src/plugins/python/pipsupport.h b/src/plugins/python/pipsupport.h index 24db560b61a..9aeded08ab0 100644 --- a/src/plugins/python/pipsupport.h +++ b/src/plugins/python/pipsupport.h @@ -84,7 +84,7 @@ signals: private: void cancel(); - void installFinished(); + void handleDone(); void handleOutput(); void handleError(); From be5a77a76797c1dd3ae72317d795fee170c77504 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Jun 2022 16:49:21 +0200 Subject: [PATCH 057/100] TarPackageInstaller: Connect to done() signal instead of finished() This should also handle a failed to start case. Change-Id: I1f85873834c316263d132e357e23654a4bb7777f Reviewed-by: Reviewed-by: hjk --- src/plugins/remotelinux/tarpackagedeploystep.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/remotelinux/tarpackagedeploystep.cpp b/src/plugins/remotelinux/tarpackagedeploystep.cpp index 12add3a4faa..83732a071ba 100644 --- a/src/plugins/remotelinux/tarpackagedeploystep.cpp +++ b/src/plugins/remotelinux/tarpackagedeploystep.cpp @@ -77,7 +77,7 @@ TarPackageInstaller::TarPackageInstaller() connect(&m_installer, &QtcProcess::readyReadStandardError, this, [this] { emit stderrData(QString::fromUtf8(m_installer.readAllStandardError())); }); - connect(&m_installer, &QtcProcess::finished, this, [this] { + connect(&m_installer, &QtcProcess::done, this, [this] { const QString errorMessage = m_installer.result() == ProcessResult::FinishedWithSuccess ? QString() : tr("Installing package failed.") + m_installer.errorString(); emit finished(errorMessage); From 8e22e08d21224205dbe4f34971d4a7364f69453a Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Jun 2022 12:26:37 +0200 Subject: [PATCH 058/100] Test: Make valgrind modeldemo test compile with cmake As on it, correct the handling of the launcher interface. This still does not work due to wrong call of valgrind-fake. Change-Id: Id835e84eee29720579ac2947906bb95f84377185 Reviewed-by: hjk Reviewed-by: Christian Stenger --- tests/auto/valgrind/callgrind/CMakeLists.txt | 31 +++----------------- tests/auto/valgrind/memcheck/CMakeLists.txt | 26 ++++++++++++++++ tests/auto/valgrind/memcheck/modeldemo.cpp | 10 ++++++- tests/auto/valgrind/memcheck/modeldemo.qbs | 15 +++++++--- tests/auto/valgrind/valgrind.cmake | 30 +++++++++++++++++++ 5 files changed, 80 insertions(+), 32 deletions(-) create mode 100644 tests/auto/valgrind/valgrind.cmake diff --git a/tests/auto/valgrind/callgrind/CMakeLists.txt b/tests/auto/valgrind/callgrind/CMakeLists.txt index 76859938aed..74ed6ef157a 100644 --- a/tests/auto/valgrind/callgrind/CMakeLists.txt +++ b/tests/auto/valgrind/callgrind/CMakeLists.txt @@ -1,3 +1,5 @@ +include(../valgrind.cmake) + add_qtc_test(tst_callgrindparsertests DEPENDS Utils Core ProjectExplorer Debugger Qt5::Core Qt5::Network DEFINES @@ -7,31 +9,6 @@ add_qtc_test(tst_callgrindparsertests SOURCES callgrindparsertests.cpp callgrindparsertests.h ) -extend_qtc_test(tst_callgrindparsertests - SOURCES_PREFIX "${PROJECT_SOURCE_DIR}/src/plugins/valgrind/" - SOURCES - callgrind/callgrindcallmodel.h callgrind/callgrindcallmodel.cpp - callgrind/callgrindcostitem.h callgrind/callgrindcostitem.cpp - callgrind/callgrindcycledetection.h callgrind/callgrindcycledetection.cpp - callgrind/callgrinddatamodel.h callgrind/callgrinddatamodel.cpp - callgrind/callgrindfunction.h callgrind/callgrindfunction_p.h callgrind/callgrindfunction.cpp - callgrind/callgrindfunctioncall.h callgrind/callgrindfunctioncall.cpp - callgrind/callgrindfunctioncycle.h callgrind/callgrindfunctioncycle.cpp - callgrind/callgrindparsedata.h callgrind/callgrindparsedata.cpp - callgrind/callgrindparser.h callgrind/callgrindparser.cpp - callgrind/callgrindproxymodel.h callgrind/callgrindproxymodel.cpp - callgrind/callgrindstackbrowser.h callgrind/callgrindstackbrowser.cpp - valgrindrunner.h valgrindrunner.cpp - xmlprotocol/announcethread.h xmlprotocol/announcethread.cpp - xmlprotocol/error.h xmlprotocol/error.cpp - xmlprotocol/errorlistmodel.h xmlprotocol/errorlistmodel.cpp - xmlprotocol/frame.h xmlprotocol/frame.cpp - xmlprotocol/modelhelpers.h xmlprotocol/modelhelpers.cpp - xmlprotocol/parser.h xmlprotocol/parser.cpp - xmlprotocol/stack.h xmlprotocol/stack.cpp - xmlprotocol/stackmodel.h xmlprotocol/stackmodel.cpp - xmlprotocol/status.h xmlprotocol/status.cpp - xmlprotocol/suppression.h xmlprotocol/suppression.cpp - xmlprotocol/threadedparser.h xmlprotocol/threadedparser.cpp -) +extend_valgrind_test(tst_callgrindparsertests) + # skipping modeltest (does not compile due to missing widget handler) diff --git a/tests/auto/valgrind/memcheck/CMakeLists.txt b/tests/auto/valgrind/memcheck/CMakeLists.txt index 8ea0f41a15b..653611c4d16 100644 --- a/tests/auto/valgrind/memcheck/CMakeLists.txt +++ b/tests/auto/valgrind/memcheck/CMakeLists.txt @@ -1 +1,27 @@ add_subdirectory(testapps) + +include(../valgrind.cmake) + +file(RELATIVE_PATH RELATIVE_TEST_PATH "${PROJECT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") +file(RELATIVE_PATH TEST_RELATIVE_LIBEXEC_PATH "/${RELATIVE_TEST_PATH}" "/${IDE_LIBEXEC_PATH}") + +add_qtc_test(modeldemo + MANUALTEST + DEPENDS + Utils + Core + Debugger + ProjectExplorer + TextEditor + + SOURCES + modeldemo.cpp + modeldemo.h + + DEFINES + PARSERTESTS_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data" + VALGRIND_FAKE_PATH="${PROJECT_BINARY_DIR}/src/tools/valgrindfake/valgrind-fake" + TEST_RELATIVE_LIBEXEC_PATH="${TEST_RELATIVE_LIBEXEC_PATH}" +) + +extend_valgrind_test(modeldemo) diff --git a/tests/auto/valgrind/memcheck/modeldemo.cpp b/tests/auto/valgrind/memcheck/modeldemo.cpp index 9f809161da9..996ddf1af04 100644 --- a/tests/auto/valgrind/memcheck/modeldemo.cpp +++ b/tests/auto/valgrind/memcheck/modeldemo.cpp @@ -24,6 +24,9 @@ ** ****************************************************************************/ +#include +#include + #include #include #include @@ -41,12 +44,17 @@ using namespace Valgrind::XmlProtocol; int main(int argc, char *argv[]) { QApplication app(argc, argv); + + Utils::TemporaryDirectory::setMasterTemporaryDirectory(QDir::tempPath() + "/QtCreator-XXXXXX"); + const QString libExecPath(qApp->applicationDirPath() + '/' + + QLatin1String(TEST_RELATIVE_LIBEXEC_PATH)); + Utils::LauncherInterface::setPathToLauncher(libExecPath); + qRegisterMetaType(); ValgrindRunner runner; runner.setValgrindCommand({VALGRIND_FAKE_PATH, {"-i", PARSERTESTS_DATA_DIR "/memcheck-output-sample1.xml"}}); - ModelDemo demo(&runner); QObject::connect(&runner, &ValgrindRunner::finished, &demo, &ModelDemo::finished); diff --git a/tests/auto/valgrind/memcheck/modeldemo.qbs b/tests/auto/valgrind/memcheck/modeldemo.qbs index 8da8fd139e8..7da91345ee7 100644 --- a/tests/auto/valgrind/memcheck/modeldemo.qbs +++ b/tests/auto/valgrind/memcheck/modeldemo.qbs @@ -1,4 +1,5 @@ import qbs +import qbs.FileInfo import "../valgrindautotest.qbs" as ValgrindAutotest ValgrindAutotest { @@ -6,8 +7,14 @@ ValgrindAutotest { Depends { name: "valgrind-fake" } Depends { name: "Qt.network" } files: ["modeldemo.h", "modeldemo.cpp"] - cpp.defines: base.concat([ - 'PARSERTESTS_DATA_DIR="' + path + '/data"', - 'VALGRIND_FAKE_PATH="' + project.buildDirectory + '/' + qtc.ide_bin_path + '/valgrind-fake"' - ]) + cpp.defines: { + var defines = base; + var absLibExecPath = FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix, + qtc.ide_libexec_path); + var relLibExecPath = FileInfo.relativePath(destinationDirectory, absLibExecPath); + defines.push('TEST_RELATIVE_LIBEXEC_PATH="' + relLibExecPath + '"'); + defines.push('PARSERTESTS_DATA_DIR="' + path + '/data"'); + defines.push('VALGRIND_FAKE_PATH="' + project.buildDirectory + '/' + qtc.ide_bin_path + '/valgrind-fake"'); + return defines; + } } diff --git a/tests/auto/valgrind/valgrind.cmake b/tests/auto/valgrind/valgrind.cmake new file mode 100644 index 00000000000..fa7d8b4b60b --- /dev/null +++ b/tests/auto/valgrind/valgrind.cmake @@ -0,0 +1,30 @@ + +function(extend_valgrind_test targetName) + extend_qtc_test(${targetName} + SOURCES_PREFIX "${PROJECT_SOURCE_DIR}/src/plugins/valgrind/" + SOURCES + callgrind/callgrindcallmodel.h callgrind/callgrindcallmodel.cpp + callgrind/callgrindcostitem.h callgrind/callgrindcostitem.cpp + callgrind/callgrindcycledetection.h callgrind/callgrindcycledetection.cpp + callgrind/callgrinddatamodel.h callgrind/callgrinddatamodel.cpp + callgrind/callgrindfunction.h callgrind/callgrindfunction_p.h callgrind/callgrindfunction.cpp + callgrind/callgrindfunctioncall.h callgrind/callgrindfunctioncall.cpp + callgrind/callgrindfunctioncycle.h callgrind/callgrindfunctioncycle.cpp + callgrind/callgrindparsedata.h callgrind/callgrindparsedata.cpp + callgrind/callgrindparser.h callgrind/callgrindparser.cpp + callgrind/callgrindproxymodel.h callgrind/callgrindproxymodel.cpp + callgrind/callgrindstackbrowser.h callgrind/callgrindstackbrowser.cpp + valgrindrunner.h valgrindrunner.cpp + xmlprotocol/announcethread.h xmlprotocol/announcethread.cpp + xmlprotocol/error.h xmlprotocol/error.cpp + xmlprotocol/errorlistmodel.h xmlprotocol/errorlistmodel.cpp + xmlprotocol/frame.h xmlprotocol/frame.cpp + xmlprotocol/modelhelpers.h xmlprotocol/modelhelpers.cpp + xmlprotocol/parser.h xmlprotocol/parser.cpp + xmlprotocol/stack.h xmlprotocol/stack.cpp + xmlprotocol/stackmodel.h xmlprotocol/stackmodel.cpp + xmlprotocol/status.h xmlprotocol/status.cpp + xmlprotocol/suppression.h xmlprotocol/suppression.cpp + xmlprotocol/threadedparser.h xmlprotocol/threadedparser.cpp + ) +endfunction() From 64d52bb8c3af044f0df972068a715bd1d3b70166 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Jun 2022 17:23:57 +0200 Subject: [PATCH 059/100] CppcheckRunner: Connect to done() signal instead of finished() Simplify internals a bit. Change-Id: I4871b73f605af4d56e4993b6d71bbb22b4fce27d Reviewed-by: Reviewed-by: hjk --- src/plugins/cppcheck/cppcheckrunner.cpp | 68 ++++++++++--------------- src/plugins/cppcheck/cppcheckrunner.h | 9 ++-- 2 files changed, 29 insertions(+), 48 deletions(-) diff --git a/src/plugins/cppcheck/cppcheckrunner.cpp b/src/plugins/cppcheck/cppcheckrunner.cpp index 4e4e3d40524..542631beb71 100644 --- a/src/plugins/cppcheck/cppcheckrunner.cpp +++ b/src/plugins/cppcheck/cppcheckrunner.cpp @@ -28,7 +28,6 @@ #include #include -#include #include @@ -37,11 +36,9 @@ using namespace Utils; namespace Cppcheck { namespace Internal { -CppcheckRunner::CppcheckRunner(CppcheckTool &tool) : - m_tool(tool), - m_process(new Utils::QtcProcess(this)) +CppcheckRunner::CppcheckRunner(CppcheckTool &tool) : m_tool(tool) { - if (Utils::HostOsInfo::hostOs() == Utils::OsTypeLinux) { + if (HostOsInfo::hostOs() == OsTypeLinux) { QtcProcess getConf; getConf.setCommand({"getconf", {"ARG_MAX"}}); getConf.start(); @@ -50,17 +47,15 @@ CppcheckRunner::CppcheckRunner(CppcheckTool &tool) : m_maxArgumentsLength = std::max(argMax.toInt(), m_maxArgumentsLength); } - m_process->setStdOutLineCallback([this](const QString &line) { + m_process.setStdOutLineCallback([this](const QString &line) { m_tool.parseOutputLine(line); }); - m_process->setStdErrLineCallback([this](const QString &line) { + m_process.setStdErrLineCallback([this](const QString &line) { m_tool.parseErrorLine(line); }); - connect(m_process, &QtcProcess::started, - this, &CppcheckRunner::handleStarted); - connect(m_process, &QtcProcess::finished, - this, &CppcheckRunner::handleFinished); + connect(&m_process, &QtcProcess::started, &m_tool, &CppcheckTool::startParsing); + connect(&m_process, &QtcProcess::done, this, &CppcheckRunner::handleDone); m_queueTimer.setSingleShot(true); const int checkDelayInMs = 200; @@ -81,18 +76,18 @@ void CppcheckRunner::reconfigure(const FilePath &binary, const QString &argument m_arguments = arguments; } -void CppcheckRunner::addToQueue(const Utils::FilePaths &files, +void CppcheckRunner::addToQueue(const FilePaths &files, const QString &additionalArguments) { - Utils::FilePaths &existing = m_queue[additionalArguments]; + FilePaths &existing = m_queue[additionalArguments]; if (existing.isEmpty()) { existing = files; } else { std::copy_if(files.cbegin(), files.cend(), std::back_inserter(existing), - [&existing](const Utils::FilePath &file) { return !existing.contains(file); }); + [&existing](const FilePath &file) { return !existing.contains(file); }); } - if (m_isRunning) { + if (m_process.isRunning()) { stop(existing); return; } @@ -100,16 +95,16 @@ void CppcheckRunner::addToQueue(const Utils::FilePaths &files, m_queueTimer.start(); } -void CppcheckRunner::stop(const Utils::FilePaths &files) +void CppcheckRunner::stop(const FilePaths &files) { - if (!m_isRunning) + if (!m_process.isRunning()) return; if (files.isEmpty() || m_currentFiles == files) - m_process->kill(); + m_process.stop(); } -void CppcheckRunner::removeFromQueue(const Utils::FilePaths &files) +void CppcheckRunner::removeFromQueue(const FilePaths &files) { if (m_queue.isEmpty()) return; @@ -118,21 +113,21 @@ void CppcheckRunner::removeFromQueue(const Utils::FilePaths &files) m_queue.clear(); } else { for (auto it = m_queue.begin(), end = m_queue.end(); it != end;) { - for (const Utils::FilePath &file : files) + for (const FilePath &file : files) it.value().removeOne(file); it = !it.value().isEmpty() ? ++it : m_queue.erase(it); } } } -const Utils::FilePaths &CppcheckRunner::currentFiles() const +const FilePaths &CppcheckRunner::currentFiles() const { return m_currentFiles; } QString CppcheckRunner::currentCommand() const { - return m_process->commandLine().toUserOutput(); + return m_process.commandLine().toUserOutput(); } void CppcheckRunner::checkQueued() @@ -140,7 +135,7 @@ void CppcheckRunner::checkQueued() if (m_queue.isEmpty() || m_binary.isEmpty()) return; - Utils::FilePaths files = m_queue.begin().value(); + FilePaths files = m_queue.begin().value(); QString arguments = m_arguments + ' ' + m_queue.begin().key(); m_currentFiles.clear(); int argumentsLength = arguments.length(); @@ -158,30 +153,19 @@ void CppcheckRunner::checkQueued() else m_queue.begin().value() = files; - m_process->setCommand(CommandLine(m_binary, arguments, CommandLine::Raw)); - m_process->start(); + m_process.setCommand(CommandLine(m_binary, arguments, CommandLine::Raw)); + m_process.start(); } -void CppcheckRunner::handleStarted() +void CppcheckRunner::handleDone() { - if (m_isRunning) - return; - - m_isRunning = true; - m_tool.startParsing(); -} - -void CppcheckRunner::handleFinished() -{ - if (m_process->error() != QProcess::FailedToStart) { + if (m_process.result() == ProcessResult::FinishedWithSuccess) m_tool.finishParsing(); - } else { - const QString message = tr("Cppcheck failed to start: \"%1\".").arg(currentCommand()); - Core::MessageManager::writeSilently(message); - } + else + Core::MessageManager::writeSilently(m_process.exitMessage()); + m_currentFiles.clear(); - m_process->close(); - m_isRunning = false; + m_process.close(); if (!m_queue.isEmpty()) checkQueued(); diff --git a/src/plugins/cppcheck/cppcheckrunner.h b/src/plugins/cppcheck/cppcheckrunner.h index d49a9016dea..d35943b31f0 100644 --- a/src/plugins/cppcheck/cppcheckrunner.h +++ b/src/plugins/cppcheck/cppcheckrunner.h @@ -26,12 +26,11 @@ #pragma once #include +#include #include #include -namespace Utils { class QtcProcess; } - namespace Cppcheck { namespace Internal { @@ -58,18 +57,16 @@ private: void checkQueued(); void readOutput(); void readError(); - void handleStarted(); - void handleFinished(); + void handleDone(); CppcheckTool &m_tool; - Utils::QtcProcess *m_process = nullptr; + Utils::QtcProcess m_process; Utils::FilePath m_binary; QString m_arguments; QHash m_queue; Utils::FilePaths m_currentFiles; QTimer m_queueTimer; int m_maxArgumentsLength = 32767; - bool m_isRunning = false; }; } // namespace Internal From 17129dc93192783574cb4ea9c96fc6a42c5ffd15 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 20 Jun 2022 11:18:37 +0200 Subject: [PATCH 060/100] CMake build: Re-add qtcreatorcrashhandler On Linux for Debug configurations, like it was for the qmake build. Change-Id: I9ffc8687010ba7900203520c1609f7112c5434be Reviewed-by: Reviewed-by: Cristian Adam --- .../qtcreatorcrashhandler/CMakeLists.txt | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/tools/qtcreatorcrashhandler/CMakeLists.txt b/src/tools/qtcreatorcrashhandler/CMakeLists.txt index 74dfd2199f4..64eb7d3d35d 100644 --- a/src/tools/qtcreatorcrashhandler/CMakeLists.txt +++ b/src/tools/qtcreatorcrashhandler/CMakeLists.txt @@ -1,11 +1,10 @@ -if (LINUX) # Debug build only! - add_qtc_executable(qtcreatorcrashhandler - DEPENDS Utils Qt5::Widgets - SOURCES - backtracecollector.cpp backtracecollector.h - crashhandler.cpp crashhandler.h - crashhandlerdialog.cpp crashhandlerdialog.h crashhandlerdialog.ui - main.cpp - utils.cpp utils.h - ) -endif() +add_qtc_executable(qtcreatorcrashhandler + CONDITION UNIX AND NOT APPLE AND (CMAKE_BUILD_TYPE STREQUAL "Debug") + DEPENDS app_version Utils Qt5::Widgets + SOURCES + backtracecollector.cpp backtracecollector.h + crashhandler.cpp crashhandler.h + crashhandlerdialog.cpp crashhandlerdialog.h crashhandlerdialog.ui + main.cpp + utils.cpp utils.h +) From e50aa5bb41f67df5ba00e259671caea0c203c40e Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Mon, 20 Jun 2022 13:18:28 +0200 Subject: [PATCH 061/100] Arm64: Separate Arm64 from Arm on Windows The separation is the first step of proper supporting the native Visual C++ Arm64 that is now in preview in Visual Studio v17.3 Change-Id: I8cfa4b5b248158db68cb4af081dd59cabcd28c95 Reviewed-by: David Schulz --- src/libs/utils/hostosinfo.cpp | 3 ++- src/libs/utils/hostosinfo.h | 2 +- src/plugins/debugger/debuggeritemmanager.cpp | 2 +- src/plugins/projectexplorer/msvctoolchain.cpp | 5 ++++- src/plugins/projectexplorer/msvctoolchain.h | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libs/utils/hostosinfo.cpp b/src/libs/utils/hostosinfo.cpp index 48518f8fc1a..657bf08470a 100644 --- a/src/libs/utils/hostosinfo.cpp +++ b/src/libs/utils/hostosinfo.cpp @@ -65,8 +65,9 @@ HostOsInfo::HostArchitecture HostOsInfo::hostArchitecture() case PROCESSOR_ARCHITECTURE_IA64: return HostOsInfo::HostArchitectureItanium; case PROCESSOR_ARCHITECTURE_ARM: - case PROCESSOR_ARCHITECTURE_ARM64: return HostOsInfo::HostArchitectureArm; + case PROCESSOR_ARCHITECTURE_ARM64: + return HostOsInfo::HostArchitectureArm64; default: return HostOsInfo::HostArchitectureUnknown; } diff --git a/src/libs/utils/hostosinfo.h b/src/libs/utils/hostosinfo.h index 694146e3459..9fa6689d4b6 100644 --- a/src/libs/utils/hostosinfo.h +++ b/src/libs/utils/hostosinfo.h @@ -60,7 +60,7 @@ public: } enum HostArchitecture { HostArchitectureX86, HostArchitectureAMD64, HostArchitectureItanium, - HostArchitectureArm, HostArchitectureUnknown }; + HostArchitectureArm, HostArchitectureArm64, HostArchitectureUnknown }; static HostArchitecture hostArchitecture(); static constexpr bool isWindowsHost() { return hostOs() == OsTypeWindows; } diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp index 4f0d4702589..9afc0877680 100644 --- a/src/plugins/debugger/debuggeritemmanager.cpp +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -670,7 +670,7 @@ void DebuggerItemManagerPrivate::autoDetectCdbDebuggers() for (const QFileInfo &kitFolderFi : kitFolders) { const QString path = kitFolderFi.absoluteFilePath(); QStringList abis = {"x86", "x64"}; - if (HostOsInfo::hostArchitecture() == HostOsInfo::HostArchitectureArm) + if (HostOsInfo::hostArchitecture() == HostOsInfo::HostArchitectureArm64) abis << "arm64"; for (const QString &abi: abis) { const QFileInfo cdbBinary(path + "/Debuggers/" + abi + "/cdb.exe"); diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 99b1e0bad06..e6ca8375aa8 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -147,6 +147,9 @@ static bool hostPrefersPlatform(MsvcToolChain::Platform platform) || platform == MsvcToolChain::x86_arm64; case HostOsInfo::HostArchitectureArm: return platform == MsvcToolChain::arm; + case HostOsInfo::HostArchitectureArm64: + return platform == MsvcToolChain::arm64 + || platform == MsvcToolChain::arm64_x86 || platform == MsvcToolChain::arm64_amd64; case HostOsInfo::HostArchitectureItanium: return platform == MsvcToolChain::ia64; default: @@ -167,7 +170,7 @@ static bool hostSupportsPlatform(MsvcToolChain::Platform platform) || platform == MsvcToolChain::x86_ia64 || platform == MsvcToolChain::x86_arm || platform == MsvcToolChain::x86_arm64; // The Arm64 host can run the cross-compilers via emulation of x86 and amd64 - case HostOsInfo::HostArchitectureArm: + case HostOsInfo::HostArchitectureArm64: return platform == MsvcToolChain::x86_arm || platform == MsvcToolChain::x86_arm64 || platform == MsvcToolChain::amd64_arm || platform == MsvcToolChain::amd64_arm64 || platform == MsvcToolChain::x86 || platform == MsvcToolChain::x86_amd64 diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h index 56c926141c5..b3df781fd13 100644 --- a/src/plugins/projectexplorer/msvctoolchain.h +++ b/src/plugins/projectexplorer/msvctoolchain.h @@ -58,7 +58,7 @@ class MsvcToolChain : public ToolChain public: enum Type { WindowsSDK, VS }; enum Platform { x86, amd64, x86_amd64, ia64, x86_ia64, arm, x86_arm, amd64_arm, amd64_x86, - x86_arm64, amd64_arm64 }; + x86_arm64, amd64_arm64, arm64, arm64_x86, arm64_amd64 }; explicit MsvcToolChain(Utils::Id typeId); ~MsvcToolChain() override; From 8c2120d15533465506fbb3dadcb31939469b42cb Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Mon, 20 Jun 2022 17:25:46 +0200 Subject: [PATCH 062/100] ProjectExplorer: MSVC arm64 native toolchain support Visual Studio 2022 v17.3 is in preview state and adds support for arm64, arm64_x86 and arm64_amd64 toolchains. Change-Id: Iff2cb13c9ebef77d40804c7dd8b3df6488e6ce41 Reviewed-by: Reviewed-by: David Schulz --- src/plugins/projectexplorer/msvctoolchain.cpp | 21 ++++++++++++++++--- src/plugins/projectexplorer/msvctoolchain.h | 1 - 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index e6ca8375aa8..cd76162d402 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -31,7 +31,6 @@ #include "projectexplorerconstants.h" #include "projectexplorersettings.h" #include "taskhub.h" -#include "toolchainmanager.h" #include @@ -106,7 +105,10 @@ const MsvcPlatform platforms[] {MsvcToolChain::amd64_arm, "amd64_arm", "/bin/amd64_arm", "vcvarsamd64_arm.bat"}, {MsvcToolChain::amd64_x86, "amd64_x86", "/bin/amd64_x86", "vcvarsamd64_x86.bat"}, {MsvcToolChain::x86_arm64, "x86_arm64", "/bin/x86_arm64", "vcvarsx86_arm64.bat"}, - {MsvcToolChain::amd64_arm64, "amd64_arm64", "/bin/amd64_arm64", "vcvarsamd64_arm64.bat"}}; + {MsvcToolChain::amd64_arm64, "amd64_arm64", "/bin/amd64_arm64", "vcvarsamd64_arm64.bat"}, + {MsvcToolChain::arm64, "arm64", "/bin/arm64", "vcvarsarm64.bat"}, + {MsvcToolChain::arm64_x86, "arm64_x86", "/bin/arm64_x86", "vcvarsarm64_x86.bat"}, + {MsvcToolChain::arm64_amd64, "arm64_amd64", "/bin/arm64_amd64", "vcvarsarm64_amd64.bat"}}; static QList g_availableMsvcToolchains; @@ -397,6 +399,7 @@ static unsigned char wordWidthForPlatform(MsvcToolChain::Platform platform) case ProjectExplorer::Internal::MsvcToolChain::x86_arm: case ProjectExplorer::Internal::MsvcToolChain::amd64_arm: case ProjectExplorer::Internal::MsvcToolChain::amd64_x86: + case ProjectExplorer::Internal::MsvcToolChain::arm64_x86: return 32; case ProjectExplorer::Internal::MsvcToolChain::amd64: case ProjectExplorer::Internal::MsvcToolChain::x86_amd64: @@ -404,6 +407,8 @@ static unsigned char wordWidthForPlatform(MsvcToolChain::Platform platform) case ProjectExplorer::Internal::MsvcToolChain::x86_ia64: case ProjectExplorer::Internal::MsvcToolChain::amd64_arm64: case ProjectExplorer::Internal::MsvcToolChain::x86_arm64: + case ProjectExplorer::Internal::MsvcToolChain::arm64: + case ProjectExplorer::Internal::MsvcToolChain::arm64_amd64: return 64; } @@ -417,12 +422,15 @@ static Abi::Architecture archForPlatform(MsvcToolChain::Platform platform) case ProjectExplorer::Internal::MsvcToolChain::amd64: case ProjectExplorer::Internal::MsvcToolChain::x86_amd64: case ProjectExplorer::Internal::MsvcToolChain::amd64_x86: + case ProjectExplorer::Internal::MsvcToolChain::arm64_x86: + case ProjectExplorer::Internal::MsvcToolChain::arm64_amd64: return Abi::X86Architecture; case ProjectExplorer::Internal::MsvcToolChain::arm: case ProjectExplorer::Internal::MsvcToolChain::x86_arm: case ProjectExplorer::Internal::MsvcToolChain::amd64_arm: case ProjectExplorer::Internal::MsvcToolChain::x86_arm64: case ProjectExplorer::Internal::MsvcToolChain::amd64_arm64: + case ProjectExplorer::Internal::MsvcToolChain::arm64: return Abi::ArmArchitecture; case ProjectExplorer::Internal::MsvcToolChain::ia64: case ProjectExplorer::Internal::MsvcToolChain::x86_ia64: @@ -1328,6 +1336,9 @@ MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc) m_varsBatArchCombo->addItem("amd64_arm64", MsvcToolChain::amd64_arm64); m_varsBatArchCombo->addItem("ia64", MsvcToolChain::ia64); m_varsBatArchCombo->addItem("x86_ia64", MsvcToolChain::x86_ia64); + m_varsBatArchCombo->addItem("arm64", MsvcToolChain::arm64); + m_varsBatArchCombo->addItem("arm64_x86", MsvcToolChain::arm64_x86); + m_varsBatArchCombo->addItem("arm64_amd64", MsvcToolChain::arm64_amd64); m_varsBatArgumentsEdit->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); m_varsBatArgumentsEdit->setToolTip(tr("Additional arguments for the vcvarsall.bat call")); hLayout->addWidget(m_varsBatPathCombo); @@ -1943,6 +1954,7 @@ Toolchains MsvcToolChainFactory::autoDetect(const ToolchainDetector &detector) c {MsvcToolChain::x86, "x86"}, {MsvcToolChain::amd64, "x64"}, {MsvcToolChain::ia64, "ia64"}, + {MsvcToolChain::arm64, "arm64"}, }; for (const auto &platform : platforms) { tmp.append(findOrCreateToolchains(detector, @@ -1978,7 +1990,10 @@ Toolchains MsvcToolChainFactory::autoDetect(const ToolchainDetector &detector) c MsvcToolChain::x86_arm64, MsvcToolChain::amd64_arm64, MsvcToolChain::ia64, - MsvcToolChain::x86_ia64}; + MsvcToolChain::x86_ia64, + MsvcToolChain::arm64, + MsvcToolChain::arm64_x86, + MsvcToolChain::arm64_amd64}; const QVector studios = detectVisualStudio(); for (const VisualStudioInstallation &i : studios) { diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h index b3df781fd13..05090e721b5 100644 --- a/src/plugins/projectexplorer/msvctoolchain.h +++ b/src/plugins/projectexplorer/msvctoolchain.h @@ -28,7 +28,6 @@ #include "abi.h" #include "abiwidget.h" #include "toolchain.h" -#include "toolchaincache.h" #include "toolchainconfigwidget.h" #include From a235aa29a1e0efb62f49a9b6586a721800295f77 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Fri, 17 Jun 2022 15:46:52 +0200 Subject: [PATCH 063/100] qmljs: avoid linking to files in the build directory cmake creates a consistent uri structure in the build directory. We use that as import path, but when we find a type in them we should refer back to the original file, as editing those is dangerous because any edit are lost with the next build. To find the original file we use the qrc, as the qrc path is mostly the same of as the uri path. It is possible to add prefixes which would make an exact match fail, so we compare the paths from the right to the left and find the longest match. To acheive this: * QrcParser keeps a reversedResources, so the match from right can be done efficiently, and provides a longestReverseMatches method * the model manager keeps a list of all common prefixes of the application paths (build directories), and identify all files in build directories * the method fileToSource identifies the files in the build directory and tries to find the corresponding source file, warning if he cannot find it * fileToSource is used for follow Symbol and find usages We could use fileToSource much more aggressively, to use to in editor content for the files in the build directory, increasing the consistency, but that is a more dangerous change for later. Fixes: QTCREATORBUG-27173 Change-Id: Iea61b9825e5f6e433a7390cf2de9564b792458a5 Reviewed-by: Ulf Hermann --- src/libs/qmljs/qmljsmodelmanagerinterface.cpp | 101 ++++++++++++++++-- src/libs/qmljs/qmljsmodelmanagerinterface.h | 3 + src/libs/utils/qrcparser.cpp | 46 +++++++- src/libs/utils/qrcparser.h | 9 ++ src/plugins/qmljseditor/qmljseditor.cpp | 13 ++- .../qmljseditor/qmljsfindreferences.cpp | 25 ++++- 6 files changed, 178 insertions(+), 19 deletions(-) diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp index 5f649931ad3..444d429a4bc 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp @@ -446,6 +446,20 @@ bool pInfoLessThanImports(const ModelManagerInterface::ProjectInfo &p1, } +static QList generatedQrc(QStringList applicationDirectories) +{ + QList res; + for (const QString &pathStr : applicationDirectories) { + Utils::FilePath path = Utils::FilePath::fromString(pathStr); + Utils::FilePath generatedQrcDir = path.pathAppended(".rcc"); + if (generatedQrcDir.isReadableDir()) { + for (const Utils::FilePath & qrcPath: generatedQrcDir.dirEntries(FileFilter(QStringList({QStringLiteral(u"*.qrc")}), QDir::Files))) + res.append(qrcPath.canonicalPath()); + } + } + return res; +} + void ModelManagerInterface::iterateQrcFiles( ProjectExplorer::Project *project, QrcResourceSelector resources, const std::function &callback) @@ -461,18 +475,21 @@ void ModelManagerInterface::iterateQrcFiles( Utils::sort(pInfos, &pInfoLessThanAll); } - QSet pathsChecked; + QSet pathsChecked; for (const ModelManagerInterface::ProjectInfo &pInfo : qAsConst(pInfos)) { QStringList qrcFilePaths; if (resources == ActiveQrcResources) qrcFilePaths = pInfo.activeResourceFiles; else qrcFilePaths = pInfo.allResourceFiles; - for (const QString &qrcFilePath : qAsConst(qrcFilePaths)) { + for (const Utils::FilePath &p : generatedQrc(pInfo.applicationDirectories)) + qrcFilePaths.append(p.toString()); + for (const QString &qrcFilePathStr : qAsConst(qrcFilePaths)) { + auto qrcFilePath = Utils::FilePath::fromString(qrcFilePathStr); if (pathsChecked.contains(qrcFilePath)) continue; pathsChecked.insert(qrcFilePath); - QrcParser::ConstPtr qrcFile = m_qrcCache.parsedPath(qrcFilePath); + QrcParser::ConstPtr qrcFile = m_qrcCache.parsedPath(qrcFilePath.toString()); if (qrcFile.isNull()) continue; callback(qrcFile); @@ -589,6 +606,8 @@ void ModelManagerInterface::updateProjectInfo(const ProjectInfo &pinfo, ProjectE m_qrcContents = pinfo.resourceFileContents; for (const QString &newQrc : qAsConst(pinfo.allResourceFiles)) m_qrcCache.addPath(newQrc, m_qrcContents.value(newQrc)); + for (const Utils::FilePath &newQrc : generatedQrc(pinfo.applicationDirectories)) + m_qrcCache.addPath(newQrc.toString(), m_qrcContents.value(newQrc.toString())); for (const QString &oldQrc : qAsConst(oldInfo.allResourceFiles)) m_qrcCache.removePath(oldQrc); @@ -1180,6 +1199,29 @@ void ModelManagerInterface::maybeScan(const PathsAndLanguages &importPaths) } } +static QList minimalPrefixPaths(const QStringList &paths) +{ + QList sortedPaths; + // find minimal prefix, ensure '/' at end + for (const QString &pathStr : qAsConst(paths)) { + Utils::FilePath path = Utils::FilePath::fromString(pathStr); + if (!path.endsWith("/")) + path.setPath(path.path() + "/"); + if (path.path().length() > 1) + sortedPaths.append(path); + } + std::sort(sortedPaths.begin(), sortedPaths.end()); + QList res; + QString lastPrefix; + for (auto it = sortedPaths.begin(); it != sortedPaths.end(); ++it) { + if (lastPrefix.isEmpty() || !it->startsWith(lastPrefix)) { + lastPrefix = it->path(); + res.append(*it); + } + } + return res; +} + void ModelManagerInterface::updateImportPaths() { if (m_indexerDisabled) @@ -1243,6 +1285,7 @@ void ModelManagerInterface::updateImportPaths() m_allImportPaths = allImportPaths; m_activeBundles = activeBundles; m_extendedBundles = extendedBundles; + m_applicationPaths = minimalPrefixPaths(allApplicationDirectories); } @@ -1253,10 +1296,13 @@ void ModelManagerInterface::updateImportPaths() QSet newLibraries; for (const Document::Ptr &doc : qAsConst(snapshot)) findNewLibraryImports(doc, snapshot, this, &importedFiles, &scannedPaths, &newLibraries); - for (const QString &path : qAsConst(allApplicationDirectories)) { - allImportPaths.maybeInsert(FilePath::fromString(path), Dialect::Qml); - findNewQmlApplicationInPath(FilePath::fromString(path), snapshot, this, &newLibraries); + for (const QString &pathStr : qAsConst(allApplicationDirectories)) { + Utils::FilePath path = Utils::FilePath::fromString(pathStr); + allImportPaths.maybeInsert(path, Dialect::Qml); + findNewQmlApplicationInPath(path, snapshot, this, &newLibraries); } + for (const Utils::FilePath &qrcPath : generatedQrc(allApplicationDirectories)) + updateQrcFile(qrcPath.toString()); updateSourceFiles(importedFiles, true); @@ -1668,4 +1714,47 @@ void ModelManagerInterface::resetCodeModel() updateImportPaths(); } +Utils::FilePath ModelManagerInterface::fileToSource(const Utils::FilePath &path) +{ + if (!path.scheme().isEmpty()) + return path; + for (const Utils::FilePath &p : m_applicationPaths) { + if (!p.isEmpty() && path.startsWith(p.path())) { + // if it is an applicationPath (i.e. in the build directory) + // try to use the path from the build dir as resource path + // and recover the path of the corresponding source file + QString reducedPath = path.path().mid(p.path().size()); + QString reversePath(reducedPath); + std::reverse(reversePath.begin(), reversePath.end()); + if (!reversePath.endsWith('/')) + reversePath.append('/'); + QrcParser::MatchResult res; + iterateQrcFiles(nullptr, + QrcResourceSelector::AllQrcResources, + [&](const QrcParser::ConstPtr &qrcFile) { + if (!qrcFile) + return; + QrcParser::MatchResult matchNow = qrcFile->longestReverseMatches( + reversePath); + + if (matchNow.matchDepth < res.matchDepth) + return; + if (matchNow.matchDepth == res.matchDepth) { + res.reversedPaths += matchNow.reversedPaths; + res.sourceFiles += matchNow.sourceFiles; + } else { + res = matchNow; + } + }); + std::sort(res.sourceFiles.begin(), res.sourceFiles.end()); + if (!res.sourceFiles.isEmpty()) { + return res.sourceFiles.first(); + } + qCWarning(qmljsLog) << "Could not find source file for file" << path + << "in application path" << p; + } + } + return path; +} + } // namespace QmlJS diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.h b/src/libs/qmljs/qmljsmodelmanagerinterface.h index 5a4f711a1be..4ed02c2c96d 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.h +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -149,6 +150,7 @@ public: ProjectExplorer::Project *project = nullptr, bool addDirs = false, QrcResourceSelector resources = AllQrcResources); + Utils::FilePath fileToSource(const Utils::FilePath &file); QList projectInfos() const; bool containsProject(ProjectExplorer::Project *project) const; @@ -254,6 +256,7 @@ private: QmlJS::Snapshot m_validSnapshot; QmlJS::Snapshot m_newestSnapshot; PathsAndLanguages m_allImportPaths; + QList m_applicationPaths; QStringList m_defaultImportPaths; QmlJS::QmlLanguageBundles m_activeBundles; QmlJS::QmlLanguageBundles m_extendedBundles; diff --git a/src/libs/utils/qrcparser.cpp b/src/libs/utils/qrcparser.cpp index 24846ebf63b..58935f12100 100644 --- a/src/libs/utils/qrcparser.cpp +++ b/src/libs/utils/qrcparser.cpp @@ -57,6 +57,7 @@ public: const QLocale *locale = nullptr) const; void collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *res, const QLocale *locale = nullptr) const; + QrcParser::MatchResult longestReverseMatches(const QString &) const; QStringList errorMessages() const; QStringList languages() const; @@ -65,6 +66,7 @@ private: const QStringList allUiLanguages(const QLocale *locale) const; SMap m_resources; + SMap m_reverseResources; SMap m_files; QStringList m_languages; QStringList m_errorMessages; @@ -207,6 +209,11 @@ void QrcParser::collectFilesAtPath(const QString &path, QStringList *res, const d->collectFilesAtPath(path, res, locale); } +QrcParser::MatchResult QrcParser::longestReverseMatches(const QString &p) const +{ + return d->longestReverseMatches(p); +} + /*! Returns \c true if \a path is a non-empty directory and matches \a locale. @@ -414,8 +421,14 @@ bool QrcParserPrivate::parseFile(const QString &path, const QString &contents) else accessPath = language + prefix + fileName; QStringList &resources = m_resources[accessPath]; - if (!resources.contains(filePath)) + if (!resources.contains(filePath)) { resources.append(filePath); + QString reversePath(accessPath); + std::reverse(reversePath.begin(), reversePath.end()); + if (!reversePath.endsWith('/')) + reversePath.append('/'); + m_reverseResources[reversePath].append(filePath); + } QStringList &files = m_files[filePath]; if (!files.contains(accessPath)) files.append(accessPath); @@ -517,6 +530,37 @@ void QrcParserPrivate::collectResourceFilesForSourceFile(const QString &sourceFi } } +QrcParser::MatchResult QrcParserPrivate::longestReverseMatches(const QString &reversePath) const +{ + QrcParser::MatchResult res; + if (reversePath.length() == 1) + return res; + auto lastMatch = m_reverseResources.end(); + qsizetype matchedUntil = 0; + for (qsizetype i = 1, j = 0; i < reversePath.size(); i = j + 1) { + j = reversePath.indexOf(u'/', i); + if (j == -1) + j = reversePath.size() - 1; + auto match = m_reverseResources.lowerBound(reversePath.mid(0, j + 1)); + QString pNow = reversePath.left(j + 1); + if (match == m_reverseResources.end() || match.key().left(j + 1) != pNow) + break; + ++res.matchDepth; + matchedUntil = j + 1; + lastMatch = match; + } + res.reversedPaths.clear(); + res.sourceFiles.clear(); + for (auto it = lastMatch; it != m_reverseResources.end() + && it.key().left(matchedUntil) == reversePath.left(matchedUntil); + ++it) { + res.reversedPaths.append(it.key()); + for (const QString &filePath : it.value()) + res.sourceFiles.append(Utils::FilePath::fromString(filePath)); + } + return res; +} + QStringList QrcParserPrivate::errorMessages() const { return m_errorMessages; diff --git a/src/libs/utils/qrcparser.h b/src/libs/utils/qrcparser.h index 665df445484..3027076a97e 100644 --- a/src/libs/utils/qrcparser.h +++ b/src/libs/utils/qrcparser.h @@ -26,6 +26,7 @@ #pragma once #include "utils_global.h" +#include "utils/filepath.h" #include #include @@ -47,12 +48,20 @@ class QrcCachePrivate; class QTCREATOR_UTILS_EXPORT QrcParser { public: + struct MatchResult + { + int matchDepth = {}; + QStringList reversedPaths; + QList sourceFiles; + }; + typedef QSharedPointer Ptr; typedef QSharedPointer ConstPtr; ~QrcParser(); bool parseFile(const QString &path, const QString &contents); QString firstFileAtPath(const QString &path, const QLocale &locale) const; void collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale = nullptr) const; + MatchResult longestReverseMatches(const QString &) const; bool hasDirAtPath(const QString &path, const QLocale *locale = nullptr) const; void collectFilesInPath(const QString &path, QMap *res, bool addDirs = false, const QLocale *locale = nullptr) const; diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index 894e0be8d99..9052ca40f13 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -771,7 +771,8 @@ void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor, const QList imports = semanticInfo.document->bind()->imports(); for (const ImportInfo &import : imports) { if (import.ast() == importAst && import.type() == ImportType::File) { - Utils::Link link(Utils::FilePath::fromString(import.path())); + Utils::Link link( + m_modelManager->fileToSource(FilePath::fromString(import.path()))); link.linkTextStart = importAst->firstSourceLocation().begin(); link.linkTextEnd = importAst->lastSourceLocation().end(); processLinkCallback(Utils::Link()); @@ -793,11 +794,9 @@ void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor, processLinkCallback(link); return; } - const QString relative = QString::fromLatin1("%1/%2").arg( - semanticInfo.document->path(), - text); - if (QFileInfo::exists(relative)) { - link.targetFilePath = Utils::FilePath::fromString(relative); + const Utils::FilePath relative = Utils::FilePath::fromString(semanticInfo.document->path()).pathAppended(text); + if (relative.exists()) { + link.targetFilePath = m_modelManager->fileToSource(relative); processLinkCallback(link); return; } @@ -814,7 +813,7 @@ void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor, return processLinkCallback(Utils::Link()); Utils::Link link; - link.targetFilePath = Utils::FilePath::fromString(fileName); + link.targetFilePath = m_modelManager->fileToSource(FilePath::fromString(fileName)); link.targetLine = line; link.targetColumn = column - 1; // adjust the column diff --git a/src/plugins/qmljseditor/qmljsfindreferences.cpp b/src/plugins/qmljseditor/qmljsfindreferences.cpp index e0a0f3269aa..38717948ee6 100644 --- a/src/plugins/qmljseditor/qmljsfindreferences.cpp +++ b/src/plugins/qmljseditor/qmljsfindreferences.cpp @@ -28,10 +28,11 @@ #include #include #include -#include #include +#include #include #include +#include #include #include @@ -745,6 +746,7 @@ public: future->waitForResume(); if (future->isCanceled()) return usages; + ModelManagerInterface *modelManager = ModelManagerInterface::instance(); Document::Ptr doc = context->snapshot().document(fileName); if (!doc) return usages; @@ -753,7 +755,7 @@ public: FindUsages findUsages(doc, context); const FindUsages::Result results = findUsages(name, scope); for (const SourceLocation &loc : results) - usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length)); + usages.append(Usage(modelManager->fileToSource(Utils::FilePath::fromString(fileName)).toString(), matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length)); if (future->isPaused()) future->waitForResume(); return usages; @@ -896,8 +898,9 @@ static void find_helper(QFutureInterface &future, QStringList files; for (const Document::Ptr &doc : qAsConst(snapshot)) { // ### skip files that don't contain the name token - files.append(doc->fileName()); + files.append(modelManager->fileToSource(Utils::FilePath::fromString(doc->fileName())).toString()); } + files = Utils::filteredUnique(files); future.setProgressRange(0, files.size()); @@ -976,11 +979,23 @@ QList FindReferences::findUsageOfType(const QString &file QmlJS::Snapshot snapshot = modelManager->snapshot(); + QSet docDone; for (const QmlJS::Document::Ptr &doc : qAsConst(snapshot)) { - FindTypeUsages findUsages(doc, context); + QString sourceFile = modelManager->fileToSource(Utils::FilePath::fromString(doc->fileName())).toString(); + if (docDone.contains(sourceFile)) + continue; + docDone.insert(sourceFile); + QmlJS::Document::Ptr sourceDoc = doc; + if (sourceFile != doc->fileName()) + sourceDoc = snapshot.document(sourceFile); + FindTypeUsages findUsages(sourceDoc, context); const FindTypeUsages::Result results = findUsages(typeName, targetValue); for (const SourceLocation &loc : results) { - usages.append(Usage(doc->fileName(), matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length)); + usages.append(Usage(sourceFile, + matchingLine(loc.offset, doc->source()), + loc.startLine, + loc.startColumn - 1, + loc.length)); } } return usages; From 7a14ee1393976312870049b81a54607df3a5e2ba Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 16 Jun 2022 18:27:17 +0200 Subject: [PATCH 064/100] PluginDumper: Connect to done() signal Instead of connecting to errorOccurred() and finished() signals. Change-Id: Iaf5fb4ec46919e37b0ab12ec4cbff904ae192de7 Reviewed-by: hjk --- src/libs/qmljs/qmljsplugindumper.cpp | 33 ++++++++++------------------ src/libs/qmljs/qmljsplugindumper.h | 1 - 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp index e5e3a952c05..56d444f9d9e 100644 --- a/src/libs/qmljs/qmljsplugindumper.cpp +++ b/src/libs/qmljs/qmljsplugindumper.cpp @@ -264,13 +264,20 @@ void PluginDumper::qmlPluginTypeDumpDone(QtcProcess *process) return; const Snapshot snapshot = m_modelManager->snapshot(); LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath); - bool privatePlugin = libraryPath.endsWith(QLatin1String("private")); + const bool privatePlugin = libraryPath.endsWith(QLatin1String("private")); - if (process->exitCode() != 0) { + if (process->exitCode() || process->error() != QProcess::UnknownError) { const QString errorMessages = qmlPluginDumpErrorMessage(process); if (!privatePlugin) ModelManagerInterface::writeWarning(qmldumpErrorMessage(libraryPath, errorMessages)); - libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(libraryPath, errorMessages)); + libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, + qmldumpFailedMessage(libraryPath, errorMessages)); + + if (process->error() != QProcess::UnknownError) { + libraryInfo.updateFingerprint(); + m_modelManager->updateLibraryInfo(libraryPath, libraryInfo); + return; + } const QByteArray output = process->readAllStandardOutput(); @@ -324,23 +331,6 @@ void PluginDumper::qmlPluginTypeDumpDone(QtcProcess *process) } } -void PluginDumper::qmlPluginTypeDumpError(QtcProcess *process) -{ - process->deleteLater(); - - const FilePath libraryPath = m_runningQmldumps.take(process); - if (libraryPath.isEmpty()) - return; - const QString errorMessages = qmlPluginDumpErrorMessage(process); - const Snapshot snapshot = m_modelManager->snapshot(); - LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath); - if (!libraryPath.path().endsWith(QLatin1String("private"), Qt::CaseInsensitive)) - ModelManagerInterface::writeWarning(qmldumpErrorMessage(libraryPath, errorMessages)); - libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(libraryPath, errorMessages)); - libraryInfo.updateFingerprint(); - m_modelManager->updateLibraryInfo(libraryPath, libraryInfo); -} - void PluginDumper::pluginChanged(const QString &pluginLibrary) { const int pluginIndex = m_libraryToPluginIndex.value(pluginLibrary, -1); @@ -628,8 +618,7 @@ void PluginDumper::runQmlDump(const ModelManagerInterface::ProjectInfo &info, process->setEnvironment(info.qmlDumpEnvironment); process->setWorkingDirectory(importPath); process->setCommand({info.qmlDumpPath, arguments}); - connect(process, &QtcProcess::finished, this, [this, process] { qmlPluginTypeDumpDone(process); }); - connect(process, &QtcProcess::errorOccurred, this, [this, process] { qmlPluginTypeDumpError(process); }); + connect(process, &QtcProcess::done, this, [this, process] { qmlPluginTypeDumpDone(process); }); process->start(); m_runningQmldumps.insert(process, importPath); } diff --git a/src/libs/qmljs/qmljsplugindumper.h b/src/libs/qmljs/qmljsplugindumper.h index 7b4e035013e..7d289a4258f 100644 --- a/src/libs/qmljs/qmljsplugindumper.h +++ b/src/libs/qmljs/qmljsplugindumper.h @@ -60,7 +60,6 @@ private: const QString &importUri, const QString &importVersion); Q_INVOKABLE void dumpAllPlugins(); void qmlPluginTypeDumpDone(Utils::QtcProcess *process); - void qmlPluginTypeDumpError(Utils::QtcProcess *process); void pluginChanged(const QString &pluginLibrary); private: From 283673a5d99f25ff882aa51aed9e3272bd6d73ba Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Jun 2022 12:56:13 +0200 Subject: [PATCH 065/100] AbstractSettings: Introduce VersionUpdater Uniform version number parsing inside AbstractSettings. Get rid of updateVersion() virtual method and add protected setVersionRegExp() instead. If the user calls version() we wait for version process to finish if it was running. This makes sure that we don't return old / invalid version number while version process is still running. Change-Id: Ie27816534dd52c086acde721f3b49e669a7c30bc Reviewed-by: hjk --- src/plugins/beautifier/abstractsettings.cpp | 87 +++++++++++++++---- src/plugins/beautifier/abstractsettings.h | 16 +++- .../artisticstyle/artisticstyle.cpp | 7 +- .../artisticstyle/artisticstylesettings.cpp | 54 ++---------- .../artisticstyle/artisticstylesettings.h | 15 ---- .../beautifier/uncrustify/uncrustify.cpp | 3 +- .../uncrustify/uncrustifysettings.cpp | 30 +------ .../uncrustify/uncrustifysettings.h | 8 -- 8 files changed, 96 insertions(+), 124 deletions(-) diff --git a/src/plugins/beautifier/abstractsettings.cpp b/src/plugins/beautifier/abstractsettings.cpp index d691984d62f..e9768041452 100644 --- a/src/plugins/beautifier/abstractsettings.cpp +++ b/src/plugins/beautifier/abstractsettings.cpp @@ -34,11 +34,16 @@ #include #include #include +#include #include #include +#include +#include #include +using namespace Utils; + namespace Beautifier { namespace Internal { @@ -47,12 +52,65 @@ const char COMMAND[] = "command"; const char SUPPORTED_MIME[] = "supportedMime"; } +class VersionUpdater +{ +public: + VersionUpdater() + { + QObject::connect(&m_process, &QtcProcess::done, [this] { + if (m_process.result() != ProcessResult::FinishedWithSuccess) + return; + + m_versionNumber = parseVersion(m_process.cleanedStdOut()); + if (m_versionNumber.isNull()) + m_versionNumber = parseVersion(m_process.cleanedStdErr()); + }); + } + + void setVersionRegExp(const QRegularExpression &versionRegExp) + { + m_versionRegExp = versionRegExp; + } + + void update(const FilePath &executable) + { + m_versionNumber = {}; + if (m_versionRegExp.pattern().isEmpty()) + return; + m_process.close(); + m_process.setCommand({executable, {"--version"}}); + m_process.start(); + } + + QVersionNumber version() const + { + if (m_process.state() != QProcess::NotRunning) + m_process.waitForFinished(-1); + return m_versionNumber; + } + +private: + QVersionNumber parseVersion(const QString &text) const + { + const QRegularExpressionMatch match = m_versionRegExp.match(text); + if (!match.hasMatch()) + return {}; + + return {match.captured(1).toInt(), match.captured(2).toInt()}; + } + + QRegularExpression m_versionRegExp; + mutable QtcProcess m_process; + QVersionNumber m_versionNumber; +}; + AbstractSettings::AbstractSettings(const QString &name, const QString &ending) : m_ending(ending) , m_styleDir(Core::ICore::userResourcePath(Beautifier::Constants::SETTINGS_DIRNAME) .pathAppended(name) .toString()) , m_name(name) + , m_versionUpdater(new VersionUpdater) { } @@ -122,29 +180,28 @@ QString AbstractSettings::styleFileName(const QString &key) const return m_styleDir.absoluteFilePath(key + m_ending); } -Utils::FilePath AbstractSettings::command() const +FilePath AbstractSettings::command() const { - return Utils::FilePath::fromString(m_command); + return FilePath::fromString(m_command); } -void AbstractSettings::setCommand(const QString &command) +void AbstractSettings::setCommand(const QString &cmd) { - if (command == m_command) + if (cmd == m_command) return; - m_command = command; - updateVersion(); + m_command = cmd; + m_versionUpdater->update(command()); } -int AbstractSettings::version() const +QVersionNumber AbstractSettings::version() const { - return m_version; + return m_versionUpdater->version(); } -void AbstractSettings::updateVersion() +void AbstractSettings::setVersionRegExp(const QRegularExpression &versionRegExp) { - // If a beautifier needs to know the current tool's version, reimplement and store the version - // in m_version. + m_versionUpdater->setVersionRegExp(versionRegExp); } QString AbstractSettings::supportedMimeTypesAsString() const @@ -157,7 +214,7 @@ void AbstractSettings::setSupportedMimeTypes(const QString &mimes) const QStringList stringTypes = mimes.split(';'); QStringList types; for (const QString &type : stringTypes) { - const Utils::MimeType mime = Utils::mimeTypeForName(type.trimmed()); + const MimeType mime = mimeTypeForName(type.trimmed()); if (!mime.isValid()) continue; const QString canonicalName = mime.name(); @@ -179,8 +236,8 @@ bool AbstractSettings::isApplicable(const Core::IDocument *document) const if (m_supportedMimeTypes.isEmpty()) return true; - const Utils::MimeType documentMimeType = Utils::mimeTypeForName(document->mimeType()); - return Utils::anyOf(m_supportedMimeTypes, [&documentMimeType](const QString &mime) { + const MimeType documentMimeType = mimeTypeForName(document->mimeType()); + return anyOf(m_supportedMimeTypes, [&documentMimeType](const QString &mime) { return documentMimeType.inherits(mime); }); } @@ -246,7 +303,7 @@ void AbstractSettings::save() continue; } - Utils::FileSaver saver(Utils::FilePath::fromUserInput(fi.absoluteFilePath())); + FileSaver saver(FilePath::fromUserInput(fi.absoluteFilePath())); if (saver.hasError()) { BeautifierPlugin::showError(tr("Cannot open file \"%1\": %2.") .arg(saver.filePath().toUserOutput()) diff --git a/src/plugins/beautifier/abstractsettings.h b/src/plugins/beautifier/abstractsettings.h index ae61bde2676..477f5c77187 100644 --- a/src/plugins/beautifier/abstractsettings.h +++ b/src/plugins/beautifier/abstractsettings.h @@ -35,12 +35,19 @@ #include #include +QT_BEGIN_NAMESPACE +class QRegularExpression; +class QVersionNumber; +QT_END_NAMESPACE + namespace Core { class IDocument; } namespace Utils { class FilePath; } namespace Beautifier { namespace Internal { +class VersionUpdater; + class AbstractSettings : public QObject { Q_OBJECT @@ -66,9 +73,8 @@ public: virtual QString styleFileName(const QString &key) const; Utils::FilePath command() const; - void setCommand(const QString &command); - int version() const; - virtual void updateVersion(); + void setCommand(const QString &cmd); + QVersionNumber version() const; QString supportedMimeTypesAsString() const; void setSupportedMimeTypes(const QString &mimes); @@ -81,9 +87,10 @@ signals: void supportedMimeTypesChanged(); protected: + void setVersionRegExp(const QRegularExpression &versionRegExp); + QMap m_styles; QMap m_settings; - int m_version = 0; QString m_ending; QDir m_styleDir; @@ -92,6 +99,7 @@ protected: private: QString m_name; + std::unique_ptr m_versionUpdater; QStringList m_stylesToRemove; QSet m_changedStyles; QString m_command; diff --git a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp index a8851b43cc5..04fda15a819 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp +++ b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp @@ -53,6 +53,7 @@ #include #include +#include using namespace TextEditor; @@ -150,10 +151,10 @@ Command ArtisticStyle::command(const QString &cfgFile) const command.addOption("-q"); command.addOption("--options=" + cfgFile); - const int version = m_settings.version(); - if (version > ArtisticStyleSettings::Version_2_03) { + const QVersionNumber version = m_settings.version(); + if (version > QVersionNumber(2, 3)) { command.setProcessing(Command::PipeProcessing); - if (version == ArtisticStyleSettings::Version_2_04) + if (version == QVersionNumber(2, 4)) command.setPipeAddsNewline(true); command.setReturnsCRLF(Utils::HostOsInfo::isWindowsHost()); command.addOption("-z2"); diff --git a/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp b/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp index a47fdda1011..5e7f8425cb9 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp +++ b/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp @@ -57,9 +57,7 @@ const char SETTINGS_NAME[] = "artisticstyle"; ArtisticStyleSettings::ArtisticStyleSettings() : AbstractSettings(SETTINGS_NAME, ".astyle") { - connect(&m_versionWatcher, &QFutureWatcherBase::finished, - this, &ArtisticStyleSettings::helperSetVersion); - + setVersionRegExp(QRegularExpression("([2-9]{1})\\.([0-9]{1,2})(\\.[1-9]{1})?$")); setCommand("astyle"); m_settings.insert(USE_OTHER_FILES, QVariant(true)); m_settings.insert(USE_SPECIFIC_CONFIG_FILE, QVariant(false)); @@ -70,48 +68,6 @@ ArtisticStyleSettings::ArtisticStyleSettings() : read(); } -static int parseVersion(const QString &text) -{ - // The version in Artistic Style is printed like "Artistic Style Version 2.04" - const QRegularExpression rx("([2-9]{1})\\.([0-9]{1,2})(\\.[1-9]{1})?$"); - const QRegularExpressionMatch match = rx.match(text); - if (match.hasMatch()) { - const int major = match.captured(1).toInt() * 100; - const int minor = match.captured(2).toInt(); - return major + minor; - } - return 0; -} - -static int updateVersionHelper(const FilePath &command) -{ - QtcProcess process; - process.setCommand({command, {"--version"}}); - process.runBlocking(); - if (process.result() != ProcessResult::FinishedWithSuccess) - return 0; - - // Astyle prints the version on stdout or stderr, depending on platform - const int version = parseVersion(process.cleanedStdOut().trimmed()); - if (version != 0) - return version; - return parseVersion(process.cleanedStdErr().trimmed()); -} - -void ArtisticStyleSettings::updateVersion() -{ - if (m_versionFuture.isRunning()) - m_versionFuture.cancel(); - - m_versionFuture = runAsync(updateVersionHelper, command()); - m_versionWatcher.setFuture(m_versionFuture); -} - -void ArtisticStyleSettings::helperSetVersion() -{ - m_version = m_versionWatcher.result(); -} - bool ArtisticStyleSettings::useOtherFiles() const { return m_settings.value(USE_OTHER_FILES).toBool(); @@ -132,12 +88,12 @@ void ArtisticStyleSettings::setUseSpecificConfigFile(bool useSpecificConfigFile) m_settings.insert(USE_SPECIFIC_CONFIG_FILE, QVariant(useSpecificConfigFile)); } -Utils::FilePath ArtisticStyleSettings::specificConfigFile() const +FilePath ArtisticStyleSettings::specificConfigFile() const { - return Utils::FilePath::fromString(m_settings.value(SPECIFIC_CONFIG_FILE).toString()); + return FilePath::fromString(m_settings.value(SPECIFIC_CONFIG_FILE).toString()); } -void ArtisticStyleSettings::setSpecificConfigFile(const Utils::FilePath &specificConfigFile) +void ArtisticStyleSettings::setSpecificConfigFile(const FilePath &specificConfigFile) { m_settings.insert(SPECIFIC_CONFIG_FILE, QVariant(specificConfigFile.toString())); } @@ -182,7 +138,7 @@ QString ArtisticStyleSettings::documentationFilePath() const void ArtisticStyleSettings::createDocumentationFile() const { - Utils::QtcProcess process; + QtcProcess process; process.setTimeoutS(2); process.setCommand({command(), {"-h"}}); process.runBlocking(); diff --git a/src/plugins/beautifier/artisticstyle/artisticstylesettings.h b/src/plugins/beautifier/artisticstyle/artisticstylesettings.h index e0fa1b8866e..cf125810317 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstylesettings.h +++ b/src/plugins/beautifier/artisticstyle/artisticstylesettings.h @@ -29,9 +29,6 @@ #include -#include -#include - namespace Beautifier { namespace Internal { @@ -40,15 +37,8 @@ class ArtisticStyleSettings : public AbstractSettings Q_OBJECT public: - enum ArtisticStyleVersion { - Version_2_03 = 203, - Version_2_04 = 204 - }; - ArtisticStyleSettings(); - void updateVersion() override; - bool useOtherFiles() const; void setUseOtherFiles(bool useOtherFiles); @@ -69,11 +59,6 @@ public: QString documentationFilePath() const override; void createDocumentationFile() const override; - -private: - void helperSetVersion(); - QFuture m_versionFuture; - QFutureWatcher m_versionWatcher; }; } // namespace Internal diff --git a/src/plugins/beautifier/uncrustify/uncrustify.cpp b/src/plugins/beautifier/uncrustify/uncrustify.cpp index 689ef3714a0..370a7f37a00 100644 --- a/src/plugins/beautifier/uncrustify/uncrustify.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustify.cpp @@ -49,6 +49,7 @@ #include #include +#include using namespace TextEditor; @@ -180,7 +181,7 @@ Command Uncrustify::command(const QString &cfgFile, bool fragment) const Command command; command.setExecutable(m_settings.command().toString()); command.setProcessing(Command::PipeProcessing); - if (m_settings.version() >= 62) { + if (m_settings.version() >= QVersionNumber(0, 62)) { command.addOption("--assume"); command.addOption("%file"); } else { diff --git a/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp b/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp index 77b775bc9c3..fbc8bfe079b 100644 --- a/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp @@ -30,7 +30,6 @@ #include "../beautifierconstants.h" #include - #include #include @@ -56,6 +55,7 @@ const char SETTINGS_NAME[] = "uncrustify"; UncrustifySettings::UncrustifySettings() : AbstractSettings(SETTINGS_NAME, ".cfg") { + setVersionRegExp(QRegularExpression("([0-9]{1})\\.([0-9]{2})")); setCommand("uncrustify"); m_settings.insert(USE_OTHER_FILES, QVariant(true)); m_settings.insert(USE_HOME_FILE, QVariant(false)); @@ -210,33 +210,5 @@ void UncrustifySettings::createDocumentationFile() const } } -static bool parseVersion(const QString &text, int &version) -{ - // The version in Uncrustify is printed like "uncrustify 0.62" - const QRegularExpression rx("([0-9]{1})\\.([0-9]{2})"); - const QRegularExpressionMatch match = rx.match(text); - if (!match.hasMatch()) - return false; - - const int major = match.captured(1).toInt() * 100; - const int minor = match.captured(2).toInt(); - version = major + minor; - return true; -} - -void UncrustifySettings::updateVersion() -{ - m_versionProcess.reset(new QtcProcess); - connect(m_versionProcess.get(), &QtcProcess::finished, this, [this] { - if (m_versionProcess->exitStatus() == QProcess::NormalExit) { - if (!parseVersion(QString::fromUtf8(m_versionProcess->readAllStandardOutput()), m_version)) - parseVersion(QString::fromUtf8(m_versionProcess->readAllStandardError()), m_version); - } - m_versionProcess.release()->deleteLater(); - }); - m_versionProcess->setCommand({ command(), { "--version" } }); - m_versionProcess->start(); -} - } // namespace Internal } // namespace Beautifier diff --git a/src/plugins/beautifier/uncrustify/uncrustifysettings.h b/src/plugins/beautifier/uncrustify/uncrustifysettings.h index 8c2db0ef2c4..e2cd9e99ec2 100644 --- a/src/plugins/beautifier/uncrustify/uncrustifysettings.h +++ b/src/plugins/beautifier/uncrustify/uncrustifysettings.h @@ -26,9 +26,6 @@ #pragma once #include "../abstractsettings.h" -#include - -namespace Utils { class QtcProcess; } namespace Beautifier { namespace Internal { @@ -59,16 +56,11 @@ public: QString documentationFilePath() const override; void createDocumentationFile() const override; - void updateVersion() override; - Utils::FilePath specificConfigFile() const; void setSpecificConfigFile(const Utils::FilePath &filePath); bool useSpecificConfigFile() const; void setUseSpecificConfigFile(bool useConfigFile); - -private: - std::unique_ptr m_versionProcess; }; } // namespace Internal From 05a7f93f965e2e11800f08fe3b1915c5d9c4eb96 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 21 Jun 2022 11:10:19 +0200 Subject: [PATCH 066/100] ProjectExplorer: Fix crash in TaskHub::addTask Change-Id: Ic51d6b30e96161e5e99f61d4de1ab674246c426c Reviewed-by: Alessandro Portale --- src/plugins/projectexplorer/taskhub.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/taskhub.cpp b/src/plugins/projectexplorer/taskhub.cpp index 02d1f713e60..d8962d8fc9c 100644 --- a/src/plugins/projectexplorer/taskhub.cpp +++ b/src/plugins/projectexplorer/taskhub.cpp @@ -154,7 +154,7 @@ void TaskHub::addTask(Task::TaskType type, const QString &description, Utils::Id void TaskHub::addTask(Task task) { if (QThread::currentThread() != qApp->thread()) { - QMetaObject::invokeMethod(qApp, [&task] { + QMetaObject::invokeMethod(qApp, [task = std::move(task)] { TaskHub::addTask(task); }); From ea868c8b46ae5c8fbf69a922b938884dcf2685f6 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Jun 2022 11:58:14 +0200 Subject: [PATCH 067/100] ClangCodeModel: Check system for clangd suitability on first run Turn off clangd by default if we think the system does not have enough memory. Inform the user and let them override our decision. Task-number: QTCREATORBUG-19297 Change-Id: Ib9715c2f089c10d7a2a559a25180e9a943c118b1 Reviewed-by: Eike Ziller --- src/libs/utils/hostosinfo.cpp | 28 ++++++++++++++ src/libs/utils/hostosinfo.h | 3 ++ .../clangmodelmanagersupport.cpp | 37 +++++++++++++++++++ .../cppeditor/cppcodemodelsettings.cpp | 22 ++++++++++- src/plugins/cppeditor/cppcodemodelsettings.h | 9 ++++- 5 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/libs/utils/hostosinfo.cpp b/src/libs/utils/hostosinfo.cpp index 657bf08470a..79f042e0f05 100644 --- a/src/libs/utils/hostosinfo.cpp +++ b/src/libs/utils/hostosinfo.cpp @@ -31,6 +31,10 @@ #include #endif +#ifdef Q_OS_LINUX +#include +#endif + #ifdef Q_OS_WIN #include #endif @@ -111,3 +115,27 @@ bool HostOsInfo::canCreateOpenGLContext(QString *errorMessage) return canCreate; #endif } + +optional HostOsInfo::totalMemoryInstalledInBytes() +{ +#ifdef Q_OS_LINUX + struct sysinfo info; + if (sysinfo(&info) == -1) + return {}; + return info.totalram; +#elif defined(Q_OS_WIN) + MEMORYSTATUSEX statex; + statex.dwLength = sizeof statex; + if (!GlobalMemoryStatusEx(&statex)) + return {}; + return statex.ullTotalPhys; +#elif defined(Q_OS_MACOS) + int mib[] = {CTL_HW, HW_MEMSIZE}; + int64_t ram; + size_t length = sizeof(int64_t); + if (sysctl(mib, 2, &ram, &length, nullptr, 0) == -1) + return {}; + return ram; +#endif + return {}; +} diff --git a/src/libs/utils/hostosinfo.h b/src/libs/utils/hostosinfo.h index 9fa6689d4b6..9823c7e6f23 100644 --- a/src/libs/utils/hostosinfo.h +++ b/src/libs/utils/hostosinfo.h @@ -27,6 +27,7 @@ #include "utils_global.h" +#include "optional.h" #include "osspecificaspects.h" QT_BEGIN_NAMESPACE @@ -104,6 +105,8 @@ public: static bool canCreateOpenGLContext(QString *errorMessage); + static optional totalMemoryInstalledInBytes(); + private: static Qt::CaseSensitivity m_overrideFileNameCaseSensitivity; static bool m_useOverrideFileNameCaseSensitivity; diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index a33d2863563..1437aff83f6 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -62,10 +62,12 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -124,6 +126,40 @@ static Client *clientForGeneratedFile(const Utils::FilePath &filePath) return nullptr; } +static void checkSystemForClangdSuitability() +{ + if (ClangdSettings::haveCheckedHardwareRequirements()) + return; + if (ClangdSettings::hardwareFulfillsRequirements()) + return; + + ClangdSettings::setUseClangd(false); + const QString warnStr = ClangModelManagerSupport::tr("The use of clangd for the C/C++ " + "code model was disabled, because it is likely that its memory requirements " + "would be higher than what your system can handle."); + const Utils::Id clangdWarningSetting("WarnAboutClangd"); + Utils::InfoBarEntry info(clangdWarningSetting, warnStr); + info.setDetailsWidgetCreator([] { + const auto label = new QLabel(ClangModelManagerSupport::tr( + "With clangd enabled, Qt Creator fully supports modern C++ " + "when highlighting code, completing symbols and so on.
" + "This comes at a higher cost in terms of CPU load and memory usage compared " + "to the built-in code model, which therefore might be the better choice " + "on older machines and/or with legacy code.
" + "You can enable/disable and fine-tune clangd here.")); + label->setWordWrap(true); + QObject::connect(label, &QLabel::linkActivated, [] { + Core::ICore::showOptionsDialog(CppEditor::Constants::CPP_CLANGD_SETTINGS_ID); + }); + return label; + }); + info.addCustomButton(ClangModelManagerSupport::tr("Enable Anyway"), [clangdWarningSetting] { + ClangdSettings::setUseClangd(true); + Core::ICore::infoBar()->removeInfo(clangdWarningSetting); + }); + Core::ICore::infoBar()->addInfo(info); +} + ClangModelManagerSupport::ClangModelManagerSupport() { QTC_CHECK(!m_instance); @@ -132,6 +168,7 @@ ClangModelManagerSupport::ClangModelManagerSupport() watchForExternalChanges(); watchForInternalChanges(); setupClangdConfigFile(); + checkSystemForClangdSuitability(); cppModelManager()->setCurrentDocumentFilter(std::make_unique()); cppModelManager()->setLocatorFilter(std::make_unique()); cppModelManager()->setClassesFilter(std::make_unique()); diff --git a/src/plugins/cppeditor/cppcodemodelsettings.cpp b/src/plugins/cppeditor/cppcodemodelsettings.cpp index 0c59d923c25..69f61e2e549 100644 --- a/src/plugins/cppeditor/cppcodemodelsettings.cpp +++ b/src/plugins/cppeditor/cppcodemodelsettings.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -81,6 +82,7 @@ static QString clangdSizeThresholdKey() { return QLatin1String("ClangdSizeThresh static QString clangdUseGlobalSettingsKey() { return QLatin1String("useGlobalSettings"); } static QString sessionsWithOneClangdKey() { return QLatin1String("SessionsWithOneClangd"); } static QString diagnosticConfigIdKey() { return QLatin1String("diagnosticConfigId"); } +static QString checkedHardwareKey() { return QLatin1String("checkedHardware"); } static FilePath g_defaultClangdFilePath; static FilePath fallbackClangdFilePath() @@ -206,6 +208,22 @@ bool ClangdSettings::useClangd() const return m_data.useClangd && clangdVersion() >= QVersionNumber(14); } +void ClangdSettings::setUseClangd(bool use) { instance().m_data.useClangd = use; } + +bool ClangdSettings::hardwareFulfillsRequirements() +{ + instance().m_data.haveCheckedHardwareReqirements = true; + instance().saveSettings(); + const quint64 minRam = quint64(12) * 1024 * 1024 * 1024; + const Utils::optional totalRam = Utils::HostOsInfo::totalMemoryInstalledInBytes(); + return !totalRam || *totalRam >= minRam; +} + +bool ClangdSettings::haveCheckedHardwareRequirements() +{ + return instance().data().haveCheckedHardwareReqirements; +} + void ClangdSettings::setDefaultClangdPath(const FilePath &filePath) { g_defaultClangdFilePath = filePath; @@ -350,8 +368,6 @@ void ClangdSettings::saveSettings() } #ifdef WITH_TESTS -void ClangdSettings::setUseClangd(bool use) { instance().m_data.useClangd = use; } - void ClangdSettings::setClangdFilePath(const FilePath &filePath) { instance().m_data.executableFilePath = filePath; @@ -435,6 +451,7 @@ QVariantMap ClangdSettings::Data::toMap() const map.insert(clangdSizeThresholdKey(), sizeThresholdInKb); map.insert(sessionsWithOneClangdKey(), sessionsWithOneClangd); map.insert(diagnosticConfigIdKey(), diagnosticConfigId.toSetting()); + map.insert(checkedHardwareKey(), true); return map; } @@ -451,6 +468,7 @@ void ClangdSettings::Data::fromMap(const QVariantMap &map) sessionsWithOneClangd = map.value(sessionsWithOneClangdKey()).toStringList(); diagnosticConfigId = Id::fromSetting(map.value(diagnosticConfigIdKey(), initialClangDiagnosticConfigId().toSetting())); + haveCheckedHardwareReqirements = map.value(checkedHardwareKey(), false).toBool(); } } // namespace CppEditor diff --git a/src/plugins/cppeditor/cppcodemodelsettings.h b/src/plugins/cppeditor/cppcodemodelsettings.h index 1bf5b46616a..8cf0bac463c 100644 --- a/src/plugins/cppeditor/cppcodemodelsettings.h +++ b/src/plugins/cppeditor/cppcodemodelsettings.h @@ -111,7 +111,8 @@ public: && s1.autoIncludeHeaders == s2.autoIncludeHeaders && s1.documentUpdateThreshold == s2.documentUpdateThreshold && s1.sizeThresholdEnabled == s2.sizeThresholdEnabled - && s1.sizeThresholdInKb == s2.sizeThresholdInKb; + && s1.sizeThresholdInKb == s2.sizeThresholdInKb + && s1.haveCheckedHardwareReqirements == s2.haveCheckedHardwareReqirements; } friend bool operator!=(const Data &s1, const Data &s2) { return !(s1 == s2); } @@ -126,12 +127,17 @@ public: bool enableIndexing = true; bool autoIncludeHeaders = false; bool sizeThresholdEnabled = false; + bool haveCheckedHardwareReqirements = false; }; ClangdSettings(const Data &data) : m_data(data) {} static ClangdSettings &instance(); bool useClangd() const; + static void setUseClangd(bool use); + + static bool hardwareFulfillsRequirements(); + static bool haveCheckedHardwareRequirements(); static void setDefaultClangdPath(const Utils::FilePath &filePath); static void setCustomDiagnosticConfigs(const ClangDiagnosticConfigs &configs); @@ -159,7 +165,6 @@ public: static Utils::FilePath clangdUserConfigFilePath(); #ifdef WITH_TESTS - static void setUseClangd(bool use); static void setClangdFilePath(const Utils::FilePath &filePath); #endif From 1a3f9155864ef8dc1731e0fc9c151a1889860f6e Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 21 Jun 2022 11:02:54 +0200 Subject: [PATCH 068/100] ClangCodeModel: Fix following virtual functions Amends 79b8e5397d340d70ad755c7bd8301846d89cafab. Change-Id: I8c4e3c7cb8cb26d51cdf77c15891110c6b213d46 Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdfollowsymbol.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdfollowsymbol.cpp b/src/plugins/clangcodemodel/clangdfollowsymbol.cpp index 64993a03ba0..4c7400914ab 100644 --- a/src/plugins/clangcodemodel/clangdfollowsymbol.cpp +++ b/src/plugins/clangcodemodel/clangdfollowsymbol.cpp @@ -134,6 +134,7 @@ public: SymbolDataList symbolsToDisplay; std::set openedFiles; VirtualFunctionAssistProcessor *virtualFuncAssistProcessor = nullptr; + QMetaObject::Connection focusChangedConnection; bool finished = false; }; @@ -151,8 +152,8 @@ ClangdFollowSymbol::ClangdFollowSymbol(ClangdClient *client, const QTextCursor & connect(editorWidget, &CppEditorWidget::cursorPositionChanged, this, &ClangdFollowSymbol::done, Qt::QueuedConnection); } - connect(qApp, &QApplication::focusChanged, - this, &ClangdFollowSymbol::done, Qt::QueuedConnection); + d->focusChangedConnection = connect(qApp, &QApplication::focusChanged, + this, &ClangdFollowSymbol::done, Qt::QueuedConnection); // Step 1: Follow the symbol via "Go to Definition". At the same time, request the // AST node corresponding to the cursor position, so we can find out whether @@ -413,8 +414,10 @@ void ClangdFollowSymbol::Private::handleGotoImplementationResult( // As soon as we know that there is more than one candidate, we start the code assist // procedure, to let the user know that things are happening. - if (allLinks.size() > 1 && !virtualFuncAssistProcessor && editorWidget) + if (allLinks.size() > 1 && !virtualFuncAssistProcessor && editorWidget) { + QObject::disconnect(focusChangedConnection); editorWidget->invokeTextEditorWidgetAssist(FollowSymbol, &virtualFuncAssistProvider); + } if (!pendingGotoImplRequests.isEmpty()) return; From bbbae099a741ed1eaf305cae72452d1ae2ca0c4e Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 20 Jun 2022 15:22:27 +0200 Subject: [PATCH 069/100] ClangCodeModel: Move decl/def switch functionality to dedicated class Change-Id: Id583ac58933e35e979083311907331b627d3c067 Reviewed-by: David Schulz --- src/plugins/clangcodemodel/CMakeLists.txt | 1 + src/plugins/clangcodemodel/clangcodemodel.qbs | 2 + src/plugins/clangcodemodel/clangdclient.cpp | 124 +----------- src/plugins/clangcodemodel/clangdclient.h | 1 + .../clangcodemodel/clangdswitchdecldef.cpp | 188 ++++++++++++++++++ .../clangcodemodel/clangdswitchdecldef.h | 59 ++++++ 6 files changed, 261 insertions(+), 114 deletions(-) create mode 100644 src/plugins/clangcodemodel/clangdswitchdecldef.cpp create mode 100644 src/plugins/clangcodemodel/clangdswitchdecldef.h diff --git a/src/plugins/clangcodemodel/CMakeLists.txt b/src/plugins/clangcodemodel/CMakeLists.txt index 896df4e18ce..e64d17b5f01 100644 --- a/src/plugins/clangcodemodel/CMakeLists.txt +++ b/src/plugins/clangcodemodel/CMakeLists.txt @@ -22,6 +22,7 @@ add_qtc_plugin(ClangCodeModel clangdquickfixfactory.cpp clangdquickfixfactory.h clangdqpropertyhighlighter.cpp clangdqpropertyhighlighter.h clangdsemantichighlighting.cpp clangdsemantichighlighting.h + clangdswitchdecldef.cpp clangdswitchdecldef.h clangeditordocumentprocessor.cpp clangeditordocumentprocessor.h clangfixitoperation.cpp clangfixitoperation.h clangdlocatorfilters.cpp clangdlocatorfilters.h diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index 19a0e7604a9..bd0f341cc50 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -46,6 +46,8 @@ QtcPlugin { "clangdquickfixfactory.h", "clangdsemantichighlighting.cpp", "clangdsemantichighlighting.h", + "clangdswitchdecldef.cpp", + "clangdswitchdecldef.h", "clangeditordocumentprocessor.cpp", "clangeditordocumentprocessor.h", "clangfixitoperation.cpp", diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 6441202bb6a..96034c1052c 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -30,6 +30,7 @@ #include "clangdast.h" #include "clangdfollowsymbol.h" #include "clangdlocatorfilters.h" +#include "clangdswitchdecldef.h" #include "clangpreprocessorassistproposalitem.h" #include "clangtextmark.h" #include "clangutils.h" @@ -59,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -117,8 +117,8 @@ namespace ClangCodeModel { namespace Internal { Q_LOGGING_CATEGORY(clangdLog, "qtc.clangcodemodel.clangd", QtWarningMsg); +Q_LOGGING_CATEGORY(clangdLogAst, "qtc.clangcodemodel.clangd.ast", QtWarningMsg); static Q_LOGGING_CATEGORY(clangdLogServer, "qtc.clangcodemodel.clangd.server", QtWarningMsg); -static Q_LOGGING_CATEGORY(clangdLogAst, "qtc.clangcodemodel.clangd.ast", QtWarningMsg); static Q_LOGGING_CATEGORY(clangdLogCompletion, "qtc.clangcodemodel.clangd.completion", QtWarningMsg); static QString indexingToken() { return "backgroundIndexProgress"; } @@ -310,59 +310,6 @@ public: bool categorize = CppEditor::codeModelSettings()->categorizeFindReferences(); }; -class SwitchDeclDefData { -public: - SwitchDeclDefData(quint64 id, TextDocument *doc, const QTextCursor &cursor, - CppEditor::CppEditorWidget *editorWidget, - const Utils::LinkHandler &callback) - : id(id), document(doc), uri(DocumentUri::fromFilePath(doc->filePath())), - cursor(cursor), editorWidget(editorWidget), callback(callback) {} - - Utils::optional getFunctionNode() const - { - QTC_ASSERT(ast, return {}); - - const ClangdAstPath path = getAstPath(*ast, Range(cursor)); - for (auto it = path.rbegin(); it != path.rend(); ++it) { - if (it->role() == "declaration" - && (it->kind() == "CXXMethod" || it->kind() == "CXXConversion" - || it->kind() == "CXXConstructor" || it->kind() == "CXXDestructor" - || it->kind() == "Function")) { - return *it; - } - } - return {}; - } - - QTextCursor cursorForFunctionName(const ClangdAstNode &functionNode) const - { - QTC_ASSERT(docSymbols, return {}); - - const auto symbolList = Utils::get_if>(&*docSymbols); - if (!symbolList) - return {}; - const Range &astRange = functionNode.range(); - QList symbolsToCheck = *symbolList; - while (!symbolsToCheck.isEmpty()) { - const DocumentSymbol symbol = symbolsToCheck.takeFirst(); - if (symbol.range() == astRange) - return symbol.selectionRange().start().toTextCursor(document->document()); - if (symbol.range().contains(astRange)) - symbolsToCheck << symbol.children().value_or(QList()); - } - return {}; - } - - const quint64 id; - const QPointer document; - const DocumentUri uri; - const QTextCursor cursor; - const QPointer editorWidget; - Utils::LinkHandler callback; - Utils::optional docSymbols; - Utils::optional ast; -}; - class LocalRefsData { public: LocalRefsData(quint64 id, TextDocument *doc, const QTextCursor &cursor, @@ -700,7 +647,7 @@ public: const CppEditor::ClangdSettings::Data settings; QHash runningFindUsages; ClangdFollowSymbol *followSymbol = nullptr; - Utils::optional switchDeclDefData; + ClangdSwitchDeclDef *switchDeclDef = nullptr; Utils::optional localRefsData; Utils::optional versionNumber; @@ -1017,15 +964,6 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir) QTC_CHECK(d->runningFindUsages.isEmpty()); }); - connect(documentSymbolCache(), &DocumentSymbolCache::gotSymbols, this, - [this](const DocumentUri &uri, const DocumentSymbolsResult &symbols) { - if (!d->switchDeclDefData || d->switchDeclDefData->uri != uri) - return; - d->switchDeclDefData->docSymbols = symbols; - if (d->switchDeclDefData->ast) - d->handleDeclDefSwitchReplies(); - }); - start(); } @@ -1684,26 +1622,13 @@ void ClangdClient::switchDeclDef(TextDocument *document, const QTextCursor &curs qCDebug(clangdLog) << "switch decl/dev requested" << document->filePath() << cursor.blockNumber() << cursor.positionInBlock(); - d->switchDeclDefData.emplace(++d->nextJobId, document, cursor, editorWidget, callback); - - // Retrieve AST and document symbols. - const auto astHandler = [this, id = d->switchDeclDefData->id](const ClangdAstNode &ast, - const MessageId &) { - qCDebug(clangdLog) << "received ast for decl/def switch"; - if (!d->switchDeclDefData || d->switchDeclDefData->id != id - || !d->switchDeclDefData->document) - return; - if (!ast.isValid()) { - d->switchDeclDefData.reset(); - return; - } - d->switchDeclDefData->ast = ast; - if (d->switchDeclDefData->docSymbols) - d->handleDeclDefSwitchReplies(); - - }; - d->getAndHandleAst(document, astHandler, AstCallbackMode::SyncIfPossible); - documentSymbolCache()->requestSymbols(d->switchDeclDefData->uri, Schedule::Now); + if (d->switchDeclDef) + delete d->switchDeclDef; + d->switchDeclDef = new ClangdSwitchDeclDef(this, document, cursor, editorWidget, callback); + connect(d->switchDeclDef, &ClangdSwitchDeclDef::done, this, [this] { + delete d->switchDeclDef; + d->switchDeclDef = nullptr; + }); } void ClangdClient::switchHeaderSource(const Utils::FilePath &filePath, bool inNextSplit) @@ -1981,35 +1906,6 @@ void ClangdClient::setVirtualRanges(const Utils::FilePath &filePath, const QList d->highlightingData[doc].virtualRanges = {ranges, revision}; } -void ClangdClient::Private::handleDeclDefSwitchReplies() -{ - if (!switchDeclDefData->document) { - switchDeclDefData.reset(); - return; - } - - // Find the function declaration or definition associated with the cursor. - // For instance, the cursor could be somwehere inside a function body or - // on a function return type, or ... - if (clangdLogAst().isDebugEnabled()) - switchDeclDefData->ast->print(0); - const Utils::optional functionNode = switchDeclDefData->getFunctionNode(); - if (!functionNode) { - switchDeclDefData.reset(); - return; - } - - // Unfortunately, the AST does not contain the location of the actual function name symbol, - // so we have to look for it in the document symbols. - const QTextCursor funcNameCursor = switchDeclDefData->cursorForFunctionName(*functionNode); - if (!funcNameCursor.isNull()) { - q->followSymbol(switchDeclDefData->document.data(), funcNameCursor, - switchDeclDefData->editorWidget, std::move(switchDeclDefData->callback), - true, false); - } - switchDeclDefData.reset(); -} - Utils::optional ClangdClient::Private::getContainingFunctionName( const ClangdAstPath &astPath, const Range& range) { diff --git a/src/plugins/clangcodemodel/clangdclient.h b/src/plugins/clangcodemodel/clangdclient.h index 13530b168f7..2aec6f8b570 100644 --- a/src/plugins/clangcodemodel/clangdclient.h +++ b/src/plugins/clangcodemodel/clangdclient.h @@ -51,6 +51,7 @@ namespace Internal { class ClangdAstNode; Q_DECLARE_LOGGING_CATEGORY(clangdLog); +Q_DECLARE_LOGGING_CATEGORY(clangdLogAst); void setupClangdConfigFile(); diff --git a/src/plugins/clangcodemodel/clangdswitchdecldef.cpp b/src/plugins/clangcodemodel/clangdswitchdecldef.cpp new file mode 100644 index 00000000000..d3ce7187631 --- /dev/null +++ b/src/plugins/clangcodemodel/clangdswitchdecldef.cpp @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "clangdswitchdecldef.h" + +#include "clangdast.h" +#include "clangdclient.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace CppEditor; +using namespace LanguageClient; +using namespace LanguageServerProtocol; +using namespace TextEditor; +using namespace Utils; + +namespace ClangCodeModel::Internal { + +class ClangdSwitchDeclDef::Private +{ +public: + Private(ClangdSwitchDeclDef * q, ClangdClient *client, TextDocument *doc, + const QTextCursor &cursor, CppEditorWidget *editorWidget, const LinkHandler &callback) + : q(q), client(client), document(doc), uri(DocumentUri::fromFilePath(doc->filePath())), + cursor(cursor), editorWidget(editorWidget), callback(callback) + {} + + optional getFunctionNode() const; + QTextCursor cursorForFunctionName(const ClangdAstNode &functionNode) const; + void handleDeclDefSwitchReplies(); + + ClangdSwitchDeclDef * const q; + ClangdClient * const client; + const QPointer document; + const DocumentUri uri; + const QTextCursor cursor; + const QPointer editorWidget; + const LinkHandler callback; + optional ast; + optional docSymbols; +}; + +ClangdSwitchDeclDef::ClangdSwitchDeclDef(ClangdClient *client, TextDocument *doc, + const QTextCursor &cursor, CppEditorWidget *editorWidget, const LinkHandler &callback) + : QObject(client), d(new Private(this, client, doc, cursor, editorWidget, callback)) +{ + // Abort if the user does something else with the document in the meantime. + connect(doc, &TextDocument::contentsChanged, this, &ClangdSwitchDeclDef::done, + Qt::QueuedConnection); + if (editorWidget) { + connect(editorWidget, &CppEditorWidget::cursorPositionChanged, + this, &ClangdSwitchDeclDef::done, Qt::QueuedConnection); + } + connect(qApp, &QApplication::focusChanged, + this, &ClangdSwitchDeclDef::done, Qt::QueuedConnection); + + connect(client->documentSymbolCache(), &DocumentSymbolCache::gotSymbols, this, + [this](const DocumentUri &uri, const DocumentSymbolsResult &symbols) { + if (uri != d->uri) + return; + d->docSymbols = symbols; + if (d->ast) + d->handleDeclDefSwitchReplies(); + }); + + + // Retrieve AST and document symbols. + const auto astHandler = [this, self = QPointer(this)] + (const ClangdAstNode &ast, const MessageId &) { + qCDebug(clangdLog) << "received ast for decl/def switch"; + if (!self) + return; + if (!d->document) { + emit done(); + return; + } + if (!ast.isValid()) { + emit done(); + return; + } + d->ast = ast; + if (d->docSymbols) + d->handleDeclDefSwitchReplies(); + + }; + client->getAndHandleAst(doc, astHandler, ClangdClient::AstCallbackMode::SyncIfPossible, {}); + client->documentSymbolCache()->requestSymbols(d->uri, Schedule::Now); +} + +ClangdSwitchDeclDef::~ClangdSwitchDeclDef() +{ + delete d; +} + +optional ClangdSwitchDeclDef::Private::getFunctionNode() const +{ + QTC_ASSERT(ast, return {}); + + const ClangdAstPath path = getAstPath(*ast, Range(cursor)); + for (auto it = path.rbegin(); it != path.rend(); ++it) { + if (it->role() == "declaration" + && (it->kind() == "CXXMethod" || it->kind() == "CXXConversion" + || it->kind() == "CXXConstructor" || it->kind() == "CXXDestructor" + || it->kind() == "Function")) { + return *it; + } + } + return {}; +} + +QTextCursor ClangdSwitchDeclDef::Private::cursorForFunctionName(const ClangdAstNode &functionNode) const +{ + QTC_ASSERT(docSymbols, return {}); + + const auto symbolList = Utils::get_if>(&*docSymbols); + if (!symbolList) + return {}; + const Range &astRange = functionNode.range(); + QList symbolsToCheck = *symbolList; + while (!symbolsToCheck.isEmpty()) { + const DocumentSymbol symbol = symbolsToCheck.takeFirst(); + if (symbol.range() == astRange) + return symbol.selectionRange().start().toTextCursor(document->document()); + if (symbol.range().contains(astRange)) + symbolsToCheck << symbol.children().value_or(QList()); + } + return {}; +} + +void ClangdSwitchDeclDef::Private::handleDeclDefSwitchReplies() +{ + if (!document) { + emit q->done(); + return; + } + + // Find the function declaration or definition associated with the cursor. + // For instance, the cursor could be somwehere inside a function body or + // on a function return type, or ... + if (clangdLogAst().isDebugEnabled()) + ast->print(0); + const Utils::optional functionNode = getFunctionNode(); + if (!functionNode) { + emit q->done(); + return; + } + + // Unfortunately, the AST does not contain the location of the actual function name symbol, + // so we have to look for it in the document symbols. + const QTextCursor funcNameCursor = cursorForFunctionName(*functionNode); + if (!funcNameCursor.isNull()) { + client->followSymbol(document.data(), funcNameCursor, editorWidget, callback, + true, false); + } + emit q->done(); +} + +} // namespace ClangCodeModel::Internal diff --git a/src/plugins/clangcodemodel/clangdswitchdecldef.h b/src/plugins/clangcodemodel/clangdswitchdecldef.h new file mode 100644 index 00000000000..8c278bf6555 --- /dev/null +++ b/src/plugins/clangcodemodel/clangdswitchdecldef.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +#include + +namespace CppEditor { class CppEditorWidget; } +namespace TextEditor { class TextDocument; } + +QT_BEGIN_NAMESPACE +class QTextCursor; +QT_END_NAMESPACE + +namespace ClangCodeModel::Internal { +class ClangdClient; + +class ClangdSwitchDeclDef : public QObject +{ + Q_OBJECT +public: + ClangdSwitchDeclDef(ClangdClient *client, TextEditor::TextDocument *doc, + const QTextCursor &cursor, CppEditor::CppEditorWidget *editorWidget, + const Utils::LinkHandler &callback); + ~ClangdSwitchDeclDef(); + +signals: + void done(); + +private: + class Private; + Private * const d; +}; + +} // namespace ClangCodeModel::Internal From 627f6a2916f1a53cc2d5a775818b0d610d1dd9c0 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 21 Jun 2022 10:06:47 +0200 Subject: [PATCH 070/100] cppeditor: Show hints for qmlRegister... diagnostics This fixes passing the hints from FindExportedCppTypes to the actual cppeditor so they can be displayed to the user. Fixes: QTCREATORBUG-27243 Change-Id: Ibcb68296f044a9c6a96f40945d8a0e964be7f042 Reviewed-by: Christian Kandeler --- src/libs/qmljs/qmljsfindexportedcpptypes.cpp | 2 +- src/libs/qmljs/qmljslink.cpp | 3 +- src/plugins/cppeditor/cppeditordocument.cpp | 51 ++++++++++++++++++++ src/plugins/cppeditor/cppeditordocument.h | 2 + src/plugins/cppeditor/cppmodelmanager.cpp | 16 ++++++ src/plugins/cppeditor/cppmodelmanager.h | 8 +++ 6 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp index 40358b6c954..72a4cfad511 100644 --- a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp +++ b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp @@ -334,7 +334,7 @@ protected: _doc->fileName(), line, column, QmlJS::FindExportedCppTypes::tr( - "The module URI cannot be determined by static analysis. The type will be available\n" + "The module URI cannot be determined by static analysis. The type will not be available\n" "globally in the QML editor. You can add a \"// @uri My.Module.Uri\" annotation to let\n" "the QML editor know about a likely URI.")); } diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index fe3301db933..df881a09ab4 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -465,7 +465,8 @@ Import LinkPrivate::importNonFile(const Document::Ptr &doc, const ImportInfo &im "For Qbs projects, declare and set a qmlImportPaths property in your product " "to add import paths.\n" "For qmlproject projects, use the importPaths property to add import paths.\n" - "For CMake projects, make sure QML_IMPORT_PATH variable is in CMakeCache.txt.\n") + "For CMake projects, make sure QML_IMPORT_PATH variable is in CMakeCache.txt.\n" + "For qmlRegister... calls, make sure that you define the Module URI as a string literal.\n") .arg(importInfo.name(), m_importPaths.join(QLatin1Char('\n')))); } diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index e7621e823ee..80a8cce0bd3 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -50,7 +50,9 @@ #include #include #include +#include +#include #include const char NO_PROJECT_CONFIGURATION[] = "NoProject"; @@ -121,6 +123,9 @@ CppEditorDocument::CppEditorDocument() connect(this, &IDocument::filePathChanged, this, &CppEditorDocument::onFilePathChanged); + connect(mm(), &CppModelManager::diagnosticsChanged, + this, &CppEditorDocument::onDiagnosticsChanged); + connect(&m_parseContextModel, &ParseContextModel::preferredParseContextChanged, this, &CppEditorDocument::reparseWithPreferredParseContext); @@ -483,5 +488,51 @@ bool CppEditorDocument::save(QString *errorString, const FilePath &filePath, boo return TextEditor::TextDocument::save(errorString, filePath, autoSave); } +void CppEditorDocument::onDiagnosticsChanged(const QString &fileName, const QString &kind) +{ + if (FilePath::fromString(fileName) != filePath()) + return; + + TextMarks removedMarks = marks(); + + const Utils::Id category = Utils::Id::fromString(kind); + + for (const auto &diagnostic : mm()->diagnosticMessages()) { + if (FilePath::fromString(diagnostic.fileName()) == filePath()) { + auto it = std::find_if(std::begin(removedMarks), + std::end(removedMarks), + [&category, &diagnostic](TextMark *existing) { + return (diagnostic.line() == existing->lineNumber() + && diagnostic.text() == existing->lineAnnotation() + && category == existing->category()); + }); + + if (it != std::end(removedMarks)) { + removedMarks.erase(it); + continue; + } + + auto mark = new TextMark(filePath(), diagnostic.line(), category); + mark->setLineAnnotation(diagnostic.text()); + mark->setToolTip(diagnostic.text()); + + mark->setIcon(diagnostic.isWarning() ? Utils::Icons::CODEMODEL_WARNING.icon() + : Utils::Icons::CODEMODEL_ERROR.icon()); + mark->setColor(diagnostic.isWarning() ? Utils::Theme::CodeModel_Warning_TextMarkColor + : Utils::Theme::CodeModel_Error_TextMarkColor); + mark->setPriority(diagnostic.isWarning() ? TextEditor::TextMark::NormalPriority + : TextEditor::TextMark::HighPriority); + addMark(mark); + } + } + + for (auto it = removedMarks.begin(); it != removedMarks.end(); ++it) { + if ((*it)->category() == category) { + removeMark(*it); + delete *it; + } + } +} + } // namespace Internal } // namespace CppEditor diff --git a/src/plugins/cppeditor/cppeditordocument.h b/src/plugins/cppeditor/cppeditordocument.h index 54009a04ebd..09d5ab96b63 100644 --- a/src/plugins/cppeditor/cppeditordocument.h +++ b/src/plugins/cppeditor/cppeditordocument.h @@ -94,6 +94,8 @@ private: void onAboutToReload(); void onReloadFinished(); + void onDiagnosticsChanged(const QString &fileName, const QString &kind); + void reparseWithPreferredParseContext(const QString &id); diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index f646631a90e..7bbf588383f 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -201,6 +201,8 @@ public: std::unique_ptr m_functionsFilter; std::unique_ptr m_symbolsFindFilter; std::unique_ptr m_currentDocumentFilter; + + QList m_diagnosticMessages; }; } // namespace Internal @@ -1704,4 +1706,18 @@ QThreadPool *CppModelManager::sharedThreadPool() return &d->m_threadPool; } +bool CppModelManager::setExtraDiagnostics(const QString &fileName, + const QString &kind, + const QList &diagnostics) +{ + d->m_diagnosticMessages = diagnostics; + emit diagnosticsChanged(fileName, kind); + return true; +} + +const QList CppModelManager::diagnosticMessages() +{ + return d->m_diagnosticMessages; +} + } // namespace CppEditor diff --git a/src/plugins/cppeditor/cppmodelmanager.h b/src/plugins/cppeditor/cppmodelmanager.h index 3526bb5fbe0..efccd521190 100644 --- a/src/plugins/cppeditor/cppmodelmanager.h +++ b/src/plugins/cppeditor/cppmodelmanager.h @@ -104,6 +104,12 @@ public: QByteArray codeModelConfiguration() const; CppLocatorData *locatorData() const; + bool setExtraDiagnostics(const QString &fileName, + const QString &kind, + const QList &diagnostics) override; + + const QList diagnosticMessages(); + QList projectInfos() const; ProjectInfo::ConstPtr projectInfo(ProjectExplorer::Project *project) const; QFuture updateProjectInfo(const ProjectInfo::ConstPtr &newProjectInfo, @@ -256,6 +262,8 @@ signals: void abstractEditorSupportRemoved(const QString &filePath); void fallbackProjectPartUpdated(); + void diagnosticsChanged(const QString &fileName, const QString &kind); + public slots: void updateModifiedSourceFiles(); void GC(); From e3f27b3d53e94aa81088edb019f2b6383fcdc170 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Jun 2022 15:25:52 +0200 Subject: [PATCH 071/100] GdbEngine: Don't call blocking waitForStarted() Connect to started() signal instead and continue setup in its handler. Handle failed to start case inside done() signal handler. Change-Id: Iaf184ed3e934b1bd5f8128a6aa9c72e9f27e0f56 Reviewed-by: hjk --- src/plugins/debugger/gdb/gdbengine.cpp | 34 ++++++++++++++++---------- src/plugins/debugger/gdb/gdbengine.h | 1 + 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 1fd3aef4aad..6dc3cb9d800 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -169,6 +169,8 @@ GdbEngine::GdbEngine() connect(&s.useDynamicType, &BaseAspect::changed, this, &GdbEngine::reloadLocals); + connect(&m_gdbProc, &QtcProcess::started, + this, &GdbEngine::handleGdbStarted); connect(&m_gdbProc, &QtcProcess::done, this, &GdbEngine::handleGdbDone); connect(&m_gdbProc, &QtcProcess::readyReadStandardOutput, @@ -3865,20 +3867,10 @@ void GdbEngine::setupEngine() m_gdbProc.setWorkingDirectory(rp.debugger.workingDirectory); m_gdbProc.setEnvironment(gdbEnv); m_gdbProc.start(); +} - if (!m_gdbProc.waitForStarted()) { - handleGdbStartFailed(); - QString msg; - FilePath wd = m_gdbProc.workingDirectory(); - if (!wd.isReadableDir()) - msg = failedToStartMessage() + ' ' + tr("The working directory \"%1\" is not usable.") - .arg(wd.toUserOutput()); - else - msg = RunWorker::userMessageForProcessError(QProcess::FailedToStart, rp.debugger.command.executable()); - handleAdapterStartFailed(msg); - return; - } - +void GdbEngine::handleGdbStarted() +{ showMessage("GDB STARTED, INITIALIZING IT"); runCommand({"show version", CB(handleShowVersion)}); runCommand({"show debug-file-directory", CB(handleDebugInfoLocation)}); @@ -3938,6 +3930,7 @@ void GdbEngine::setupEngine() showStatusMessage(tr("Setting up inferior...")); + const DebuggerRunParameters &rp = runParameters(); // Addint executable to modules list. Module module; module.startAddress = 0; @@ -4079,6 +4072,21 @@ void GdbEngine::reloadDebuggingHelpers() void GdbEngine::handleGdbDone() { + if (m_gdbProc.result() == ProcessResult::StartFailed) { + handleGdbStartFailed(); + QString msg; + const FilePath wd = m_gdbProc.workingDirectory(); + if (!wd.isReadableDir()) { + msg = failedToStartMessage() + ' ' + tr("The working directory \"%1\" is not usable.") + .arg(wd.toUserOutput()); + } else { + msg = RunWorker::userMessageForProcessError(QProcess::FailedToStart, + runParameters().debugger.command.executable()); + } + handleAdapterStartFailed(msg); + return; + } + const QProcess::ProcessError error = m_gdbProc.error(); if (error != QProcess::UnknownError) { QString msg = RunWorker::userMessageForProcessError(error, diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index a8dd2882e0d..49a090951a8 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -111,6 +111,7 @@ private: ////////// General Interface ////////// // The engine is still running just fine, but it failed to acquire a debuggee. void notifyInferiorSetupFailedHelper(const QString &msg); + void handleGdbStarted(); void handleGdbDone(); void readGdbStandardOutput(); void readGdbStandardError(); From d8ad6b2a9e300310cc303fe75909d77b5e30d037 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Jun 2022 16:43:47 +0200 Subject: [PATCH 072/100] tst_QtcProcess: Connect to done() signal instead of finished() Change-Id: Ie01349b1f9ec8189d6503df3ed0b2e1e1252d0f6 Reviewed-by: hjk --- tests/auto/utils/qtcprocess/tst_qtcprocess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp index 461da201e5f..e73ad97ad4e 100644 --- a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp +++ b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp @@ -1190,7 +1190,7 @@ void tst_QtcProcess::emitOneErrorOnCrash() QVERIFY(process.waitForStarted(1000)); QEventLoop loop; - connect(&process, &QtcProcess::finished, &loop, &QEventLoop::quit); + connect(&process, &QtcProcess::done, &loop, &QEventLoop::quit); loop.exec(); QCOMPARE(errorCount, 1); From 35c3d9430b28a05c200a631ce05f60c24f7889b6 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Jun 2022 16:24:57 +0200 Subject: [PATCH 073/100] QueryContext: Connect to done() signal instead of finished() Change-Id: I642138a90c4e13fcdb4dbb065e26aa5e3d509b9e Reviewed-by: hjk --- src/plugins/git/gerrit/gerritmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/git/gerrit/gerritmodel.cpp b/src/plugins/git/gerrit/gerritmodel.cpp index 9c835c98a5b..c213744b61a 100644 --- a/src/plugins/git/gerrit/gerritmodel.cpp +++ b/src/plugins/git/gerrit/gerritmodel.cpp @@ -375,7 +375,7 @@ void QueryContext::timeout() arg(timeOutMS / 1000), QMessageBox::NoButton, parent); QPushButton *terminateButton = box.addButton(tr("Terminate"), QMessageBox::YesRole); box.addButton(tr("Keep Running"), QMessageBox::NoRole); - connect(&m_process, &QtcProcess::finished, &box, &QDialog::reject); + connect(&m_process, &QtcProcess::done, &box, &QDialog::reject); box.exec(); if (m_process.state() != QProcess::Running) return; From 94adc1a566eaf8e29970e85619ffdc4b64d3561b Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 22 Jun 2022 07:28:15 +0200 Subject: [PATCH 074/100] MergeTool: Don't call blocking waitForStarted() Connect to done() signal instead of finished(). In case the process failed to start it will delete itself from inside done handler. Change-Id: I277779904d571759bf3877860d64e80ad304c2da Reviewed-by: Orgad Shaneh --- src/plugins/git/gitclient.cpp | 3 +-- src/plugins/git/mergetool.cpp | 28 ++++++++++------------------ src/plugins/git/mergetool.h | 2 +- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 4b3b59a06d6..1a2b211156b 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1141,8 +1141,7 @@ void GitClient::diffBranch(const FilePath &workingDirectory, const QString &bran void GitClient::merge(const FilePath &workingDirectory, const QStringList &unmergedFileNames) { auto mergeTool = new MergeTool(this); - if (!mergeTool->start(workingDirectory, unmergedFileNames)) - delete mergeTool; + mergeTool->start(workingDirectory, unmergedFileNames); } void GitClient::status(const FilePath &workingDirectory) const diff --git a/src/plugins/git/mergetool.cpp b/src/plugins/git/mergetool.cpp index 97259483beb..ceaf634b00d 100644 --- a/src/plugins/git/mergetool.cpp +++ b/src/plugins/git/mergetool.cpp @@ -52,7 +52,7 @@ MergeTool::~MergeTool() delete m_process; } -bool MergeTool::start(const FilePath &workingDirectory, const QStringList &files) +void MergeTool::start(const FilePath &workingDirectory, const QStringList &files) { QStringList arguments; arguments << "mergetool" << "-y" << files; @@ -60,6 +60,8 @@ bool MergeTool::start(const FilePath &workingDirectory, const QStringList &files env.set("LANG", "C"); env.set("LANGUAGE", "C"); m_process = new QtcProcess; + connect(m_process, &QtcProcess::done, this, &MergeTool::done); + connect(m_process, &QtcProcess::readyReadStandardOutput, this, &MergeTool::readData); m_process->setProcessMode(ProcessMode::Writer); m_process->setWorkingDirectory(workingDirectory); m_process->setEnvironment(env); @@ -69,15 +71,6 @@ bool MergeTool::start(const FilePath &workingDirectory, const QStringList &files VcsOutputWindow::appendCommand(workingDirectory, cmd); m_process->setCommand(cmd); m_process->start(); - if (m_process->waitForStarted()) { - connect(m_process, &QtcProcess::finished, this, &MergeTool::done); - connect(m_process, &QtcProcess::readyReadStandardOutput, this, &MergeTool::readData); - } else { - delete m_process; - m_process = nullptr; - return false; - } - return true; } MergeTool::FileState MergeTool::parseStatus(const QString &line, QString &extraInfo) @@ -254,15 +247,14 @@ void MergeTool::readLine(const QString &line) void MergeTool::done() { + const bool success = m_process->result() == ProcessResult::FinishedWithSuccess; + if (success) + VcsOutputWindow::appendMessage(m_process->exitMessage()); + else + VcsOutputWindow::appendError(m_process->exitMessage()); + const FilePath workingDirectory = m_process->workingDirectory(); - int exitCode = m_process->exitCode(); - if (!exitCode) { - VcsOutputWindow::appendMessage(tr("Merge tool process finished successfully.")); - } else { - VcsOutputWindow::appendError(tr("Merge tool process terminated with exit code %1") - .arg(exitCode)); - } - GitClient::instance()->continueCommandIfNeeded(workingDirectory, exitCode == 0); + GitClient::instance()->continueCommandIfNeeded(workingDirectory, success); GitPlugin::emitRepositoryChanged(workingDirectory); deleteLater(); } diff --git a/src/plugins/git/mergetool.h b/src/plugins/git/mergetool.h index 7d0fba01b80..4d7dfb830ea 100644 --- a/src/plugins/git/mergetool.h +++ b/src/plugins/git/mergetool.h @@ -57,7 +57,7 @@ class MergeTool : public QObject public: explicit MergeTool(QObject *parent = nullptr); ~MergeTool() override; - bool start(const Utils::FilePath &workingDirectory, const QStringList &files = {}); + void start(const Utils::FilePath &workingDirectory, const QStringList &files = {}); enum MergeType { NormalMerge, From a78b38653aafe59c326ba54368a3e79c0378bafd Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 22 Jun 2022 08:06:06 +0200 Subject: [PATCH 075/100] MergeTool: De-pointer process Get rid of unused m_merging field. Change-Id: I0e6d80f6422881ad37982a6946fa3916b4574094 Reviewed-by: Orgad Shaneh --- src/plugins/git/mergetool.cpp | 49 ++++++++++++++--------------------- src/plugins/git/mergetool.h | 12 +++------ 2 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/plugins/git/mergetool.cpp b/src/plugins/git/mergetool.cpp index ceaf634b00d..71ac736ef26 100644 --- a/src/plugins/git/mergetool.cpp +++ b/src/plugins/git/mergetool.cpp @@ -30,9 +30,7 @@ #include #include #include -#include #include -#include #include #include @@ -45,32 +43,26 @@ namespace Git { namespace Internal { MergeTool::MergeTool(QObject *parent) : QObject(parent) -{ } - -MergeTool::~MergeTool() { - delete m_process; + connect(&m_process, &QtcProcess::done, this, &MergeTool::done); + connect(&m_process, &QtcProcess::readyReadStandardOutput, this, &MergeTool::readData); + Environment env = Environment::systemEnvironment(); + env.set("LANG", "C"); + env.set("LANGUAGE", "C"); + m_process.setEnvironment(env); + m_process.setProcessMode(ProcessMode::Writer); + m_process.setProcessChannelMode(QProcess::MergedChannels); } void MergeTool::start(const FilePath &workingDirectory, const QStringList &files) { QStringList arguments; arguments << "mergetool" << "-y" << files; - Environment env = Environment::systemEnvironment(); - env.set("LANG", "C"); - env.set("LANGUAGE", "C"); - m_process = new QtcProcess; - connect(m_process, &QtcProcess::done, this, &MergeTool::done); - connect(m_process, &QtcProcess::readyReadStandardOutput, this, &MergeTool::readData); - m_process->setProcessMode(ProcessMode::Writer); - m_process->setWorkingDirectory(workingDirectory); - m_process->setEnvironment(env); - m_process->setProcessChannelMode(QProcess::MergedChannels); - const Utils::FilePath binary = GitClient::instance()->vcsBinary(); - const CommandLine cmd = {binary, arguments}; + const CommandLine cmd = {GitClient::instance()->vcsBinary(), arguments}; VcsOutputWindow::appendCommand(workingDirectory, cmd); - m_process->setCommand(cmd); - m_process->start(); + m_process.setCommand(cmd); + m_process.setWorkingDirectory(workingDirectory); + m_process.start(); } MergeTool::FileState MergeTool::parseStatus(const QString &line, QString &extraInfo) @@ -141,8 +133,7 @@ QString MergeTool::stateName(MergeTool::FileState state, const QString &extraInf void MergeTool::chooseAction() { - m_merging = (m_mergeType == NormalMerge); - if (m_merging) + if (m_mergeType == NormalMerge) return; QMessageBox msgBox; msgBox.setWindowTitle(tr("Merge Conflict")); @@ -199,7 +190,7 @@ void MergeTool::prompt(const QString &title, const QString &question) void MergeTool::readData() { - QString newData = QString::fromLocal8Bit(m_process->readAllStandardOutput()); + QString newData = QString::fromLocal8Bit(m_process.readAllStandardOutput()); newData.remove('\r'); VcsOutputWindow::append(newData); QString data = m_unfinishedLine + newData; @@ -223,7 +214,7 @@ void MergeTool::readData() tr("Merge tool is not configured."), tr("Run git config --global merge.tool <tool> " "to configure it, then try again."))); - m_process->kill(); + m_process.stop(); } else { m_unfinishedLine = data; } @@ -247,13 +238,13 @@ void MergeTool::readLine(const QString &line) void MergeTool::done() { - const bool success = m_process->result() == ProcessResult::FinishedWithSuccess; + const bool success = m_process.result() == ProcessResult::FinishedWithSuccess; if (success) - VcsOutputWindow::appendMessage(m_process->exitMessage()); + VcsOutputWindow::appendMessage(m_process.exitMessage()); else - VcsOutputWindow::appendError(m_process->exitMessage()); + VcsOutputWindow::appendError(m_process.exitMessage()); - const FilePath workingDirectory = m_process->workingDirectory(); + const FilePath workingDirectory = m_process.workingDirectory(); GitClient::instance()->continueCommandIfNeeded(workingDirectory, success); GitPlugin::emitRepositoryChanged(workingDirectory); deleteLater(); @@ -261,7 +252,7 @@ void MergeTool::done() void MergeTool::write(const QString &str) { - m_process->write(str); + m_process.write(str); VcsOutputWindow::append(str); } diff --git a/src/plugins/git/mergetool.h b/src/plugins/git/mergetool.h index 4d7dfb830ea..735c53ea711 100644 --- a/src/plugins/git/mergetool.h +++ b/src/plugins/git/mergetool.h @@ -25,6 +25,8 @@ #pragma once +#include + #include #include @@ -32,12 +34,6 @@ QT_BEGIN_NAMESPACE class QMessageBox; QT_END_NAMESPACE -namespace Utils -{ -class FilePath; -class QtcProcess; -} - namespace Git { namespace Internal { @@ -56,7 +52,6 @@ class MergeTool : public QObject public: explicit MergeTool(QObject *parent = nullptr); - ~MergeTool() override; void start(const Utils::FilePath &workingDirectory, const QStringList &files = {}); enum MergeType { @@ -79,7 +74,7 @@ private: void chooseAction(); void addButton(QMessageBox *msgBox, const QString &text, char key); - Utils::QtcProcess *m_process = nullptr; + Utils::QtcProcess m_process; MergeType m_mergeType = NormalMerge; QString m_fileName; FileState m_localState = UnknownState; @@ -87,7 +82,6 @@ private: FileState m_remoteState = UnknownState; QString m_remoteInfo; QString m_unfinishedLine; - bool m_merging = false; }; } // namespace Internal From 9341733b3759b8fd2340cc539a041d5f08c1edb7 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Jun 2022 15:50:11 +0200 Subject: [PATCH 076/100] Utils: Document escaping rules for % and / in FilePath Change-Id: Ief9e739e167f724b1626c3478ac4d6f94fc3bac0 Reviewed-by: Christian Stenger Reviewed-by: Eike Ziller Reviewed-by: --- src/libs/utils/filepath.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 14436bdc1d1..4c903640f79 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -945,8 +945,30 @@ QString FilePath::displayName(const QString &args) const .arg(m_data, args, deviceName); } -/// Constructs a FilePath from \a filename -/// \a filename is not checked for validity. +/*! + Constructs a FilePath from \a filepath + + \a filepath is not checked for validity. It can be given in the following forms: + + \list + \li /some/absolute/local/path + \li some/relative/path + \li scheme://host/absolute/path + \li scheme://host/./relative/path \note the ./ is verbatim part of the path + \endlist + + Some decoding happens when parsing the \a filepath + A sequence %25 present in the host part is replaced by % in the host name, + a sequence %2f present in the host part is replaced by / in the host name. + + The path part might consist of several parts separated by /, independent + of the platform or file system. + + To create FilePath objects from strings possibly containing backslashes as + path separator, use \c fromUserInput. + + \sa toString, fromUserInput + */ FilePath FilePath::fromString(const QString &filepath) { FilePath fn; From fb36cb99f9be4864d55da38d8b0977cc25915a53 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Jun 2022 17:20:39 +0200 Subject: [PATCH 077/100] TextEditor: Inline behaviorsettingspage.ui Less code, indirections and allocations. Change-Id: I41011f90255a035eabe8f755fed6213f8f773a7e Reviewed-by: Reviewed-by: David Schulz --- src/plugins/texteditor/CMakeLists.txt | 2 +- .../texteditor/behaviorsettingspage.cpp | 60 ++++++++++--------- .../texteditor/behaviorsettingspage.ui | 45 -------------- src/plugins/texteditor/texteditor.qbs | 1 - 4 files changed, 33 insertions(+), 75 deletions(-) delete mode 100644 src/plugins/texteditor/behaviorsettingspage.ui diff --git a/src/plugins/texteditor/CMakeLists.txt b/src/plugins/texteditor/CMakeLists.txt index caaa4846b7f..73b52c8bc96 100644 --- a/src/plugins/texteditor/CMakeLists.txt +++ b/src/plugins/texteditor/CMakeLists.txt @@ -13,7 +13,7 @@ add_qtc_plugin(TextEditor basefilefind.cpp basefilefind.h basehoverhandler.cpp basehoverhandler.h behaviorsettings.cpp behaviorsettings.h - behaviorsettingspage.cpp behaviorsettingspage.h behaviorsettingspage.ui + behaviorsettingspage.cpp behaviorsettingspage.h behaviorsettingswidget.cpp behaviorsettingswidget.h behaviorsettingswidget.ui blockrange.h circularclipboard.cpp circularclipboard.h diff --git a/src/plugins/texteditor/behaviorsettingspage.cpp b/src/plugins/texteditor/behaviorsettingspage.cpp index f1c25b45470..d38c2926d36 100644 --- a/src/plugins/texteditor/behaviorsettingspage.cpp +++ b/src/plugins/texteditor/behaviorsettingspage.cpp @@ -26,15 +26,15 @@ #include "behaviorsettingspage.h" #include "behaviorsettings.h" -#include "typingsettings.h" +#include "behaviorsettingswidget.h" +#include "codestylepool.h" +#include "extraencodingsettings.h" +#include "simplecodestylepreferences.h" #include "storagesettings.h" #include "tabsettings.h" -#include "extraencodingsettings.h" -#include "ui_behaviorsettingspage.h" -#include "simplecodestylepreferences.h" #include "texteditorconstants.h" -#include "codestylepool.h" #include "texteditorsettings.h" +#include "typingsettings.h" #include #include @@ -48,8 +48,10 @@ #include #include +#include #include #include +#include namespace TextEditor { @@ -59,7 +61,7 @@ struct BehaviorSettingsPage::BehaviorSettingsPagePrivate : public QObject const QString m_settingsPrefix{"text"}; QPointer m_widget; - Internal::Ui::BehaviorSettingsPage *m_page = nullptr; + TextEditor::BehaviorSettingsWidget *m_behaviorWidget = nullptr; CodeStylePool *m_defaultCodeStylePool = nullptr; SimpleCodeStylePreferences *m_codeStyle = nullptr; @@ -110,17 +112,23 @@ QWidget *BehaviorSettingsPage::widget() { if (!d->m_widget) { d->m_widget = new QWidget; - d->m_page = new Internal::Ui::BehaviorSettingsPage; - d->m_page->setupUi(d->m_widget); + d->m_behaviorWidget = new BehaviorSettingsWidget(d->m_widget); + + auto verticalSpacer = new QSpacerItem(20, 13, QSizePolicy::Minimum, QSizePolicy::Expanding); + + auto gridLayout = new QGridLayout(d->m_widget); if (Utils::HostOsInfo::isMacHost()) - d->m_page->gridLayout->setContentsMargins(-1, 0, -1, 0); // don't ask. + gridLayout->setContentsMargins(-1, 0, -1, 0); // don't ask. + gridLayout->addWidget(d->m_behaviorWidget, 0, 0, 1, 1); + gridLayout->addItem(verticalSpacer, 1, 0, 1, 1); + d->m_pageCodeStyle = new SimpleCodeStylePreferences(d->m_widget); d->m_pageCodeStyle->setDelegatingPool(d->m_codeStyle->delegatingPool()); d->m_pageCodeStyle->setTabSettings(d->m_codeStyle->tabSettings()); d->m_pageCodeStyle->setCurrentDelegate(d->m_codeStyle->currentDelegate()); - d->m_page->behaviorWidget->setCodeStyle(d->m_pageCodeStyle); + d->m_behaviorWidget->setCodeStyle(d->m_pageCodeStyle); - TabSettingsWidget *tabSettingsWidget = d->m_page->behaviorWidget->tabSettingsWidget(); + TabSettingsWidget *tabSettingsWidget = d->m_behaviorWidget->tabSettingsWidget(); tabSettingsWidget->setCodingStyleWarningVisible(true); connect(tabSettingsWidget, &TabSettingsWidget::codingStyleLinkClicked, this, &BehaviorSettingsPage::openCodingStylePreferences); @@ -132,7 +140,7 @@ QWidget *BehaviorSettingsPage::widget() void BehaviorSettingsPage::apply() { - if (!d->m_page) // page was never shown + if (!d->m_behaviorWidget) // page was never shown return; TypingSettings newTypingSettings; @@ -185,9 +193,9 @@ void BehaviorSettingsPage::apply() } s->setValue(QLatin1String(Core::Constants::SETTINGS_DEFAULTTEXTENCODING), - d->m_page->behaviorWidget->assignedCodecName()); + d->m_behaviorWidget->assignedCodecName()); s->setValue(QLatin1String(Core::Constants::SETTINGS_DEFAULT_LINE_TERMINATOR), - d->m_page->behaviorWidget->assignedLineEnding()); + d->m_behaviorWidget->assignedLineEnding()); } void BehaviorSettingsPage::settingsFromUI(TypingSettings *typingSettings, @@ -195,29 +203,25 @@ void BehaviorSettingsPage::settingsFromUI(TypingSettings *typingSettings, BehaviorSettings *behaviorSettings, ExtraEncodingSettings *extraEncodingSettings) const { - d->m_page->behaviorWidget->assignedTypingSettings(typingSettings); - d->m_page->behaviorWidget->assignedStorageSettings(storageSettings); - d->m_page->behaviorWidget->assignedBehaviorSettings(behaviorSettings); - d->m_page->behaviorWidget->assignedExtraEncodingSettings(extraEncodingSettings); + d->m_behaviorWidget->assignedTypingSettings(typingSettings); + d->m_behaviorWidget->assignedStorageSettings(storageSettings); + d->m_behaviorWidget->assignedBehaviorSettings(behaviorSettings); + d->m_behaviorWidget->assignedExtraEncodingSettings(extraEncodingSettings); } void BehaviorSettingsPage::settingsToUI() { - d->m_page->behaviorWidget->setAssignedTypingSettings(d->m_typingSettings); - d->m_page->behaviorWidget->setAssignedStorageSettings(d->m_storageSettings); - d->m_page->behaviorWidget->setAssignedBehaviorSettings(d->m_behaviorSettings); - d->m_page->behaviorWidget->setAssignedExtraEncodingSettings(d->m_extraEncodingSettings); - d->m_page->behaviorWidget->setAssignedCodec(Core::EditorManager::defaultTextCodec()); - d->m_page->behaviorWidget->setAssignedLineEnding(Core::EditorManager::defaultLineEnding()); + d->m_behaviorWidget->setAssignedTypingSettings(d->m_typingSettings); + d->m_behaviorWidget->setAssignedStorageSettings(d->m_storageSettings); + d->m_behaviorWidget->setAssignedBehaviorSettings(d->m_behaviorSettings); + d->m_behaviorWidget->setAssignedExtraEncodingSettings(d->m_extraEncodingSettings); + d->m_behaviorWidget->setAssignedCodec(Core::EditorManager::defaultTextCodec()); + d->m_behaviorWidget->setAssignedLineEnding(Core::EditorManager::defaultLineEnding()); } void BehaviorSettingsPage::finish() { delete d->m_widget; - if (!d->m_page) // page was never shown - return; - delete d->m_page; - d->m_page = nullptr; } ICodeStylePreferences *BehaviorSettingsPage::codeStyle() const diff --git a/src/plugins/texteditor/behaviorsettingspage.ui b/src/plugins/texteditor/behaviorsettingspage.ui deleted file mode 100644 index 44fcf405dc2..00000000000 --- a/src/plugins/texteditor/behaviorsettingspage.ui +++ /dev/null @@ -1,45 +0,0 @@ - - - TextEditor::Internal::BehaviorSettingsPage - - - - 0 - 0 - 432 - 50 - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 13 - - - - - - - - - TextEditor::BehaviorSettingsWidget - QWidget -
texteditor/behaviorsettingswidget.h
- 1 -
-
- - -
diff --git a/src/plugins/texteditor/texteditor.qbs b/src/plugins/texteditor/texteditor.qbs index 896c9d515ef..b25d0ea222d 100644 --- a/src/plugins/texteditor/texteditor.qbs +++ b/src/plugins/texteditor/texteditor.qbs @@ -30,7 +30,6 @@ Project { "behaviorsettings.h", "behaviorsettingspage.cpp", "behaviorsettingspage.h", - "behaviorsettingspage.ui", "behaviorsettingswidget.cpp", "behaviorsettingswidget.h", "behaviorsettingswidget.ui", From 253ef8f6065b29c4800551cf13c21c9305a8269d Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Jun 2022 16:35:20 +0200 Subject: [PATCH 078/100] StdIOClientInterface: Connect to done() signal Instead of connecting to finished() signal. This should also handle a failed to start case. Change-Id: I000625adcceff94cf374cb2bfa9a994650cc261a Reviewed-by: David Schulz Reviewed-by: hjk Reviewed-by: --- .../languageclient/languageclientinterface.cpp | 15 +++++---------- .../languageclient/languageclientinterface.h | 1 - 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/plugins/languageclient/languageclientinterface.cpp b/src/plugins/languageclient/languageclientinterface.cpp index 5b7431cda00..c20fa7c121a 100644 --- a/src/plugins/languageclient/languageclientinterface.cpp +++ b/src/plugins/languageclient/languageclientinterface.cpp @@ -120,8 +120,12 @@ void StdIOClientInterface::startImpl() this, &StdIOClientInterface::readError); connect(m_process, &QtcProcess::readyReadStandardOutput, this, &StdIOClientInterface::readOutput); - connect(m_process, &QtcProcess::finished, this, &StdIOClientInterface::onProcessFinished); connect(m_process, &QtcProcess::started, this, &StdIOClientInterface::started); + connect(m_process, &QtcProcess::done, this, [this] { + if (m_process->result() != ProcessResult::FinishedWithSuccess) + emit error(m_process->exitMessage()); + emit finished(); + }); m_process->setCommand(m_cmd); m_process->setWorkingDirectory(m_workingDirectory); m_process->setEnvironment(m_env); @@ -155,15 +159,6 @@ void StdIOClientInterface::sendData(const QByteArray &data) m_process->writeRaw(data); } -void StdIOClientInterface::onProcessFinished() -{ - QTC_ASSERT(m_process, return); - if (m_process->exitStatus() == QProcess::CrashExit) - emit error(tr("Crashed with exit code %1: %2") - .arg(m_process->exitCode()).arg(m_process->errorString())); - emit finished(); -} - void StdIOClientInterface::readError() { QTC_ASSERT(m_process, return); diff --git a/src/plugins/languageclient/languageclientinterface.h b/src/plugins/languageclient/languageclientinterface.h index 083d7c3a675..0482c0e834b 100644 --- a/src/plugins/languageclient/languageclientinterface.h +++ b/src/plugins/languageclient/languageclientinterface.h @@ -97,7 +97,6 @@ protected: private: void readError(); void readOutput(); - void onProcessFinished(); }; } // namespace LanguageClient From cb0ff08518c30ec73ec09ae77c358c26698662ff Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Jun 2022 16:06:28 +0200 Subject: [PATCH 079/100] Designer: Inline formclasswizardpage.ui No change of translation context yet, just removing a form with a single widget (and setting of object names etc). Change-Id: I00a23b63caeff18e1199e6232d1afe6d89696bb7 Reviewed-by: Jarek Kobus --- src/plugins/designer/CMakeLists.txt | 2 +- .../designer/cpp/formclasswizardpage.cpp | 78 ++++++++++--------- .../designer/cpp/formclasswizardpage.h | 14 ++-- .../designer/cpp/formclasswizardpage.ui | 33 -------- src/plugins/designer/designer.qbs | 2 +- 5 files changed, 48 insertions(+), 81 deletions(-) delete mode 100644 src/plugins/designer/cpp/formclasswizardpage.ui diff --git a/src/plugins/designer/CMakeLists.txt b/src/plugins/designer/CMakeLists.txt index 32fa078e9fc..ebc81260d0c 100644 --- a/src/plugins/designer/CMakeLists.txt +++ b/src/plugins/designer/CMakeLists.txt @@ -10,7 +10,7 @@ add_qtc_plugin(Designer codemodelhelpers.cpp codemodelhelpers.h cpp/formclasswizard.cpp cpp/formclasswizard.h cpp/formclasswizarddialog.cpp cpp/formclasswizarddialog.h - cpp/formclasswizardpage.cpp cpp/formclasswizardpage.h cpp/formclasswizardpage.ui + cpp/formclasswizardpage.cpp cpp/formclasswizardpage.h cpp/formclasswizardparameters.cpp cpp/formclasswizardparameters.h cpp/newclasswidget.cpp cpp/newclasswidget.h cpp/newclasswidget.ui designer_export.h diff --git a/src/plugins/designer/cpp/formclasswizardpage.cpp b/src/plugins/designer/cpp/formclasswizardpage.cpp index 52bdfe7ccba..81220b532cf 100644 --- a/src/plugins/designer/cpp/formclasswizardpage.cpp +++ b/src/plugins/designer/cpp/formclasswizardpage.cpp @@ -24,41 +24,53 @@ ****************************************************************************/ #include "formclasswizardpage.h" -#include "ui_formclasswizardpage.h" -#include "formclasswizardparameters.h" -#include +#include "formclasswizardparameters.h" +#include "newclasswidget.h" #include -#include -#include -#include +#include + +#include +#include + +#include +#include #include +#include +#include namespace Designer { namespace Internal { -// ----------------- FormClassWizardPage - -FormClassWizardPage::FormClassWizardPage(QWidget * parent) : - QWizardPage(parent), - m_ui(new Ui::FormClassWizardPage) +FormClassWizardPage::FormClassWizardPage() { - m_ui->setupUi(this); + setTitle(tr("Choose a Class Name")); - connect(m_ui->newClassWidget, &NewClassWidget::validChanged, this, - &FormClassWizardPage::slotValidChanged); + auto classGroupBox = new QGroupBox(this); + classGroupBox->setTitle(tr("Class")); - initFileGenerationSettings(); + m_newClassWidget = new NewClassWidget(classGroupBox); + m_newClassWidget->setHeaderExtension( + Utils::mimeTypeForName(CppEditor::Constants::CPP_HEADER_MIMETYPE).preferredSuffix()); + m_newClassWidget->setSourceExtension( + Utils::mimeTypeForName(CppEditor::Constants::CPP_SOURCE_MIMETYPE).preferredSuffix()); + m_newClassWidget->setLowerCaseFiles(lowercaseHeaderFiles()); + + connect(m_newClassWidget, &NewClassWidget::validChanged, + this, &FormClassWizardPage::slotValidChanged); setProperty(Utils::SHORT_TITLE_PROPERTY, tr("Class Details")); + + auto verticalLayout = new QVBoxLayout(classGroupBox); + verticalLayout->addWidget(m_newClassWidget); + + auto gridLayout = new QGridLayout(this); + gridLayout->addWidget(classGroupBox, 0, 0, 1, 1); } -FormClassWizardPage::~FormClassWizardPage() -{ - delete m_ui; -} +FormClassWizardPage::~FormClassWizardPage() = default; // Retrieve settings of CppEditor plugin. bool FormClassWizardPage::lowercaseHeaderFiles() @@ -70,45 +82,35 @@ bool FormClassWizardPage::lowercaseHeaderFiles() return Core::ICore::settings()->value(lowerCaseSettingsKey, QVariant(lowerCaseDefault)).toBool(); } -// Set up new class widget from settings -void FormClassWizardPage::initFileGenerationSettings() -{ - m_ui->newClassWidget->setHeaderExtension( - Utils::mimeTypeForName(CppEditor::Constants::CPP_HEADER_MIMETYPE).preferredSuffix()); - m_ui->newClassWidget->setSourceExtension( - Utils::mimeTypeForName(CppEditor::Constants::CPP_SOURCE_MIMETYPE).preferredSuffix()); - m_ui->newClassWidget->setLowerCaseFiles(lowercaseHeaderFiles()); -} - void FormClassWizardPage::setClassName(const QString &suggestedClassName) { // Is it valid, now? - m_ui->newClassWidget->setClassName(suggestedClassName); + m_newClassWidget->setClassName(suggestedClassName); slotValidChanged(); } Utils::FilePath FormClassWizardPage::filePath() const { - return m_ui->newClassWidget->filePath(); + return m_newClassWidget->filePath(); } void FormClassWizardPage::setFilePath(const Utils::FilePath &p) { - m_ui->newClassWidget->setFilePath(p); + m_newClassWidget->setFilePath(p); } void FormClassWizardPage::getParameters(FormClassWizardParameters *p) const { - p->className = m_ui->newClassWidget->className(); + p->className = m_newClassWidget->className(); p->path = filePath(); - p->sourceFile = m_ui->newClassWidget->sourceFileName(); - p->headerFile = m_ui->newClassWidget->headerFileName(); - p->uiFile = m_ui->newClassWidget-> formFileName(); + p->sourceFile = m_newClassWidget->sourceFileName(); + p->headerFile = m_newClassWidget->headerFileName(); + p->uiFile = m_newClassWidget-> formFileName(); } void FormClassWizardPage::slotValidChanged() { - const bool validNow = m_ui->newClassWidget->isValid(); + const bool validNow = m_newClassWidget->isValid(); if (m_isValid != validNow) { m_isValid = validNow; emit completeChanged(); @@ -123,7 +125,7 @@ bool FormClassWizardPage::isComplete() const bool FormClassWizardPage::validatePage() { QString errorMessage; - const bool rc = m_ui->newClassWidget->isValid(&errorMessage); + const bool rc = m_newClassWidget->isValid(&errorMessage); if (!rc) QMessageBox::warning(this, tr("%1 - Error").arg(title()), errorMessage); return rc; diff --git a/src/plugins/designer/cpp/formclasswizardpage.h b/src/plugins/designer/cpp/formclasswizardpage.h index 60e848433e1..7ba67ed42c6 100644 --- a/src/plugins/designer/cpp/formclasswizardpage.h +++ b/src/plugins/designer/cpp/formclasswizardpage.h @@ -25,6 +25,7 @@ #pragma once +#include #include namespace Utils { class FilePath; } @@ -36,21 +37,21 @@ class FormClassWizardGenerationParameters; namespace Internal { -namespace Ui { class FormClassWizardPage; } - +class NewClassWidget; class FormClassWizardPage : public QWizardPage { - Q_OBJECT + Q_DECLARE_TR_FUNCTIONS(Designer::Internal::FormClassWizardPage) public: - explicit FormClassWizardPage(QWidget *parent = nullptr); + FormClassWizardPage(); ~FormClassWizardPage() override; bool isComplete () const override; bool validatePage() override; void setClassName(const QString &suggestedClassName); + void setFilePath(const Utils::FilePath &); Utils::FilePath filePath() const; @@ -65,11 +66,8 @@ public: private: void slotValidChanged(); -private: - void initFileGenerationSettings(); - - Ui::FormClassWizardPage *m_ui = nullptr; bool m_isValid = false; + Designer::Internal::NewClassWidget *m_newClassWidget; }; } // namespace Internal diff --git a/src/plugins/designer/cpp/formclasswizardpage.ui b/src/plugins/designer/cpp/formclasswizardpage.ui deleted file mode 100644 index b58e58c4b5a..00000000000 --- a/src/plugins/designer/cpp/formclasswizardpage.ui +++ /dev/null @@ -1,33 +0,0 @@ - - - Designer::Internal::FormClassWizardPage - - - Choose a Class Name - - - - - - Class - - - - - - - - - - - - - Designer::Internal::NewClassWidget - QWidget -
designer/cpp/newclasswidget.h
- 1 -
-
- - -
diff --git a/src/plugins/designer/designer.qbs b/src/plugins/designer/designer.qbs index 739b1c1f989..ff98dfb04ff 100644 --- a/src/plugins/designer/designer.qbs +++ b/src/plugins/designer/designer.qbs @@ -70,7 +70,7 @@ QtcPlugin { files: [ "formclasswizard.cpp", "formclasswizard.h", "formclasswizarddialog.cpp", "formclasswizarddialog.h", - "formclasswizardpage.cpp", "formclasswizardpage.h", "formclasswizardpage.ui", + "formclasswizardpage.cpp", "formclasswizardpage.h", "formclasswizardparameters.cpp", "formclasswizardparameters.h", "newclasswidget.cpp", "newclasswidget.h", "newclasswidget.ui", ] From f4ea9e09ec3fc2883e13b55ea3cf4ce034f8f487 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Mon, 20 Jun 2022 19:51:16 +0200 Subject: [PATCH 080/100] cdb: Use separate qtcreatorcdbext suffix for arm architecture This would allow arm64 to coexist with amd64 on the same installation. Change-Id: I578aab3d363bf93c2f61d4a7c93576ce19fba4b6 Reviewed-by: Reviewed-by: David Schulz --- src/libs/qtcreatorcdbext/CMakeLists.txt | 8 ++++++-- src/plugins/debugger/cdb/cdbengine.cpp | 25 ++++++++++++++++--------- src/plugins/debugger/cdb/cdbengine.h | 2 +- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/libs/qtcreatorcdbext/CMakeLists.txt b/src/libs/qtcreatorcdbext/CMakeLists.txt index 334d226af4d..ba6508c43e0 100644 --- a/src/libs/qtcreatorcdbext/CMakeLists.txt +++ b/src/libs/qtcreatorcdbext/CMakeLists.txt @@ -20,9 +20,13 @@ endif() find_library(DbgEngLib dbgeng) -set(ArchSuffix 32) +set(ArchSuffix "32") if (CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ArchSuffix 64) + set(ArchSuffix "64") +endif() + +if (MSVC_CXX_ARCHITECTURE_ID MATCHES "^ARM") + set(ArchSuffix "arm${ArchSuffix}") endif() add_qtc_library(qtcreatorcdbext SHARED diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index b8566b78740..b4d538485b9 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -56,6 +56,7 @@ #include #include +#include #include #include #include @@ -290,14 +291,13 @@ bool CdbEngine::canHandleToolTip(const DebuggerToolTipContext &context) const } // Determine full path to the CDB extension library. -QString CdbEngine::extensionLibraryName(bool is64Bit) +QString CdbEngine::extensionLibraryName(bool is64Bit, bool isArm) { // Determine extension lib name and path to use - QString rc; - QTextStream(&rc) << QFileInfo(QCoreApplication::applicationDirPath()).path() - << "/lib/" << (is64Bit ? QT_CREATOR_CDB_EXT "64" : QT_CREATOR_CDB_EXT "32") - << '/' << QT_CREATOR_CDB_EXT << ".dll"; - return rc; + return QString("%1/lib/" QT_CREATOR_CDB_EXT "%2%3/" QT_CREATOR_CDB_EXT ".dll") + .arg(QFileInfo(QCoreApplication::applicationDirPath()).path()) + .arg(isArm ? "arm" : QString()) + .arg(is64Bit ? "64": "32"); } int CdbEngine::elapsedLogTime() @@ -353,10 +353,17 @@ void CdbEngine::setupEngine() return; } - bool cdbIs64Bit = is64BitWindowsBinary(sp.debugger.command.executable()); - if (!cdbIs64Bit) + bool cdbIs64Bit = true; + bool cdbIsArm = false; + Abis abisOfCdb = Abi::abisOfBinary(sp.debugger.command.executable()); + if (abisOfCdb.size() == 1) { + Abi abi = abisOfCdb.at(0); + cdbIs64Bit = abi.wordWidth() == 64; + cdbIsArm = abi.architecture() == Abi::Architecture::ArmArchitecture; + } + if (!cdbIs64Bit || cdbIsArm) m_wow64State = noWow64Stack; - const QFileInfo extensionFi(CdbEngine::extensionLibraryName(cdbIs64Bit)); + const QFileInfo extensionFi(CdbEngine::extensionLibraryName(cdbIs64Bit, cdbIsArm)); if (!extensionFi.isFile()) { handleSetupFailure(tr("Internal error: The extension %1 cannot be found.\n" "If you have updated %2 via Maintenance Tool, you may " diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 4fdc5f957cd..92d434f2bc3 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -101,7 +101,7 @@ public: void loadAdditionalQmlStack() override; void listBreakpoints(); - static QString extensionLibraryName(bool is64Bit); + static QString extensionLibraryName(bool is64Bit, bool isArm = false); private: void readyReadStandardOut(); From 61f04d260c6035bf06d3b11b3e2326c78b7f613c Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Tue, 21 Jun 2022 13:34:04 +0200 Subject: [PATCH 081/100] scripts: remove deployment of libclang-cpp All the clang binaries that we ship (clangd, clang-tidy, clazy-standalone) are compiled statically and libclang-cpp is not needed anymore. Change-Id: I486fc0d1a55a18916c0abf56ec6a966321ef2b46 Reviewed-by: Eike Ziller Reviewed-by: --- scripts/deployqt.py | 2 +- scripts/deployqtHelper_mac.sh | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/deployqt.py b/scripts/deployqt.py index bfbc9ebf30a..f02f41652fa 100755 --- a/scripts/deployqt.py +++ b/scripts/deployqt.py @@ -262,7 +262,7 @@ def deploy_clang(install_dir, llvm_install_dir, chrpath_bin): if not os.path.exists(clanglibs_targetdir): os.makedirs(clanglibs_targetdir) # on RHEL ClazyPlugin is in lib64 - for lib_pattern in ['lib64/ClazyPlugin.so', 'lib/ClazyPlugin.so', 'lib/libclang-cpp.so*']: + for lib_pattern in ['lib64/ClazyPlugin.so', 'lib/ClazyPlugin.so']: for lib in glob(os.path.join(llvm_install_dir, lib_pattern)): deployinfo.append((lib, clanglibs_targetdir)) resourcetarget = os.path.join(install_dir, 'libexec', 'qtcreator', 'clang', 'lib', 'clang') diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh index e3a0871d4d6..487cdfda656 100755 --- a/scripts/deployqtHelper_mac.sh +++ b/scripts/deployqtHelper_mac.sh @@ -111,14 +111,13 @@ fi # copy clang if needed if [ $LLVM_INSTALL_DIR ]; then - if [ "$LLVM_INSTALL_DIR"/lib/libclang-cpp.dylib -nt "$libexec_path"/clang/lib/libclang-cpp.dylib ]; then + if [ "$LLVM_INSTALL_DIR"/bin/clangd -nt "$libexec_path"/clang/bin/clangd ]; then echo "- Copying clang" mkdir -p "$app_path/Contents/Frameworks" || exit 1 # use recursive copy to make it copy symlinks as symlinks mkdir -p "$libexec_path/clang/bin" mkdir -p "$libexec_path/clang/lib" cp -Rf "$LLVM_INSTALL_DIR"/lib/clang "$libexec_path/clang/lib/" || exit 1 - cp -Rf "$LLVM_INSTALL_DIR"/lib/libclang-cpp.dylib "$libexec_path/clang/lib/" || exit 1 cp -Rf "$LLVM_INSTALL_DIR"/lib/ClazyPlugin.dylib "$libexec_path/clang/lib/" || exit 1 clangdsource="$LLVM_INSTALL_DIR"/bin/clangd cp -Rf "$clangdsource" "$libexec_path/clang/bin/" || exit 1 From 73e072c7bb7839ecddaa5c6a4bc6454317614afe Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 30 Sep 2021 09:34:05 +0200 Subject: [PATCH 082/100] Git: Modernize executable search Change-Id: I3bc1293aab74fcff5574d9a339a52776c891b6cf Reviewed-by: Orgad Shaneh --- src/libs/utils/filepath.cpp | 11 +++++++++-- src/libs/utils/filepath.h | 5 ++++- src/plugins/git/gitsettings.cpp | 8 +++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 4c903640f79..cbde3ddd092 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -1307,9 +1307,16 @@ FilePath FilePath::searchInDirectories(const FilePaths &dirs) const return Environment::systemEnvironment().searchInDirectories(path(), dirs); } -FilePath FilePath::searchInPath(const QList &additionalDirs) const +FilePath FilePath::searchInPath(const FilePaths &additionalDirs, PathAmending amending) const { - return searchInDirectories(deviceEnvironment().path() + additionalDirs); + FilePaths directories = deviceEnvironment().path(); + if (!additionalDirs.isEmpty()) { + if (amending == AppendToPath) + directories.append(additionalDirs); + else + directories = additionalDirs + directories; + } + return searchInDirectories(directories); } Environment FilePath::deviceEnvironment() const diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h index faf61ee66fb..4b589389b4d 100644 --- a/src/libs/utils/filepath.h +++ b/src/libs/utils/filepath.h @@ -164,13 +164,16 @@ public: [[nodiscard]] FilePath relativeChildPath(const FilePath &parent) const; [[nodiscard]] FilePath relativePath(const FilePath &anchor) const; [[nodiscard]] FilePath searchInDirectories(const QList &dirs) const; - [[nodiscard]] FilePath searchInPath(const QList &additionalDirs = {}) const; [[nodiscard]] Environment deviceEnvironment() const; [[nodiscard]] FilePath onDevice(const FilePath &deviceTemplate) const; [[nodiscard]] FilePath withNewPath(const QString &newPath) const; void iterateDirectory(const std::function &callBack, const FileFilter &filter) const; + enum PathAmending { AppendToPath, PrependToPath }; + [[nodiscard]] FilePath searchInPath(const QList &additionalDirs = {}, + PathAmending = AppendToPath) const; + // makes sure that capitalization of directories is canonical // on Windows and macOS. This is rarely needed. [[nodiscard]] FilePath normalizedPathName() const; diff --git a/src/plugins/git/gitsettings.cpp b/src/plugins/git/gitsettings.cpp index 8a265d35bc5..6ab4b8edc6b 100644 --- a/src/plugins/git/gitsettings.cpp +++ b/src/plugins/git/gitsettings.cpp @@ -141,11 +141,9 @@ FilePath GitSettings::gitExecutable(bool *ok, QString *errorMessage) const errorMessage->clear(); FilePath binPath = binaryPath.filePath(); - if (!binPath.isAbsolutePath()) { - Environment env = Environment::systemEnvironment(); - env.prependOrSetPath(path.filePath()); - binPath = env.searchInPath(binPath.toString()); - } + if (!binPath.isAbsolutePath()) + binPath = binPath.searchInPath({path.filePath()}, FilePath::PrependToPath); + if (binPath.isEmpty()) { if (ok) *ok = false; From 4c4f787e840f9443c4237a37b9c688ddcca768dd Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 22 Jun 2022 08:21:02 +0200 Subject: [PATCH 083/100] COIN: Fix installing Qt after script updates 'wget' is now imported by one of the python scripts Change-Id: I8e4fe32f813550586d19ccb76a55ec7ed13441c7 Reviewed-by: Eike Ziller --- coin/instructions/provision.yaml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/coin/instructions/provision.yaml b/coin/instructions/provision.yaml index 5d0431a273b..302103ec3f6 100644 --- a/coin/instructions/provision.yaml +++ b/coin/instructions/provision.yaml @@ -31,6 +31,15 @@ instructions: condition: property property: host.os in_values: [MacOS, Linux, Windows] + - type: ExecuteCommand + command: "pip3 install wget colorlog" + maxTimeInSeconds: 1200 + maxTimeBetweenOutput: 120 + userMessageOnFailure: "Failed to install Python packages, check logs." + enable_if: + condition: property + property: host.os + in_values: [MacOS, Linux] - type: ExecuteCommand command: "python3 -u {{.AgentWorkingDir}}/build/qtsdk/packaging-tools/install_qt.py --qt-path {{.AgentWorkingDir}}/build/qt_install_dir --temp-path {{.AgentWorkingDir}}/build/qt_temp --base-url {{.Env.QTC_QT_BASE_URL}} --base-url-postfix={{.Env.QTC_QT_POSTFIX}} --icu7z http://master.qt.io/development_releases/prebuilt/icu/prebuilt/56.1/icu-linux-g++-Rhel7.2-x64.7z {{.Env.QTC_QT_MODULES}}" executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution @@ -52,10 +61,10 @@ instructions: property: host.os equals_value: MacOS - type: ExecuteCommand - command: "pip.exe install pywin32" + command: "pip.exe install pywin32 wget colorlog" maxTimeInSeconds: 1200 maxTimeBetweenOutput: 120 - userMessageOnFailure: "Failed to install win32api, check logs." + userMessageOnFailure: "Failed to install Python packages, check logs." enable_if: condition: property property: host.os From 5c5b3cac941673e931bfa4230d0d16fd6197c3d6 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 22 Jun 2022 11:01:04 +0200 Subject: [PATCH 084/100] Beautifier: Build with Qt 5 Amends 283673a5d99f25ff882aa51aed9e3272bd6d73ba Change-Id: I3ce759193a29d1c0dbc7d6ed7762503b3700b229 Reviewed-by: Jarek Kobus --- src/plugins/beautifier/abstractsettings.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/beautifier/abstractsettings.h b/src/plugins/beautifier/abstractsettings.h index 477f5c77187..ae39c6ce690 100644 --- a/src/plugins/beautifier/abstractsettings.h +++ b/src/plugins/beautifier/abstractsettings.h @@ -35,6 +35,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE class QRegularExpression; class QVersionNumber; From 418ce762df54f6146b241b21a7535893defeab68 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 22 Jun 2022 06:45:00 +0200 Subject: [PATCH 085/100] PdbEngine: Don't call blocking waitForStarted() Connect to started() signal instead and continue setup in its handler. Handle failed to start case inside done() signal handler. Change-Id: I9878490e8d30cf189c63800db658afae50141ce0 Reviewed-by: hjk --- src/plugins/debugger/pdb/pdbengine.cpp | 21 ++++++++++++--------- src/plugins/debugger/pdb/pdbengine.h | 1 + 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index bd34b36cddf..54375baf7f1 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -121,7 +121,8 @@ void PdbEngine::setupEngine() m_interpreter = runParameters().interpreter; QString bridge = ICore::resourcePath("debugger/pdbbridge.py").toString(); - connect(&m_proc, &QtcProcess::finished, this, &PdbEngine::handlePdbDone); + connect(&m_proc, &QtcProcess::started, this, &PdbEngine::handlePdbStarted); + connect(&m_proc, &QtcProcess::done, this, &PdbEngine::handlePdbDone); connect(&m_proc, &QtcProcess::readyReadStandardOutput, this, &PdbEngine::readPdbStandardOutput); connect(&m_proc, &QtcProcess::readyReadStandardError, this, &PdbEngine::readPdbStandardError); @@ -138,15 +139,10 @@ void PdbEngine::setupEngine() m_proc.setEnvironment(runParameters().debugger.environment); m_proc.setCommand(cmd); m_proc.start(); +} - if (!m_proc.waitForStarted()) { - notifyEngineSetupFailed(); - showMessage("ADAPTER START FAILED"); - ICore::showWarningWithOptions(tr("Adapter start failed"), m_proc.exitMessage()); - notifyEngineSetupFailed(); - return; - } - +void PdbEngine::handlePdbStarted() +{ notifyEngineSetupOk(); QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); @@ -416,6 +412,13 @@ QString PdbEngine::errorMessage(QProcess::ProcessError error) const void PdbEngine::handlePdbDone() { + if (m_proc.result() == ProcessResult::StartFailed) { + notifyEngineSetupFailed(); + showMessage("ADAPTER START FAILED"); + ICore::showWarningWithOptions(tr("Adapter start failed"), m_proc.exitMessage()); + return; + } + const QProcess::ProcessError error = m_proc.error(); if (error != QProcess::UnknownError) { showMessage("HANDLE PDB ERROR"); diff --git a/src/plugins/debugger/pdb/pdbengine.h b/src/plugins/debugger/pdb/pdbengine.h index b8edaf5f44a..efde41e2ce9 100644 --- a/src/plugins/debugger/pdb/pdbengine.h +++ b/src/plugins/debugger/pdb/pdbengine.h @@ -100,6 +100,7 @@ private: QString errorMessage(QProcess::ProcessError error) const; bool hasCapability(unsigned cap) const override; + void handlePdbStarted(); void handlePdbDone(); void readPdbStandardOutput(); void readPdbStandardError(); From fdf81b8768d0bc78ba8c3d0a8fbf3c729ba48e5d Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 22 Jun 2022 06:53:24 +0200 Subject: [PATCH 086/100] QmlEngine: Connect to done() signal instead of finished() Change-Id: Iffccd6425ff5bf3b47064b6883ecab7474a987f7 Reviewed-by: Reviewed-by: hjk --- src/plugins/debugger/qml/qmlengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index ef6a753b23f..c1511dbac7a 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -281,7 +281,7 @@ QmlEngine::QmlEngine() showMessage(QString::fromUtf8(d->process.readAllStandardError()), AppOutput); }); - connect(&d->process, &QtcProcess::finished, this, &QmlEngine::disconnected); + connect(&d->process, &QtcProcess::done, this, &QmlEngine::disconnected); connect(&d->process, &QtcProcess::started, this, &QmlEngine::handleLauncherStarted); debuggerConsole()->populateFileFinder(); From bbbb1fd0a51896570e0752055478d02ef4018070 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Jun 2022 18:22:50 +0200 Subject: [PATCH 087/100] NodeInstanceView: Connect to done() signal instead of finished() Don't block the caller thread when starting the process. Handle failed to start case inside done() handler. Change-Id: I57e2fd1e069c3c6285603cbe30f42bad9d80cecd Reviewed-by: Reviewed-by: hjk Reviewed-by: Miikka Heikkinen --- .../designercore/include/nodeinstanceview.h | 1 - .../instances/nodeinstanceview.cpp | 30 +++++-------------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index 62efb225d44..d6e30746661 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 1db2bc3cb6a..bd6102243fd 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -2035,14 +2035,12 @@ void NodeInstanceView::handleQsbProcessExit(Utils::QtcProcess *qsbProcess, const { --m_remainingQsbTargets; - QString errStr = qsbProcess->errorString(); - QByteArray stdErrStr = qsbProcess->readAllStandardError(); + const QString errStr = qsbProcess->errorString(); + const QByteArray stdErrStr = qsbProcess->readAllStandardError(); if (!errStr.isEmpty() || !stdErrStr.isEmpty()) { - Core::MessageManager::writeSilently( - QCoreApplication::translate("QmlDesigner::NodeInstanceView", - "Failed to generate QSB file for: %1") - .arg(shader)); + Core::MessageManager::writeSilently(QCoreApplication::translate( + "QmlDesigner::NodeInstanceView", "Failed to generate QSB file for: %1").arg(shader)); if (!errStr.isEmpty()) Core::MessageManager::writeSilently(errStr); if (!stdErrStr.isEmpty()) @@ -2138,26 +2136,12 @@ void NodeInstanceView::handleShaderChanges() args.append(outPath.toString()); args.append(shader); auto qsbProcess = new Utils::QtcProcess; + connect(qsbProcess, &Utils::QtcProcess::done, this, [this, qsbProcess, shader] { + handleQsbProcessExit(qsbProcess, shader); + }); qsbProcess->setWorkingDirectory(srcPath); qsbProcess->setCommand({m_qsbPath, args}); qsbProcess->start(); - - if (!qsbProcess->waitForStarted()) { - handleQsbProcessExit(qsbProcess, shader); - continue; - } - - if (qsbProcess->state() == QProcess::Running) { - connect(qsbProcess, &Utils::QtcProcess::finished, - [thisView = QPointer(this), qsbProcess, shader]() { - if (thisView) - thisView->handleQsbProcessExit(qsbProcess, shader); - else - qsbProcess->deleteLater(); - }); - } else { - handleQsbProcessExit(qsbProcess, shader); - } } } From 4686db5590e9be7e13d12afd380571ab145c28cb Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 22 Jun 2022 06:59:26 +0200 Subject: [PATCH 088/100] NodeInstanceView: Fix potential leak of process instances Don't leak the process when d'tor of NodeInstanceView was called after successful start of the process and before process finished. Change-Id: Ib1e0192ebfa20b6e5e43c9247a18e9092c64b2d6 Reviewed-by: Reviewed-by: Miikka Heikkinen --- .../qmldesigner/designercore/instances/nodeinstanceview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index bd6102243fd..3555bcdefca 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -2135,7 +2135,7 @@ void NodeInstanceView::handleShaderChanges() QStringList args = baseArgs; args.append(outPath.toString()); args.append(shader); - auto qsbProcess = new Utils::QtcProcess; + auto qsbProcess = new Utils::QtcProcess(this); connect(qsbProcess, &Utils::QtcProcess::done, this, [this, qsbProcess, shader] { handleQsbProcessExit(qsbProcess, shader); }); From 8066ce8a6f4b61ddf1847a19ed1bc0618ca3809a Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Jun 2022 13:05:45 +0200 Subject: [PATCH 089/100] Remove a the necessity of a few weak vtables For background, see QTBUG-45582. Change-Id: I6c4758ce62149437c26971056b465d5dbd2b13b0 Reviewed-by: Eike Ziller --- src/libs/utils/aspects.cpp | 4 ++++ src/libs/utils/aspects.h | 2 +- src/libs/utils/temporaryfile.cpp | 2 ++ src/libs/utils/temporaryfile.h | 1 + src/plugins/vcsbase/basevcseditorfactory.cpp | 2 ++ src/plugins/vcsbase/basevcseditorfactory.h | 2 ++ src/plugins/vcsbase/basevcssubmiteditorfactory.cpp | 2 ++ src/plugins/vcsbase/basevcssubmiteditorfactory.h | 2 ++ src/plugins/vcsbase/vcsbaseclientsettings.cpp | 2 ++ src/plugins/vcsbase/vcsbaseclientsettings.h | 1 + 10 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index 998d9fa5cc1..1af70360c1c 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -2442,6 +2442,10 @@ void AspectContainerData::append(const BaseAspect::Data::Ptr &data) m_data.append(data); } +// BaseAspect::Data + +BaseAspect::Data::~Data() = default; + void BaseAspect::Data::Ptr::operator=(const Ptr &other) { if (this == &other) diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h index bade3c9495f..bb39a398cb1 100644 --- a/src/libs/utils/aspects.h +++ b/src/libs/utils/aspects.h @@ -145,7 +145,7 @@ public: // The (unique) address of the "owning" aspect's meta object is used as identifier. using ClassId = const void *; - virtual ~Data() = default; + virtual ~Data(); Id id() const { return m_id; } ClassId classId() const { return m_classId; } diff --git a/src/libs/utils/temporaryfile.cpp b/src/libs/utils/temporaryfile.cpp index 2ee6a3a40a7..06a4ba00200 100644 --- a/src/libs/utils/temporaryfile.cpp +++ b/src/libs/utils/temporaryfile.cpp @@ -36,4 +36,6 @@ TemporaryFile::TemporaryFile(const QString &pattern) : QTC_CHECK(!QFileInfo(pattern).isAbsolute()); } +TemporaryFile::~TemporaryFile() = default; + } // namespace Utils diff --git a/src/libs/utils/temporaryfile.h b/src/libs/utils/temporaryfile.h index 2cb38e39289..a9b02adf429 100644 --- a/src/libs/utils/temporaryfile.h +++ b/src/libs/utils/temporaryfile.h @@ -35,6 +35,7 @@ class QTCREATOR_UTILS_EXPORT TemporaryFile : public QTemporaryFile { public: explicit TemporaryFile(const QString &pattern); + ~TemporaryFile(); }; } // namespace Utils diff --git a/src/plugins/vcsbase/basevcseditorfactory.cpp b/src/plugins/vcsbase/basevcseditorfactory.cpp index 84414bf76da..e97de8f308e 100644 --- a/src/plugins/vcsbase/basevcseditorfactory.cpp +++ b/src/plugins/vcsbase/basevcseditorfactory.cpp @@ -82,4 +82,6 @@ VcsEditorFactory::VcsEditorFactory(const VcsBaseEditorParameters *parameters, setMarksVisible(false); } +VcsEditorFactory::~VcsEditorFactory() = default; + } // namespace VcsBase diff --git a/src/plugins/vcsbase/basevcseditorfactory.h b/src/plugins/vcsbase/basevcseditorfactory.h index ddd90a93dac..bbc57669784 100644 --- a/src/plugins/vcsbase/basevcseditorfactory.h +++ b/src/plugins/vcsbase/basevcseditorfactory.h @@ -41,6 +41,8 @@ public: VcsEditorFactory(const VcsBaseEditorParameters *parameters, const EditorWidgetCreator editorWidgetCreator, std::function describeFunc); + + ~VcsEditorFactory(); }; } // namespace VcsBase diff --git a/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp b/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp index b285f6453d1..ba6d4fe5c62 100644 --- a/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp +++ b/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp @@ -74,4 +74,6 @@ VcsSubmitEditorFactory::VcsSubmitEditorFactory ActionManager::registerAction(&m_diffAction, DIFF_SELECTED, context); } +VcsSubmitEditorFactory::~VcsSubmitEditorFactory() = default; + } // namespace VcsBase diff --git a/src/plugins/vcsbase/basevcssubmiteditorfactory.h b/src/plugins/vcsbase/basevcssubmiteditorfactory.h index f71d61bbbbf..30e1696d335 100644 --- a/src/plugins/vcsbase/basevcssubmiteditorfactory.h +++ b/src/plugins/vcsbase/basevcssubmiteditorfactory.h @@ -53,6 +53,8 @@ public: const EditorCreator &editorCreator, VcsBasePluginPrivate *plugin); + ~VcsSubmitEditorFactory(); + private: QAction m_submitAction; QAction m_diffAction; diff --git a/src/plugins/vcsbase/vcsbaseclientsettings.cpp b/src/plugins/vcsbase/vcsbaseclientsettings.cpp index 00e20342adf..419e26268f9 100644 --- a/src/plugins/vcsbase/vcsbaseclientsettings.cpp +++ b/src/plugins/vcsbase/vcsbaseclientsettings.cpp @@ -75,6 +75,8 @@ VcsBaseSettings::VcsBaseSettings() timeout.setSuffix(tr("s")); } +VcsBaseSettings::~VcsBaseSettings() = default; + FilePaths VcsBaseSettings::searchPathList() const { return Utils::transform(path.value().split(HostOsInfo::pathListSeparator(), Qt::SkipEmptyParts), diff --git a/src/plugins/vcsbase/vcsbaseclientsettings.h b/src/plugins/vcsbase/vcsbaseclientsettings.h index d6597945038..76091f1d3c5 100644 --- a/src/plugins/vcsbase/vcsbaseclientsettings.h +++ b/src/plugins/vcsbase/vcsbaseclientsettings.h @@ -37,6 +37,7 @@ class VCSBASE_EXPORT VcsBaseSettings : public Utils::AspectContainer public: VcsBaseSettings(); + ~VcsBaseSettings(); Utils::StringAspect binaryPath; Utils::StringAspect userName; From 37a820f67a656a5dd7a3ac0f10cc72c9a7808a5b Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 22 Jun 2022 06:36:37 +0200 Subject: [PATCH 090/100] LldbEngine: Don't call blocking waitForStarted() Connect to started() signal instead and continue setup in its handler. Handle failed to start case inside done() signal handler. Change-Id: I2c2eb14bf2948c23bae1e35a7581f52d25ab1dd4 Reviewed-by: hjk Reviewed-by: --- src/plugins/debugger/lldb/lldbengine.cpp | 22 +++++++++++++--------- src/plugins/debugger/lldb/lldbengine.h | 1 + 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 62009240f55..40a369049f1 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -99,6 +99,7 @@ LldbEngine::LldbEngine() connect(&ds.useDynamicType, &BaseAspect::changed, this, &LldbEngine::updateLocals); connect(&ds.intelFlavor, &BaseAspect::changed, this, &LldbEngine::updateAll); + connect(&m_lldbProc, &QtcProcess::started, this, &LldbEngine::handleLldbStarted); connect(&m_lldbProc, &QtcProcess::done, this, &LldbEngine::handleLldbDone); connect(&m_lldbProc, &QtcProcess::readyReadStandardOutput, this, &LldbEngine::readLldbStandardOutput); @@ -230,16 +231,10 @@ void LldbEngine::setupEngine() m_lldbProc.setCommand(CommandLine(lldbCmd)); m_lldbProc.start(); +} - if (!m_lldbProc.waitForStarted()) { - const QString msg = tr("Unable to start LLDB \"%1\": %2") - .arg(lldbCmd.toUserOutput(), m_lldbProc.errorString()); - notifyEngineSetupFailed(); - showMessage("ADAPTER START FAILED"); - if (!msg.isEmpty()) - ICore::showWarningWithOptions(adapterStartFailed(), msg); - return; - } +void LldbEngine::handleLldbStarted() +{ m_lldbProc.waitForReadyRead(1000); showStatusMessage(tr("Setting up inferior...")); @@ -788,6 +783,15 @@ void LldbEngine::doUpdateLocals(const UpdateParameters ¶ms) void LldbEngine::handleLldbDone() { + if (m_lldbProc.result() == ProcessResult::StartFailed) { + notifyEngineSetupFailed(); + showMessage("ADAPTER START FAILED"); + ICore::showWarningWithOptions(adapterStartFailed(), tr("Unable to start LLDB \"%1\": %2") + .arg(runParameters().debugger.command.executable().toUserOutput(), + m_lldbProc.errorString())); + return; + } + if (m_lldbProc.error() == QProcess::UnknownError) { notifyDebuggerProcessFinished(m_lldbProc.resultData(), "LLDB"); return; diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index 7562eb98e24..5a0f7d63284 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -110,6 +110,7 @@ private: QString errorMessage(QProcess::ProcessError error) const; bool hasCapability(unsigned cap) const override; + void handleLldbStarted(); void handleLldbDone(); void readLldbStandardOutput(); void readLldbStandardError(); From e49e0f87cd0f64e67c29e0a65017c8df384ebb83 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 22 Jun 2022 14:43:54 +0200 Subject: [PATCH 091/100] QtcProcess: Connect to done() signal instead of finished() Change-Id: Ie9005e2dc225907e46bb46086a663763b58c5152 Reviewed-by: hjk --- src/libs/utils/qtcprocess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 6c00b1d291c..18283cc3a08 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -1034,7 +1034,7 @@ QtcProcess::QtcProcess(QObject *parent) Q_UNUSED(qProcessProcessErrorMeta) if (processLog().isDebugEnabled()) { - connect(this, &QtcProcess::finished, [this] { + connect(this, &QtcProcess::done, [this] { if (!d->m_process.get()) return; const QVariant n = d->m_process.get()->property(QTC_PROCESS_NUMBER); From 42ab928a27ed02b3fff7e6347d0a9c857720e58d Mon Sep 17 00:00:00 2001 From: Tapani Mattila Date: Fri, 10 Jun 2022 12:30:42 +0300 Subject: [PATCH 092/100] CorePlugin: Prevent double warnings for overwriting files Task-number: QDS-6824 Change-Id: I935b2b1076a4e765230a7462c470d7c134063249 Reviewed-by: Reviewed-by: Eike Ziller --- src/plugins/coreplugin/documentmanager.cpp | 23 ++++++++++---------- src/plugins/qmldesigner/generateresource.cpp | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index 12ad4c3e60e..789374133cf 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -830,8 +830,7 @@ FilePath DocumentManager::getSaveFileName(const QString &title, const FilePath & bool repeat; do { repeat = false; - filePath = FileUtils::getSaveFilePath(nullptr, title, path, filter, selectedFilter, - QFileDialog::DontConfirmOverwrite); + filePath = FileUtils::getSaveFilePath(nullptr, title, path, filter, selectedFilter); if (!filePath.isEmpty()) { // If the selected filter is All Files (*) we leave the name exactly as the user // specified. Otherwise the suffix must be one available in the selected filter. If @@ -852,18 +851,20 @@ FilePath DocumentManager::getSaveFileName(const QString &title, const FilePath & suffixOk = true; break; } - if (!suffixOk && !suffixes.isEmpty()) + if (!suffixOk && !suffixes.isEmpty()) { filePath = filePath.stringAppended(suffixes.at(0)); + if (filePath.exists()) { + if (QMessageBox::warning(ICore::dialogParent(), tr("Overwrite?"), + tr("An item named \"%1\" already exists at this location. " + "Do you want to overwrite it?").arg(filePath.toUserOutput()), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { + repeat = true; + } + } + } } } - if (filePath.exists()) { - if (QMessageBox::warning(ICore::dialogParent(), tr("Overwrite?"), - tr("An item named \"%1\" already exists at this location. " - "Do you want to overwrite it?").arg(filePath.toUserOutput()), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { - repeat = true; - } - } + } } while (repeat); if (!filePath.isEmpty()) diff --git a/src/plugins/qmldesigner/generateresource.cpp b/src/plugins/qmldesigner/generateresource.cpp index b85370f60f9..9d6be4e1c7c 100644 --- a/src/plugins/qmldesigner/generateresource.cpp +++ b/src/plugins/qmldesigner/generateresource.cpp @@ -217,7 +217,7 @@ void GenerateResource::generateMenuEntry() QTC_ASSERT(currentProject, return); const FilePath projectPath = currentProject->projectFilePath().parentDir(); - auto projectFileName = Core::DocumentManager::getSaveFileName( + auto projectFileName = Core::DocumentManager::getSaveFileNameWithExtension( QCoreApplication::translate("QmlDesigner::GenerateResource", "Save Project as QRC File"), projectPath.pathAppended(currentProject->displayName() + ".qrc"), QCoreApplication::translate("QmlDesigner::GenerateResource", @@ -366,7 +366,7 @@ void GenerateResource::generateMenuEntry() QTC_ASSERT(currentProject, return); const FilePath projectPath = currentProject->projectFilePath().parentDir(); - const FilePath resourceFileName = Core::DocumentManager::getSaveFileName( + const FilePath resourceFileName = Core::DocumentManager::getSaveFileNameWithExtension( QCoreApplication::translate("QmlDesigner::GenerateResource", "Save Project as Resource"), projectPath.pathAppended(currentProject->displayName() + ".qmlrc"), QCoreApplication::translate("QmlDesigner::GenerateResource", From b77645d1335f966507d895d045bcb23232880655 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 22 Jun 2022 15:17:25 +0200 Subject: [PATCH 093/100] tst_QtcProcess: Don't use errorOccurred() in tests Change-Id: I71657e111ab09b599480874ed22e714142697c19 Reviewed-by: Reviewed-by: David Schulz --- .../processtestapp/processtestapp.cpp | 2 +- .../processtestapp/processtestapp.h | 2 +- .../auto/utils/qtcprocess/tst_qtcprocess.cpp | 21 +++++++++---------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/tests/auto/utils/qtcprocess/processtestapp/processtestapp.cpp b/tests/auto/utils/qtcprocess/processtestapp/processtestapp.cpp index d5591b787a7..28330786d38 100644 --- a/tests/auto/utils/qtcprocess/processtestapp/processtestapp.cpp +++ b/tests/auto/utils/qtcprocess/processtestapp/processtestapp.cpp @@ -207,7 +207,7 @@ int ProcessTestApp::BlockingProcess::main() return 1; } -int ProcessTestApp::EmitOneErrorOnCrash::main() +int ProcessTestApp::Crash::main() { doCrash(); return 1; diff --git a/tests/auto/utils/qtcprocess/processtestapp/processtestapp.h b/tests/auto/utils/qtcprocess/processtestapp/processtestapp.h index 4050cb9a2e5..7fbcabc25dc 100644 --- a/tests/auto/utils/qtcprocess/processtestapp/processtestapp.h +++ b/tests/auto/utils/qtcprocess/processtestapp/processtestapp.h @@ -72,7 +72,7 @@ public: SUB_PROCESS(StandardOutputAndErrorWriter); SUB_PROCESS(ChannelForwarding); SUB_PROCESS(BlockingProcess); - SUB_PROCESS(EmitOneErrorOnCrash); + SUB_PROCESS(Crash); SUB_PROCESS(CrashAfterOneSecond); SUB_PROCESS(RecursiveCrashingProcess); SUB_PROCESS(RecursiveBlockingProcess); diff --git a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp index e73ad97ad4e..c422b690d1f 100644 --- a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp +++ b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp @@ -144,7 +144,7 @@ private slots: void destroyBlockingProcess_data(); void destroyBlockingProcess(); void flushFinishedWhileWaitingForReadyRead(); - void emitOneErrorOnCrash(); + void crash(); void crashAfterOneSecond(); void recursiveCrashingProcess(); void recursiveBlockingProcess(); @@ -1012,11 +1012,10 @@ void tst_QtcProcess::notRunningAfterStartingNonExistingProgram() process.setCommand({ FilePath::fromString( "there_is_a_big_chance_that_executable_with_that_name_does_not_exists"), {} }); - int errorCount = 0; - QObject::connect(&process, &QtcProcess::errorOccurred, - [&errorCount](QProcess::ProcessError error) { - ++errorCount; - QCOMPARE(error, QProcess::FailedToStart); + int doneCount = 0; + QObject::connect(&process, &QtcProcess::done, [&process, &doneCount]() { + ++doneCount; + QCOMPARE(process.error(), QProcess::FailedToStart); }); const int loopCount = 2; @@ -1036,6 +1035,7 @@ void tst_QtcProcess::notRunningAfterStartingNonExistingProgram() QVERIFY(process.exitCode() != 0); QCOMPARE(process.result(), ProcessResult::StartFailed); } + QCOMPARE(doneCount, loopCount); } // Since we want to test whether the process forwards its channels or not, we can't just create @@ -1178,23 +1178,22 @@ void tst_QtcProcess::flushFinishedWhileWaitingForReadyRead() QVERIFY(reply.contains(s_simpleTestData)); } -void tst_QtcProcess::emitOneErrorOnCrash() +void tst_QtcProcess::crash() { - SubProcessConfig subConfig(ProcessTestApp::EmitOneErrorOnCrash::envVar(), {}); + SubProcessConfig subConfig(ProcessTestApp::Crash::envVar(), {}); QtcProcess process; subConfig.setupSubProcess(&process); - int errorCount = 0; - connect(&process, &QtcProcess::errorOccurred, this, [&errorCount] { ++errorCount; }); process.start(); QVERIFY(process.waitForStarted(1000)); + QVERIFY(process.isRunning()); QEventLoop loop; connect(&process, &QtcProcess::done, &loop, &QEventLoop::quit); loop.exec(); - QCOMPARE(errorCount, 1); QCOMPARE(process.error(), QProcess::Crashed); + QCOMPARE(process.exitStatus(), QProcess::CrashExit); } void tst_QtcProcess::crashAfterOneSecond() From fd47b37298827c399bc1e40774aeb0372c1d5735 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Jun 2022 15:40:30 +0200 Subject: [PATCH 094/100] ProjectExplorer: Do not remove "-Xclang" from command line ... when retrieving built-in header paths. Fixes: QTCREATORBUG-22136 Change-Id: I2e403392b14b4cdea89fc33eb503fff303618d71 Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/projectexplorer/gcctoolchain.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 8a3ffe5b53b..fa62339215d 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -442,6 +442,8 @@ static QStringList filteredFlags(const QStringList &allFlags, bool considerSysro } else if (a == "-arch") { if (++i < allFlags.length() && !filtered.contains(a)) filtered << a << allFlags.at(i); + } else if (a == "-Xclang") { + filtered << a; } else if ((considerSysroot && (a == "--sysroot" || a == "-isysroot")) || a == "-D" || a == "-U" || a == "-gcc-toolchain" || a == "-target" || a == "-mllvm" || a == "-isystem") { From 1e8139ecec107d5bb155ed7561fd43fdfb945bb2 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Jun 2022 18:00:03 +0200 Subject: [PATCH 095/100] CdbEngine: Don't call blocking waitForStarted() Connect to started() signal instead and continue setup in its handler. Handle failed to start case inside done() signal handler. Change-Id: I23fd222a6c73147ee439381cac79f29cffad560c Reviewed-by: David Schulz Reviewed-by: --- src/plugins/debugger/cdb/cdbengine.cpp | 27 +++++++++++++++----------- src/plugins/debugger/cdb/cdbengine.h | 2 ++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index b4d538485b9..ce6ffac2564 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -212,6 +212,7 @@ CdbEngine::CdbEngine() : DebuggerSettings *s = debuggerSettings(); connect(s->createFullBacktrace.action(), &QAction::triggered, this, &CdbEngine::createFullBacktrace); + connect(&m_process, &QtcProcess::started, this, &CdbEngine::processStarted); connect(&m_process, &QtcProcess::done, this, &CdbEngine::processDone); connect(&m_process, &QtcProcess::readyReadStandardOutput, this, &CdbEngine::readyReadStandardOut); @@ -382,12 +383,12 @@ void CdbEngine::setupEngine() // Prepare command line. CommandLine debugger{sp.debugger.command}; - const QString extensionFileName = extensionFi.fileName(); + m_extensionFileName = extensionFi.fileName(); const bool isRemote = sp.startMode == AttachToRemoteServer; if (isRemote) { // Must be first debugger.addArgs({"-remote", sp.remoteChannel}); } else { - debugger.addArg("-a" + extensionFileName); + debugger.addArg("-a" + m_extensionFileName); } // Source line info/No terminal breakpoint / Pull extension @@ -469,20 +470,19 @@ void CdbEngine::setupEngine() m_process.setCommand(debugger); m_process.start(); - if (!m_process.waitForStarted()) { - handleSetupFailure(QString("Internal error: Cannot start process %1: %2"). - arg(debugger.toUserOutput(), m_process.errorString())); - return; - } +} +void CdbEngine::processStarted() +{ const qint64 pid = m_process.processId(); - showMessage(QString("%1 running as %2").arg(debugger.executable().toUserOutput()).arg(pid), - LogMisc); + const FilePath execPath = runParameters().debugger.command.executable(); + showMessage(QString("%1 running as %2").arg(execPath.toUserOutput()).arg(pid), LogMisc); m_hasDebuggee = true; m_initialSessionIdleHandled = false; - if (isRemote) { // We do not get an 'idle' in a remote session, but are accessible + if (runParameters().startMode == AttachToRemoteServer) { + // We do not get an 'idle' in a remote session, but are accessible m_accessible = true; - runCommand({".load " + extensionFileName, NoFlags}); + runCommand({".load " + m_extensionFileName, NoFlags}); handleInitialSessionIdle(); } } @@ -710,6 +710,11 @@ void CdbEngine::abortDebuggerProcess() void CdbEngine::processDone() { + if (m_process.result() == ProcessResult::StartFailed) { + handleSetupFailure(m_process.exitMessage()); + return; + } + if (m_process.error() != QProcess::UnknownError) showMessage(m_process.errorString(), LogError); diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 92d434f2bc3..1209d0ad3a7 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -106,6 +106,7 @@ public: private: void readyReadStandardOut(); void readyReadStandardError(); + void processStarted(); void processDone(); void runCommand(const DebuggerCommand &cmd) override; void adjustOperateByInstruction(bool); @@ -222,6 +223,7 @@ private: wow64Stack64Bit } m_wow64State = wow64Uninitialized; QElapsedTimer m_logTimer; + QString m_extensionFileName; QString m_extensionMessageBuffer; bool m_sourceStepInto = false; int m_watchPointX = 0; From 146f59e808bf0c60c0a373e6e569b08589d11d0f Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 23 Jun 2022 10:29:22 +0300 Subject: [PATCH 096/100] Set solibSearchPath to LLDB Change-Id: Iedfc3850b568dc336eb3df309b2b36ab25d1aa20 Reviewed-by: hjk --- src/plugins/debugger/lldb/lldbengine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 40a369049f1..5d54fc56b59 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -278,6 +278,9 @@ void LldbEngine::handleLldbStarted() "settings append target.source-map " + it.key() + ' ' + expand(it.value())); } + for (const QString &path : rp.solibSearchPath) + executeDebuggerCommand("settings append target.exec-search-paths " + path); + DebuggerCommand cmd2("setupInferior"); cmd2.arg("executable", rp.inferior.command.executable().toString()); cmd2.arg("breakonmain", rp.breakOnMain); From aaf2318a19799bbbc15f925022bddf57f4b1c28f Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 22 Jun 2022 15:15:48 +0300 Subject: [PATCH 097/100] Fix Android debugging - gatherFilesToPull depends on AndroidManager::setDeviceAbis - use the same path for app_process. gatherFilesToPull pulls app_process to AndroidManager::buildDirectory(target) which might be different than activeRunConfig->buildTargetInfo().workingDirectory. Change-Id: Id47c4380fed5a8b3ad922359e5f9f25e529bacff Reviewed-by: hjk --- src/plugins/android/androiddebugsupport.cpp | 4 ++-- src/plugins/android/androiddeployqtstep.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index c92ec6af462..055c8d8f8fc 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -140,10 +140,10 @@ void AndroidDebugSupport::start() solibSearchPath.append(qtVersion->qtSoPaths()); solibSearchPath.append(uniquePaths(extraLibs)); + FilePath buildDir = AndroidManager::buildDirectory(target); const RunConfiguration *activeRunConfig = target->activeRunConfiguration(); - FilePath buildDir; if (activeRunConfig) - buildDir = activeRunConfig->buildTargetInfo().workingDirectory; + solibSearchPath.append(activeRunConfig->buildTargetInfo().workingDirectory.toString()); solibSearchPath.append(buildDir.toString()); solibSearchPath.removeDuplicates(); setSolibSearchPath(solibSearchPath); diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index 104d1151a04..a8b8124fd9c 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -213,12 +213,12 @@ bool AndroidDeployQtStep::init() m_serialNumber = info.serialNumber; qCDebug(deployStepLog) << "Selected device info:" << info; - gatherFilesToPull(); - AndroidManager::setDeviceSerialNumber(target(), m_serialNumber); AndroidManager::setDeviceApiLevel(target(), info.sdk); AndroidManager::setDeviceAbis(target(), info.cpuAbi); + gatherFilesToPull(); + emit addOutput(tr("Deploying to %1").arg(m_serialNumber), OutputFormat::NormalMessage); m_uninstallPreviousPackageRun = m_uninstallPreviousPackage->value(); From 8bb22fa4f3864ce8b4ce00eddd3205ecd416695e Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Jun 2022 12:12:27 +0200 Subject: [PATCH 098/100] Debugger: Fail gracefully on systems without working base64 module Change-Id: I341b0fdb1c9e32fda3ce80f3e7569cffbb0708d2 Reviewed-by: Rafael Roquetto --- share/qtcreator/debugger/dumper.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 7a54f7676f6..3f3acbe46da 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -29,7 +29,6 @@ import collections import glob import struct import sys -import base64 import re import time import inspect @@ -45,6 +44,14 @@ except: "Native combined debugging might not work.") pass +try: + # That fails on some QNX via Windows installations + import base64 + def hexencode_(s): + return base64.b16encode(s).decode('utf8') +except: + def hexencode_(s): + return ''.join(["%x" % c for c in s]) if sys.version_info[0] >= 3: toInteger = int @@ -550,7 +557,7 @@ class DumperBase(): return s.encode('hex') if isinstance(s, str): s = s.encode('utf8') - return base64.b16encode(s).decode('utf8') + return hexencode_(s) def isQt3Support(self): # assume no Qt 3 support by default From 0ce0ad6cf9a5d9cc66007a05cad55e6f07f99dc1 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 23 Jun 2022 10:26:34 +0300 Subject: [PATCH 099/100] Add android-build/libs/ to solibSearchPath All android libs that can be loaded are placed in android-build/libs/ /. These libs are not stripped anymore, so let's add also this folder to solibSearchPath. Change-Id: I34de8bf7ee68725903fd7250a39b407c6ae57cac Reviewed-by: hjk Reviewed-by: BogDan Vatra --- src/plugins/android/androiddebugsupport.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 055c8d8f8fc..2cc37d7e931 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -145,6 +145,11 @@ void AndroidDebugSupport::start() if (activeRunConfig) solibSearchPath.append(activeRunConfig->buildTargetInfo().workingDirectory.toString()); solibSearchPath.append(buildDir.toString()); + const auto androidLibsPath = AndroidManager::androidBuildDirectory(target) + .pathAppended("libs") + .pathAppended(AndroidManager::apkDevicePreferredAbi(target)) + .toString(); + solibSearchPath.append(androidLibsPath); solibSearchPath.removeDuplicates(); setSolibSearchPath(solibSearchPath); qCDebug(androidDebugSupportLog) << "SoLibSearchPath: "< Date: Thu, 23 Jun 2022 10:27:26 +0200 Subject: [PATCH 100/100] Fix application of value to StringAspect/LineEditDisplay It was not applying the value when changing the text via a completer. That lead to confusing result where values were cut off (and also saved in the settings as such) at seemingly arbitrary cases. Ensure that the text from the line edit ends up in the aspect by also applying it on editingFinished(). One example where that exposed, was the executable aspect in the RemoteLinuxCustomRunConfiguration. Change-Id: I65c434fd675eeead76a73f680c126fd204d7c996 Reviewed-by: Christian Kandeler --- src/libs/utils/aspects.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index 1af70360c1c..79f6428a4a2 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -1138,6 +1138,9 @@ void StringAspect::addToLayout(LayoutBuilder &builder) &FancyLineEdit::textEdited, this, &StringAspect::setValue); + connect(d->m_lineEditDisplay, &FancyLineEdit::editingFinished, this, [this] { + setValue(d->m_lineEditDisplay->text()); + }); } } if (d->m_useResetButton) {