From 53397306b962e6f7dade3292694b2387078fee07 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Tue, 21 Feb 2023 20:05:17 +0100 Subject: [PATCH 01/43] LLVM/Clang: Update to version 16.0.0-rc2 This was the newest release tag last week. Change-Id: Idd272db9dc7ff797023fac72ea8a252729d979b3 Reviewed-by: Reviewed-by: Eike Ziller Reviewed-by: Christian Kandeler --- .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 0c04d2691c7..6c14dcfb55a 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -9,7 +9,7 @@ on: env: QT_VERSION: 6.4.2 MACOS_DEPLOYMENT_TARGET: 10.14 - CLANG_VERSION: 15.0.0 + CLANG_VERSION: 16.0.0-rc2 ELFUTILS_VERSION: 0.175 CMAKE_VERSION: 3.21.1 NINJA_VERSION: 1.10.2 diff --git a/coin/instructions/common_environment.yaml b/coin/instructions/common_environment.yaml index 33557ea11d5..1124788c83b 100644 --- a/coin/instructions/common_environment.yaml +++ b/coin/instructions/common_environment.yaml @@ -7,7 +7,7 @@ instructions: variableValue: "RelWithDebInfo" - type: EnvironmentVariable variableName: LLVM_BASE_URL - variableValue: http://master.qt.io/development_releases/prebuilt/libclang/libclang-release_15.0.0-based + variableValue: http://master.qt.io/development_releases/prebuilt/libclang/libclang-release_16.0.0-rc2-based - type: EnvironmentVariable variableName: QTC_QT_BASE_URL variableValue: "http://ci-files02-hki.intra.qt.io/packages/jenkins/archive/qt/6.4/6.4.2-released/Qt" From 0c72395148c27891c6e9adbc618d72c28c8cce60 Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Tue, 24 Jan 2023 15:25:20 +0100 Subject: [PATCH 02/43] Android: Add SdkManagerOutputParser tests Change-Id: I0d0f7318aa670885def5c6a41b9c76ab539713c2 Reviewed-by: Alessandro Portale --- src/plugins/android/CMakeLists.txt | 1 + src/plugins/android/android.qbs | 2 + src/plugins/android/androidplugin.cpp | 7 +- .../android/androidsdkmanager_test.cpp | 1 - .../android/sdkmanageroutputparser.cpp | 7 +- src/plugins/android/sdkmanageroutputparser.h | 2 +- .../android/sdkmanageroutputparser_test.cpp | 793 ++++++++++++++++++ .../android/sdkmanageroutputparser_test.h | 74 ++ 8 files changed, 881 insertions(+), 6 deletions(-) create mode 100644 src/plugins/android/sdkmanageroutputparser_test.cpp create mode 100644 src/plugins/android/sdkmanageroutputparser_test.h diff --git a/src/plugins/android/CMakeLists.txt b/src/plugins/android/CMakeLists.txt index b00b254e8a8..9246c94e829 100644 --- a/src/plugins/android/CMakeLists.txt +++ b/src/plugins/android/CMakeLists.txt @@ -59,5 +59,6 @@ extend_qtc_plugin(Android CONDITION WITH_TESTS SOURCES androidsdkmanager_test.cpp androidsdkmanager_test.h + sdkmanageroutputparser_test.cpp sdkmanageroutputparser_test.h android_tst.qrc ) diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs index 1d18d0b708a..3db92841863 100644 --- a/src/plugins/android/android.qbs +++ b/src/plugins/android/android.qbs @@ -123,6 +123,8 @@ Project { "android_tst.qrc", "androidsdkmanager_test.cpp", "androidsdkmanager_test.h", + "sdkmanageroutputparser_test.cpp", + "sdkmanageroutputparser_test.h, ] } } diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp index 8d4d14d3980..b8ff5dbe0b8 100644 --- a/src/plugins/android/androidplugin.cpp +++ b/src/plugins/android/androidplugin.cpp @@ -17,11 +17,15 @@ #include "androidqtversion.h" #include "androidrunconfiguration.h" #include "androidruncontrol.h" -#include "androidsdkmanager_test.h" #include "androidsettingswidget.h" #include "androidtoolchain.h" #include "androidtr.h" +#ifdef WITH_TESTS +# include "androidsdkmanager_test.h" +# include "sdkmanageroutputparser_test.h" +#endif + #include "javaeditor.h" #include "javalanguageserver.h" @@ -118,6 +122,7 @@ void AndroidPlugin::initialize() #ifdef WITH_TESTS addTest(); + addTest(); #endif } diff --git a/src/plugins/android/androidsdkmanager_test.cpp b/src/plugins/android/androidsdkmanager_test.cpp index 9bed162cbda..de97bbc85e1 100644 --- a/src/plugins/android/androidsdkmanager_test.cpp +++ b/src/plugins/android/androidsdkmanager_test.cpp @@ -1,4 +1,3 @@ - // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 diff --git a/src/plugins/android/sdkmanageroutputparser.cpp b/src/plugins/android/sdkmanageroutputparser.cpp index 2989ec35ddc..96eb9e4b171 100644 --- a/src/plugins/android/sdkmanageroutputparser.cpp +++ b/src/plugins/android/sdkmanageroutputparser.cpp @@ -3,8 +3,9 @@ #include "sdkmanageroutputparser.h" -#include "avdmanageroutputparser.h" +#include "androidconstants.h" #include "androidsdkpackage.h" +#include "avdmanageroutputparser.h" #include @@ -440,8 +441,8 @@ SdkManagerOutputParser::MarkerTag SdkManagerOutputParser::parseMarkers(const QSt if (line.startsWith(QLatin1String(pair.second))) return pair.first; } - - QRegularExpressionMatch match = QRegularExpression("^[a-zA-Z]+[A-Za-z0-9;._-]+").match(line); + static const QRegularExpression reg("^[a-zA-Z]+[A-Za-z0-9;._-]+"); + const QRegularExpressionMatch match = reg.match(line); if (match.hasMatch() && match.captured(0) == line) return GenericToolMarker; diff --git a/src/plugins/android/sdkmanageroutputparser.h b/src/plugins/android/sdkmanageroutputparser.h index 5f0534dfbde..9457d88e1c1 100644 --- a/src/plugins/android/sdkmanageroutputparser.h +++ b/src/plugins/android/sdkmanageroutputparser.h @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once -#include "androidconstants.h" #include "androidsdkpackage.h" #include @@ -74,6 +73,7 @@ private: MarkerTag m_currentSection = MarkerTag::None; QHash m_systemImages; + friend class SdkManagerOutputParserTest; }; } // namespace Internal } // namespace Android diff --git a/src/plugins/android/sdkmanageroutputparser_test.cpp b/src/plugins/android/sdkmanageroutputparser_test.cpp new file mode 100644 index 00000000000..f7f2388b1fc --- /dev/null +++ b/src/plugins/android/sdkmanageroutputparser_test.cpp @@ -0,0 +1,793 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "sdkmanageroutputparser_test.h" +#include "sdkmanageroutputparser.h" + +#include "androidsdkpackage.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace Android::Internal { + +SdkManagerOutputParserTest::SdkManagerOutputParserTest(QObject *parent) + : QObject(parent) + , m_parser(std::make_unique(m_packages)) +{} + +SdkManagerOutputParserTest::~SdkManagerOutputParserTest() = default; + +void SdkManagerOutputParserTest::testParseMarkers_data() +{ + QTest::addColumn("output"); + QTest::addColumn("markerTag"); + + QMap testData + = {{SdkManagerOutputParser::MarkerTag::InstalledPackagesMarker, "Installed packages:"}, + {SdkManagerOutputParser::MarkerTag::AvailablePackagesMarkers, "Available Packages:"}, + {SdkManagerOutputParser::MarkerTag::AvailableUpdatesMarker, "Available Updates:"}, + {SdkManagerOutputParser::MarkerTag::EmptyMarker, ""}, + {SdkManagerOutputParser::MarkerTag::PlatformMarker, "platforms"}, + {SdkManagerOutputParser::MarkerTag::SystemImageMarker, "system-images"}, + {SdkManagerOutputParser::MarkerTag::BuildToolsMarker, "build-tools"}, + {SdkManagerOutputParser::MarkerTag::SdkToolsMarker, "tools"}, + {SdkManagerOutputParser::MarkerTag::PlatformToolsMarker, "platform-tools"}, + {SdkManagerOutputParser::MarkerTag::EmulatorToolsMarker, "emulator"}, + {SdkManagerOutputParser::MarkerTag::NdkMarker, "ndk"}, + {SdkManagerOutputParser::MarkerTag::ExtrasMarker, "extras"}, + {SdkManagerOutputParser::MarkerTag::CmdlineSdkToolsMarker, "cmdline-tools"}, + {SdkManagerOutputParser::MarkerTag::GenericToolMarker, "sources;android-32"}}; + + for (const SdkManagerOutputParser::MarkerTag data : testData.keys()) + QTest::newRow(testData.value(data).toLatin1().constData()) << testData.value(data) << data; + + QTest::newRow("Installed packages") + << "Installed packages:" << SdkManagerOutputParser::MarkerTag::InstalledPackagesMarker; +} + +void SdkManagerOutputParserTest::testParseMarkers() +{ + QFETCH(QString, output); + QFETCH(SdkManagerOutputParser::MarkerTag, markerTag); + + SdkManagerOutputParser::MarkerTag actualMarkerTag = m_parser->parseMarkers(output); + + QCOMPARE(actualMarkerTag, markerTag); +} + +// BuildTools +void SdkManagerOutputParserTest::testParseBuildToolsPackage_data() +{ + QTest::addColumn("output"); + + QTest::addColumn("description"); + QTest::addColumn("displayText"); + QTest::addColumn("revision"); + + QTest::newRow("build-tools;33.0.1") + << QStringList({"build-tools;33.0.1", + " Description: Android SDK Build-Tools 33.0.1", + " Version: 33.0.1"}) + << "Android SDK Build-Tools 33.0.1" + << "Android SDK Build-Tools 33.0.1" << QVersionNumber({33, 0, 1}); + + QTest::newRow("build-tools;33.0.3") + << QStringList({"build-tools;33.0.3", + " Description: Android SDK Build-Tools 33.0.3", + " Version: 33.0.3"}) + << "Android SDK Build-Tools 33.0.3" + << "Android SDK Build-Tools 33.0.3" << QVersionNumber({33, 0, 3}); +} + +void SdkManagerOutputParserTest::testParseBuildToolsPackage() +{ + QFETCH(QStringList, output); + QFETCH(QString, description); + QFETCH(QString, displayText); + QFETCH(QVersionNumber, revision); + + BuildTools *actualBuildTools = m_parser->parseBuildToolsPackage(output); + + QCOMPARE_NE(actualBuildTools, nullptr); + QCOMPARE(actualBuildTools->descriptionText(), description); + QCOMPARE(actualBuildTools->displayText(), displayText); + QCOMPARE(actualBuildTools->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseBuildToolsPackageEmpty() +{ + BuildTools *actualBuildTools = m_parser->parseBuildToolsPackage({""}); + + QCOMPARE_EQ(actualBuildTools, nullptr); +} + +// SdkTools +void SdkManagerOutputParserTest::testParseSdkToolsPackage_data() +{ + QTest::addColumn("output"); + + QTest::addColumn("description"); + QTest::addColumn("displayText"); + QTest::addColumn("revision"); + + QTest::newRow("cmdline-tools;latest") + << QStringList({"cmdline-tools;latest", + " Description: Android SDK Command-line Tools (latest)", + " Version: 9.0"}) + << "Android SDK Command-line Tools (latest)" + << "Android SDK Command-line Tools (latest)" << QVersionNumber({9, 0}); + + QTest::newRow("cmdline-tools;8.0") + << QStringList({"cmdline-tools;8.0", + " Description: Android SDK Command-line Tools", + " Version: 8.0"}) + << "Android SDK Command-line Tools" + << "Android SDK Command-line Tools" << QVersionNumber({8, 0}); +} + +void SdkManagerOutputParserTest::testParseSdkToolsPackage() +{ + QFETCH(QStringList, output); + QFETCH(QString, description); + QFETCH(QString, displayText); + QFETCH(QVersionNumber, revision); + + std::unique_ptr actualSdkTool(m_parser->parseSdkToolsPackage(output)); + + QCOMPARE_NE(actualSdkTool, nullptr); + QCOMPARE(actualSdkTool->descriptionText(), description); + QCOMPARE(actualSdkTool->displayText(), displayText); + QCOMPARE(actualSdkTool->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseSdkToolsPackageEmpty() +{ + std::unique_ptr actualSdkTool(m_parser->parseSdkToolsPackage({""})); + + QCOMPARE_EQ(actualSdkTool, nullptr); +} + +// PlatformTools +void SdkManagerOutputParserTest::testParsePlatformToolsPackage_data() +{ + QTest::addColumn("output"); + + QTest::addColumn("description"); + QTest::addColumn("displayText"); + QTest::addColumn("revision"); + + QTest::newRow("platform-tools") + << QStringList({"platform-tools", + " Description: Android SDK Platform-Tools", + " Version: 33.0.3"}) + << "Android SDK Platform-Tools" + << "Android SDK Platform-Tools" << QVersionNumber({33, 0, 3}); +} + +void SdkManagerOutputParserTest::testParsePlatformToolsPackage() +{ + QFETCH(QStringList, output); + QFETCH(QString, description); + QFETCH(QString, displayText); + QFETCH(QVersionNumber, revision); + + std::unique_ptr actualPlatformTool( + m_parser->parsePlatformToolsPackage(output)); + + QCOMPARE_NE(actualPlatformTool, nullptr); + QCOMPARE(actualPlatformTool->descriptionText(), description); + QCOMPARE(actualPlatformTool->displayText(), displayText); + QCOMPARE(actualPlatformTool->revision(), revision); +} + +void SdkManagerOutputParserTest::testParsePlatformToolsPackageEmpty() +{ + std::unique_ptr actualPlatformTool( + m_parser->parsePlatformToolsPackage({""})); + + QCOMPARE_EQ(actualPlatformTool, nullptr); +} + +// EmulatorTools +void SdkManagerOutputParserTest::testParseEmulatorToolsPackage_data() +{ + QTest::addColumn("output"); + + QTest::addColumn("description"); + QTest::addColumn("displayText"); + QTest::addColumn("revision"); + + QTest::newRow("emulator") << QStringList( + {"emulator", " Description: Android Emulator", " Version: 30.0.12"}) + << "Android Emulator" + << "Android Emulator" << QVersionNumber({30, 0, 12}); +} + +void SdkManagerOutputParserTest::testParseEmulatorToolsPackage() +{ + QFETCH(QStringList, output); + QFETCH(QString, description); + QFETCH(QString, displayText); + QFETCH(QVersionNumber, revision); + + std::unique_ptr actualEmulatorTools( + m_parser->parseEmulatorToolsPackage(output)); + + QCOMPARE_NE(actualEmulatorTools, nullptr); + QCOMPARE(actualEmulatorTools->descriptionText(), description); + QCOMPARE(actualEmulatorTools->displayText(), displayText); + QCOMPARE(actualEmulatorTools->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseEmulatorToolsPackageEmpty() +{ + std::unique_ptr actualEmulatorTools( + m_parser->parseEmulatorToolsPackage({""})); + + QCOMPARE_EQ(actualEmulatorTools, nullptr); +} + +// NDK +void SdkManagerOutputParserTest::testParseNdkPackage_data() +{ + QTest::addColumn("output"); + + QTest::addColumn("description"); + QTest::addColumn("displayText"); + QTest::addColumn("revision"); + + QTest::newRow("ndk;21.0.6113669") << QStringList({"ndk;21.0.6113669", + " Description: Android NDK", + " Version: 21.0.6113669"}) + << "Android NDK" + << "Android NDK" << QVersionNumber({21, 0, 6113669}); +} + +void SdkManagerOutputParserTest::testParseNdkPackage() +{ + QFETCH(QStringList, output); + QFETCH(QString, description); + QFETCH(QString, displayText); + QFETCH(QVersionNumber, revision); + + std::unique_ptr actualNdkPackage(m_parser->parseNdkPackage(output)); + + QCOMPARE_NE(actualNdkPackage, nullptr); + QCOMPARE(actualNdkPackage->descriptionText(), description); + QCOMPARE(actualNdkPackage->displayText(), displayText); + QCOMPARE(actualNdkPackage->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseNdkPackageEmpty() +{ + std::unique_ptr actualNdkPackage(m_parser->parseNdkPackage({""})); + + QCOMPARE_EQ(actualNdkPackage, nullptr); +} + +// ExtraTools +void SdkManagerOutputParserTest::testParseExtraToolsPackage_data() +{ + QTest::addColumn("output"); + + QTest::addColumn("description"); + QTest::addColumn("displayText"); + QTest::addColumn("revision"); + + QTest::newRow( + "extras;m2repository;com;android;support;constraint;constraint-layout;1.0.0-beta5") + << QStringList( + {"extras;m2repository;com;android;support;constraint;constraint-layout;1.0.1", + " Description: ConstraintLayout for Android 1.0.1", + " Version: 1", + " Dependencies:"}) + << "ConstraintLayout for Android 1.0.1" + << "ConstraintLayout for Android 1.0.1" << QVersionNumber({1}); +} + +void SdkManagerOutputParserTest::testParseExtraToolsPackage() +{ + QFETCH(QStringList, output); + QFETCH(QString, description); + QFETCH(QString, displayText); + QFETCH(QVersionNumber, revision); + + std::unique_ptr actualExtraTools( + m_parser->parseExtraToolsPackage(output)); + + QCOMPARE_NE(actualExtraTools, nullptr); + QCOMPARE(actualExtraTools->descriptionText(), description); + QCOMPARE(actualExtraTools->displayText(), displayText); + QCOMPARE(actualExtraTools->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseExtraToolsPackageEmpty() +{ + std::unique_ptr actualExtraTools( + m_parser->parseExtraToolsPackage({""})); + + QCOMPARE_EQ(actualExtraTools, nullptr); +} + +// GenericTools +void SdkManagerOutputParserTest::testParseGenericToolsPackage_data() +{ + QTest::addColumn("output"); + + QTest::addColumn("description"); + QTest::addColumn("displayText"); + QTest::addColumn("revision"); + + QTest::newRow("sources;android-33") + << QStringList({"sources;android-33", + " Description: Sources for Android 33", + " Version: 1"}) + << "Sources for Android 33" + << "Sources for Android 33" << QVersionNumber({1}); +} + +void SdkManagerOutputParserTest::testParseGenericToolsPackage() +{ + QFETCH(QStringList, output); + QFETCH(QString, description); + QFETCH(QString, displayText); + QFETCH(QVersionNumber, revision); + + std::unique_ptr actualGenericTools( + m_parser->parseGenericTools(output)); + + QCOMPARE_NE(actualGenericTools, nullptr); + QCOMPARE(actualGenericTools->descriptionText(), description); + QCOMPARE(actualGenericTools->displayText(), displayText); + QCOMPARE(actualGenericTools->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseGenericToolsPackageEmpty() +{ + std::unique_ptr actualGenericTools( + m_parser->parseGenericTools({""})); + + QCOMPARE_EQ(actualGenericTools, nullptr); +} + +// Platform +void SdkManagerOutputParserTest::testParsePlatformPackage_data() +{ + QTest::addColumn("output"); + + QTest::addColumn("description"); + QTest::addColumn("installLocation"); + QTest::addColumn("revision"); + QTest::addColumn("extension"); + + QTest::newRow("platforms;android-31") + << QStringList({"platforms;android-31", + " Description: Android SDK Platform 31", + " Version: 5", + " Installed Location: /home/name/Android/Sdk/platforms/android-31"}) + << "Android SDK Platform 31" + << "/home/name/Android/Sdk/platforms/android-31" << QVersionNumber({5}) << ""; + + QTest::newRow("platforms;android-33-ext4") + << QStringList({"platforms;android-33-ext4", + " Description: Android SDK Platform 33", + " Version: 1", + " Installed Location: /home/name/Android/Sdk/platforms/android-33"}) + << "Android SDK Platform 33" + << "/home/name/Android/Sdk/platforms/android-33" << QVersionNumber({1}) << " Extension 4"; +} + +void SdkManagerOutputParserTest::testParsePlatformPackage() +{ + QFETCH(QStringList, output); + QFETCH(QString, description); + QFETCH(QString, installLocation); + QFETCH(QVersionNumber, revision); + QFETCH(QString, extension); + + std::unique_ptr actualPlatform(m_parser->parsePlatform(output)); + + QCOMPARE_NE(actualPlatform, nullptr); + QCOMPARE(actualPlatform->descriptionText(), description); + QCOMPARE(actualPlatform->installedLocation().path(), installLocation); + QCOMPARE(actualPlatform->revision(), revision); + QCOMPARE(actualPlatform->extension(), extension); +} + +void SdkManagerOutputParserTest::testParsePlatformPackageEmpty() +{ + std::unique_ptr actualPlatform(m_parser->parsePlatform({""})); + + QCOMPARE_EQ(actualPlatform, nullptr); +} + +// SystemImage +void SdkManagerOutputParserTest::testParseSystemImagePackage_data() +{ + QTest::addColumn("output"); + + QTest::addColumn("description"); + QTest::addColumn("installLocation"); + QTest::addColumn("revision"); + + QTest::newRow("system-images;android-31;google_apis;x86") + << QStringList({"system-images;android-31;google_apis;x86", + " Description: Google APIs Intel x86 Atom System Image", + " Version: 7", + " Installed Location: /home/name/Android/Sdk/system-images/android-31/" + "google_apis/x86"}) + << "Google APIs Intel x86 Atom System Image" + << "/home/name/Android/Sdk/system-images/android-31/google_apis/x86" + << QVersionNumber({7}); +} + +void SdkManagerOutputParserTest::testParseSystemImagePackage() +{ + QFETCH(QStringList, output); + QFETCH(QString, description); + QFETCH(QString, installLocation); + QFETCH(QVersionNumber, revision); + + QPair actualSystemImagePair(m_parser->parseSystemImage(output)); + + SystemImage *actualSystemImage = actualSystemImagePair.first; + + QCOMPARE_NE(actualSystemImage, nullptr); + QCOMPARE(actualSystemImage->descriptionText(), description); + QCOMPARE(actualSystemImage->installedLocation().path(), installLocation); + QCOMPARE(actualSystemImage->revision(), revision); + delete actualSystemImage; +} + +void SdkManagerOutputParserTest::testParseSystemImagePackageEmpty() +{ + QPair actualSystemImagePair(m_parser->parseSystemImage({""})); + SystemImage *actualSystemImage = actualSystemImagePair.first; + + QCOMPARE_EQ(actualSystemImage, nullptr); + delete actualSystemImage; +} +void SdkManagerOutputParserTest::testParsePackageListing() +{ + QFETCH(QString, sdkManagerOutput); + QFETCH(QList, packageTypes); + QFETCH(int, sdkManagerOutputPackagesNumber); + + m_parser->parsePackageListing(sdkManagerOutput); + + QCOMPARE(m_packages.length(), sdkManagerOutputPackagesNumber); + + for (int i = 0; i < m_packages.length(); ++i) + QCOMPARE(m_packages.at(i)->type(), packageTypes.at(i)); +} + +void SdkManagerOutputParserTest::testParsePackageListing_data() +{ + QTest::addColumn("sdkManagerOutputPackagesNumber"); + QTest::addColumn>("packageTypes"); + QTest::addColumn("sdkManagerOutput"); + + const QList packageTypes = { + AndroidSdkPackage::PackageType::BuildToolsPackage, + AndroidSdkPackage::PackageType::SdkToolsPackage, + AndroidSdkPackage::PackageType::EmulatorToolsPackage, + AndroidSdkPackage::PackageType::NDKPackage, + AndroidSdkPackage::PackageType::GenericSdkPackage, + AndroidSdkPackage::PackageType::SdkPlatformPackage, + AndroidSdkPackage::PackageType::GenericSdkPackage, + + AndroidSdkPackage::PackageType::BuildToolsPackage, + AndroidSdkPackage::PackageType::GenericSdkPackage, + AndroidSdkPackage::PackageType::SdkToolsPackage, + AndroidSdkPackage::PackageType::SdkToolsPackage, + AndroidSdkPackage::PackageType::ExtraToolsPackage, + AndroidSdkPackage::PackageType::NDKPackage, + AndroidSdkPackage::PackageType::NDKPackage, + AndroidSdkPackage::PackageType::PlatformToolsPackage, + AndroidSdkPackage::PackageType::SdkPlatformPackage, + AndroidSdkPackage::PackageType::SdkPlatformPackage, + AndroidSdkPackage::PackageType::SdkPlatformPackage, + AndroidSdkPackage::PackageType::SdkPlatformPackage, + AndroidSdkPackage::PackageType::GenericSdkPackage, + AndroidSdkPackage::PackageType::GenericSdkPackage, + }; + + QTest::newRow("sdkmanager --list --verbose") // version 8.0 + << 21 + << packageTypes + << QString(R"( +Loading package information... +Loading local repository... +Info: Parsing /home/artem/Android/Sdk/build-tools/31.0.0/package.xml +Info: Parsing /home/artem/Android/Sdk/cmdline-tools/latest/package.xml +Info: Parsing /home/artem/Android/Sdk/emulator/package.xml +Info: Parsing /home/artem/Android/Sdk/ndk/21.3.6528147/package.xml +Info: Parsing /home/artem/Android/Sdk/ndk/23.1.7779620/package.xml +Info: Parsing /home/artem/Android/Sdk/ndk/25.1.8937393/package.xml +Info: Parsing /home/artem/Android/Sdk/patcher/v4/package.xml +Info: Parsing /home/artem/Android/Sdk/platform-tools/package.xml +Info: Parsing /home/artem/Android/Sdk/platforms/android-31/package.xml +Info: Parsing +/home/artem/Android/Sdk/system-images/android-25/google_apis/armeabi-v7a +package.xml +Info: Parsing +/home/artem/Android/Sdk/system-images/android-27/default/arm64-v8a/package.xml +Info: Parsing +/home/artem/Android/Sdk/system-images/android-29/google_apis/x86/package.xml +Info: Parsing +/home/artem/Android/Sdk/system-images/android-31/android-tv/arm64-v8a/package.xml +Info: Parsing +/home/artem/Android/Sdk/system-images/android-31/android-tv/x86/package.xml +Info: Parsing +/home/artem/Android/Sdk/system-images/android-31/default/x86_64/package.xml +Info: Parsing +/home/artem/Android/Sdk/system-images/android-31/google_apis/x86_64/package.xml +Info: Parsing +/home/artem/Android/Sdk/system-images/android-32/google_apis/arm64-v8a/package.xml +Info: Parsing +/home/artem/Android/Sdk/system-images/android-32/google_apis/x86_64/package.xml +Info: Parsing +/home/artem/Android/Sdk/system-images/android-33/google_apis/arm64-v8a/package.xml +[========= ] 25% Loading local repository... +[========= ] 25% Fetch remote repository... +[========== ] 26% Fetch remote repository... +[============ ] 31% Fetch remote repository... +[============= ] 33% Fetch remote repository... +[============= ] 34% Fetch remote repository... +[============== ] 36% Fetch remote repository... +[============== ] 37% Fetch remote repository... +[=============== ] 38% Fetch remote repository... +[=============== ] 40% Fetch remote repository... +[================ ] 41% Fetch remote repository... +[================= ] 43% Fetch remote repository... +[================= ] 44% Fetch remote repository... +[================== ] 45% Fetch remote repository... +[================== ] 47% Fetch remote repository... +[=================== ] 48% Fetch remote repository... +[=================== ] 50% Fetch remote repository... +[==================== ] 51% Fetch remote repository... +[==================== ] 53% Fetch remote repository... +[===================== ] 54% Fetch remote repository... +[====================== ] 55% Fetch remote repository... +[====================== ] 57% Fetch remote repository... +[======================= ] 58% Fetch remote repository... +[======================= ] 60% Fetch remote repository... +[======================== ] 61% Fetch remote repository... +[======================== ] 62% Fetch remote repository... +[========================= ] 64% Fetch remote repository... +[========================== ] 65% Fetch remote repository... +[========================== ] 67% Fetch remote repository... +[=========================== ] 68% Fetch remote repository... +[=========================== ] 69% Fetch remote repository... +[============================ ] 71% Fetch remote repository... +[============================ ] 72% Fetch remote repository... +[============================= ] 74% Fetch remote repository... +[============================= ] 75% Fetch remote repository... +[============================= ] 75% Computing updates... +[=======================================] 100% Computing updates... +Installed packages: +-------------------------------------- +build-tools;31.0.0 + Description: Android SDK Build-Tools 31 + Version: 31.0.0 + Installed Location: /home/artem/Android/Sdk/build-tools/31.0.0 + +cmdline-tools;latest + Description: Android SDK Command-line Tools (latest) + Version: 8.0 + Installed Location: /home/artem/Android/Sdk/cmdline-tools/latest + +emulator + Description: Android Emulator + Version: 31.3.14 + Installed Location: /home/artem/Android/Sdk/emulator + +ndk;25.1.8937393 + Description: NDK (Side by side) 25.1.8937393 + Version: 25.1.8937393 + Installed Location: /home/artem/Android/Sdk/ndk/25.1.8937393 + +patcher;v4 + Description: SDK Patch Applier v4 + Version: 1 + Installed Location: /home/artem/Android/Sdk/patcher/v4 + +platforms;android-31 + Description: Android SDK Platform 31 + Version: 1 + Installed Location: /home/artem/Android/Sdk/platforms/android-31 + +system-images;android-33;google_apis;arm64-v8a + Description: Google APIs ARM 64 v8a System Image + Version: 8 + Installed Location: +/home/artem/Android/Sdk/system-images/android-33/google_apis/arm64-v8a + +Available Packages: +-------------------------------------- +add-ons;addon-google_apis-google-24 + Description: Google APIs + Version: 1 + +build-tools;33.0.1 + Description: Android SDK Build-Tools 33.0.1 + Version: 33.0.1 + +cmake;3.22.1 + Description: CMake 3.22.1 + Version: 3.22.1 + +cmdline-tools;9.0 + Description: Android SDK Command-line Tools + Version: 9.0 + +cmdline-tools;latest + Description: Android SDK Command-line Tools (latest) + Version: 9.0 + +emulator + Description: Android Emulator + Version: 31.3.14 + Dependencies: + patcher;v4 + +extras;android;m2repository + Description: Android Support Repository + Version: 47.0.0 + +ndk-bundle + Description: NDK + Version: 22.1.7171670 + Dependencies: + patcher;v4 + +ndk;25.0.8775105 + Description: NDK (Side by side) 25.0.8775105 + Version: 25.0.8775105 + Dependencies: + patcher;v4 + +ndk;25.1.8937393 + Description: NDK (Side by side) 25.1.8937393 + Version: 25.1.8937393 + Dependencies: + patcher;v4 + +patcher;v4 + Description: SDK Patch Applier v4 + Version: 1 + +platform-tools + Description: Android SDK Platform-Tools + Version: 33.0.3 + +platforms;android-33 + Description: Android SDK Platform 33 + Version: 2 + +platforms;android-33-ext4 + Description: Android SDK Platform 33 + Version: 1 + +platforms;android-9 + Description: Android SDK Platform 9 + Version: 2 + +platforms;android-TiramisuPrivacySandbox + Description: Android SDK Platform TiramisuPrivacySandbox + Version: 8 + +sources;android-32 + Description: Sources for Android 32 + Version: 1 + +sources;android-33 + Description: Sources for Android 33 + Version: 1 + +system-images;android-10;default;armeabi-v7a + Description: ARM EABI v7a System Image + Version: 5 + Dependencies: + patcher;v4 + +system-images;android-33-ext4;google_apis_playstore;arm64-v8a + Description: Google Play ARM 64 v8a System Image + Version: 1 + Dependencies: + patcher;v4 + emulator Revision 30.7.3 + +system-images;android-33-ext4;google_apis_playstore;x86_64 + Description: Google Play Intel x86 Atom_64 System Image + Version: 1 + Dependencies: + patcher;v4 + emulator Revision 30.7.3 + +system-images;android-33;android-tv;arm64-v8a + Description: Android TV ARM 64 v8a System Image + Version: 5 + Dependencies: + patcher;v4 + emulator Revision 28.1.6 + +system-images;android-33;android-tv;x86 + Description: Android TV Intel x86 Atom System Image + Version: 5 + Dependencies: + patcher;v4 + emulator Revision 28.1.6 + +system-images;android-33;google-tv;arm64-v8a + Description: Google TV ARM 64 v8a System Image + Version: 5 + Dependencies: + patcher;v4 + emulator Revision 28.1.6 + +system-images;android-33;google-tv;x86 + Description: Google TV Intel x86 Atom System Image + Version: 5 + Dependencies: + patcher;v4 + emulator Revision 28.1.6 + +system-images;android-33;google_apis;arm64-v8a + Description: Google APIs ARM 64 v8a System Image + Version: 8 + Dependencies: + patcher;v4 + emulator Revision 30.7.3 + +system-images;android-33;google_apis;x86_64 + Description: Google APIs Intel x86 Atom_64 System Image + Version: 8 + Dependencies: + patcher;v4 + emulator Revision 30.7.3 + +system-images;android-33;google_apis_playstore;arm64-v8a + Description: Google Play ARM 64 v8a System Image + Version: 7 + Dependencies: + patcher;v4 + emulator Revision 30.7.3 + +system-images;android-33;google_apis_playstore;x86_64 + Description: Google Play Intel x86 Atom_64 System Image + Version: 7 + Dependencies: + patcher;v4 + emulator Revision 30.7.3 + +system-images;android-TiramisuPrivacySandbox;google_apis_playstore;arm64-v8a + Description: Google Play ARM 64 v8a System Image + Version: 8 + Dependencies: + patcher;v4 + emulator Revision 30.7.3 + +system-images;android-TiramisuPrivacySandbox;google_apis_playstore;x86_64 + Description: Google Play Intel x86 Atom_64 System Image + Version: 8 + Dependencies: + patcher;v4 + emulator Revision 30.7.3 + +Available Updates: +-------------------------------------- +cmdline-tools;latest + Installed Version: 8.0 + Available Version: 9.)"); + +} + +} // namespace Android::Internal + diff --git a/src/plugins/android/sdkmanageroutputparser_test.h b/src/plugins/android/sdkmanageroutputparser_test.h new file mode 100644 index 00000000000..c2094e532a4 --- /dev/null +++ b/src/plugins/android/sdkmanageroutputparser_test.h @@ -0,0 +1,74 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#include "androidsdkpackage.h" + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +namespace Android { +namespace Internal { + +class SdkManagerOutputParser; + +class SdkManagerOutputParserTest : public QObject +{ + Q_OBJECT +public: + SdkManagerOutputParserTest(QObject *parent = nullptr); + ~SdkManagerOutputParserTest(); + +private: + AndroidSdkPackageList m_packages; + std::unique_ptr m_parser; + +private slots: + void testParsePackageListing_data(); + void testParsePackageListing(); + + void testParseMarkers_data(); + void testParseMarkers(); + + void testParseBuildToolsPackage_data(); + void testParseBuildToolsPackage(); + void testParseBuildToolsPackageEmpty(); + + void testParseSdkToolsPackage_data(); + void testParseSdkToolsPackage(); + void testParseSdkToolsPackageEmpty(); + + void testParsePlatformToolsPackage_data(); + void testParsePlatformToolsPackage(); + void testParsePlatformToolsPackageEmpty(); + + void testParseEmulatorToolsPackage_data(); + void testParseEmulatorToolsPackage(); + void testParseEmulatorToolsPackageEmpty(); + + void testParseNdkPackage_data(); + void testParseNdkPackage(); + void testParseNdkPackageEmpty(); + + void testParseExtraToolsPackage_data(); + void testParseExtraToolsPackage(); + void testParseExtraToolsPackageEmpty(); + + void testParseGenericToolsPackage_data(); + void testParseGenericToolsPackage(); + void testParseGenericToolsPackageEmpty(); + + void testParsePlatformPackage_data(); + void testParsePlatformPackage(); + void testParsePlatformPackageEmpty(); + + void testParseSystemImagePackage_data(); + void testParseSystemImagePackage(); + void testParseSystemImagePackageEmpty(); +}; +} // namespace Internal +} // namespace Android From 75071b1464ea02afbd7ace553d5b2740a7d8b13c Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Feb 2023 16:17:17 +0100 Subject: [PATCH 03/43] Qnx: Improve reading installed configuration for remote build devices Simplify the code in the process. In fact, looks like this was not doing much except setting the name and version number, which are not even really needed for building. Change-Id: Iafa65f0e2a0708888d1fc4ca19c932560ee4af68 Reviewed-by: Christian Stenger --- src/plugins/qnx/qnxconfiguration.cpp | 52 +++++++++++++------ src/plugins/qnx/qnxconfigurationmanager.cpp | 1 - src/plugins/qnx/qnxsettingspage.cpp | 3 +- src/plugins/qnx/qnxutils.cpp | 56 --------------------- src/plugins/qnx/qnxutils.h | 20 +------- 5 files changed, 39 insertions(+), 93 deletions(-) diff --git a/src/plugins/qnx/qnxconfiguration.cpp b/src/plugins/qnx/qnxconfiguration.cpp index 57bac90106b..8e8751ceb1d 100644 --- a/src/plugins/qnx/qnxconfiguration.cpp +++ b/src/plugins/qnx/qnxconfiguration.cpp @@ -27,13 +27,11 @@ #include #include -#include #include #include -#include +#include #include -#include using namespace ProjectExplorer; using namespace QtSupport; @@ -194,7 +192,7 @@ FilePath QnxConfiguration::sdpPath() const QnxQtVersion *QnxConfiguration::qnxQtVersion(const Target &target) const { - const QtVersions versions = QtVersionManager::instance()->versions( + const QtVersions versions = QtVersionManager::versions( Utils::equal(&QtVersion::type, QString::fromLatin1(Constants::QNX_QNX_QT))); for (QtVersion *version : versions) { auto qnxQt = dynamic_cast(version); @@ -336,19 +334,43 @@ void QnxConfiguration::setVersion(const QnxVersionNumber &version) void QnxConfiguration::readInformation() { - const QString qConfigPath = m_qnxConfiguration.pathAppended("qconfig").toString(); - const QList installInfoList = QnxUtils::installedConfigs(qConfigPath); - if (installInfoList.isEmpty()) + const FilePath configPath = m_qnxConfiguration / "qconfig"; + if (!configPath.isDir()) return; - for (const ConfigInstallInformation &info : installInfoList) { - if (m_qnxHost == FilePath::fromString(info.host).canonicalPath() - && m_qnxTarget == FilePath::fromString(info.target).canonicalPath()) { - m_configName = info.name; - setVersion(QnxVersionNumber(info.version)); - break; - } - } + configPath.iterateDirectory([this, configPath](const FilePath &sdpFile) { + QFile xmlFile(sdpFile.toFSPathString()); + if (!xmlFile.open(QIODevice::ReadOnly)) + return IterationPolicy::Continue; + + QDomDocument doc; + if (!doc.setContent(&xmlFile)) // Skip error message + return IterationPolicy::Continue; + + QDomElement docElt = doc.documentElement(); + if (docElt.tagName() != QLatin1String("qnxSystemDefinition")) + return IterationPolicy::Continue; + + QDomElement childElt = docElt.firstChildElement(QLatin1String("installation")); + // The file contains only one installation node + if (childElt.isNull()) // The file contains only one base node + return IterationPolicy::Continue; + + FilePath host = configPath.withNewPath( + childElt.firstChildElement(QLatin1String("host")).text()).canonicalPath(); + if (m_qnxHost != host) + return IterationPolicy::Continue; + + FilePath target = configPath.withNewPath( + childElt.firstChildElement(QLatin1String("target")).text()).canonicalPath(); + if (m_qnxTarget != target) + return IterationPolicy::Continue; + + m_configName = childElt.firstChildElement(QLatin1String("name")).text(); + QString version = childElt.firstChildElement(QLatin1String("version")).text(); + setVersion(QnxVersionNumber(version)); + return IterationPolicy::Stop; + }, {{"*.xml"}, QDir::Files}); } void QnxConfiguration::setDefaultConfiguration(const FilePath &envScript) diff --git a/src/plugins/qnx/qnxconfigurationmanager.cpp b/src/plugins/qnx/qnxconfigurationmanager.cpp index 7f8ed764b10..f947d4a6e25 100644 --- a/src/plugins/qnx/qnxconfigurationmanager.cpp +++ b/src/plugins/qnx/qnxconfigurationmanager.cpp @@ -99,7 +99,6 @@ void QnxConfigurationManager::saveConfigs() ++count; } - data.insert(QLatin1String(QNXConfigCountKey), count); m_writer->save(data, Core::ICore::dialogParent()); } diff --git a/src/plugins/qnx/qnxsettingspage.cpp b/src/plugins/qnx/qnxsettingspage.cpp index daaa03b6f90..e809ca876f7 100644 --- a/src/plugins/qnx/qnxsettingspage.cpp +++ b/src/plugins/qnx/qnxsettingspage.cpp @@ -130,8 +130,7 @@ void QnxSettingsWidget::addConfiguration() return; QnxConfiguration *config = new QnxConfiguration(envFile); - if (m_qnxConfigManager->configurations().contains(config) - || !config->isValid()) { + if (m_qnxConfigManager->configurations().contains(config) || !config->isValid()) { QMessageBox::warning(Core::ICore::dialogParent(), Tr::tr("Warning"), Tr::tr("Configuration already exists or is invalid.")); diff --git a/src/plugins/qnx/qnxutils.cpp b/src/plugins/qnx/qnxutils.cpp index 3e0f5106cec..d38fb976d89 100644 --- a/src/plugins/qnx/qnxutils.cpp +++ b/src/plugins/qnx/qnxutils.cpp @@ -10,9 +10,6 @@ #include #include -#include -#include -#include #include #include @@ -139,59 +136,6 @@ FilePath QnxUtils::envFilePath(const FilePath &sdpPath) return {}; } -QString QnxUtils::defaultTargetVersion(const QString &sdpPath) -{ - const QList configs = installedConfigs(); - for (const ConfigInstallInformation &sdpInfo : configs) { - if (!sdpInfo.path.compare(sdpPath, HostOsInfo::fileNameCaseSensitivity())) - return sdpInfo.version; - } - - return QString(); -} - -QList QnxUtils::installedConfigs(const QString &configPath) -{ - QList sdpList; - QString sdpConfigPath = configPath; - - if (!QDir(sdpConfigPath).exists()) - return sdpList; - - const QFileInfoList sdpfileList - = QDir(sdpConfigPath).entryInfoList(QStringList{"*.xml"}, QDir::Files, QDir::Time); - for (const QFileInfo &sdpFile : sdpfileList) { - QFile xmlFile(sdpFile.absoluteFilePath()); - if (!xmlFile.open(QIODevice::ReadOnly)) - continue; - - QDomDocument doc; - if (!doc.setContent(&xmlFile)) // Skip error message - continue; - - QDomElement docElt = doc.documentElement(); - if (docElt.tagName() != QLatin1String("qnxSystemDefinition")) - continue; - - QDomElement childElt = docElt.firstChildElement(QLatin1String("installation")); - // The file contains only one installation node - if (!childElt.isNull()) { - // The file contains only one base node - ConfigInstallInformation sdpInfo; - sdpInfo.path = childElt.firstChildElement(QLatin1String("base")).text(); - sdpInfo.name = childElt.firstChildElement(QLatin1String("name")).text(); - sdpInfo.host = childElt.firstChildElement(QLatin1String("host")).text(); - sdpInfo.target = childElt.firstChildElement(QLatin1String("target")).text(); - sdpInfo.version = childElt.firstChildElement(QLatin1String("version")).text(); - sdpInfo.installationXmlFilePath = sdpFile.absoluteFilePath(); - - sdpList.append(sdpInfo); - } - } - - return sdpList; -} - EnvironmentItems QnxUtils::qnxEnvironment(const FilePath &sdpPath) { return qnxEnvironmentFromEnvFile(envFilePath(sdpPath)); diff --git a/src/plugins/qnx/qnxutils.h b/src/plugins/qnx/qnxutils.h index ab108f72051..152d1d96ade 100644 --- a/src/plugins/qnx/qnxutils.h +++ b/src/plugins/qnx/qnxutils.h @@ -3,30 +3,14 @@ #pragma once -#include "qnxconstants.h" - #include #include #include -#include +#include namespace Qnx::Internal { -class ConfigInstallInformation -{ -public: - QString path; - QString name; - QString host; - QString target; - QString version; - QString installationXmlFilePath; - - bool isValid() { return !path.isEmpty() && !name.isEmpty() && !host.isEmpty() - && !target.isEmpty() && !version.isEmpty() && !installationXmlFilePath.isEmpty(); } -}; - class QnxTarget { public: @@ -45,8 +29,6 @@ public: static QString cpuDirShortDescription(const QString &cpuDir); static Utils::EnvironmentItems qnxEnvironmentFromEnvFile(const Utils::FilePath &filePath); static Utils::FilePath envFilePath(const Utils::FilePath &sdpPath); - static QString defaultTargetVersion(const QString &sdpPath); - static QList installedConfigs(const QString &configPath = QString()); static Utils::EnvironmentItems qnxEnvironment(const Utils::FilePath &sdpPath); static QList findTargets(const Utils::FilePath &basePath); static ProjectExplorer::Abi convertAbi(const ProjectExplorer::Abi &abi); From 5358249ed9ba6d3d13c60c8b31306c829065bc42 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Feb 2023 09:49:33 +0100 Subject: [PATCH 04/43] Qnx: Simplify QnxUtils Make a 'static' class a namespace, inline one function that's only used once. Change-Id: Ibaac2b677847dbc803bdfa50f483d6811182dcf1 Reviewed-by: Christian Stenger --- src/plugins/qnx/qnxutils.cpp | 13 ++++--------- src/plugins/qnx/qnxutils.h | 21 +++++++++------------ 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/plugins/qnx/qnxutils.cpp b/src/plugins/qnx/qnxutils.cpp index d38fb976d89..4e315b95a15 100644 --- a/src/plugins/qnx/qnxutils.cpp +++ b/src/plugins/qnx/qnxutils.cpp @@ -122,7 +122,7 @@ EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const FilePath &filePath) return items; } -FilePath QnxUtils::envFilePath(const FilePath &sdpPath) +EnvironmentItems QnxUtils::qnxEnvironment(const FilePath &sdpPath) { FilePaths entries; if (sdpPath.osType() == OsTypeWindows) @@ -130,15 +130,10 @@ FilePath QnxUtils::envFilePath(const FilePath &sdpPath) else entries = sdpPath.dirEntries({{"*-env.sh"}}); - if (!entries.isEmpty()) - return entries.first(); + if (entries.isEmpty()) + return {}; - return {}; -} - -EnvironmentItems QnxUtils::qnxEnvironment(const FilePath &sdpPath) -{ - return qnxEnvironmentFromEnvFile(envFilePath(sdpPath)); + return qnxEnvironmentFromEnvFile(entries.first()); } QList QnxUtils::findTargets(const FilePath &basePath) diff --git a/src/plugins/qnx/qnxutils.h b/src/plugins/qnx/qnxutils.h index 152d1d96ade..4f523953e46 100644 --- a/src/plugins/qnx/qnxutils.h +++ b/src/plugins/qnx/qnxutils.h @@ -22,17 +22,14 @@ public: ProjectExplorer::Abi m_abi; }; -class QnxUtils -{ -public: - static QString cpuDirFromAbi(const ProjectExplorer::Abi &abi); - static QString cpuDirShortDescription(const QString &cpuDir); - static Utils::EnvironmentItems qnxEnvironmentFromEnvFile(const Utils::FilePath &filePath); - static Utils::FilePath envFilePath(const Utils::FilePath &sdpPath); - static Utils::EnvironmentItems qnxEnvironment(const Utils::FilePath &sdpPath); - static QList findTargets(const Utils::FilePath &basePath); - static ProjectExplorer::Abi convertAbi(const ProjectExplorer::Abi &abi); - static ProjectExplorer::Abis convertAbis(const ProjectExplorer::Abis &abis); -}; +namespace QnxUtils { +QString cpuDirFromAbi(const ProjectExplorer::Abi &abi); +QString cpuDirShortDescription(const QString &cpuDir); +Utils::EnvironmentItems qnxEnvironmentFromEnvFile(const Utils::FilePath &filePath); +Utils::EnvironmentItems qnxEnvironment(const Utils::FilePath &sdpPath); +QList findTargets(const Utils::FilePath &basePath); +ProjectExplorer::Abi convertAbi(const ProjectExplorer::Abi &abi); +ProjectExplorer::Abis convertAbis(const ProjectExplorer::Abis &abis); +} } // Qnx::Internal From ae6ebe067e1237aac5888ed2fdfafb7f280eef18 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 22 Feb 2023 15:31:03 +0100 Subject: [PATCH 05/43] Android: Fix qbs build Amends 0c72395148c27891. Change-Id: I018e5a04bada7d3b8fd714c76fe3fac560880e0b Reviewed-by: David Schulz --- src/plugins/android/android.qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs index 3db92841863..5c9b6564c7b 100644 --- a/src/plugins/android/android.qbs +++ b/src/plugins/android/android.qbs @@ -124,7 +124,7 @@ Project { "androidsdkmanager_test.cpp", "androidsdkmanager_test.h", "sdkmanageroutputparser_test.cpp", - "sdkmanageroutputparser_test.h, + "sdkmanageroutputparser_test.h", ] } } From 0f49b488ee281c66e8111853610947c9fd3ef136 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 22 Feb 2023 15:41:05 +0100 Subject: [PATCH 06/43] Android: Fix compile with Qt6.2 Amends 0c72395148c27891. Change-Id: Ia4e074311e42fdb29d956bcd0cfce36e3aeda226 Reviewed-by: David Schulz --- .../android/sdkmanageroutputparser_test.cpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/plugins/android/sdkmanageroutputparser_test.cpp b/src/plugins/android/sdkmanageroutputparser_test.cpp index f7f2388b1fc..b3967acf1e0 100644 --- a/src/plugins/android/sdkmanageroutputparser_test.cpp +++ b/src/plugins/android/sdkmanageroutputparser_test.cpp @@ -94,7 +94,7 @@ void SdkManagerOutputParserTest::testParseBuildToolsPackage() BuildTools *actualBuildTools = m_parser->parseBuildToolsPackage(output); - QCOMPARE_NE(actualBuildTools, nullptr); + QVERIFY(actualBuildTools != nullptr); QCOMPARE(actualBuildTools->descriptionText(), description); QCOMPARE(actualBuildTools->displayText(), displayText); QCOMPARE(actualBuildTools->revision(), revision); @@ -104,7 +104,7 @@ void SdkManagerOutputParserTest::testParseBuildToolsPackageEmpty() { BuildTools *actualBuildTools = m_parser->parseBuildToolsPackage({""}); - QCOMPARE_EQ(actualBuildTools, nullptr); + QVERIFY(actualBuildTools == nullptr); } // SdkTools @@ -140,7 +140,7 @@ void SdkManagerOutputParserTest::testParseSdkToolsPackage() std::unique_ptr actualSdkTool(m_parser->parseSdkToolsPackage(output)); - QCOMPARE_NE(actualSdkTool, nullptr); + QVERIFY(actualSdkTool != nullptr); QCOMPARE(actualSdkTool->descriptionText(), description); QCOMPARE(actualSdkTool->displayText(), displayText); QCOMPARE(actualSdkTool->revision(), revision); @@ -150,7 +150,7 @@ void SdkManagerOutputParserTest::testParseSdkToolsPackageEmpty() { std::unique_ptr actualSdkTool(m_parser->parseSdkToolsPackage({""})); - QCOMPARE_EQ(actualSdkTool, nullptr); + QVERIFY(actualSdkTool == nullptr); } // PlatformTools @@ -180,7 +180,7 @@ void SdkManagerOutputParserTest::testParsePlatformToolsPackage() std::unique_ptr actualPlatformTool( m_parser->parsePlatformToolsPackage(output)); - QCOMPARE_NE(actualPlatformTool, nullptr); + QVERIFY(actualPlatformTool != nullptr); QCOMPARE(actualPlatformTool->descriptionText(), description); QCOMPARE(actualPlatformTool->displayText(), displayText); QCOMPARE(actualPlatformTool->revision(), revision); @@ -191,7 +191,7 @@ void SdkManagerOutputParserTest::testParsePlatformToolsPackageEmpty() std::unique_ptr actualPlatformTool( m_parser->parsePlatformToolsPackage({""})); - QCOMPARE_EQ(actualPlatformTool, nullptr); + QVERIFY(actualPlatformTool == nullptr); } // EmulatorTools @@ -219,7 +219,7 @@ void SdkManagerOutputParserTest::testParseEmulatorToolsPackage() std::unique_ptr actualEmulatorTools( m_parser->parseEmulatorToolsPackage(output)); - QCOMPARE_NE(actualEmulatorTools, nullptr); + QVERIFY(actualEmulatorTools != nullptr); QCOMPARE(actualEmulatorTools->descriptionText(), description); QCOMPARE(actualEmulatorTools->displayText(), displayText); QCOMPARE(actualEmulatorTools->revision(), revision); @@ -230,7 +230,7 @@ void SdkManagerOutputParserTest::testParseEmulatorToolsPackageEmpty() std::unique_ptr actualEmulatorTools( m_parser->parseEmulatorToolsPackage({""})); - QCOMPARE_EQ(actualEmulatorTools, nullptr); + QVERIFY(actualEmulatorTools == nullptr); } // NDK @@ -258,7 +258,7 @@ void SdkManagerOutputParserTest::testParseNdkPackage() std::unique_ptr actualNdkPackage(m_parser->parseNdkPackage(output)); - QCOMPARE_NE(actualNdkPackage, nullptr); + QVERIFY(actualNdkPackage != nullptr); QCOMPARE(actualNdkPackage->descriptionText(), description); QCOMPARE(actualNdkPackage->displayText(), displayText); QCOMPARE(actualNdkPackage->revision(), revision); @@ -268,7 +268,7 @@ void SdkManagerOutputParserTest::testParseNdkPackageEmpty() { std::unique_ptr actualNdkPackage(m_parser->parseNdkPackage({""})); - QCOMPARE_EQ(actualNdkPackage, nullptr); + QVERIFY(actualNdkPackage == nullptr); } // ExtraTools @@ -301,7 +301,7 @@ void SdkManagerOutputParserTest::testParseExtraToolsPackage() std::unique_ptr actualExtraTools( m_parser->parseExtraToolsPackage(output)); - QCOMPARE_NE(actualExtraTools, nullptr); + QVERIFY(actualExtraTools != nullptr); QCOMPARE(actualExtraTools->descriptionText(), description); QCOMPARE(actualExtraTools->displayText(), displayText); QCOMPARE(actualExtraTools->revision(), revision); @@ -312,7 +312,7 @@ void SdkManagerOutputParserTest::testParseExtraToolsPackageEmpty() std::unique_ptr actualExtraTools( m_parser->parseExtraToolsPackage({""})); - QCOMPARE_EQ(actualExtraTools, nullptr); + QVERIFY(actualExtraTools == nullptr); } // GenericTools @@ -342,7 +342,7 @@ void SdkManagerOutputParserTest::testParseGenericToolsPackage() std::unique_ptr actualGenericTools( m_parser->parseGenericTools(output)); - QCOMPARE_NE(actualGenericTools, nullptr); + QVERIFY(actualGenericTools != nullptr); QCOMPARE(actualGenericTools->descriptionText(), description); QCOMPARE(actualGenericTools->displayText(), displayText); QCOMPARE(actualGenericTools->revision(), revision); @@ -353,7 +353,7 @@ void SdkManagerOutputParserTest::testParseGenericToolsPackageEmpty() std::unique_ptr actualGenericTools( m_parser->parseGenericTools({""})); - QCOMPARE_EQ(actualGenericTools, nullptr); + QVERIFY(actualGenericTools == nullptr); } // Platform @@ -393,7 +393,7 @@ void SdkManagerOutputParserTest::testParsePlatformPackage() std::unique_ptr actualPlatform(m_parser->parsePlatform(output)); - QCOMPARE_NE(actualPlatform, nullptr); + QVERIFY(actualPlatform != nullptr); QCOMPARE(actualPlatform->descriptionText(), description); QCOMPARE(actualPlatform->installedLocation().path(), installLocation); QCOMPARE(actualPlatform->revision(), revision); @@ -404,7 +404,7 @@ void SdkManagerOutputParserTest::testParsePlatformPackageEmpty() { std::unique_ptr actualPlatform(m_parser->parsePlatform({""})); - QCOMPARE_EQ(actualPlatform, nullptr); + QVERIFY(actualPlatform == nullptr); } // SystemImage @@ -438,7 +438,7 @@ void SdkManagerOutputParserTest::testParseSystemImagePackage() SystemImage *actualSystemImage = actualSystemImagePair.first; - QCOMPARE_NE(actualSystemImage, nullptr); + QVERIFY(actualSystemImage != nullptr); QCOMPARE(actualSystemImage->descriptionText(), description); QCOMPARE(actualSystemImage->installedLocation().path(), installLocation); QCOMPARE(actualSystemImage->revision(), revision); @@ -450,7 +450,7 @@ void SdkManagerOutputParserTest::testParseSystemImagePackageEmpty() QPair actualSystemImagePair(m_parser->parseSystemImage({""})); SystemImage *actualSystemImage = actualSystemImagePair.first; - QCOMPARE_EQ(actualSystemImage, nullptr); + QVERIFY(actualSystemImage == nullptr); delete actualSystemImage; } void SdkManagerOutputParserTest::testParsePackageListing() From a759e400cc08efc1f7f9efd2782c50091bbc1d23 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 21 Feb 2023 13:45:30 +0100 Subject: [PATCH 07/43] Debugger: disable inheritance dumper tests for LLDB Change-Id: I6944d156cbef49838a6fcbae066d3a59f91325b7 Reviewed-by: David Schulz Reviewed-by: --- tests/auto/debugger/tst_dumpers.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 1e563d0a35b..c1d86644867 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -3576,10 +3576,10 @@ void tst_Dumpers::dumper_data() + Check("ptr50.data", "", "Foo") + Check("ptr53", "", "@QWeakPointer") - + Check("ptr60.data", "", "MyClass") - + Check("ptr61.data", "", "MyClass") - + Check("ptr60.data.val", "44", "int") - + Check("ptr61.data.val", "44", "int"); + + Check("ptr60.data", "", "MyClass") % NoLldbEngine + + Check("ptr61.data", "", "MyClass") % NoLldbEngine + + Check("ptr60.data.val", "44", "int") % NoLldbEngine + + Check("ptr61.data.val", "44", "int") % NoLldbEngine; QTest::newRow("QLazilyAllocated") @@ -7465,7 +7465,7 @@ void tst_Dumpers::dumper_data() + Check("dr.@2.c", "3", "int") + Check("dr.d", "4", "int") - + Check("array.0.val", "44", "int"); + + Check("array.0.val", "44", "int") % NoLldbEngine; QTest::newRow("Gdb13393") From db80574b2577a610d5171d23a086dbce56d6bc1d Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 2 Feb 2023 10:01:54 +0100 Subject: [PATCH 08/43] Utils: Use runBlocking() Change-Id: I9df8b8fcdc08129691cac818c779a73f47b789c6 Reviewed-by: Reviewed-by: Jarek Kobus --- src/libs/utils/deviceshell.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/utils/deviceshell.cpp b/src/libs/utils/deviceshell.cpp index f349e6db568..283e9789c00 100644 --- a/src/libs/utils/deviceshell.cpp +++ b/src/libs/utils/deviceshell.cpp @@ -87,9 +87,7 @@ RunResult DeviceShell::run(const CommandLine &cmd, const QByteArray &stdInData) qCDebug(deviceShellLog) << "Running fallback:" << fallbackCmd; proc.setCommand(fallbackCmd); proc.setWriteData(stdInData); - - proc.start(); - proc.waitForFinished(); + proc.runBlocking(); return RunResult{ proc.exitCode(), From 3d8b46685a5de6dfde3d37028eaf765522ea4f03 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Wed, 22 Feb 2023 12:44:05 +0200 Subject: [PATCH 09/43] MSVC: Enable exception handling for libs that use STL streams Sample warning: Building CXX object src\libs\qtcreatorcdbext\CMakeFiles\qtcreatorcdbext.dir\common.cpp.obj C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\ostream(342): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\ostream(335): note: while compiling class template member function 'std::basic_ostream> &std::basic_ostream>::operator <<(unsigned long)' F:\Projects\qt-creator\qt-creator\src\libs\qtcreatorcdbext\common.cpp(20): note: see reference to function template instantiation 'std::basic_ostream> &std::basic_ostream>::operator <<(unsigned long)' being compiled C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\sstream(655): note: see reference to class template instantiation 'std::basic_ostream>' being compiled Change-Id: I26508048a875aabe4c5b80ef4cccfe091a2a145e Reviewed-by: David Schulz --- cmake/Findyaml-cpp.cmake | 2 +- src/libs/qtcreatorcdbext/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/Findyaml-cpp.cmake b/cmake/Findyaml-cpp.cmake index e6b65053bfe..e7b3d361d3b 100644 --- a/cmake/Findyaml-cpp.cmake +++ b/cmake/Findyaml-cpp.cmake @@ -124,7 +124,7 @@ else() set(yaml-cpp_FOUND 1) set_package_properties(yaml-cpp PROPERTIES DESCRIPTION "using internal src/libs/3rdparty/yaml-cpp") if(MSVC) - target_compile_options(yaml-cpp PUBLIC /wd4251 /wd4275) + target_compile_options(yaml-cpp PUBLIC /wd4251 /wd4275 /EHsc) endif() endif() unset(YAML_SOURCE_DIR) diff --git a/src/libs/qtcreatorcdbext/CMakeLists.txt b/src/libs/qtcreatorcdbext/CMakeLists.txt index ba6508c43e0..7bf3bcc9e89 100644 --- a/src/libs/qtcreatorcdbext/CMakeLists.txt +++ b/src/libs/qtcreatorcdbext/CMakeLists.txt @@ -54,6 +54,7 @@ qtc_library_enabled(_library_enabled qtcreatorcdbext) if (_library_enabled) # statically link MSVC runtime set_property(TARGET qtcreatorcdbext PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + target_compile_options(qtcreatorcdbext PUBLIC /EHsc) find_package(Python3 3.8 COMPONENTS Development) From a8e424f75e7644faf86379749c1f9551cbbfc648 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 22 Feb 2023 16:57:00 +0100 Subject: [PATCH 10/43] Doc: Select the tool to automatically format QML files For example, qmlformat. Task-number: QTCREATORBUG-28721 Change-Id: I509cba3fd842f94e7656a3356cc1de81e41fd8e2 Reviewed-by: Reviewed-by: Eike Ziller --- .../images/qtcreator-qml-js-editing.png | Bin 5888 -> 0 bytes .../images/qtcreator-qml-js-editing.webp | Bin 0 -> 6992 bytes .../src/editors/creator-code-syntax.qdoc | 10 +++++++++- doc/qtcreator/src/qtquick/qtquick-toolbars.qdoc | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) delete mode 100644 doc/qtcreator/images/qtcreator-qml-js-editing.png create mode 100644 doc/qtcreator/images/qtcreator-qml-js-editing.webp diff --git a/doc/qtcreator/images/qtcreator-qml-js-editing.png b/doc/qtcreator/images/qtcreator-qml-js-editing.png deleted file mode 100644 index 731c97f1c2328ed4c1add9e21e9890c4cc851e0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5888 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 diff --git a/doc/qtcreator/images/qtcreator-qml-js-editing.webp b/doc/qtcreator/images/qtcreator-qml-js-editing.webp new file mode 100644 index 0000000000000000000000000000000000000000..ab9a9f48422b32447096eff9ea2a254091fffc0d GIT binary patch literal 6992 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 XKKwhw&g$Rvm$OAre|dZ5JUasbPi4G8 literal 0 HcmV?d00001 diff --git a/doc/qtcreator/src/editors/creator-code-syntax.qdoc b/doc/qtcreator/src/editors/creator-code-syntax.qdoc index 609e2837915..791bb4fc295 100644 --- a/doc/qtcreator/src/editors/creator-code-syntax.qdoc +++ b/doc/qtcreator/src/editors/creator-code-syntax.qdoc @@ -729,8 +729,16 @@ To automatically format QML/JS files upon saving, select \uicontrol Edit > \uicontrol Preferences > \uicontrol {Qt Quick} > \uicontrol {QML/JS Editing} > \uicontrol {Enable auto format on file save}. + To only format files that belong to the current project, select + \uicontrol {Restrict to files contained in the current project}. - \image qtcreator-qml-js-editing.png "QML/JS Editing preferences" + To use an external tool, such as \l {qmlformat}, which automatically + formats QML files according to QML coding conventions, select + \uicontrol {Use custom command instead of built-in formatter}. In + the \uicontrol Command field, enter the path to the tool. In the + \uicontrol Arguments field, enter options for running the tool. + + \image qtcreator-qml-js-editing.webp {QML/JS Editing preferences} \if defined(qtcreator) \section1 Inspecting Preprocessed C++ Code diff --git a/doc/qtcreator/src/qtquick/qtquick-toolbars.qdoc b/doc/qtcreator/src/qtquick/qtquick-toolbars.qdoc index 674a733357f..a1eea8edfb2 100644 --- a/doc/qtcreator/src/qtquick/qtquick-toolbars.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-toolbars.qdoc @@ -26,7 +26,7 @@ \uicontrol Edit > \uicontrol Preferences > \uicontrol {Qt Quick} > \uicontrol {QML/JS Editing} > \uicontrol {Always show Qt Quick Toolbar}. - \image qtcreator-qml-js-editing.png "QML/JS Editing preferences" + \image qtcreator-qml-js-editing.webp {QML/JS Editing preferences} Drag the toolbar to pin it to another location. Select \inlineimage icons/pin.png From 08ace8288a66fce30e6bd02a0f2ea9f21713fcad Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 23 Feb 2023 09:58:17 +0100 Subject: [PATCH 11/43] Avoid triggering device login from recent project list We filter the list of recent projects for existing files, but for remote projects that triggers a login request directly at startup. Just don't check projects on devices. Change-Id: I786745a7bee9c8984b926886bcae9fe825f7649a Reviewed-by: Marcus Tillmanns --- src/plugins/projectexplorer/projectexplorer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index d2fee3f2bda..f76f10175b6 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -2725,7 +2725,8 @@ void ProjectExplorerPluginPrivate::buildQueueFinished(bool success) RecentProjectsEntries ProjectExplorerPluginPrivate::recentProjects() const { return Utils::filtered(dd->m_recentProjects, [](const RecentProjectsEntry &p) { - return p.first.isFile(); + // check if project is available, but avoid querying devices + return p.first.needsDevice() || p.first.isFile(); }); } From 3048a14cebb026334f6a8948903de07a4a527c07 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 22 Feb 2023 17:17:57 +0100 Subject: [PATCH 12/43] Doc: Update info about using QML language server You can enable it in QML/JS Editing preferences. Task-number: QTCREATORBUG-28721 Change-Id: I64b8692fb7a69bd897364b370835ef1e2b3f79ef Reviewed-by: David Schulz --- .../creator-only/creator-language-server.qdoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/qtcreator/src/editors/creator-only/creator-language-server.qdoc b/doc/qtcreator/src/editors/creator-only/creator-language-server.qdoc index 99dcfb69eac..248569aa78d 100644 --- a/doc/qtcreator/src/editors/creator-only/creator-language-server.qdoc +++ b/doc/qtcreator/src/editors/creator-only/creator-language-server.qdoc @@ -149,14 +149,14 @@ \section2 QML Language Server - Qt 6.4 ships with the \c qmlls language server that offers completion and - issues warnings for QML. To set it up as a \l {Generic StdIO Language Server}, - select \c {text/x-qml} and \c {application/x-qt.ui+qml} as MIME types, and - \c {/bin/qmlls} as executable. + Since Qt 6.4, the \c qmlls language server offers code completion and + issues warnings for QML. To enable QML language server support, select + \uicontrol Edit > \uicontrol Preferences > \uicontrol {Qt Quick} > + \uicontrol {QML/JS Editing} > \uicontrol {Use qmlls (EXPERIMENTAL!)}. + To use the latest version of the language server installed on your + system, select the \uicontrol {Always use latest qmlls} check box. - If the language server is used together with the \c QmlJSEditor plugin, - duplicate suggestions and warnings might be shown. To avoid this, disable - the editor plugin as described in \l {Enabling and Disabling Plugins}. + \image qtcreator-qml-js-editing.webp {QML/JS Editing preferences} \section1 Supported Locator Filters From ef731faa4784af8323b8c747730bcf9674c70026 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Feb 2023 08:23:18 +0100 Subject: [PATCH 13/43] Coding style: Avoid empty round brackets in lambdas Remove outdated rules. Use QList instead of QVector. Change-Id: I11ea6be09080ddccfdcfc3d09f79cbeff448659e Reviewed-by: Leena Miettinen Reviewed-by: hjk --- doc/qtcreatordev/src/coding-style.qdoc | 59 ++++++++++---------------- 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/doc/qtcreatordev/src/coding-style.qdoc b/doc/qtcreatordev/src/coding-style.qdoc index 1aed25bc3ef..02636e3ab59 100644 --- a/doc/qtcreatordev/src/coding-style.qdoc +++ b/doc/qtcreatordev/src/coding-style.qdoc @@ -741,43 +741,28 @@ \section3 Lambdas - When using lambdas, note the following: - - \list - \li You do not have to explicitly specify the return type. If you are not using one - of the previously mentioned compilers, do note that this is a C++14 feature and you - might need to enable C++14 support in your compiler. - \code - []() { - Foo *foo = activeFoo(); - return foo ? foo->displayName() : QString(); - }); - \endcode - - \li If you use static functions from the class that the lambda is located in, you have to - explicitly capture \c this. Otherwise it does not compile with g++ 4.7 and earlier. - \code - void Foo::something() - { - ... - [this]() { Foo::someStaticFunction(); } - ... - } - - -NOT- - - void Foo::something() - { - ... - []() { Foo::someStaticFunction(); } - ... - } - \endcode - \endlist - Format the lambda according to the following rules: \list + \li When the lambda neither takes arguments nor specifies a return type, + drop round brackets. + \code + [] { ... lambda body ... } + + -NOT- + + []() { ... lambda body ... } + \endcode + + \li Glue square brackets with round brackets when defining a lambda. + \code + [](int a) { ... lambda body ... } + + -NOT- + + [] (int a) { ... lambda body ... } + \endcode + \li Place the capture-list, parameter list, return type, and opening brace on the first line, the body indented on the following lines, and the closing brace on a new line. \code @@ -795,7 +780,7 @@ \li Place a closing parenthesis and semicolon of an enclosing function call on the same line as the closing brace of the lambda. \code - foo([]() { + foo([] { something(); }); \endcode @@ -866,7 +851,7 @@ Use initializer lists to initialize containers, for example: \code - const QVector values = {1, 2, 3, 4, 5}; + const QList values = {1, 2, 3, 4, 5}; \endcode \section3 Initialization with Curly Brackets @@ -878,7 +863,7 @@ class Values // the following code is quite useful for test fixtures { float floatValue = 4; // prefer that for simple types - QVector values = {1, 2, 3, 4, integerValue}; // prefer that syntax for initializer lists + QList values = {1, 2, 3, 4, integerValue}; // prefer that syntax for initializer lists SomeValues someValues{"One", 2, 3.4}; // not an initializer_list SomeValues &someValuesReference = someValues; ComplexType complexType{values, otherValues} // constructor call From 3a7ab3ce8e4a3270de557ea377370a0342f33a9f Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 22 Feb 2023 13:49:54 +0100 Subject: [PATCH 14/43] SquishTests: Rename helper class Change-Id: I39890cbd98b7e6ebcc0fdf4722d0311eb6650397 Reviewed-by: David Schulz --- tests/system/shared/classes.py | 22 +++++++++---------- tests/system/shared/project.py | 2 +- tests/system/suite_CCOM/tst_CCOM01/test.py | 2 +- tests/system/suite_CCOM/tst_CCOM02/test.py | 2 +- tests/system/suite_CSUP/tst_CSUP04/test.py | 2 +- tests/system/suite_CSUP/tst_CSUP05/test.py | 2 +- tests/system/suite_HELP/tst_HELP04/test.py | 2 +- tests/system/suite_HELP/tst_HELP05/test.py | 2 +- tests/system/suite_QMLS/tst_QMLS03/test.py | 2 +- tests/system/suite_WELP/tst_WELP02/test.py | 2 +- tests/system/suite_WELP/tst_WELP03/test.py | 6 ++--- .../suite_editors/tst_qml_editor/test.py | 4 ++-- .../suite_general/tst_rename_file/test.py | 2 +- .../tst_session_handling/test.py | 4 ++-- .../suite_qtquick/tst_qml_outline/test.py | 2 +- 15 files changed, 29 insertions(+), 29 deletions(-) diff --git a/tests/system/shared/classes.py b/tests/system/shared/classes.py index 37a3b812fa1..49026fa425d 100644 --- a/tests/system/shared/classes.py +++ b/tests/system/shared/classes.py @@ -75,7 +75,7 @@ class LibType: return "Qt Plugin" return None -class Qt5Path: +class QtPath: DOCS = 0 EXAMPLES = 1 @@ -84,10 +84,10 @@ class Qt5Path: qt5targets = [Targets.DESKTOP_5_10_1_DEFAULT, Targets.DESKTOP_5_14_1_DEFAULT] if platform.system() != 'Darwin': qt5targets.append(Targets.DESKTOP_5_4_1_GCC) - if pathSpec == Qt5Path.DOCS: - return map(lambda target: Qt5Path.docsPath(target), qt5targets) - elif pathSpec == Qt5Path.EXAMPLES: - return map(lambda target: Qt5Path.examplesPath(target), qt5targets) + if pathSpec == QtPath.DOCS: + return map(lambda target: QtPath.docsPath(target), qt5targets) + elif pathSpec == QtPath.EXAMPLES: + return map(lambda target: QtPath.examplesPath(target), qt5targets) else: test.fatal("Unknown pathSpec given: %s" % str(pathSpec)) return [] @@ -116,29 +116,29 @@ class Qt5Path: @staticmethod def getQtMinorAndPatchVersion(target): - qtVersionStr = Qt5Path.__preCheckAndExtractQtVersionStr__(target) - versionTuple = Qt5Path.toVersionTuple(qtVersionStr) + qtVersionStr = QtPath.__preCheckAndExtractQtVersionStr__(target) + versionTuple = QtPath.toVersionTuple(qtVersionStr) return versionTuple[1], versionTuple[2] @staticmethod def examplesPath(target): - qtMinorVersion, qtPatchVersion = Qt5Path.getQtMinorAndPatchVersion(target) + qtMinorVersion, qtPatchVersion = QtPath.getQtMinorAndPatchVersion(target) if qtMinorVersion < 10: path = "Examples/Qt-5.%d" % qtMinorVersion else: path = "Examples/Qt-5.%d.%d" % (qtMinorVersion, qtPatchVersion) - return os.path.join(Qt5Path.__createPlatformQtPath__(qtMinorVersion), path) + return os.path.join(QtPath.__createPlatformQtPath__(qtMinorVersion), path) @staticmethod def docsPath(target): - qtMinorVersion, qtPatchVersion = Qt5Path.getQtMinorAndPatchVersion(target) + qtMinorVersion, qtPatchVersion = QtPath.getQtMinorAndPatchVersion(target) if qtMinorVersion < 10: path = "Docs/Qt-5.%d" % qtMinorVersion else: path = "Docs/Qt-5.%d.%d" % (qtMinorVersion, qtPatchVersion) - return os.path.join(Qt5Path.__createPlatformQtPath__(qtMinorVersion), path) + return os.path.join(QtPath.__createPlatformQtPath__(qtMinorVersion), path) class TestSection: def __init__(self, description): diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index 2e12ac9c627..0ee2db614d6 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -188,7 +188,7 @@ def __modifyAvailableTargets__(available, requiredQt, asStrings=False): item = Targets.getStringForTarget(currentItem) found = versionFinder.search(item) if found: - if Qt5Path.toVersionTuple(found.group(1)) < Qt5Path.toVersionTuple(requiredQt): + if QtPath.toVersionTuple(found.group(1)) < QtPath.toVersionTuple(requiredQt): available.discard(currentItem) elif currentItem.endswith(" (invalid)"): available.discard(currentItem) diff --git a/tests/system/suite_CCOM/tst_CCOM01/test.py b/tests/system/suite_CCOM/tst_CCOM01/test.py index 5fe2647a852..1168ca94a50 100644 --- a/tests/system/suite_CCOM/tst_CCOM01/test.py +++ b/tests/system/suite_CCOM/tst_CCOM01/test.py @@ -6,7 +6,7 @@ source("../../shared/qtcreator.py") # entry of test def main(): # prepare example project - sourceExample = os.path.join(Qt5Path.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), + sourceExample = os.path.join(QtPath.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), "quick", "animation") proFile = "animation.pro" if not neededFilePresent(os.path.join(sourceExample, proFile)): diff --git a/tests/system/suite_CCOM/tst_CCOM02/test.py b/tests/system/suite_CCOM/tst_CCOM02/test.py index 011d576a599..491f8770d03 100644 --- a/tests/system/suite_CCOM/tst_CCOM02/test.py +++ b/tests/system/suite_CCOM/tst_CCOM02/test.py @@ -7,7 +7,7 @@ source("../../shared/qtcreator.py") # entry of test def main(): # prepare example project - sourceExample = os.path.join(Qt5Path.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), + sourceExample = os.path.join(QtPath.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), "quick", "animation") proFile = "animation.pro" if not neededFilePresent(os.path.join(sourceExample, proFile)): diff --git a/tests/system/suite_CSUP/tst_CSUP04/test.py b/tests/system/suite_CSUP/tst_CSUP04/test.py index cf96aaf9a36..efede6848bb 100644 --- a/tests/system/suite_CSUP/tst_CSUP04/test.py +++ b/tests/system/suite_CSUP/tst_CSUP04/test.py @@ -6,7 +6,7 @@ source("../../shared/qtcreator.py") # entry of test def main(): # prepare example project - sourceExample = os.path.join(Qt5Path.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), + sourceExample = os.path.join(QtPath.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), "gui", "openglwindow") proFile = "openglwindow.pro" diff --git a/tests/system/suite_CSUP/tst_CSUP05/test.py b/tests/system/suite_CSUP/tst_CSUP05/test.py index 33b804503fb..e67d563b44c 100644 --- a/tests/system/suite_CSUP/tst_CSUP05/test.py +++ b/tests/system/suite_CSUP/tst_CSUP05/test.py @@ -6,7 +6,7 @@ source("../../shared/qtcreator.py") # entry of test def main(): # prepare example project - sourceExample = os.path.join(Qt5Path.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), + sourceExample = os.path.join(QtPath.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), "gui", "openglwindow") proFile = "openglwindow.pro" if not neededFilePresent(os.path.join(sourceExample, proFile)): diff --git a/tests/system/suite_HELP/tst_HELP04/test.py b/tests/system/suite_HELP/tst_HELP04/test.py index 40370622149..e4c0500d234 100644 --- a/tests/system/suite_HELP/tst_HELP04/test.py +++ b/tests/system/suite_HELP/tst_HELP04/test.py @@ -48,7 +48,7 @@ def main(): if not startedWithoutPluginError(): return docFiles = ["qtdoc.qch", "qtsql.qch"] - docFiles = [os.path.join(Qt5Path.docsPath(Targets.DESKTOP_5_14_1_DEFAULT), file) for file in docFiles] + docFiles = [os.path.join(QtPath.docsPath(Targets.DESKTOP_5_14_1_DEFAULT), file) for file in docFiles] addHelpDocumentation(docFiles) # switch to help mode switchViewTo(ViewConstants.HELP) diff --git a/tests/system/suite_HELP/tst_HELP05/test.py b/tests/system/suite_HELP/tst_HELP05/test.py index d8232b5d6e2..7facd9635af 100644 --- a/tests/system/suite_HELP/tst_HELP05/test.py +++ b/tests/system/suite_HELP/tst_HELP05/test.py @@ -25,7 +25,7 @@ def main(): if not startedWithoutPluginError(): return qchs = [] - for p in Qt5Path.getPaths(Qt5Path.DOCS): + for p in QtPath.getPaths(QtPath.DOCS): qchs.append(os.path.join(p, "qtquick.qch")) addHelpDocumentation(qchs) setFixedHelpViewer(HelpViewer.SIDEBYSIDE) diff --git a/tests/system/suite_QMLS/tst_QMLS03/test.py b/tests/system/suite_QMLS/tst_QMLS03/test.py index 5273984a84b..be01c125dec 100644 --- a/tests/system/suite_QMLS/tst_QMLS03/test.py +++ b/tests/system/suite_QMLS/tst_QMLS03/test.py @@ -45,7 +45,7 @@ def checkUsages(resultsView, expectedResults, directory): def main(): # prepare example project - sourceExample = os.path.join(Qt5Path.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), + sourceExample = os.path.join(QtPath.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), "quick", "animation") proFile = "animation.pro" if not neededFilePresent(os.path.join(sourceExample, proFile)): diff --git a/tests/system/suite_WELP/tst_WELP02/test.py b/tests/system/suite_WELP/tst_WELP02/test.py index 25b1f725ef7..d79391d1213 100644 --- a/tests/system/suite_WELP/tst_WELP02/test.py +++ b/tests/system/suite_WELP/tst_WELP02/test.py @@ -43,7 +43,7 @@ def checkTypeAndProperties(typePropertiesDetails): def main(): # prepare example project - sourceExample = os.path.join(Qt5Path.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), + sourceExample = os.path.join(QtPath.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), "quick", "animation") if not neededFilePresent(sourceExample): return diff --git a/tests/system/suite_WELP/tst_WELP03/test.py b/tests/system/suite_WELP/tst_WELP03/test.py index bb96a8be45d..3b60d15a2e2 100644 --- a/tests/system/suite_WELP/tst_WELP03/test.py +++ b/tests/system/suite_WELP/tst_WELP03/test.py @@ -41,7 +41,7 @@ def main(): if not startedWithoutPluginError(): return qchs = [] - for p in Qt5Path.getPaths(Qt5Path.DOCS): + for p in QtPath.getPaths(QtPath.DOCS): qchs.extend([os.path.join(p, "qtopengl.qch"), os.path.join(p, "qtwidgets.qch")]) addHelpDocumentation(qchs) setFixedHelpViewer(HelpViewer.HELPMODE) @@ -72,7 +72,7 @@ def main(): test.verify(example is None, "Verifying: No example is shown.") proFiles = [os.path.join(p, "opengl", "2dpainting", "2dpainting.pro") - for p in Qt5Path.getPaths(Qt5Path.EXAMPLES)] + for p in QtPath.getPaths(QtPath.EXAMPLES)] cleanUpUserFiles(proFiles) for p in proFiles: removePackagingDirectory(os.path.dirname(p)) @@ -94,7 +94,7 @@ def main(): # go to "Welcome" page and choose another example switchViewTo(ViewConstants.WELCOME) proFiles = [os.path.join(p, "widgets", "itemviews", "addressbook", "addressbook.pro") - for p in Qt5Path.getPaths(Qt5Path.EXAMPLES)] + for p in QtPath.getPaths(QtPath.EXAMPLES)] cleanUpUserFiles(proFiles) for p in proFiles: removePackagingDirectory(os.path.dirname(p)) diff --git a/tests/system/suite_editors/tst_qml_editor/test.py b/tests/system/suite_editors/tst_qml_editor/test.py index ca634d0f4b9..1cfa67e066d 100644 --- a/tests/system/suite_editors/tst_qml_editor/test.py +++ b/tests/system/suite_editors/tst_qml_editor/test.py @@ -7,7 +7,7 @@ focusDocumentPath = "keyinteraction.Resources.keyinteraction\.qrc./keyinteractio def main(): target = Targets.DESKTOP_5_14_1_DEFAULT - sourceExample = os.path.join(Qt5Path.examplesPath(target), "quick/keyinteraction") + sourceExample = os.path.join(QtPath.examplesPath(target), "quick/keyinteraction") proFile = "keyinteraction.pro" if not neededFilePresent(os.path.join(sourceExample, proFile)): return @@ -15,7 +15,7 @@ def main(): if not startedWithoutPluginError(): return # add docs to have the correct tool tips - addHelpDocumentation([os.path.join(Qt5Path.docsPath(target), "qtquick.qch")]) + addHelpDocumentation([os.path.join(QtPath.docsPath(target), "qtquick.qch")]) templateDir = prepareTemplate(sourceExample) openQmakeProject(os.path.join(templateDir, proFile), [target]) openDocument(focusDocumentPath % "focus\\.qml") diff --git a/tests/system/suite_general/tst_rename_file/test.py b/tests/system/suite_general/tst_rename_file/test.py index 5fa8c416c28..693303553a6 100644 --- a/tests/system/suite_general/tst_rename_file/test.py +++ b/tests/system/suite_general/tst_rename_file/test.py @@ -6,7 +6,7 @@ source("../../shared/qtcreator.py") def main(): # prepare example project projectName = "adding" - sourceExample = os.path.join(Qt5Path.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), + sourceExample = os.path.join(QtPath.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), "qml", "referenceexamples", "adding") proFile = projectName + ".pro" if not neededFilePresent(os.path.join(sourceExample, proFile)): diff --git a/tests/system/suite_general/tst_session_handling/test.py b/tests/system/suite_general/tst_session_handling/test.py index d1782c69cea..1e4b9af0fac 100644 --- a/tests/system/suite_general/tst_session_handling/test.py +++ b/tests/system/suite_general/tst_session_handling/test.py @@ -45,9 +45,9 @@ def main(): invokeMenuItem("File", "Exit") def prepareTestExamples(): - examples = [os.path.join(Qt5Path.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), + examples = [os.path.join(QtPath.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), "quick", "animation", "animation.pro"), - os.path.join(Qt5Path.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), + os.path.join(QtPath.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), "quick", "keyinteraction", "keyinteraction.pro") ] projects = [] diff --git a/tests/system/suite_qtquick/tst_qml_outline/test.py b/tests/system/suite_qtquick/tst_qml_outline/test.py index f495c786591..1508dc9aaa8 100644 --- a/tests/system/suite_qtquick/tst_qml_outline/test.py +++ b/tests/system/suite_qtquick/tst_qml_outline/test.py @@ -8,7 +8,7 @@ outline = ":Qt Creator_QmlJSEditor::Internal::QmlJSOutlineTreeView" treebase = "keyinteraction.Resources.keyinteraction\\.qrc./keyinteraction.focus." def main(): - sourceExample = os.path.join(Qt5Path.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), + sourceExample = os.path.join(QtPath.examplesPath(Targets.DESKTOP_5_14_1_DEFAULT), "quick", "keyinteraction") proFile = "keyinteraction.pro" if not neededFilePresent(os.path.join(sourceExample, proFile)): From 0604027834b04df7407785715741fe958762f49b Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 22 Feb 2023 14:40:41 +0100 Subject: [PATCH 15/43] SquishTests: Fix path handling for pre-installed Qts There is now a Qt6 and a new possible location. Change-Id: I4feac6da2756bde77e98ce08f945ddefec7e2fb4 Reviewed-by: David Schulz --- tests/system/shared/classes.py | 52 +++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/tests/system/shared/classes.py b/tests/system/shared/classes.py index 49026fa425d..dcc702295b4 100644 --- a/tests/system/shared/classes.py +++ b/tests/system/shared/classes.py @@ -21,6 +21,10 @@ class Targets: "Desktop 5.14.1 default", "Desktop 6.2.4"])) + @staticmethod + def isOnlineInstaller(target): + return target == Targets.DESKTOP_6_2_4 + @staticmethod def availableTargetClasses(ignoreValidity=False): availableTargets = set(Targets.ALL_TARGETS) @@ -81,13 +85,14 @@ class QtPath: @staticmethod def getPaths(pathSpec): - qt5targets = [Targets.DESKTOP_5_10_1_DEFAULT, Targets.DESKTOP_5_14_1_DEFAULT] + qtTargets = [Targets.DESKTOP_5_10_1_DEFAULT, Targets.DESKTOP_5_14_1_DEFAULT, + Targets.DESKTOP_6_2_4] if platform.system() != 'Darwin': - qt5targets.append(Targets.DESKTOP_5_4_1_GCC) + qtTargets.append(Targets.DESKTOP_5_4_1_GCC) if pathSpec == QtPath.DOCS: - return map(lambda target: QtPath.docsPath(target), qt5targets) + return map(lambda target: QtPath.docsPath(target), qtTargets) elif pathSpec == QtPath.EXAMPLES: - return map(lambda target: QtPath.examplesPath(target), qt5targets) + return map(lambda target: QtPath.examplesPath(target), qtTargets) else: test.fatal("Unknown pathSpec given: %s" % str(pathSpec)) return [] @@ -97,9 +102,9 @@ class QtPath: if target not in Targets.ALL_TARGETS: raise Exception("Unexpected target '%s'" % str(target)) - matcher = re.match("^Desktop (5\.\\d{1,2}\.\\d{1,2}).*$", Targets.getStringForTarget(target)) + matcher = re.match("^Desktop ([56]\.\\d{1,2}\.\\d{1,2}).*$", Targets.getStringForTarget(target)) if matcher is None: - raise Exception("Currently this is supported for Desktop Qt5 only, got target '%s'" + raise Exception("Currently this is supported for Desktop Qt5/Qt6 only, got target '%s'" % str(Targets.getStringForTarget(target))) return matcher.group(1) @@ -110,34 +115,49 @@ class QtPath: else: return os.path.expanduser("~/Qt5.%d.1" % qt5Minor) + @staticmethod + def __createQtOnlineInstallerPath__(): + qtBasePath = os.getenv('SYSTEST_QTOI_BASEPATH', None) + if qtBasePath is None: + qtBasePath = 'C:/Qt' if platform.system() in ('Microsoft', 'Windows') else '~/Qt' + qtBasePath = os.path.expanduser(qtBasePath) + if not os.path.exists(qtBasePath): + test.fatal("Unexpected Qt install path '%s'" % qtBasePath) + return "" + return qtBasePath + @staticmethod def toVersionTuple(versionString): return tuple(map(__builtin__.int, versionString.split("."))) @staticmethod - def getQtMinorAndPatchVersion(target): + def getQtVersion(target): qtVersionStr = QtPath.__preCheckAndExtractQtVersionStr__(target) versionTuple = QtPath.toVersionTuple(qtVersionStr) - return versionTuple[1], versionTuple[2] + return versionTuple @staticmethod def examplesPath(target): - qtMinorVersion, qtPatchVersion = QtPath.getQtMinorAndPatchVersion(target) - if qtMinorVersion < 10: - path = "Examples/Qt-5.%d" % qtMinorVersion + qtMajorVersion, qtMinorVersion, qtPatchVersion = QtPath.getQtVersion(target) + if qtMajorVersion == 5 and qtMinorVersion < 10: + path = "Examples/Qt-%d.%d" % (qtMajorVersion, qtMinorVersion) else: - path = "Examples/Qt-5.%d.%d" % (qtMinorVersion, qtPatchVersion) + path = "Examples/Qt-%d.%d.%d" % (qtMajorVersion, qtMinorVersion, qtPatchVersion) + if Targets.isOnlineInstaller(target): + return os.path.join(QtPath.__createQtOnlineInstallerPath__(), path) return os.path.join(QtPath.__createPlatformQtPath__(qtMinorVersion), path) @staticmethod def docsPath(target): - qtMinorVersion, qtPatchVersion = QtPath.getQtMinorAndPatchVersion(target) - if qtMinorVersion < 10: - path = "Docs/Qt-5.%d" % qtMinorVersion + qtMajorVersion, qtMinorVersion, qtPatchVersion = QtPath.getQtVersion(target) + if qtMajorVersion == 5 and qtMinorVersion < 10: + path = "Docs/Qt-%d.%d" % (qtMajorVersion, qtMinorVersion) else: - path = "Docs/Qt-5.%d.%d" % (qtMinorVersion, qtPatchVersion) + path = "Docs/Qt-%d.%d.%d" % (qtMajorVersion, qtMinorVersion, qtPatchVersion) + if Targets.isOnlineInstaller(target): + return os.path.join(QtPath.__createQtOnlineInstallerPath__(), path) return os.path.join(QtPath.__createPlatformQtPath__(qtMinorVersion), path) class TestSection: From 5c4cf2d018600836b7f83f642d2bf6dc174cf81d Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 22 Feb 2023 15:19:56 +0100 Subject: [PATCH 16/43] SquishTests: More adaption to changed wizard template Change-Id: Ib073a8eae3ee87dc46699083799a8316da66b32d Reviewed-by: David Schulz --- tests/system/suite_SCOM/tst_SCOM02/test.py | 2 +- tests/system/suite_editors/tst_qml_indent/test.py | 4 ++-- tests/system/suite_qtquick/tst_qtquick_creation/test.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/system/suite_SCOM/tst_SCOM02/test.py b/tests/system/suite_SCOM/tst_SCOM02/test.py index 623fb090f41..6753e27cbdb 100644 --- a/tests/system/suite_SCOM/tst_SCOM02/test.py +++ b/tests/system/suite_SCOM/tst_SCOM02/test.py @@ -12,7 +12,7 @@ def main(): # create qt quick application createNewQtQuickApplication(tempDir(), "SampleApp") # create syntax error in qml file - openDocument("SampleApp.Resources.qml\.qrc./.main\\.qml") + openDocument("SampleApp.appSampleApp.Main\\.qml") if not appendToLine(waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget"), "Window {", "SyntaxError"): invokeMenuItem("File", "Exit") return diff --git a/tests/system/suite_editors/tst_qml_indent/test.py b/tests/system/suite_editors/tst_qml_indent/test.py index d1f8922607b..bb0df6a683c 100644 --- a/tests/system/suite_editors/tst_qml_indent/test.py +++ b/tests/system/suite_editors/tst_qml_indent/test.py @@ -15,8 +15,8 @@ def main(): invokeMenuItem("File", "Exit") def prepareQmlFile(): - if not openDocument("untitled.untitled.qml\\.qrc./.main\\.qml"): - test.fatal("Could not open main.qml") + if not openDocument("untitled.appuntitled.Main\\.qml"): + test.fatal("Could not open Main.qml") return None editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget") isDarwin = platform.system() == 'Darwin' diff --git a/tests/system/suite_qtquick/tst_qtquick_creation/test.py b/tests/system/suite_qtquick/tst_qtquick_creation/test.py index 2ca7164c66e..164dc5cc948 100644 --- a/tests/system/suite_qtquick/tst_qtquick_creation/test.py +++ b/tests/system/suite_qtquick/tst_qtquick_creation/test.py @@ -33,7 +33,7 @@ def main(): checkCompile() else: appOutput = logApplicationOutput() - test.verify(not ("main.qml" in appOutput or "MainForm.ui.qml" in appOutput), + test.verify(not ("Main.qml" in appOutput or "MainForm.ui.qml" in appOutput), "Does the Application Output indicate QML errors?") invokeMenuItem("File", "Close All Projects and Editors") From b9a24753a09678034c9a2e9423d02c68c54ed218 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 21 Feb 2023 18:13:02 +0100 Subject: [PATCH 17/43] Android: Fix opening of package location after build Fixes and consolidates into one common function the package path retrieval for the eight combinations of: (apk|aab)(debug|release)(signed|unsigned) Fixes: QTCREATORBUG-28791 Change-Id: I6e8c54f555b95aca448032783938f9f7f89bc653 Reviewed-by: Assam Boudjelthia --- src/plugins/android/androidbuildapkstep.cpp | 10 +----- src/plugins/android/androiddeployqtstep.cpp | 2 +- src/plugins/android/androidmanager.cpp | 35 ++++++++++++++++----- src/plugins/android/androidmanager.h | 2 +- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index 436a58c39ac..adf96eb68d7 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -533,15 +533,7 @@ bool AndroidBuildApkStep::init() m_openPackageLocationForRun = m_openPackageLocation; const FilePath outputDir = AndroidManager::androidBuildDirectory(target()); - - if (m_buildAAB) { - const QString bt = buildType() == BuildConfiguration::Release ? QLatin1String("release") - : QLatin1String("debug"); - m_packagePath = outputDir.pathAppended( - QString("build/outputs/bundle/%1/android-build-%1.aab").arg(bt)); - } else { - m_packagePath = AndroidManager::apkPath(target()); - } + m_packagePath = AndroidManager::packagePath(target()); qCDebug(buildapkstepLog).noquote() << "APK or AAB path:" << m_packagePath.toUserOutput(); diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index df081b092c9..c305987a502 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -251,7 +251,7 @@ bool AndroidDeployQtStep::init() } else { m_uninstallPreviousPackageRun = true; m_command = AndroidConfigurations::currentConfig().adbToolPath(); - m_apkPath = AndroidManager::apkPath(target()); + m_apkPath = AndroidManager::packagePath(target()); m_workingDirectory = bc ? AndroidManager::buildDirectory(target()): FilePath(); } m_environment = bc ? bc->environment() : Utils::Environment(); diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 8b81907220e..e4d47be7337 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -268,7 +268,31 @@ FilePath AndroidManager::buildDirectory(const Target *target) return {}; } -FilePath AndroidManager::apkPath(const Target *target) +enum PackageFormat { + Apk, + Aab +}; + +QString packageSubPath(PackageFormat format, BuildConfiguration::BuildType buildType, bool sig) +{ + const bool deb = (buildType == BuildConfiguration::Debug); + + if (format == Apk) { + if (deb) + return sig ? packageSubPath(Apk, BuildConfiguration::Release, true) // Intentional + : QLatin1String("apk/debug/android-build-debug.apk"); + else + return QLatin1String(sig ? "apk/release/android-build-release-signed.apk" + : "apk/release/android-build-release-unsigned.apk"); + } else { + return QLatin1String(deb ? "bundle/debug/android-build-debug.aab" + : "bundle/release/android-build-release.aab"); + } + + return {}; +} + +FilePath AndroidManager::packagePath(const Target *target) { QTC_ASSERT(target, return {}); @@ -279,13 +303,10 @@ FilePath AndroidManager::apkPath(const Target *target) if (!buildApkStep) return {}; - QString apkPath("build/outputs/apk/android-build-"); - if (buildApkStep->signPackage()) - apkPath += QLatin1String("release.apk"); - else - apkPath += QLatin1String("debug.apk"); + const QString subPath = packageSubPath(buildApkStep->buildAAB() ? Aab : Apk, + bc->buildType(), buildApkStep->signPackage()); - return androidBuildDirectory(target) / apkPath; + return androidBuildDirectory(target) / "build/outputs" / subPath; } bool AndroidManager::matchedAbis(const QStringList &deviceAbis, const QStringList &appAbis) diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index cf03c31e938..d468ec3279e 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -78,7 +78,7 @@ public: static Utils::FilePath manifestPath(const ProjectExplorer::Target *target); static void setManifestPath(ProjectExplorer::Target *target, const Utils::FilePath &path); static Utils::FilePath manifestSourcePath(const ProjectExplorer::Target *target); - static Utils::FilePath apkPath(const ProjectExplorer::Target *target); + static Utils::FilePath packagePath(const ProjectExplorer::Target *target); static bool matchedAbis(const QStringList &deviceAbis, const QStringList &appAbis); static QString devicePreferredAbi(const QStringList &deviceAbis, const QStringList &appAbis); static ProjectExplorer::Abi androidAbi2Abi(const QString &androidAbi); From c2266981c91825838a0d5fe9ec28267c2ede42c1 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 21 Feb 2023 10:03:11 +0100 Subject: [PATCH 18/43] Add tests to Utils::wildcardToRegularExpression It was unclear if the new non-filepath version that is added to Qt is similar enough to replace our own version, so just add the new tests from Qt to check. Change-Id: I9ac2739500ab3b8557c0e6223489e0fdddd79091 Reviewed-by: Jarek Kobus Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: Christian Stenger --- .../utils/stringutils/tst_stringutils.cpp | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/auto/utils/stringutils/tst_stringutils.cpp b/tests/auto/utils/stringutils/tst_stringutils.cpp index 6b481f06025..e13e8411a5b 100644 --- a/tests/auto/utils/stringutils/tst_stringutils.cpp +++ b/tests/auto/utils/stringutils/tst_stringutils.cpp @@ -77,6 +77,8 @@ private slots: void testJoinStrings(); void testTrim_data(); void testTrim(); + void testWildcardToRegularExpression_data(); + void testWildcardToRegularExpression(); private: TestMacroExpander mx; @@ -330,6 +332,78 @@ void tst_StringUtils::testTrim() QCOMPARE(Utils::trim(data.input, data.ch), data.bothSides); } +void tst_StringUtils::testWildcardToRegularExpression_data() +{ + QTest::addColumn("pattern"); + QTest::addColumn("string"); + QTest::addColumn("matches"); + auto addRow = [](const char *pattern, const char *string, bool matchesNonPathGlob) { + QTest::addRow("%s@%s", pattern, string) << pattern << string << matchesNonPathGlob; + }; + addRow("*.html", "test.html", true); + addRow("*.html", "test.htm", false); + addRow("*bar*", "foobarbaz", true); + addRow("*", "Qt Rocks!", true); + addRow("*.h", "test.cpp", false); + addRow("*.???l", "test.html", true); + addRow("*?", "test.html", true); + addRow("*?ml", "test.html", true); + addRow("*[*]", "test.html", false); + addRow("*[?]", "test.html", false); + addRow("*[?]ml", "test.h?ml", true); + addRow("*[[]ml", "test.h[ml", true); + addRow("*[]]ml", "test.h]ml", true); + addRow("*.h[a-z]ml", "test.html", true); + addRow("*.h[A-Z]ml", "test.html", false); + addRow("*.h[A-Z]ml", "test.hTml", true); + addRow("*.h[!A-Z]ml", "test.hTml", false); + addRow("*.h[!A-Z]ml", "test.html", true); + addRow("*.h[!T]ml", "test.hTml", false); + addRow("*.h[!T]ml", "test.html", true); + addRow("*.h[!T]m[!L]", "test.htmL", false); + addRow("*.h[!T]m[!L]", "test.html", true); + addRow("*.h[][!]ml", "test.h]ml", true); + addRow("*.h[][!]ml", "test.h[ml", true); + addRow("*.h[][!]ml", "test.h!ml", true); + addRow("foo/*/bar", "foo/baz/bar", true); + addRow("foo/*/bar", "foo/fie/baz/bar", true); + addRow("foo?bar", "foo/bar", true); + addRow("foo/(*)/bar", "foo/baz/bar", false); + addRow("foo/(*)/bar", "foo/(baz)/bar", true); + addRow("foo/?/bar", "foo/Q/bar", true); + addRow("foo/?/bar", "foo/Qt/bar", false); + addRow("foo/(?)/bar", "foo/Q/bar", false); + addRow("foo/(?)/bar", "foo/(Q)/bar", true); + addRow("foo\\*\\bar", "foo\\baz\\bar", true); + addRow("foo\\*\\bar", "foo/baz/bar", false); + addRow("foo\\*\\bar", "foo/baz\\bar", false); + addRow("foo\\*\\bar", "foo\\fie\\baz\\bar", true); + addRow("foo\\*\\bar", "foo/fie/baz/bar", false); + addRow("foo/*/bar", "foo\\baz\\bar", false); + addRow("foo/*/bar", "foo/baz/bar", true); + addRow("foo/*/bar", "foo\\fie\\baz\\bar", false); + addRow("foo/*/bar", "foo/fie/baz/bar", true); + addRow("foo\\(*)\\bar", "foo\\baz\\bar", false); + addRow("foo\\(*)\\bar", "foo\\(baz)\\bar", true); + addRow("foo\\?\\bar", "foo\\Q\\bar", true); + addRow("foo\\?\\bar", "foo\\Qt\\bar", false); + addRow("foo\\(?)\\bar", "foo\\Q\\bar", false); + addRow("foo\\(?)\\bar", "foo\\(Q)\\bar", true); + + addRow("foo*bar", "foo/fie/baz/bar", true); + addRow("fie*bar", "foo/fie/baz/bar", false); +} + +void tst_StringUtils::testWildcardToRegularExpression() +{ + QFETCH(QString, pattern); + QFETCH(QString, string); + QFETCH(bool, matches); + + const QRegularExpression re(Utils::wildcardToRegularExpression(pattern)); + QCOMPARE(string.contains(re), matches); +} + QTEST_GUILESS_MAIN(tst_StringUtils) #include "tst_stringutils.moc" From 143835aea8ab25d4ceb9d1413c16de97f664f961 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 16 Feb 2023 14:16:47 +0100 Subject: [PATCH 19/43] Coding style: Avoid optional::value() Change-Id: Ic4769c6f9f016415e01ca5526f6730bc93c6ea81 Reviewed-by: Jarek Kobus Reviewed-by: Leena Miettinen --- doc/qtcreatordev/src/coding-style.qdoc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/qtcreatordev/src/coding-style.qdoc b/doc/qtcreatordev/src/coding-style.qdoc index 02636e3ab59..22da9cca0cb 100644 --- a/doc/qtcreatordev/src/coding-style.qdoc +++ b/doc/qtcreatordev/src/coding-style.qdoc @@ -899,6 +899,29 @@ container is const or unshared, use \c{std::cref()} to ensure that the container is not unnecessarily detached. + \section3 std::optional + + Avoid the throwing function \c{value()}. Check the availability of the value first, and then use + the non-throwing functions for accessing values, like \c{operator*} and \c{operator->}. + In very simple cases, you can also use \c{value_or()}. + + \code + + if (optionalThing) { + val = optionalThing->member; + other = doSomething(*optionalThing); + } + + -NOT- + + if (optionalThing) { + val = optionalThing.value().member; + other = doSomething(optionalThing.value()); + } + + \endcode + + \section2 Using QObject \list From 8b243290fbdf458970e229ac5d32e7f45576a3d2 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Feb 2023 10:54:17 +0100 Subject: [PATCH 20/43] Qnx: Use some placeholder for Qnx configuration names The authoritive source for that is apparently some qconfig/*.xml file which is not needed for actual building, so it might be missing in some otherwise functioning setups. Change-Id: I2aff53474e7fa0f7ee1c5bd0d8213b648cb894b7 Reviewed-by: Christian Stenger --- src/plugins/qnx/qnxconfiguration.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/qnx/qnxconfiguration.cpp b/src/plugins/qnx/qnxconfiguration.cpp index 8e8751ceb1d..bb3e97995ae 100644 --- a/src/plugins/qnx/qnxconfiguration.cpp +++ b/src/plugins/qnx/qnxconfiguration.cpp @@ -391,6 +391,10 @@ void QnxConfiguration::setDefaultConfiguration(const FilePath &envScript) if (qccPath.exists()) m_qccCompiler = qccPath; + // Some fall back in case the qconfig dir with .xml files is not found later + if (m_configName.isEmpty()) + m_configName = QString("%1 - %2").arg(m_qnxHost.fileName(), m_qnxTarget.fileName()); + updateTargets(); assignDebuggersToTargets(); From 78ccdb5c37b7fdebcaf399a1a159b6ede9923216 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 23 Feb 2023 14:03:50 +0100 Subject: [PATCH 21/43] Cdbext: fix collecting required modules for python > 3.10 Change-Id: Ib8f5ff953f70cfb1ad15ea29522e02d65c58cafa Reviewed-by: Cristian Adam Reviewed-by: --- cmake/CreatePythonXY.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CreatePythonXY.cmake b/cmake/CreatePythonXY.cmake index 0475b259f68..637c4940c83 100644 --- a/cmake/CreatePythonXY.cmake +++ b/cmake/CreatePythonXY.cmake @@ -3,7 +3,7 @@ function(create_python_xy PythonExe PythonZipFilePath) get_filename_component(python_lib_dir "${PythonExe}" DIRECTORY) get_filename_component(python_lib_dir "${python_lib_dir}/Lib" ABSOLUTE) - foreach(dir collections encodings importlib json urllib) + foreach(dir collections encodings importlib json urllib re) file(COPY ${python_lib_dir}/${dir} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/python-lib FILES_MATCHING PATTERN "*.py" From 2c9ca6008f71da1e05154c502f71920299a3f6a9 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 23 Feb 2023 16:41:58 +0100 Subject: [PATCH 22/43] Doc: Describe Python interpreter selector on editor toolbar Task-number: QTCREATORBUG-28721 Change-Id: I354c19a72e428e5361eaacb45f79c057affb9cb1 Reviewed-by: Reviewed-by: David Schulz --- ...qtcreator-python-interpreter-edit-mode.webp | Bin 0 -> 5834 bytes .../src/python/creator-python-project.qdocinc | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 doc/qtcreator/images/qtcreator-python-interpreter-edit-mode.webp diff --git a/doc/qtcreator/images/qtcreator-python-interpreter-edit-mode.webp b/doc/qtcreator/images/qtcreator-python-interpreter-edit-mode.webp new file mode 100644 index 0000000000000000000000000000000000000000..fbf09f8751d89740225f535d505040c3a9f6ac3c GIT binary patch literal 5834 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 \uicontrol Preferences > \uicontrol Python > \uicontrol Interpreters. + You can see the current Python interpreter on the \uicontrol Edit mode + toolbar. - \image qtcreator-python-interpreters.png "Python Interpreters in Preferences" + \image qtcreator-python-interpreter-edit-mode.webp {Python interpreter on the Edit mode toolbar} + + To see the available interpreters and change their paths, select + the interpreter, and then select \uicontrol {Manage Python Interpreters}. + Or, select \uicontrol Edit > \uicontrol Preferences > \uicontrol Python > + \uicontrol Interpreters. + + \image qtcreator-python-interpreters.png {Python Interpreters in Preferences} You can add and remove interpreters and clean up references to interpreters that you uninstalled, but that still appear in the list. In addition, you @@ -42,7 +49,7 @@ the PySide version, class name, base class, and source file for the class. - \image qtcreator-python-wizard-app-window.png "Qt for Python wizard for creating a widget-based UI" + \image qtcreator-python-wizard-app-window.png {Qt for Python wizard for creating a widget-based UI} The wizard adds the imports to the source file for access to the QApplication, the base class you selected in the Qt @@ -150,7 +157,7 @@ you to create a Python project that has a main QML file. Specify the minimum PySide version to run the application. - \image qtcreator-python-wizard-qml.png "Qt for Python wizard for creating an empty Qt Quick application" + \image qtcreator-python-wizard-qml.png {Qt for Python wizard for creating an empty Qt Quick application} The wizard adds the following imports to the source file for access to QGuiApplication and QQmlApplicationEngine: From 31740f562c9ce9014c1dc77acf5aa7b1117e4ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20K=C3=B6hne?= Date: Wed, 16 Jun 2021 16:33:00 +0200 Subject: [PATCH 23/43] span: Fix debug build with MSVC std::terminate is declared in , so we need to include this header - somewhat ironically - in the non-exception case. Change-Id: I8ff1c20fd822b8a2a4c85faedf81f783e2779b8d Reviewed-by: Qt CI Bot Reviewed-by: Alessandro Portale Reviewed-by: Marco Bubke --- src/libs/3rdparty/span/span.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/3rdparty/span/span.hpp b/src/libs/3rdparty/span/span.hpp index a8414ab6fee..51bdf1da303 100644 --- a/src/libs/3rdparty/span/span.hpp +++ b/src/libs/3rdparty/span/span.hpp @@ -27,6 +27,8 @@ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf #ifndef TCB_SPAN_NO_EXCEPTIONS #include #include +#else +#include // for std::terminate #endif // Various feature test macros From ac2d5d761dd6e41a25f0a47ed81a93c210db4295 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 15 Feb 2023 16:25:16 +0100 Subject: [PATCH 24/43] AutoTest: Fix handling of test results Broke with d05c5b7d07194b7c0fe938e88e63cfaab9ee5f4d. The id is used to identify the application running a test or a global message like some warnings or the information regarding the current running test. Fixes its usage and its display inside the results pane. In the amended patch the assumption that if the m_id is empty it corresponds to nullptr TestResultPtr was apparently wrong. This patch fixes it so that the default c'tor of TestResult always creates an invalid result, so that it corresponds now to nullptr TestResultPtr. Amends d05c5b7d07194b7c0fe938e88e63cfaab9ee5f4d Change-Id: I9949aec3fc2b7354de149433b7127933f2d9bf21 Reviewed-by: Jarek Kobus Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/autotest/gtest/gtestoutputreader.cpp | 2 +- src/plugins/autotest/qtest/qttestoutputreader.cpp | 2 +- src/plugins/autotest/testresult.cpp | 10 +++++----- src/plugins/autotest/testresult.h | 14 ++++++++------ src/plugins/autotest/testrunner.cpp | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp index 4ad273063e9..2c2aee07a6e 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.cpp +++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp @@ -105,7 +105,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine) } else if (ExactMatch match = newTestSetStarts.match(line)) { m_testSetStarted = true; setCurrentTestCase(match.captured(1)); - GTestResult testResult("internal", {}, m_projectFile); + GTestResult testResult({}, {}, m_projectFile); testResult.setResult(ResultType::MessageCurrentTest); testResult.setDescription(Tr::tr("Entering test case %1").arg(m_currentTestCase)); reportResult(testResult); diff --git a/src/plugins/autotest/qtest/qttestoutputreader.cpp b/src/plugins/autotest/qtest/qttestoutputreader.cpp index a93e74eea42..073ef0e9fed 100644 --- a/src/plugins/autotest/qtest/qttestoutputreader.cpp +++ b/src/plugins/autotest/qtest/qttestoutputreader.cpp @@ -474,7 +474,7 @@ void QtTestOutputReader::sendCompleteInformation() void QtTestOutputReader::sendMessageCurrentTest() { - QtTestResult result("internal", {}, m_projectFile, m_testType); + QtTestResult result({}, {}, m_projectFile, m_testType); result.setResult(ResultType::MessageCurrentTest); result.setDescription(Tr::tr("Entering test function %1::%2").arg(m_className, m_testCase)); reportResult(result); diff --git a/src/plugins/autotest/testresult.cpp b/src/plugins/autotest/testresult.cpp index ae885d6b48c..d0e65c554db 100644 --- a/src/plugins/autotest/testresult.cpp +++ b/src/plugins/autotest/testresult.cpp @@ -19,7 +19,7 @@ TestResult::TestResult(const QString &id, const QString &name, const ResultHooks bool TestResult::isValid() const { - return !m_id.isEmpty(); + return m_id.has_value(); } const QString TestResult::outputString(bool selected) const @@ -28,7 +28,7 @@ const QString TestResult::outputString(bool selected) const return m_hooks.outputString(*this, selected); if (m_result == ResultType::Application) - return m_id; + return id(); return selected ? m_description : m_description.split('\n').first(); } @@ -166,7 +166,7 @@ QColor TestResult::colorForType(const ResultType type) bool TestResult::isDirectParentOf(const TestResult &other, bool *needsIntermediate) const { QTC_ASSERT(other.isValid(), return false); - const bool ret = !m_id.isEmpty() && m_id == other.m_id && m_name == other.m_name; + const bool ret = m_id && m_id == other.m_id && m_name == other.m_name; if (!ret) return false; if (m_hooks.directParent) @@ -179,14 +179,14 @@ bool TestResult::isIntermediateFor(const TestResult &other) const QTC_ASSERT(other.isValid(), return false); if (m_hooks.intermediate) return m_hooks.intermediate(*this, other); - return !m_id.isEmpty() && m_id == other.m_id && m_name == other.m_name; + return m_id && m_id == other.m_id && m_name == other.m_name; } TestResult TestResult::intermediateResult() const { if (m_hooks.createResult) return m_hooks.createResult(*this); - return {m_id, m_name}; + return {id(), m_name}; } } // namespace Autotest diff --git a/src/plugins/autotest/testresult.h b/src/plugins/autotest/testresult.h index 423f76e1e24..80229d37362 100644 --- a/src/plugins/autotest/testresult.h +++ b/src/plugins/autotest/testresult.h @@ -9,6 +9,8 @@ #include +#include + namespace Autotest { class ITestTreeItem; @@ -65,9 +67,9 @@ struct ResultHooks using IntermediateHook = std::function; using CreateResultHook = std::function; QVariant extraData; - OutputStringHook outputString; - FindTestItemHook findTestItem; - DirectParentHook directParent; + OutputStringHook outputString = {}; + FindTestItemHook findTestItem = {}; + DirectParentHook directParent = {}; IntermediateHook intermediate = {}; CreateResultHook createResult = {}; }; @@ -83,7 +85,7 @@ public: const QString outputString(bool selected) const; const ITestTreeItem *findTestTreeItem() const; - QString id() const { return m_id; } + QString id() const { return m_id.value_or(QString()); } QString name() const { return m_name; } ResultType result() const { return m_result; } QString description() const { return m_description; } @@ -106,13 +108,13 @@ public: TestResult intermediateResult() const; private: - QString m_id; + std::optional m_id = {}; QString m_name; ResultType m_result = ResultType::Invalid; // the real result.. QString m_description; Utils::FilePath m_file; int m_line = 0; - ResultHooks m_hooks; + ResultHooks m_hooks = {}; }; } // namespace Autotest diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 76138a8ea4b..cb01d0d9a2a 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -784,7 +784,7 @@ void TestRunner::onFinished() void TestRunner::reportResult(ResultType type, const QString &description) { - TestResult result("internal", {}); + TestResult result({}, {}); result.setResult(type); result.setDescription(description); emit testResultReady(result); From 9655c888627dc81e1006822a773d242e770a909d Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 24 Feb 2023 07:32:23 +0100 Subject: [PATCH 25/43] LanguageClient: do not delay requesting symbols in the locator filter This qualifies as a user interaction and the results should be collected as fast as possible. Change-Id: Ia83893fab87c253b9939cfee928aa12866087aa0 Reviewed-by: Christian Kandeler --- src/plugins/languageclient/locatorfilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/languageclient/locatorfilter.cpp b/src/plugins/languageclient/locatorfilter.cpp index 2c933c12204..ddcfc6b43bc 100644 --- a/src/plugins/languageclient/locatorfilter.cpp +++ b/src/plugins/languageclient/locatorfilter.cpp @@ -171,7 +171,7 @@ void DocumentLocatorFilter::prepareSearch(const QString &/*entry*/) QMutexLocker locker(&m_mutex); if (m_symbolCache && !m_currentSymbols.has_value()) { locker.unlock(); - m_symbolCache->requestSymbols(m_currentUri, Schedule::Delayed); + m_symbolCache->requestSymbols(m_currentUri, Schedule::Now); } } From fb9e0397e64e199f69379098739e717a131fb05f Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 23 Feb 2023 17:43:38 +0100 Subject: [PATCH 26/43] Debugger: Use a QStringView for debugview into output buffer This is unused unless debugging creator itself. Change-Id: Ic30fe4970c4b0ec79e977ef932d0516ab1ba0792 Reviewed-by: David Schulz --- src/plugins/debugger/debuggerprotocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/debuggerprotocol.h b/src/plugins/debugger/debuggerprotocol.h index 46d0b38f8bc..57becd08e7b 100644 --- a/src/plugins/debugger/debuggerprotocol.h +++ b/src/plugins/debugger/debuggerprotocol.h @@ -118,7 +118,7 @@ public: QString readCString(); QString readString(const std::function &isValidChar); - QString buffer() const { return QString(from, to - from); } + QStringView buffer() const { return QStringView(from, to - from); } int remainingChars() const { return int(to - from); } void skipCommas(); From 5b0a177cdf2358e7d3f6c38bb0ccdea90901144a Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 24 Feb 2023 10:24:22 +0100 Subject: [PATCH 27/43] Debugger: Avoid reserving huge strings Fixes: QTCREATORBUG-26416 Change-Id: I3728a98f0d16f43817d46e5404bd0b65bfd1b9c0 Reviewed-by: hjk --- src/plugins/debugger/debuggerprotocol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp index 24a0e61dd87..977a09c06a7 100644 --- a/src/plugins/debugger/debuggerprotocol.cpp +++ b/src/plugins/debugger/debuggerprotocol.cpp @@ -200,7 +200,7 @@ QString DebuggerOutputParser::readCString() ++from; // Skip initial quote. QString result; - result.reserve(to - from); + result.reserve(30); while (from < to) { if (*from == '"') { ++from; From 801eb712bad5190c5947ce79c9bda294d2631c18 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Feb 2023 07:53:51 +0100 Subject: [PATCH 28/43] Debugger: Save a few string allocations on result parsing Change-Id: I5b7614bd22d41f826b4977621d77a9aeba7f961f Reviewed-by: David Schulz Reviewed-by: Qt CI Bot Reviewed-by: --- src/plugins/debugger/debuggerprotocol.cpp | 10 ++--- src/plugins/debugger/debuggerprotocol.h | 2 +- src/plugins/debugger/gdb/gdbengine.cpp | 50 +++++++++++------------ src/plugins/debugger/gdb/gdbengine.h | 2 +- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp index 977a09c06a7..808b5625d0e 100644 --- a/src/plugins/debugger/debuggerprotocol.cpp +++ b/src/plugins/debugger/debuggerprotocol.cpp @@ -47,12 +47,12 @@ void DebuggerOutputParser::skipSpaces() ++from; } -QString DebuggerOutputParser::readString(const std::function &isValidChar) +QStringView DebuggerOutputParser::readString(const std::function &isValidChar) { - QString res; + const QChar *oldFrom = from; while (from < to && isValidChar(from->unicode())) - res += *from++; - return res; + ++from; + return {oldFrom, from}; } int DebuggerOutputParser::readInt() @@ -96,7 +96,7 @@ void GdbMi::parseResultOrValue(DebuggerOutputParser &parser) return; } - m_name = parser.readString(isNameChar); + m_name = parser.readString(isNameChar).toString(); if (!parser.isAtEnd() && parser.isCurrent('=')) { parser.advance(); diff --git a/src/plugins/debugger/debuggerprotocol.h b/src/plugins/debugger/debuggerprotocol.h index 57becd08e7b..3bfd9c951b9 100644 --- a/src/plugins/debugger/debuggerprotocol.h +++ b/src/plugins/debugger/debuggerprotocol.h @@ -116,7 +116,7 @@ public: int readInt(); QChar readChar(); QString readCString(); - QString readString(const std::function &isValidChar); + QStringView readString(const std::function &isValidChar); QStringView buffer() const { return QStringView(from, to - from); } int remainingChars() const { return int(to - from); } diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index b420104afb5..ff3c9b88446 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -246,7 +246,7 @@ void GdbEngine::handleResponse(const QString &buff) case '*': case '+': case '=': { - const QString asyncClass = parser.readString(isNameChar); + const QStringView asyncClass = parser.readString(isNameChar); GdbMi result; while (!parser.isAtEnd()) { GdbMi data; @@ -365,17 +365,17 @@ void GdbEngine::handleResponse(const QString &buff) response.token = token; - QString resultClass = parser.readString(isNameChar); + const QStringView resultClass = parser.readString(isNameChar); - if (resultClass == "done") + if (resultClass == u"done") response.resultClass = ResultDone; - else if (resultClass == "running") + else if (resultClass == u"running") response.resultClass = ResultRunning; - else if (resultClass == "connected") + else if (resultClass == u"connected") response.resultClass = ResultConnected; - else if (resultClass == "error") + else if (resultClass == u"error") response.resultClass = ResultError; - else if (resultClass == "exit") + else if (resultClass == u"exit") response.resultClass = ResultExit; else response.resultClass = ResultUnknown; @@ -412,9 +412,9 @@ void GdbEngine::handleResponse(const QString &buff) } } -void GdbEngine::handleAsyncOutput(const QString &asyncClass, const GdbMi &result) +void GdbEngine::handleAsyncOutput(const QStringView asyncClass, const GdbMi &result) { - if (asyncClass == "stopped") { + if (asyncClass == u"stopped") { if (m_inUpdateLocals) { showMessage("UNEXPECTED *stopped NOTIFICATION IGNORED", LogWarning); } else { @@ -422,7 +422,7 @@ void GdbEngine::handleAsyncOutput(const QString &asyncClass, const GdbMi &result m_pendingLogStreamOutput.clear(); m_pendingConsoleStreamOutput.clear(); } - } else if (asyncClass == "running") { + } else if (asyncClass == u"running") { if (m_inUpdateLocals) { showMessage("UNEXPECTED *running NOTIFICATION IGNORED", LogWarning); } else { @@ -443,7 +443,7 @@ void GdbEngine::handleAsyncOutput(const QString &asyncClass, const GdbMi &result notifyInferiorRunOk(); } } - } else if (asyncClass == "library-loaded") { + } else if (asyncClass == u"library-loaded") { // Archer has 'id="/usr/lib/libdrm.so.2", // target-name="/usr/lib/libdrm.so.2", // host-name="/usr/lib/libdrm.so.2", @@ -464,7 +464,7 @@ void GdbEngine::handleAsyncOutput(const QString &asyncClass, const GdbMi &result module.modulePath = result["target-name"].data(); module.moduleName = QFileInfo(module.hostPath).baseName(); modulesHandler()->updateModule(module); - } else if (asyncClass == "library-unloaded") { + } else if (asyncClass == u"library-unloaded") { // Archer has 'id="/usr/lib/libdrm.so.2", // target-name="/usr/lib/libdrm.so.2", // host-name="/usr/lib/libdrm.so.2" @@ -472,9 +472,9 @@ void GdbEngine::handleAsyncOutput(const QString &asyncClass, const GdbMi &result modulesHandler()->removeModule(result["target-name"].data()); progressPing(); showStatusMessage(Tr::tr("Library %1 unloaded.").arg(id), 1000); - } else if (asyncClass == "thread-group-added") { + } else if (asyncClass == u"thread-group-added") { // 7.1-symbianelf has "{id="i1"}" - } else if (asyncClass == "thread-group-started") { + } else if (asyncClass == u"thread-group-started") { // Archer had only "{id="28902"}" at some point of 6.8.x. // *-started seems to be standard in 7.1, but in early // 7.0.x, there was a *-created instead. @@ -484,7 +484,7 @@ void GdbEngine::handleAsyncOutput(const QString &asyncClass, const GdbMi &result showStatusMessage(Tr::tr("Thread group %1 created.").arg(id), 1000); notifyInferiorPid(result["pid"].toProcessHandle()); handleThreadGroupCreated(result); - } else if (asyncClass == "thread-created") { + } else if (asyncClass == u"thread-created") { //"{id="1",group-id="28902"}" QString id = result["id"].data(); showStatusMessage(Tr::tr("Thread %1 created.").arg(id), 1000); @@ -492,23 +492,23 @@ void GdbEngine::handleAsyncOutput(const QString &asyncClass, const GdbMi &result thread.id = id; thread.groupId = result["group-id"].data(); threadsHandler()->updateThread(thread); - } else if (asyncClass == "thread-group-exited") { + } else if (asyncClass == u"thread-group-exited") { // Archer has "{id="28902"}" QString id = result["id"].data(); showStatusMessage(Tr::tr("Thread group %1 exited.").arg(id), 1000); handleThreadGroupExited(result); - } else if (asyncClass == "thread-exited") { + } else if (asyncClass == u"thread-exited") { //"{id="1",group-id="28902"}" QString id = result["id"].data(); QString groupid = result["group-id"].data(); showStatusMessage(Tr::tr("Thread %1 in group %2 exited.") .arg(id).arg(groupid), 1000); threadsHandler()->removeThread(id); - } else if (asyncClass == "thread-selected") { + } else if (asyncClass == u"thread-selected") { QString id = result["id"].data(); showStatusMessage(Tr::tr("Thread %1 selected.").arg(id), 1000); //"{id="2"}" - } else if (asyncClass == "breakpoint-modified") { + } else if (asyncClass == u"breakpoint-modified") { // New in FSF gdb since 2011-04-27. // "{bkpt={number="3",type="breakpoint",disp="keep", // enabled="y",addr="",times="1", @@ -547,7 +547,7 @@ void GdbEngine::handleAsyncOutput(const QString &asyncClass, const GdbMi &result } if (bp) bp->adjustMarker(); - } else if (asyncClass == "breakpoint-created") { + } else if (asyncClass == u"breakpoint-created") { // "{bkpt={number="1",type="breakpoint",disp="del",enabled="y", // addr="",pending="main",times="0", // original-location="main"}}" -- or -- @@ -561,7 +561,7 @@ void GdbEngine::handleAsyncOutput(const QString &asyncClass, const GdbMi &result br.updateFromGdbOutput(bkpt); handler->handleAlienBreakpoint(nr, br); } - } else if (asyncClass == "breakpoint-deleted") { + } else if (asyncClass == u"breakpoint-deleted") { // "breakpoint-deleted" "{id="1"}" // New in FSF gdb since 2011-04-27. const QString nr = result["id"].data(); @@ -571,15 +571,15 @@ void GdbEngine::handleAsyncOutput(const QString &asyncClass, const GdbMi &result // if (!bp.isOneShot()) ... is not sufficient. // It keeps temporary "Jump" breakpoints alive. breakHandler()->removeAlienBreakpoint(nr); - } else if (asyncClass == "cmd-param-changed") { + } else if (asyncClass == u"cmd-param-changed") { // New since 2012-08-09 // "{param="debug remote",value="1"}" - } else if (asyncClass == "memory-changed") { + } else if (asyncClass == u"memory-changed") { // New since 2013 // "{thread-group="i1",addr="0x0918a7a8",len="0x10"}" - } else if (asyncClass == "tsv-created") { + } else if (asyncClass == u"tsv-created") { // New since 2013-02-06 - } else if (asyncClass == "tsv-modified") { + } else if (asyncClass == u"tsv-modified") { // New since 2013-02-06 } else { qDebug() << "IGNORED ASYNC OUTPUT" diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 44185b94207..b0e60b934ac 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -134,7 +134,7 @@ private: ////////// General Interface ////////// ////////// Gdb Output, State & Capability Handling ////////// Q_INVOKABLE void handleResponse(const QString &buff); - void handleAsyncOutput(const QString &asyncClass, const GdbMi &result); + void handleAsyncOutput(const QStringView asyncClass, const GdbMi &result); void handleStopResponse(const GdbMi &data); void handleResultRecord(DebuggerResponse *response); void handleStop1(const GdbMi &data); From 040ebf81719b0c43af25f3336599f23ceb94c01b Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Feb 2023 12:17:38 +0100 Subject: [PATCH 29/43] Debugger: Suppress a message clogging the log view Eats time and won't be handled soon. Change-Id: I777bef10397d0d67daf576862975c4d4f1184504 Reviewed-by: David Schulz --- src/plugins/debugger/watchhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 83ff13b71b8..f86bcb1c62e 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -2293,7 +2293,7 @@ void WatchHandler::notifyUpdateFinished() m_model->forAllItems([this](WatchItem *item) { if (item->wantsChildren && isExpandedIName(item->iname)) { - m_model->m_engine->showMessage(QString("ADJUSTING CHILD EXPECTATION FOR " + item->iname)); + // m_model->m_engine->showMessage(QString("ADJUSTING CHILD EXPECTATION FOR " + item->iname)); item->wantsChildren = false; } }); From 6cd8bca691a260d2cc6a0e8b579888974a24cd69 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Feb 2023 08:31:58 +0100 Subject: [PATCH 30/43] Debugger: Simplify gdb output parsing structure The base problem is that gdb output is weird outside the 7 bit ASCII range. Could be true UTF-8, or \x encoded UTF-8 byte sequences, i.e. three layers of encoding. Change-Id: Id9ee4bd4a8979624f9682f28064c3ac599afe4b9 Reviewed-by: David Schulz --- src/plugins/debugger/debuggerprotocol.cpp | 31 ++++++++--------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp index 808b5625d0e..301949f822d 100644 --- a/src/plugins/debugger/debuggerprotocol.cpp +++ b/src/plugins/debugger/debuggerprotocol.cpp @@ -109,8 +109,6 @@ static bool parseOctalEscapedHelper(DebuggerOutputParser &parser, QByteArray &bu { if (parser.remainingChars() < 4) return false; - if (!parser.isCurrent('\\')) - return false; const char c1 = parser.lookAhead(1).unicode(); const char c2 = parser.lookAhead(2).unicode(); @@ -127,8 +125,6 @@ static bool parseHexEscapedHelper(DebuggerOutputParser &parser, QByteArray &buff { if (parser.remainingChars() < 4) return false; - if (!parser.isCurrent('\\')) - return false; if (parser.lookAhead(1) != 'x') return false; @@ -142,7 +138,7 @@ static bool parseHexEscapedHelper(DebuggerOutputParser &parser, QByteArray &buff return true; } -static void parseSimpleEscape(DebuggerOutputParser &parser, QString &result) +static void parseSimpleEscape(DebuggerOutputParser &parser, QByteArray &result) { if (parser.isAtEnd()) { qDebug() << "MI Parse Error, unterminated backslash escape"; @@ -167,23 +163,18 @@ static void parseSimpleEscape(DebuggerOutputParser &parser, QString &result) } } -// Reads subsequent \123 or \x12 entities and converts to Utf8, -// *or* one escaped char, *or* one unescaped char. -static void parseCharOrEscape(DebuggerOutputParser &parser, QString &result) +// Reads one \123 or \x12 entity, *or* one escaped char, *or* one unescaped char. +static void parseCharOrEscape(DebuggerOutputParser &parser, QByteArray &result) { - QByteArray buffer; - while (parseOctalEscapedHelper(parser, buffer)) - ; - while (parseHexEscapedHelper(parser, buffer)) - ; - - if (!buffer.isEmpty()) { - result.append(QString::fromUtf8(buffer)); - } else if (parser.isCurrent('\\')) { + if (parser.isCurrent('\\')) { + if (parseOctalEscapedHelper(parser, result)) + return; + if (parseHexEscapedHelper(parser, result)) + return; parser.advance(); parseSimpleEscape(parser, result); } else { - result += parser.readChar(); + result += char(parser.readChar().unicode()); } } @@ -199,12 +190,12 @@ QString DebuggerOutputParser::readCString() } ++from; // Skip initial quote. - QString result; + QByteArray result; result.reserve(30); while (from < to) { if (*from == '"') { ++from; - return result; + return QString::fromUtf8(result); } parseCharOrEscape(*this, result); } From 97b97825edf69b9a778e3eaefb11de1aee34d21c Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Feb 2023 09:49:57 +0100 Subject: [PATCH 31/43] Debugger: Also log time stamp when handling output is finished This helps to put the blame properly on either side of the communication. Change-Id: Id83de2bce1984f63427f655dce854ebb008a1a61 Reviewed-by: David Schulz Reviewed-by: --- src/plugins/debugger/gdb/gdbengine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index ff3c9b88446..1894dd3f4e5 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -410,6 +410,9 @@ void GdbEngine::handleResponse(const QString &buff) break; } } + + if (debuggerSettings()->logTimeStamps.value()) + showMessage(QString("Output handled")); } void GdbEngine::handleAsyncOutput(const QStringView asyncClass, const GdbMi &result) From 8eaf73700ecd0cd1f30b9973cb8b2ae0bc4bc52c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Feb 2023 12:05:18 +0100 Subject: [PATCH 32/43] TaskTree: Don't call storage done handlers from TaskTree's d'tor Change-Id: Ie2b04d433be3452f9e668efd3341dedfcb154290 Reviewed-by: Qt CI Bot Reviewed-by: hjk --- src/libs/utils/tasktree.cpp | 12 ++++++++++- tests/auto/utils/tasktree/tst_tasktree.cpp | 24 +++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/libs/utils/tasktree.cpp b/src/libs/utils/tasktree.cpp index f99b20d7612..90e4073e033 100644 --- a/src/libs/utils/tasktree.cpp +++ b/src/libs/utils/tasktree.cpp @@ -175,6 +175,7 @@ public: ~RuntimeData(); static QList createStorages(const TaskContainer::ConstData &constData); + void callStorageDoneHandlers(); bool updateSuccessBit(bool success); int currentLimit() const; @@ -384,6 +385,15 @@ QList TaskContainer::RuntimeData::createStorages(const TaskContainer::Const return storageIdList; } +void TaskContainer::RuntimeData::callStorageDoneHandlers() +{ + for (int i = m_constData.m_storageList.size() - 1; i >= 0; --i) { // iterate in reverse order + const TreeStorageBase storage = m_constData.m_storageList[i]; + const int storageId = m_storageIdList.value(i); + m_constData.m_taskTreePrivate->callDoneHandler(storage, storageId); + } +} + TaskContainer::RuntimeData::RuntimeData(const ConstData &constData) : m_constData(constData) , m_storageIdList(createStorages(constData)) @@ -397,7 +407,6 @@ TaskContainer::RuntimeData::~RuntimeData() for (int i = m_constData.m_storageList.size() - 1; i >= 0; --i) { // iterate in reverse order const TreeStorageBase storage = m_constData.m_storageList[i]; const int storageId = m_storageIdList.value(i); - m_constData.m_taskTreePrivate->callDoneHandler(storage, storageId); storage.deleteStorage(storageId); } } @@ -527,6 +536,7 @@ void TaskContainer::invokeEndHandler() invokeHandler(this, groupHandler.m_doneHandler); else if (!m_runtimeData->m_successBit && groupHandler.m_errorHandler) invokeHandler(this, groupHandler.m_errorHandler); + m_runtimeData->callStorageDoneHandlers(); m_runtimeData.reset(); } diff --git a/tests/auto/utils/tasktree/tst_tasktree.cpp b/tests/auto/utils/tasktree/tst_tasktree.cpp index 3e5c67050f5..43bf0468c5d 100644 --- a/tests/auto/utils/tasktree/tst_tasktree.cpp +++ b/tests/auto/utils/tasktree/tst_tasktree.cpp @@ -1054,26 +1054,40 @@ void tst_TaskTree::storageOperators() } // This test checks whether a running task tree may be safely destructed. -// It also checks whether destructor of task tree deletes properly the storage created -// while starting the task tree. +// It also checks whether the destructor of a task tree deletes properly the storage created +// while starting the task tree. When running task tree is destructed, the storage done +// handler shouldn't be invoked. void tst_TaskTree::storageDestructor() { + bool setupCalled = false; + const auto setupHandler = [&setupCalled](CustomStorage *) { + setupCalled = true; + }; + bool doneCalled = false; + const auto doneHandler = [&doneCalled](CustomStorage *) { + doneCalled = true; + }; QCOMPARE(CustomStorage::instanceCount(), 0); { + TreeStorage storage; const auto setupProcess = [testAppPath = m_testAppPath](QtcProcess &process) { process.setCommand(CommandLine(testAppPath, {"-sleep", "1000"})); }; const Group root { - Storage(TreeStorage()), + Storage(storage), Process(setupProcess) }; - TaskTree processTree(root); + TaskTree taskTree(root); QCOMPARE(CustomStorage::instanceCount(), 0); - processTree.start(); + taskTree.onStorageSetup(storage, setupHandler); + taskTree.onStorageDone(storage, doneHandler); + taskTree.start(); QCOMPARE(CustomStorage::instanceCount(), 1); } QCOMPARE(CustomStorage::instanceCount(), 0); + QVERIFY(setupCalled); + QVERIFY(!doneCalled); } QTEST_GUILESS_MAIN(tst_TaskTree) From a1e967054157e8ad65142295868f2e5c9826ba08 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Feb 2023 12:27:00 +0100 Subject: [PATCH 33/43] Utils: Simplify tree view columns width computation ... by using approximations of the value widths instead of precise comuptation. Change-Id: Ia7eefad8d79f09d1e0cfda32067d052f56b820a9 Reviewed-by: David Schulz --- src/libs/utils/basetreeview.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp index 6ca4b6983cb..6473a7830dc 100644 --- a/src/libs/utils/basetreeview.cpp +++ b/src/libs/utils/basetreeview.cpp @@ -159,10 +159,11 @@ public: a = a.sibling(a.row(), column); QFontMetrics fm = q->fontMetrics(); const int ind = q->indentation(); + const int avg = fm.averageCharWidth(); QAbstractItemModel *m = q->model(); for (int i = 0; i < 100 && a.isValid(); ++i) { const QString s = m->data(a).toString(); - int w = fm.horizontalAdvance(s) + 10; + int w = avg * s.size() + 20; if (column == 0) { for (QModelIndex b = a.parent(); b.isValid(); b = b.parent()) w += ind; From f53f006301c1a4e241bfb9867615f087adc3b32e Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Feb 2023 11:06:54 +0100 Subject: [PATCH 34/43] Debugger: Use QVarLengthArray for local buffer Change-Id: I1bca338e0ffb850ca23bf5e1d1cd2fb85227ddda Reviewed-by: David Schulz --- src/plugins/debugger/debuggerprotocol.cpp | 60 ++++++++++++----------- src/plugins/debugger/debuggerprotocol.h | 5 ++ 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp index 301949f822d..8ab7a71b339 100644 --- a/src/plugins/debugger/debuggerprotocol.cpp +++ b/src/plugins/debugger/debuggerprotocol.cpp @@ -105,7 +105,7 @@ void GdbMi::parseResultOrValue(DebuggerOutputParser &parser) } // Reads one \ooo entity. -static bool parseOctalEscapedHelper(DebuggerOutputParser &parser, QByteArray &buffer) +static bool parseOctalEscapedHelper(DebuggerOutputParser &parser, DebuggerOutputParser::Buffer &buffer) { if (parser.remainingChars() < 4) return false; @@ -121,7 +121,7 @@ static bool parseOctalEscapedHelper(DebuggerOutputParser &parser, QByteArray &bu return true; } -static bool parseHexEscapedHelper(DebuggerOutputParser &parser, QByteArray &buffer) +static bool parseHexEscapedHelper(DebuggerOutputParser &parser, DebuggerOutputParser::Buffer &buffer) { if (parser.remainingChars() < 4) return false; @@ -138,7 +138,7 @@ static bool parseHexEscapedHelper(DebuggerOutputParser &parser, QByteArray &buff return true; } -static void parseSimpleEscape(DebuggerOutputParser &parser, QByteArray &result) +static void parseSimpleEscape(DebuggerOutputParser &parser, DebuggerOutputParser::Buffer &buffer) { if (parser.isAtEnd()) { qDebug() << "MI Parse Error, unterminated backslash escape"; @@ -148,60 +148,64 @@ static void parseSimpleEscape(DebuggerOutputParser &parser, QByteArray &result) const QChar c = parser.current(); parser.advance(); switch (c.unicode()) { - case 'a': result += '\a'; break; - case 'b': result += '\b'; break; - case 'f': result += '\f'; break; - case 'n': result += '\n'; break; - case 'r': result += '\r'; break; - case 't': result += '\t'; break; - case 'v': result += '\v'; break; - case '"': result += '"'; break; - case '\'': result += '\''; break; - case '\\': result += '\\'; break; - default: - qDebug() << "MI Parse Error, unrecognized backslash escape"; + case 'a': buffer += '\a'; break; + case 'b': buffer += '\b'; break; + case 'f': buffer += '\f'; break; + case 'n': buffer += '\n'; break; + case 'r': buffer += '\r'; break; + case 't': buffer += '\t'; break; + case 'v': buffer += '\v'; break; + case '"': buffer += '"'; break; + case '\'': buffer += '\''; break; + case '\\': buffer += '\\'; break; + default: + qDebug() << "MI Parse Error, unrecognized backslash escape"; } } // Reads one \123 or \x12 entity, *or* one escaped char, *or* one unescaped char. -static void parseCharOrEscape(DebuggerOutputParser &parser, QByteArray &result) +static void parseCharOrEscape(DebuggerOutputParser &parser, DebuggerOutputParser::Buffer &buffer) { if (parser.isCurrent('\\')) { - if (parseOctalEscapedHelper(parser, result)) + if (parseOctalEscapedHelper(parser, buffer)) return; - if (parseHexEscapedHelper(parser, result)) + if (parseHexEscapedHelper(parser, buffer)) return; parser.advance(); - parseSimpleEscape(parser, result); + parseSimpleEscape(parser, buffer); } else { - result += char(parser.readChar().unicode()); + buffer += char(parser.readChar().unicode()); } } -QString DebuggerOutputParser::readCString() +void DebuggerOutputParser::readCStringData(Buffer &buffer) { if (isAtEnd()) - return QString(); + return; if (*from != '"') { qDebug() << "MI Parse Error, double quote expected"; ++from; // So we don't hang - return QString(); + return; } ++from; // Skip initial quote. - QByteArray result; - result.reserve(30); while (from < to) { if (*from == '"') { ++from; - return QString::fromUtf8(result); + return; } - parseCharOrEscape(*this, result); + parseCharOrEscape(*this, buffer); } qDebug() << "MI Parse Error, unfinished string"; - return QString(); +} + +QString DebuggerOutputParser::readCString() +{ + Buffer buffer; + readCStringData(buffer); + return QString::fromUtf8(buffer); } void GdbMi::parseValue(DebuggerOutputParser &parser) diff --git a/src/plugins/debugger/debuggerprotocol.h b/src/plugins/debugger/debuggerprotocol.h index 3bfd9c951b9..d06a95c7367 100644 --- a/src/plugins/debugger/debuggerprotocol.h +++ b/src/plugins/debugger/debuggerprotocol.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -105,6 +106,8 @@ class DebuggerOutputParser public: explicit DebuggerOutputParser(const QString &output); + using Buffer = QVarLengthArray; + QChar current() const { return *from; } bool isCurrent(QChar c) const { return *from == c; } bool isAtEnd() const { return from >= to; } @@ -116,6 +119,8 @@ public: int readInt(); QChar readChar(); QString readCString(); + void readCStringData(Buffer &buffer); + QStringView readString(const std::function &isValidChar); QStringView buffer() const { return QStringView(from, to - from); } From f2f5e4d030cf7da58a308363093ed4fda60017ff Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Feb 2023 12:49:39 +0100 Subject: [PATCH 35/43] Utils: Save a few cycles in BaseTreeView column width computation Change-Id: I5e97cae77db58a396424f5081838d2b2f3769ba7 Reviewed-by: David Schulz Reviewed-by: --- src/libs/utils/basetreeview.cpp | 57 ++++++++++++++++----------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp index 6473a7830dc..3ccbf1f86e8 100644 --- a/src/libs/utils/basetreeview.cpp +++ b/src/libs/utils/basetreeview.cpp @@ -152,46 +152,43 @@ public: } } - - void considerItems(int column, QModelIndex start, int *minimum, bool single) const - { - QModelIndex a = start; - a = a.sibling(a.row(), column); - QFontMetrics fm = q->fontMetrics(); - const int ind = q->indentation(); - const int avg = fm.averageCharWidth(); - QAbstractItemModel *m = q->model(); - for (int i = 0; i < 100 && a.isValid(); ++i) { - const QString s = m->data(a).toString(); - int w = avg * s.size() + 20; - if (column == 0) { - for (QModelIndex b = a.parent(); b.isValid(); b = b.parent()) - w += ind; - } - if (w > *minimum) - *minimum = w; - if (single) - break; - a = q->indexBelow(a); - } - } - int suggestedColumnSize(int column) const { - QHeaderView *h = q->header(); + const QHeaderView *h = q->header(); QTC_ASSERT(h, return -1); - QAbstractItemModel *m = q->model(); + const QAbstractItemModel *m = q->model(); QTC_ASSERT(m, return -1); - QFontMetrics fm = q->fontMetrics(); + const QFontMetrics fm = q->fontMetrics(); + const int ind = q->indentation(); + const int avg = fm.averageCharWidth(); int minimum = fm.horizontalAdvance(m->headerData(column, Qt::Horizontal).toString()) - + 2 * fm.horizontalAdvance(QLatin1Char('m')); - considerItems(column, q->indexAt(QPoint(1, 1)), &minimum, false); + + 2 * avg; + + auto considerItems = [&](const QModelIndex &start, bool single) { + QModelIndex a = start; + a = a.sibling(a.row(), column); + for (int i = 0; i < 100 && a.isValid(); ++i) { + const QString s = m->data(a).toString(); + int w = avg * s.size() + 20; + if (column == 0) { + for (QModelIndex b = a.parent(); b.isValid(); b = b.parent()) + w += ind; + } + if (w > minimum) + minimum = w; + if (single) + break; + a = q->indexBelow(a); + } + }; + + considerItems(q->indexAt(QPoint(1, 1)), false); const QVariant extraIndices = m->data(QModelIndex(), BaseTreeView::ExtraIndicesForColumnWidth); const QList values = extraIndices.value(); for (const QModelIndex &a : values) - considerItems(column, a, &minimum, true); + considerItems(a, true); return minimum; } From 7f04a6654604ad656590d4b15d585ab950f2aa89 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Feb 2023 12:17:03 +0100 Subject: [PATCH 36/43] Debugger: Introduce a cache for pre-rendered value columne entries Change-Id: Ibdcac8a5ccaa3eab0723205b913056530c510280 Reviewed-by: David Schulz --- src/plugins/debugger/watchdata.h | 3 +++ src/plugins/debugger/watchhandler.cpp | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h index c25e1962f9c..4ef57eacf18 100644 --- a/src/plugins/debugger/watchdata.h +++ b/src/plugins/debugger/watchdata.h @@ -78,6 +78,9 @@ public: bool outdated = false; // \internal item is to be removed. double time = 0; // Time used on the dumper side to produce this item + mutable QString valueCache; // Pre-computed displayed value + void updateValueCache() const; // implemented in watchhandler.cpp + private: void parseHelper(const GdbMi &input, bool maySort); }; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index f86bcb1c62e..4823a952b90 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -929,15 +929,22 @@ static QString displayName(const WatchItem *item) return result; } -static QString displayValue(const WatchItem *item) + +void WatchItem::updateValueCache() const { - QString result = truncateValue(formattedValue(item)); - result = watchModel(item)->removeNamespaces(result); - if (result.isEmpty() && item->address) - result += QString::fromLatin1("@0x" + QByteArray::number(item->address, 16)); + valueCache = truncateValue(formattedValue(this)); + valueCache = watchModel(this)->removeNamespaces(valueCache); + if (valueCache.isEmpty() && this->address) + valueCache += QString::fromLatin1("@0x" + QByteArray::number(this->address, 16)); // if (origaddr) // result += QString::fromLatin1(" (0x" + QByteArray::number(origaddr, 16) + ')'); - return result; +} + +static QString displayValue(const WatchItem *item) +{ + if (item->valueCache.isEmpty()) + item->updateValueCache(); + return item->valueCache; } static QString displayType(const WatchItem *item) From 708c62913330f7e4b2ba31a20edc75943161c679 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 24 Feb 2023 17:31:28 +0100 Subject: [PATCH 37/43] Utils: Use double quotes for emphasis in UI text Change-Id: I00b27ee40ba131ec6472b03ac7f23c93639a9cea Reviewed-by: Marcus Tillmanns --- src/libs/utils/filepath.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index db8008182f5..230dc251cbc 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -1732,7 +1732,7 @@ expected_str FilePath::localSource() const return *this; QTC_ASSERT(s_deviceHooks.localSource, - return make_unexpected(Tr::tr("No 'localSource' device hook set."))); + return make_unexpected(Tr::tr("No \"localSource\" device hook set."))); return s_deviceHooks.localSource(*this); } From be138dee1038a819a794e6895f62fddb7e44cff5 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 24 Feb 2023 17:34:36 +0100 Subject: [PATCH 38/43] Text editor: Fix typo in UI text: temporary > temporarily Change-Id: I45c7cfb62556f5f3dead9d90e1fe911752ca72a7 Reviewed-by: hjk --- src/plugins/texteditor/textmark.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/texteditor/textmark.cpp b/src/plugins/texteditor/textmark.cpp index 63e339ca8b2..4a8320de57b 100644 --- a/src/plugins/texteditor/textmark.cpp +++ b/src/plugins/texteditor/textmark.cpp @@ -284,7 +284,7 @@ void TextMark::addToToolTipLayout(QGridLayout *target) const const bool isHidden = TextDocument::marksAnnotationHidden(m_category.id); visibilityAction->setIcon(Utils::Icons::EYE_OPEN_TOOLBAR.icon()); const QString tooltip = (isHidden ? Tr::tr("Show inline annotations for %1") - : Tr::tr("Temporary hide inline annotations for %1")) + : Tr::tr("Temporarily hide inline annotations for %1")) .arg(m_category.displayName); visibilityAction->setToolTip(tooltip); auto callback = [id = m_category.id, isHidden] { From 55c2a55a6036fa03e8a632314df36ad070c65792 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 23 Feb 2023 14:47:43 +0100 Subject: [PATCH 39/43] Tests: Fix shootout test Broke with 435a4e9dd49 long time ago. Change-Id: I1f3c88f63f6a3141c65ee0e2fdc5d8b102283618 Reviewed-by: hjk --- tests/manual/shootout/tst_codesize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/manual/shootout/tst_codesize.cpp b/tests/manual/shootout/tst_codesize.cpp index bcc454024b1..49d24e48d6e 100644 --- a/tests/manual/shootout/tst_codesize.cpp +++ b/tests/manual/shootout/tst_codesize.cpp @@ -241,7 +241,7 @@ void tst_CodeSize::codesize() #endif const int index = suite.cmd.indexOf(' '); QString command = suite.cmd.left(index); - arguments = QString::fromLatin1(suite.cmd.mid(index + 1)) + arguments; + arguments = QString::fromLatin1(suite.cmd.mid(index + 1)) + ' ' + arguments; QProcess final; final.setWorkingDirectory(t->buildPath); final.setProcessEnvironment(m_env); From 99b1cc5c2494e56c740bf1d8665a5bf750a25f39 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Feb 2023 11:32:10 +0100 Subject: [PATCH 40/43] Qnx: Allow broader kit generation So far we insisted on a Qt version being present. For more general use, including limited testing it's more convenient to also allow kits being generated when no QNX Qt is around. Change-Id: I99954b76543f2a04063a737444dce0ae5c921929 Reviewed-by: Christian Stenger --- src/plugins/qnx/qnxconfiguration.cpp | 14 +------------- src/plugins/qnx/qnxconfiguration.h | 1 - src/plugins/qnx/qnxsettingspage.cpp | 2 +- src/plugins/qnx/qnxutils.cpp | 2 -- 4 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/plugins/qnx/qnxconfiguration.cpp b/src/plugins/qnx/qnxconfiguration.cpp index bb3e97995ae..c3ec91d1f48 100644 --- a/src/plugins/qnx/qnxconfiguration.cpp +++ b/src/plugins/qnx/qnxconfiguration.cpp @@ -176,15 +176,6 @@ bool QnxConfiguration::isActive() const return hasToolChain && hasDebugger; } -bool QnxConfiguration::canCreateKits() const -{ - if (!isValid()) - return false; - - return Utils::anyOf(m_targets, - [this](const Target &target) -> bool { return qnxQtVersion(target); }); -} - FilePath QnxConfiguration::sdpPath() const { return envFile().parentDir(); @@ -276,10 +267,7 @@ QList QnxConfiguration::findToolChain(const QList &alr void QnxConfiguration::createKit(const Target &target, const QnxToolChainMap &toolChainMap, const QVariant &debugger) { - QnxQtVersion *qnxQt = qnxQtVersion(target); - // Do not create incomplete kits if no qt qnx version found - if (!qnxQt) - return; + QnxQtVersion *qnxQt = qnxQtVersion(target); // nullptr is ok. const auto init = [&](Kit *k) { QtKitAspect::setQtVersion(k, qnxQt); diff --git a/src/plugins/qnx/qnxconfiguration.h b/src/plugins/qnx/qnxconfiguration.h index 2876535b217..34056536c35 100644 --- a/src/plugins/qnx/qnxconfiguration.h +++ b/src/plugins/qnx/qnxconfiguration.h @@ -47,7 +47,6 @@ public: bool activate(); void deactivate(); bool isActive() const; - bool canCreateKits() const; Utils::FilePath sdpPath() const; QList autoDetect( diff --git a/src/plugins/qnx/qnxsettingspage.cpp b/src/plugins/qnx/qnxsettingspage.cpp index e809ca876f7..0d354037735 100644 --- a/src/plugins/qnx/qnxsettingspage.cpp +++ b/src/plugins/qnx/qnxsettingspage.cpp @@ -183,7 +183,7 @@ void QnxSettingsWidget::updateInformation() m_configsCombo->itemData(currentIndex).value()); // update the checkbox - m_generateKitsCheckBox->setEnabled(config ? config->canCreateKits() : false); + m_generateKitsCheckBox->setEnabled(config ? config->isValid() : false); m_generateKitsCheckBox->setChecked(config ? config->isActive() : false); // update information diff --git a/src/plugins/qnx/qnxutils.cpp b/src/plugins/qnx/qnxutils.cpp index 4e315b95a15..697e95bebc6 100644 --- a/src/plugins/qnx/qnxutils.cpp +++ b/src/plugins/qnx/qnxutils.cpp @@ -4,13 +4,11 @@ #include "qnxutils.h" #include -#include #include #include #include #include -#include #include using namespace ProjectExplorer; From 8ab0c965a49694ae25b35866854b0e312e0a2f39 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Feb 2023 12:00:15 +0100 Subject: [PATCH 41/43] Qnx: Mark new debuggers from setup dialog as not autodetected And use the right device for its base environment. Change-Id: Ida6d9c5dd88b766659311f4eacca8ced3c5531cd Reviewed-by: Christian Stenger Reviewed-by: --- src/plugins/qnx/qnxconfiguration.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/qnx/qnxconfiguration.cpp b/src/plugins/qnx/qnxconfiguration.cpp index c3ec91d1f48..7a8f19926f8 100644 --- a/src/plugins/qnx/qnxconfiguration.cpp +++ b/src/plugins/qnx/qnxconfiguration.cpp @@ -217,13 +217,12 @@ void QnxConfiguration::createTools(const Target &target) QVariant QnxConfiguration::createDebugger(const Target &target) { - Utils::Environment sysEnv = Utils::Environment::systemEnvironment(); + Environment sysEnv = m_qnxHost.deviceEnvironment(); sysEnv.modify(qnxEnvironmentItems()); Debugger::DebuggerItem debugger; debugger.setCommand(target.m_debuggerPath); debugger.reinitializeFromFile(nullptr, &sysEnv); - debugger.setAutoDetected(true); debugger.setUnexpandedDisplayName(Tr::tr("Debugger for %1 (%2)") .arg(displayName()) .arg(target.shortDescription())); From be1f95082d6334da2625e73ec198797729a2b066 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Feb 2023 13:25:35 +0100 Subject: [PATCH 42/43] Debugger: Save a few cycles in WatchData Change-Id: Id2fc21fcc917969fa2f31864f4ff91f4df8c19d2 Reviewed-by: David Schulz Reviewed-by: --- src/plugins/debugger/watchdata.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index 4b64248e2f7..329e58b88b7 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -15,6 +15,10 @@ namespace Debugger::Internal { +const QStringView inameLocal = u"local."; +const QStringView inameWatch = u"watch."; +const QStringView inameInspect = u"inspect."; + bool isPointerType(const QStringView type) { return type.endsWith('*') || type.endsWith(u"* const"); @@ -308,7 +312,7 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort) if (mi.isValid()) { address = mi.toAddress(); if (exp.isEmpty()) { - if (iname.startsWith("local.") && iname.count('.') == 1) + if (iname.startsWith(inameLocal) && iname.count('.') == 1) // Solve one common case of adding 'class' in // *(class X*)0xdeadbeef for gdb. exp = name; @@ -505,7 +509,7 @@ bool WatchItem::isLocal() const if (arrayIndex >= 0) if (const WatchItem *p = parent()) return p->isLocal(); - return iname.startsWith("local."); + return iname.startsWith(inameLocal); } bool WatchItem::isWatcher() const @@ -513,7 +517,7 @@ bool WatchItem::isWatcher() const if (arrayIndex >= 0) if (const WatchItem *p = parent()) return p->isWatcher(); - return iname.startsWith("watch."); + return iname.startsWith(inameWatch); } bool WatchItem::isInspect() const @@ -521,7 +525,7 @@ bool WatchItem::isInspect() const if (arrayIndex >= 0) if (const WatchItem *p = parent()) return p->isInspect(); - return iname.startsWith("inspect."); + return iname.startsWith(inameInspect); } QString WatchItem::internalName() const From ca8d4082ecfa2efc3c8f105a8b07b7fc64e34432 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Feb 2023 17:22:53 +0100 Subject: [PATCH 43/43] Debugger: Compress consecutive calls to updateLocalsWindow() When expanding all children of a long array, this is called once per item. If we have one update in the end that's enough. Change-Id: Ibb63a9aef752418a1dcafb6190edf5a8005a855f Reviewed-by: David Schulz --- src/plugins/debugger/watchhandler.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 4823a952b90..371f7fe4975 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -469,6 +469,7 @@ public: QSet m_expandedINames; QTimer m_requestUpdateTimer; + QTimer m_localsWindowsTimer; QHash m_reportedTypeInfo; QHash m_reportedTypeFormats; // Type name -> Dumper Formats @@ -515,6 +516,14 @@ WatchModel::WatchModel(WatchHandler *handler, DebuggerEngine *engine) connect(&m_requestUpdateTimer, &QTimer::timeout, this, &WatchModel::updateStarted); + m_localsWindowsTimer.setSingleShot(true); + m_localsWindowsTimer.setInterval(50); + connect(&m_localsWindowsTimer, &QTimer::timeout, this, [this] { + // Force show/hide of return view. + const bool showReturn = m_returnRoot->childCount() != 0; + m_engine->updateLocalsWindow(showReturn); + }); + DebuggerSettings &s = *debuggerSettings(); connect(&s.sortStructMembers, &BaseAspect::changed, m_engine, &DebuggerEngine::updateLocals); @@ -2559,9 +2568,7 @@ void WatchModel::clearWatches() void WatchHandler::updateLocalsWindow() { - // Force show/hide of return view. - bool showReturn = m_model->m_returnRoot->childCount() != 0; - m_engine->updateLocalsWindow(showReturn); + m_model->m_localsWindowsTimer.start(); } QStringList WatchHandler::watchedExpressions()