Merge remote-tracking branch 'origin/10.0'

Conflicts:
	src/plugins/debugger/watchhandler.cpp

Change-Id: If759b6260dfa008738d3a0ce543eb0eead8a8bba
This commit is contained in:
Eike Ziller
2023-02-27 09:48:12 +01:00
73 changed files with 1388 additions and 407 deletions

View File

@@ -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

View File

@@ -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"

View File

@@ -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)

View File

@@ -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"

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -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

View File

@@ -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 {<Qt Installation>/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

View File

@@ -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:

View File

@@ -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

View File

@@ -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<int> values = {1, 2, 3, 4, 5};
const QList<int> 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<int> values = {1, 2, 3, 4, integerValue}; // prefer that syntax for initializer lists
QList<int> 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

View File

@@ -27,6 +27,8 @@ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf
#ifndef TCB_SPAN_NO_EXCEPTIONS
#include <cstdio>
#include <stdexcept>
#else
#include <exception> // for std::terminate
#endif
// Various feature test macros

View File

@@ -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$<$<CONFIG:Debug>:Debug>")
target_compile_options(qtcreatorcdbext PUBLIC /EHsc)
find_package(Python3 3.8 COMPONENTS Development)

View File

@@ -152,45 +152,43 @@ public:
}
}
void considerItems(int column, QModelIndex start, int *minimum, bool single) const
int suggestedColumnSize(int column) const
{
const QHeaderView *h = q->header();
QTC_ASSERT(h, return -1);
const QAbstractItemModel *m = q->model();
QTC_ASSERT(m, return -1);
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 * avg;
auto considerItems = [&](const QModelIndex &start, bool single) {
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;
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 (w > minimum)
minimum = w;
if (single)
break;
a = q->indexBelow(a);
}
}
};
int suggestedColumnSize(int column) const
{
QHeaderView *h = q->header();
QTC_ASSERT(h, return -1);
QAbstractItemModel *m = q->model();
QTC_ASSERT(m, return -1);
QFontMetrics fm = q->fontMetrics();
int minimum = fm.horizontalAdvance(m->headerData(column, Qt::Horizontal).toString())
+ 2 * fm.horizontalAdvance(QLatin1Char('m'));
considerItems(column, q->indexAt(QPoint(1, 1)), &minimum, false);
considerItems(q->indexAt(QPoint(1, 1)), false);
const QVariant extraIndices = m->data(QModelIndex(), BaseTreeView::ExtraIndicesForColumnWidth);
const QList<QModelIndex> values = extraIndices.value<QModelIndexList>();
for (const QModelIndex &a : values)
considerItems(column, a, &minimum, true);
considerItems(a, true);
return minimum;
}

View File

@@ -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(),

View File

@@ -1878,7 +1878,7 @@ expected_str<FilePath> 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);
}

View File

@@ -175,6 +175,7 @@ public:
~RuntimeData();
static QList<int> createStorages(const TaskContainer::ConstData &constData);
void callStorageDoneHandlers();
bool updateSuccessBit(bool success);
int currentLimit() const;
@@ -384,6 +385,15 @@ QList<int> 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();
}

View File

@@ -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
)

View File

@@ -123,6 +123,8 @@ Project {
"android_tst.qrc",
"androidsdkmanager_test.cpp",
"androidsdkmanager_test.h",
"sdkmanageroutputparser_test.cpp",
"sdkmanageroutputparser_test.h",
]
}
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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)

View File

@@ -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);

View File

@@ -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<AndroidSdkManagerTest>();
addTest<SdkManagerOutputParserTest>();
#endif
}

View File

@@ -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

View File

@@ -3,8 +3,9 @@
#include "sdkmanageroutputparser.h"
#include "avdmanageroutputparser.h"
#include "androidconstants.h"
#include "androidsdkpackage.h"
#include "avdmanageroutputparser.h"
#include <utils/algorithm.h>
@@ -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;

View File

@@ -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 <utils/filepath.h>
@@ -74,6 +73,7 @@ private:
MarkerTag m_currentSection = MarkerTag::None;
QHash<AndroidSdkPackage *, int> m_systemImages;
friend class SdkManagerOutputParserTest;
};
} // namespace Internal
} // namespace Android

View File

