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/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" 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/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" 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 00000000000..fbf09f8751d Binary files /dev/null and b/doc/qtcreator/images/qtcreator-python-interpreter-edit-mode.webp differ 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 731c97f1c23..00000000000 Binary files a/doc/qtcreator/images/qtcreator-qml-js-editing.png and /dev/null differ 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 00000000000..ab9a9f48422 Binary files /dev/null and b/doc/qtcreator/images/qtcreator-qml-js-editing.webp differ 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/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 diff --git a/doc/qtcreator/src/python/creator-python-project.qdocinc b/doc/qtcreator/src/python/creator-python-project.qdocinc index 3ba1ec89f20..436e712f0b1 100644 --- a/doc/qtcreator/src/python/creator-python-project.qdocinc +++ b/doc/qtcreator/src/python/creator-python-project.qdocinc @@ -17,10 +17,17 @@ such as code completion and annotations. Select \uicontrol Install to install PySide6 and the language server. - To view and manage the available Python interpreters, select \uicontrol Edit - > \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: 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 diff --git a/doc/qtcreatordev/src/coding-style.qdoc b/doc/qtcreatordev/src/coding-style.qdoc index 1aed25bc3ef..22da9cca0cb 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 @@ -914,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 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 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) diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp index 6ca4b6983cb..3ccbf1f86e8 100644 --- a/src/libs/utils/basetreeview.cpp +++ b/src/libs/utils/basetreeview.cpp @@ -152,45 +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(); - 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; - 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; } 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(), diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 7d2b07f8c22..29ee8de6f75 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -1878,7 +1878,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); } 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/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..5c9b6564c7b 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/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); 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..b3967acf1e0 --- /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); + + QVERIFY(actualBuildTools != nullptr); + QCOMPARE(actualBuildTools->descriptionText(), description); + QCOMPARE(actualBuildTools->displayText(), displayText); + QCOMPARE(actualBuildTools->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseBuildToolsPackageEmpty() +{ + BuildTools *actualBuildTools = m_parser->parseBuildToolsPackage({""}); + + QVERIFY(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)); + + QVERIFY(actualSdkTool != nullptr); + QCOMPARE(actualSdkTool->descriptionText(), description); + QCOMPARE(actualSdkTool->displayText(), displayText); + QCOMPARE(actualSdkTool->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseSdkToolsPackageEmpty() +{ + std::unique_ptr actualSdkTool(m_parser->parseSdkToolsPackage({""})); + + QVERIFY(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)); + + QVERIFY(actualPlatformTool != nullptr); + QCOMPARE(actualPlatformTool->descriptionText(), description); + QCOMPARE(actualPlatformTool->displayText(), displayText); + QCOMPARE(actualPlatformTool->revision(), revision); +} + +void SdkManagerOutputParserTest::testParsePlatformToolsPackageEmpty() +{ + std::unique_ptr actualPlatformTool( + m_parser->parsePlatformToolsPackage({""})); + + QVERIFY(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)); + + QVERIFY(actualEmulatorTools != nullptr); + QCOMPARE(actualEmulatorTools->descriptionText(), description); + QCOMPARE(actualEmulatorTools->displayText(), displayText); + QCOMPARE(actualEmulatorTools->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseEmulatorToolsPackageEmpty() +{ + std::unique_ptr actualEmulatorTools( + m_parser->parseEmulatorToolsPackage({""})); + + QVERIFY(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)); + + QVERIFY(actualNdkPackage != nullptr); + QCOMPARE(actualNdkPackage->descriptionText(), description); + QCOMPARE(actualNdkPackage->displayText(), displayText); + QCOMPARE(actualNdkPackage->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseNdkPackageEmpty() +{ + std::unique_ptr actualNdkPackage(m_parser->parseNdkPackage({""})); + + QVERIFY(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)); + + QVERIFY(actualExtraTools != nullptr); + QCOMPARE(actualExtraTools->descriptionText(), description); + QCOMPARE(actualExtraTools->displayText(), displayText); + QCOMPARE(actualExtraTools->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseExtraToolsPackageEmpty() +{ + std::unique_ptr actualExtraTools( + m_parser->parseExtraToolsPackage({""})); + + QVERIFY(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)); + + QVERIFY(actualGenericTools != nullptr); + QCOMPARE(actualGenericTools->descriptionText(), description); + QCOMPARE(actualGenericTools->displayText(), displayText); + QCOMPARE(actualGenericTools->revision(), revision); +} + +void SdkManagerOutputParserTest::testParseGenericToolsPackageEmpty() +{ + std::unique_ptr actualGenericTools( + m_parser->parseGenericTools({""})); + + QVERIFY(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)); + + QVERIFY(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({""})); + + QVERIFY(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; + + QVERIFY(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; + + QVERIFY(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 diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp index 9dea510cdde..2ec1d4afcd8 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.cpp +++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp @@ -104,7 +104,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 f7746b2f291..8916b8d9818 100644 --- a/src/plugins/autotest/qtest/qttestoutputreader.cpp +++ b/src/plugins/autotest/qtest/qttestoutputreader.cpp @@ -464,7 +464,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 ff7911dd432..1f83ff56c11 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -715,7 +715,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); diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp index 24a0e61dd87..8ab7a71b339 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(); @@ -105,12 +105,10 @@ 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; - if (!parser.isCurrent('\\')) - return false; const char c1 = parser.lookAhead(1).unicode(); const char c2 = parser.lookAhead(2).unicode(); @@ -123,12 +121,10 @@ 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; - 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, DebuggerOutputParser::Buffer &buffer) { if (parser.isAtEnd()) { qDebug() << "MI Parse Error, unterminated backslash escape"; @@ -152,65 +148,64 @@ static void parseSimpleEscape(DebuggerOutputParser &parser, QString &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 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, DebuggerOutputParser::Buffer &buffer) { - 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, buffer)) + return; + if (parseHexEscapedHelper(parser, buffer)) + return; parser.advance(); - parseSimpleEscape(parser, result); + parseSimpleEscape(parser, buffer); } else { - result += parser.readChar(); + 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. - QString result; - result.reserve(to - from); while (from < to) { if (*from == '"') { ++from; - return 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 46d0b38f8bc..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,9 +119,11 @@ public: int readInt(); QChar readChar(); QString readCString(); - QString readString(const std::function &isValidChar); + void readCStringData(Buffer &buffer); - QString buffer() const { return QString(from, to - from); } + QStringView readString(const std::function &isValidChar); + + QStringView buffer() const { return QStringView(from, to - from); } int remainingChars() const { return int(to - from); } void skipCommas(); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index b420104afb5..1894dd3f4e5 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; @@ -410,11 +410,14 @@ void GdbEngine::handleResponse(const QString &buff) break; } } + + if (debuggerSettings()->logTimeStamps.value()) + showMessage(QString("Output handled")); } -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 +425,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 +446,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 +467,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 +475,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 +487,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 +495,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 +550,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 +564,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 +574,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); diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index d42e8331ca9..8d0af0e4d31 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"); @@ -316,7 +320,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; @@ -519,7 +523,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 @@ -527,7 +531,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 @@ -535,7 +539,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 diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h index 15ccdf019b8..42d046f2a13 100644 --- a/src/plugins/debugger/watchdata.h +++ b/src/plugins/debugger/watchdata.h @@ -80,6 +80,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 144ef1d9a0c..8484f682d19 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -472,6 +472,7 @@ public: QSet m_expandedINames; QHash m_maxArrayCount; QTimer m_requestUpdateTimer; + QTimer m_localsWindowsTimer; QHash m_reportedTypeInfo; QHash m_reportedTypeFormats; // Type name -> Dumper Formats @@ -518,6 +519,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); @@ -932,15 +941,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) @@ -2311,7 +2327,7 @@ void WatchHandler::notifyUpdateFinished() m_model->forAllItems([this](WatchItem *item) { if (item->wantsChildren && isExpandedIName(item->iname) && item->name != WatchItem::loadMoreName) { - 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; } }); @@ -2570,9 +2586,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() diff --git a/src/plugins/languageclient/locatorfilter.cpp b/src/plugins/languageclient/locatorfilter.cpp index 2b0eca3a578..03f3cf50bca 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); } } diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 86f93307147..2402a8004c5 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -2726,7 +2726,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(); }); } diff --git a/src/plugins/qnx/qnxconfiguration.cpp b/src/plugins/qnx/qnxconfiguration.cpp index 57bac90106b..7a8f19926f8 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; @@ -178,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(); @@ -194,7 +183,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); @@ -228,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())); @@ -278,10 +266,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); @@ -336,19 +321,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) @@ -369,6 +378,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(); 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/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..0d354037735 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.")); @@ -184,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 3e0f5106cec..697e95bebc6 100644 --- a/src/plugins/qnx/qnxutils.cpp +++ b/src/plugins/qnx/qnxutils.cpp @@ -4,16 +4,11 @@ #include "qnxutils.h" #include -#include #include #include #include #include -#include -#include -#include -#include #include using namespace ProjectExplorer; @@ -125,7 +120,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) @@ -133,68 +128,10 @@ FilePath QnxUtils::envFilePath(const FilePath &sdpPath) else entries = sdpPath.dirEntries({{"*-env.sh"}}); - if (!entries.isEmpty()) - return entries.first(); + if (entries.isEmpty()) + return {}; - 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)); + 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 ab108f72051..4f523953e46 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: @@ -38,19 +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 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); - 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 diff --git a/src/plugins/texteditor/textmark.cpp b/src/plugins/texteditor/textmark.cpp index 01746390ffe..b7ded20d3fc 100644 --- a/src/plugins/texteditor/textmark.cpp +++ b/src/plugins/texteditor/textmark.cpp @@ -286,7 +286,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] { diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index d67e8de1f4b..39156f9a880 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -3577,10 +3577,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") @@ -7467,7 +7467,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") 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" diff --git a/tests/auto/utils/tasktree/tst_tasktree.cpp b/tests/auto/utils/tasktree/tst_tasktree.cpp index ca43a74ddd6..90ea043a11a 100644 --- a/tests/auto/utils/tasktree/tst_tasktree.cpp +++ b/tests/auto/utils/tasktree/tst_tasktree.cpp @@ -1138,26 +1138,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) 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); diff --git a/tests/system/shared/classes.py b/tests/system/shared/classes.py index 37a3b812fa1..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) @@ -75,19 +79,20 @@ class LibType: return "Qt Plugin" return None -class Qt5Path: +class QtPath: DOCS = 0 EXAMPLES = 1 @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) - if pathSpec == Qt5Path.DOCS: - return map(lambda target: Qt5Path.docsPath(target), qt5targets) - elif pathSpec == Qt5Path.EXAMPLES: - return map(lambda target: Qt5Path.examplesPath(target), qt5targets) + qtTargets.append(Targets.DESKTOP_5_4_1_GCC) + if pathSpec == QtPath.DOCS: + return map(lambda target: QtPath.docsPath(target), qtTargets) + elif pathSpec == QtPath.EXAMPLES: + return map(lambda target: QtPath.examplesPath(target), qtTargets) else: test.fatal("Unknown pathSpec given: %s" % str(pathSpec)) return [] @@ -97,9 +102,9 @@ class Qt5Path: 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,35 +115,50 @@ class Qt5Path: 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): - qtVersionStr = Qt5Path.__preCheckAndExtractQtVersionStr__(target) - versionTuple = Qt5Path.toVersionTuple(qtVersionStr) - return versionTuple[1], versionTuple[2] + def getQtVersion(target): + qtVersionStr = QtPath.__preCheckAndExtractQtVersionStr__(target) + versionTuple = QtPath.toVersionTuple(qtVersionStr) + return versionTuple @staticmethod def examplesPath(target): - qtMinorVersion, qtPatchVersion = Qt5Path.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) - return os.path.join(Qt5Path.__createPlatformQtPath__(qtMinorVersion), path) + 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 = Qt5Path.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) - return os.path.join(Qt5Path.__createPlatformQtPath__(qtMinorVersion), path) + if Targets.isOnlineInstaller(target): + return os.path.join(QtPath.__createQtOnlineInstallerPath__(), 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_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_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_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_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)): 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")