Merge remote-tracking branch 'origin/11.0'

Change-Id: Idbf5f641aa9db7574cf2a4bd09adb8bcd03da894
This commit is contained in:
David Schulz
2023-08-22 08:10:48 +02:00
15 changed files with 206 additions and 47 deletions

73
dist/changelog/changes-11.0.2.md vendored Normal file
View File

@@ -0,0 +1,73 @@
Qt Creator 11.0.2
=================
Qt Creator version 11.0.2 contains bug fixes.
The most important changes are listed in this document. For a complete list of
changes, see the Git log for the Qt Creator sources that you can check out from
the public Git repository. For example:
git clone git://code.qt.io/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline origin/v11.0.1..v11.0.2
General
-------
* Allow fractional high DPI scaling without modifying the environment
([QTCREATORBUG-29461](https://bugreports.qt.io/browse/QTCREATORBUG-29461))
Editing
-------
### General
* Fixed a potential crash when reloading a document
([QTCREATORBUG-29432](https://bugreports.qt.io/browse/QTCREATORBUG-29432))
### Copilot
* Fixed a crash when configuring an unusable copilot agent in the settings
Debug
-----
* Fixed a problem where debugging with "Run In Terminal" would fail on Linux
([QTCREATORBUG-29463](https://bugreports.qt.io/browse/QTCREATORBUG-29463))
Projects
--------
### CMake
* Fixed code completion for ui file components for CMake based projects
([QTCREATORBUG-28787](https://bugreports.qt.io/browse/QTCREATORBUG-28787))
* Fix reading ninjaPath from QtCreator.ini
([QTBUG-115754](https://bugreports.qt.io/browse/QTBUG-115754))
* Fixed incorrect device checks when using Boot2Qt
([QTCREATORBUG-29474](https://bugreports.qt.io/browse/QTCREATORBUG-29474))
### QMake
* Avoid cleaning the build directory after switching kits
([QTCREATORBUG-29451](https://bugreports.qt.io/browse/QTCREATORBUG-29451))
([QTCREATORBUG-29481](https://bugreports.qt.io/browse/QTCREATORBUG-29481))
Version Control Systems
-----------------------
### Fossil
* Show the correct dialog when reverting the current file
Credits for these changes go to:
--------------------------------
Aaron Barany
André Pönitz
Björn Schäpers
Christian Kandeler
Cristian Adam
David Schulz
Jaroslaw Kobus
Leena Miettinen
Marcus Tillmanns
Orgad Shaneh

View File

@@ -3020,6 +3020,11 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_sp
if (!_languageFeatures.cxx11Enabled || LA(2) == T_NUMERIC_LITERAL) {
parseInitializer(node->initializer, &node->equal_token);
} else {
if (LA(2) != T_NUMERIC_LITERAL && LA(2) != T_DEFAULT && LA(2) != T_DELETE) {
error(cursor(), "expected 'default', 'delete' or '0', got '%s'", tok(2).spell());
return false;
}
node->equal_token = consumeToken();
IdExpressionAST *id_expr = new (_pool) IdExpressionAST;

View File

@@ -184,29 +184,10 @@ bool UnixPtyProcess::startProcess(const QString &shellPath,
m_readMasterNotify->disconnect();
});
const QStringList defaultVars = {
"TERM=xterm-256color",
"ITERM_PROFILE=Default",
"XPC_FLAGS=0x0",
"XPC_SERVICE_NAME=0",
"LANG=en_US.UTF-8",
"LC_ALL=en_US.UTF-8",
"LC_CTYPE=UTF-8",
"INIT_CWD=" + QCoreApplication::applicationDirPath(),
"COMMAND_MODE=unix2003",
"COLORTERM=truecolor"
};
QStringList varNames;
for (const QString &line : std::as_const(environment))
varNames.append(line.split("=").first());
//append default env vars only if they don't exists in current env
for (const QString &defVar : defaultVars) {
if (!varNames.contains(defVar.split("=").first()))
environment.append(defVar);
}
QProcessEnvironment envFormat;
for (const QString &line : std::as_const(environment))
envFormat.insert(line.split("=").first(), line.split("=").last());

View File

@@ -204,7 +204,27 @@ FilePath FilePath::currentWorkingPath()
bool FilePath::isRootPath() const
{
// FIXME: Make host-independent
if (needsDevice()) {
QStringView path = pathView();
if (osType() != OsTypeWindows)
return path == QLatin1String("/");
// Remote windows paths look like this: "/c:/", so we remove the leading '/'
if (path.startsWith('/'))
path = path.mid(1);
if (path.length() > 3)
return false;
if (!startsWithDriveLetter())
return false;
if (path.length() == 3 && path[2] != QLatin1Char('/'))
return false;
return true;
}
return *this == FilePath::fromString(QDir::rootPath());
}
@@ -1383,15 +1403,15 @@ bool FilePath::contains(const QString &s) const
/*!
\brief Checks whether the FilePath starts with a drive letter.
Defaults to \c false if it is a non-Windows host or represents a path on device
Returns whether FilePath starts with a drive letter
*/
bool FilePath::startsWithDriveLetter() const
{
const QStringView p = pathView();
return !needsDevice() && p.size() >= 2 && isWindowsDriveLetter(p[0]) && p.at(1) == ':';
QStringView p = pathView();
if (needsDevice() && !p.isEmpty())
p = p.mid(1);
return p.size() >= 2 && isWindowsDriveLetter(p[0]) && p.at(1) == ':';
}
/*!

View File

@@ -82,7 +82,7 @@ QList<ITestConfiguration *> CTestTreeItem::testConfigurationsFor(const QStringLi
if (!project)
return {};
const ProjectExplorer::Target *target = project->targets().value(0);
const ProjectExplorer::Target *target = ProjectExplorer::ProjectManager::startupTarget();
if (!target)
return {};

View File

@@ -14,6 +14,8 @@
#include <android/androidconstants.h>
#include <baremetal/baremetalconstants.h>
#include <ios/iosconstants.h>
#include <webassembly/webassemblyconstants.h>
@@ -202,6 +204,8 @@ static bool supportsStageForInstallation(const Kit *kit)
return runDevice->id() != buildDevice->id()
&& runDevice->type() != Android::Constants::ANDROID_DEVICE_TYPE
&& runDevice->type() != Ios::Constants::IOS_DEVICE_TYPE
&& runDevice->type() != Ios::Constants::IOS_SIMULATOR_TYPE
&& runDevice->type() != BareMetal::Constants::BareMetalOsType
&& runDevice->type() != WebAssembly::Constants::WEBASSEMBLY_DEVICE_TYPE;
}

View File

@@ -343,10 +343,10 @@ IDocument::OpenResult IDocument::open(QString *errorString, const Utils::FilePat
*/
bool IDocument::save(QString *errorString, const Utils::FilePath &filePath, bool autoSave)
{
emit aboutToSave(filePath, autoSave);
emit aboutToSave(filePath.isEmpty() ? this->filePath() : filePath, autoSave);
const bool success = saveImpl(errorString, filePath, autoSave);
if (success)
emit saved(filePath, autoSave);
emit saved(filePath.isEmpty() ? this->filePath() : filePath, autoSave);
return success;
}

View File

@@ -131,6 +131,9 @@ bool CppRefactoringFile::isCursorOn(unsigned tokenIndex) const
bool CppRefactoringFile::isCursorOn(const AST *ast) const
{
if (!ast)
return false;
QTextCursor tc = cursor();
int cursorBegin = tc.selectionStart();

View File

@@ -273,8 +273,13 @@ public:
void setProposal(IAssistProposal *proposal, const QString &prefix)
{
if (!proposal)
if (!proposal) {
// Close the proposal if we have no running processor otherwise ignore the empty
// proposal and wait for the processor to finish
if (!m_processor || !m_processor->running())
closeProposal();
return;
}
if (proposal->id() != TextEditor::Constants::GENERIC_PROPOSAL_ID) {
// We received something else than a generic proposal so we cannot update the model
closeProposal();
@@ -291,13 +296,14 @@ public:
GenericProposalWidget::updateProposal(std::move(interface));
return;
}
auto processor = m_provider->createProcessor(interface.get());
QTC_ASSERT(processor, return);
m_processor = m_provider->createProcessor(interface.get());
QTC_ASSERT(m_processor, return);
const QString prefix = interface->textAt(m_basePosition,
interface->position() - m_basePosition);
processor->setAsyncCompletionAvailableHandler([this, processor, prefix](IAssistProposal *proposal) {
m_processor->setAsyncCompletionAvailableHandler([this, processor = m_processor, prefix](
IAssistProposal *proposal) {
QTC_ASSERT(processor == m_processor, return);
if (!processor->running()) {
// do not delete this processor directly since this function is called from within the processor
@@ -310,11 +316,11 @@ public:
setProposal(proposal, prefix);
});
setProposal(processor->start(std::move(interface)), prefix);
if (processor->running())
m_processor = processor;
else
delete processor;
setProposal(m_processor->start(std::move(interface)), prefix);
if (!m_processor->running()) {
delete m_processor;
m_processor = nullptr;
}
}
private:

View File

@@ -120,16 +120,15 @@ public:
applyCurrentSettings();
LanguageClientManager::applySettings();
for (BaseSettings *setting : m_model.removed()) {
for (BaseSettings *setting : m_settings.removed()) {
for (Client *client : LanguageClientManager::clientsForSetting(setting))
LanguageClientManager::shutdownClient(client);
}
int row = currentRow();
m_model.reset(LanguageClientManager::currentSettings());
m_settings.reset(LanguageClientManager::currentSettings());
resetCurrentSettings(row);
}
void finish()
{
m_settings.reset(LanguageClientManager::currentSettings());
@@ -148,7 +147,6 @@ private:
LanguageClientSettingsModel &m_settings;
QSet<QString> &m_changedSettings;
LanguageClientSettingsModel m_model;
};
QMap<Utils::Id, ClientType> &clientTypes()
@@ -302,8 +300,6 @@ LanguageClientSettingsPage::LanguageClientSettingsPage()
void LanguageClientSettingsPage::init()
{
m_model.reset(LanguageClientSettings::fromSettings(Core::ICore::settings()));
apply();
finish();
}
QList<BaseSettings *> LanguageClientSettingsPage::settings() const
@@ -603,6 +599,7 @@ static LanguageClientSettingsPage &settingsPage()
void LanguageClientSettings::init()
{
settingsPage().init();
LanguageClientManager::applySettings();
}
QList<BaseSettings *> LanguageClientSettings::fromSettings(QSettings *settingsIn)

View File

@@ -107,10 +107,10 @@ static FilePath filePathValue(const FilePath &value, const QStringList &candidat
{
if (!value.isEmpty())
return value;
const FilePaths additionalSearchPaths = sshSettings->searchPathRetriever();
Environment env = Environment::systemEnvironment();
env.prependToPath(sshSettings->searchPathRetriever());
for (const QString &candidate : candidateFileNames) {
const FilePath filePath = Environment::systemEnvironment()
.searchInPath(candidate, additionalSearchPaths);
const FilePath filePath = env.searchInPath(candidate);
if (!filePath.isEmpty())
return filePath;
}

View File

@@ -113,6 +113,13 @@ void TerminalWidget::setupPty()
Environment env = m_openParameters.environment.value_or(Environment{})
.appliedToEnvironment(shellCommand.executable().deviceEnvironment());
// Set some useful defaults
env.setFallback("TERM", "xterm-256color");
env.setFallback("TERM_PROGRAM", QCoreApplication::applicationName());
env.setFallback("COLORTERM", "truecolor");
env.setFallback("COMMAND_MODE", "unix2003");
env.setFallback("INIT_CWD", QCoreApplication::applicationDirPath());
// For git bash on Windows
env.prependOrSetPath(shellCommand.executable().parentDir());
if (env.hasKey("CLINK_NOAUTORUN"))

View File

@@ -24,6 +24,7 @@
#ifdef Q_OS_LINUX
#include <sys/ptrace.h>
#include <sys/wait.h>
#endif
#include <iostream>
@@ -221,7 +222,25 @@ void onInferiorStarted()
if (!debugMode)
sendPid(inferiorId);
#else
ptrace(PTRACE_DETACH, inferiorId, 0, SIGSTOP);
if (debugMode) {
qCInfo(log) << "Detaching ...";
ptrace(PTRACE_DETACH, inferiorId, 0, SIGSTOP);
// Wait until the process actually finished detaching
int status = 0;
waitpid(inferiorId, &status, WUNTRACED);
if (log().isInfoEnabled()) {
if (WIFEXITED(status))
qCInfo(log) << "inferior exited, status=" << WEXITSTATUS(status);
else if (WIFSIGNALED(status))
qCInfo(log) << "inferior killed by signal" << WTERMSIG(status);
else if (WIFSTOPPED(status))
qCInfo(log) << "inferior stopped by signal" << WSTOPSIG(status);
else if (WIFCONTINUED(status))
qCInfo(log) << "inferior continued";
}
}
sendPid(inferiorId);
#endif
}

View File

@@ -190,6 +190,7 @@ private slots:
void enumDeclaration();
void invalidEnumClassDeclaration();
void invalidEnumWithDestructorId();
void invalidFunctionInitializer();
};
void tst_AST::gcc_attributes_1()
@@ -2052,6 +2053,14 @@ void tst_AST::invalidEnumWithDestructorId()
QVERIFY(diag.errorCount != 0);
}
void tst_AST::invalidFunctionInitializer()
{
QSharedPointer<TranslationUnit> unit(parse(
"int main() { a t=b; c d(e)=\"\"; }", TranslationUnit::ParseTranlationUnit, false, false, true));
QVERIFY(diag.errorCount != 0);
}
void tst_AST::initTestCase()
{
control.setDiagnosticClient(&diag);

View File

@@ -115,6 +115,8 @@ private slots:
void sort();
void sort_data();
void isRootPath();
private:
QTemporaryDir tempDir;
QString rootPath;
@@ -1308,6 +1310,14 @@ void tst_filepath::startsWithDriveLetter_data()
QTest::newRow("simple-win") << FilePath::fromString("c:/a") << true;
QTest::newRow("simple-linux") << FilePath::fromString("/c:/a") << false;
QTest::newRow("relative") << FilePath("a/b") << false;
QTest::newRow("remote-slash") << FilePath::fromString("docker://1234/") << false;
QTest::newRow("remote-single-letter") << FilePath::fromString("docker://1234/c") << false;
QTest::newRow("remote-drive") << FilePath::fromString("docker://1234/c:") << true;
QTest::newRow("remote-invalid-drive") << FilePath::fromString("docker://1234/c:a") << true;
QTest::newRow("remote-with-path") << FilePath::fromString("docker://1234/c:/a") << true;
QTest::newRow("remote-z") << FilePath::fromString("docker://1234/z:") << true;
QTest::newRow("remote-1") << FilePath::fromString("docker://1234/1:") << false;
}
void tst_filepath::startsWithDriveLetter()
@@ -1656,6 +1666,31 @@ void tst_filepath::sort()
QCOMPARE(sortedPaths, sorted);
}
void tst_filepath::isRootPath()
{
FilePath localRoot = FilePath::fromString(QDir::rootPath());
QVERIFY(localRoot.isRootPath());
FilePath localNonRoot = FilePath::fromString(QDir::rootPath() + "x");
QVERIFY(!localNonRoot.isRootPath());
if (HostOsInfo::isWindowsHost()) {
FilePath remoteWindowsRoot = FilePath::fromString("device://test/c:/");
QVERIFY(remoteWindowsRoot.isRootPath());
FilePath remoteWindowsRoot1 = FilePath::fromString("device://test/c:");
QVERIFY(remoteWindowsRoot1.isRootPath());
FilePath remoteWindowsNotRoot = FilePath::fromString("device://test/c:/x");
QVERIFY(!remoteWindowsNotRoot.isRootPath());
} else {
FilePath remoteRoot = FilePath::fromString("device://test/");
QVERIFY(remoteRoot.isRootPath());
FilePath remotePath = FilePath::fromString("device://test/x");
QVERIFY(!remotePath.isRootPath());
}
}
void tst_filepath::sort_data()
{
QTest::addColumn<QStringList>("input");