@@ -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 <QMap>
#include <QString>
#include <QTest>
#include <QVersionNumber>
#include <QtGlobal>
#include <qtestcase.h>
#include <QVersionNumber>
namespace Android::Internal {
SdkManagerOutputParserTest::SdkManagerOutputParserTest(QObject *parent)
: QObject(parent)
, m_parser(std::make_unique<SdkManagerOutputParser>(m_packages))
{}
SdkManagerOutputParserTest::~SdkManagerOutputParserTest() = default;
void SdkManagerOutputParserTest::testParseMarkers_data()
{
QTest::addColumn<QString>("output");
QTest::addColumn<SdkManagerOutputParser::MarkerTag>("markerTag");
QMap<SdkManagerOutputParser::MarkerTag, QString> 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<QStringList>("output");
QTest::addColumn<QString>("description");
QTest::addColumn<QString>("displayText");
QTest::addColumn<QVersionNumber>("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<QStringList>("output");
QTest::addColumn<QString>("description");
QTest::addColumn<QString>("displayText");
QTest::addColumn<QVersionNumber>("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<SdkTools> 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<SdkTools> actualSdkTool(m_parser->parseSdkToolsPackage({""}));
QVERIFY(actualSdkTool == nullptr);
}
// PlatformTools
void SdkManagerOutputParserTest::testParsePlatformToolsPackage_data()
{
QTest::addColumn<QStringList>("output");
QTest::addColumn<QString>("description");
QTest::addColumn<QString>("displayText");
QTest::addColumn<QVersionNumber>("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<PlatformTools> 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<PlatformTools> actualPlatformTool(
m_parser->parsePlatformToolsPackage({""}));
QVERIFY(actualPlatformTool == nullptr);
}
// EmulatorTools
void SdkManagerOutputParserTest::testParseEmulatorToolsPackage_data()
{
QTest::addColumn<QStringList>("output");
QTest::addColumn<QString>("description");
QTest::addColumn<QString>("displayText");
QTest::addColumn<QVersionNumber>("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<EmulatorTools> 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<EmulatorTools> actualEmulatorTools(
m_parser->parseEmulatorToolsPackage({""}));
QVERIFY(actualEmulatorTools == nullptr);
}
// NDK
void SdkManagerOutputParserTest::testParseNdkPackage_data()
{
QTest::addColumn<QStringList>("output");
QTest::addColumn<QString>("description");
QTest::addColumn<QString>("displayText");
QTest::addColumn<QVersionNumber>("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<Ndk> 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<Ndk> actualNdkPackage(m_parser->parseNdkPackage({""}));
QVERIFY(actualNdkPackage == nullptr);
}
// ExtraTools
void SdkManagerOutputParserTest::testParseExtraToolsPackage_data()
{
QTest::addColumn<QStringList>("output");
QTest::addColumn<QString>("description");
QTest::addColumn<QString>("displayText");
QTest::addColumn<QVersionNumber>("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<ExtraTools> 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<ExtraTools> actualExtraTools(
m_parser->parseExtraToolsPackage({""}));
QVERIFY(actualExtraTools == nullptr);
}
// GenericTools
void SdkManagerOutputParserTest::testParseGenericToolsPackage_data()
{
QTest::addColumn<QStringList>("output");
QTest::addColumn<QString>("description");
QTest::addColumn<QString>("displayText");
QTest::addColumn<QVersionNumber>("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<GenericSdkPackage> 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<GenericSdkPackage> actualGenericTools(
m_parser->parseGenericTools({""}));
QVERIFY(actualGenericTools == nullptr);
}
// Platform
void SdkManagerOutputParserTest::testParsePlatformPackage_data()
{
QTest::addColumn<QStringList>("output");
QTest::addColumn<QString>("description");
QTest::addColumn<QString>("installLocation");
QTest::addColumn<QVersionNumber>("revision");
QTest::addColumn<QString>("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<AndroidSdkPackage> 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<AndroidSdkPackage> actualPlatform(m_parser->parsePlatform({""}));
QVERIFY(actualPlatform == nullptr);
}
// SystemImage
void SdkManagerOutputParserTest::testParseSystemImagePackage_data()
{
QTest::addColumn<QStringList>("output");
QTest::addColumn<QString>("description");
QTest::addColumn<QString>("installLocation");
QTest::addColumn<QVersionNumber>("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<SystemImage *, int> 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<SystemImage *, int> actualSystemImagePair(m_parser->parseSystemImage({""}));
SystemImage *actualSystemImage = actualSystemImagePair.first;
QVERIFY(actualSystemImage == nullptr);
delete actualSystemImage;
}
void SdkManagerOutputParserTest::testParsePackageListing()
{
QFETCH(QString, sdkManagerOutput);
QFETCH(QList<AndroidSdkPackage::PackageType>, 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<int>("sdkManagerOutputPackagesNumber");
QTest::addColumn<QList<AndroidSdkPackage::PackageType>>("packageTypes");
QTest::addColumn<QString>("sdkManagerOutput");
const QList<AndroidSdkPackage::PackageType> 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

View File

@@ -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 <QObject>
#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<SdkManagerOutputParser> 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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -9,6 +9,8 @@
#include <QColor>
#include <optional>
namespace Autotest {
class ITestTreeItem;
@@ -65,9 +67,9 @@ struct ResultHooks
using IntermediateHook = std::function<bool(const TestResult &, const TestResult &)>;
using CreateResultHook = std::function<TestResult(const TestResult &)>;
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<QString> 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

View File

@@ -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);

View File

@@ -47,12 +47,12 @@ void DebuggerOutputParser::skipSpaces()
++from;
}
QString DebuggerOutputParser::readString(const std::function<bool(char)> &isValidChar)
QStringView DebuggerOutputParser::readString(const std::function<bool(char)> &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;
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)

View File

@@ -8,6 +8,7 @@
#include <QString>
#include <QJsonValue>
#include <QJsonObject>
#include <QVarLengthArray>
#include <QVector>
#include <utils/filepath.h>
@@ -105,6 +106,8 @@ class DebuggerOutputParser
public:
explicit DebuggerOutputParser(const QString &output);
using Buffer = QVarLengthArray<char, 30>;
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<bool(char)> &isValidChar);
void readCStringData(Buffer &buffer);
QString buffer() const { return QString(from, to - from); }
QStringView readString(const std::function<bool(char)> &isValidChar);
QStringView buffer() const { return QStringView(from, to - from); }
int remainingChars() const { return int(to - from); }
void skipCommas();

View File

@@ -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="<MULTIPLE>",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>",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"

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
};

View File

@@ -472,6 +472,7 @@ public:
QSet<QString> m_expandedINames;
QHash<QString, int> m_maxArrayCount;
QTimer m_requestUpdateTimer;
QTimer m_localsWindowsTimer;
QHash<QString, TypeInfo> m_reportedTypeInfo;
QHash<QString, DisplayFormats> 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()

View File

@@ -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);
}
}

View File

@@ -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();
});
}

View File

@@ -27,13 +27,11 @@
#include <debugger/debuggeritemmanager.h>
#include <debugger/debuggerkitinformation.h>
#include <coreplugin/icore.h>
#include <utils/algorithm.h>
#include <QDebug>
#include <QDir>
#include <QDomDocument>
#include <QMessageBox>
#include <QFileInfo>
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<QnxQtVersion *>(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<ToolChain *> QnxConfiguration::findToolChain(const QList<ToolChain *> &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 <ConfigInstallInformation> 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();

View File

@@ -47,7 +47,6 @@ public:
bool activate();
void deactivate();
bool isActive() const;
bool canCreateKits() const;
Utils::FilePath sdpPath() const;
QList<ProjectExplorer::ToolChain *> autoDetect(

View File

@@ -99,7 +99,6 @@ void QnxConfigurationManager::saveConfigs()
++count;
}
data.insert(QLatin1String(QNXConfigCountKey), count);
m_writer->save(data, Core::ICore::dialogParent());
}

View File

@@ -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<void*>());
// 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

View File

@@ -4,16 +4,11 @@
#include "qnxutils.h"
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/qtcprocess.h>
#include <utils/temporaryfile.h>
#include <QDebug>
#include <QDir>
#include <QDirIterator>
#include <QDomDocument>
#include <QStandardPaths>
#include <QApplication>
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 {};
}
QString QnxUtils::defaultTargetVersion(const QString &sdpPath)
{
const QList<ConfigInstallInformation> configs = installedConfigs();
for (const ConfigInstallInformation &sdpInfo : configs) {
if (!sdpInfo.path.compare(sdpPath, HostOsInfo::fileNameCaseSensitivity()))
return sdpInfo.version;
}
return QString();
}
QList<ConfigInstallInformation> QnxUtils::installedConfigs(const QString &configPath)
{
QList<ConfigInstallInformation> 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<QnxTarget> QnxUtils::findTargets(const FilePath &basePath)

View File

@@ -3,30 +3,14 @@
#pragma once
#include "qnxconstants.h"
#include <projectexplorer/abi.h>
#include <utils/environment.h>
#include <utils/qtcassert.h>
#include <utils/fileutils.h>
#include <utils/filepath.h>
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<ConfigInstallInformation> installedConfigs(const QString &configPath = QString());
static Utils::EnvironmentItems qnxEnvironment(const Utils::FilePath &sdpPath);
static QList<QnxTarget> 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<QnxTarget> findTargets(const Utils::FilePath &basePath);
ProjectExplorer::Abi convertAbi(const ProjectExplorer::Abi &abi);
ProjectExplorer::Abis convertAbis(const ProjectExplorer::Abis &abis);
}
} // Qnx::Internal

View File

@@ -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] {

View File

@@ -3577,10 +3577,10 @@ void tst_Dumpers::dumper_data()
+ Check("ptr50.data", "", "Foo")
+ Check("ptr53", "", "@QWeakPointer<Foo>")
+ 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")

View File

@@ -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<QString>("pattern");
QTest::addColumn<QString>("string");
QTest::addColumn<bool>("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"

View File

@@ -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<CustomStorage> storage;
const auto setupProcess = [testAppPath = m_testAppPath](QtcProcess &process) {
process.setCommand(CommandLine(testAppPath, {"-sleep", "1000"}));
};
const Group root {
Storage(TreeStorage<CustomStorage>()),
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)

View File

@@ -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);

View File

@@ -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):

View File

@@ -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)

View File

@@ -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)):

View File

@@ -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)):

View File

@@ -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"

View File

@@ -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)):

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)):

View File

@@ -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

View File

@@ -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

View File

@@ -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))

View File

@@ -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")

View File

@@ -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'

View File

@@ -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)):

View File

@@ -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 = []

View File

@@ -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)):

View File

@@ -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")