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) { if (!_languageFeatures.cxx11Enabled || LA(2) == T_NUMERIC_LITERAL) {
parseInitializer(node->initializer, &node->equal_token); parseInitializer(node->initializer, &node->equal_token);
} else { } 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(); node->equal_token = consumeToken();
IdExpressionAST *id_expr = new (_pool) IdExpressionAST; IdExpressionAST *id_expr = new (_pool) IdExpressionAST;

View File

@@ -184,29 +184,10 @@ bool UnixPtyProcess::startProcess(const QString &shellPath,
m_readMasterNotify->disconnect(); 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; QStringList varNames;
for (const QString &line : std::as_const(environment)) for (const QString &line : std::as_const(environment))
varNames.append(line.split("=").first()); 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; QProcessEnvironment envFormat;
for (const QString &line : std::as_const(environment)) for (const QString &line : std::as_const(environment))
envFormat.insert(line.split("=").first(), line.split("=").last()); envFormat.insert(line.split("=").first(), line.split("=").last());

View File

@@ -204,7 +204,27 @@ FilePath FilePath::currentWorkingPath()
bool FilePath::isRootPath() const 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()); 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. \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 Returns whether FilePath starts with a drive letter
*/ */
bool FilePath::startsWithDriveLetter() const bool FilePath::startsWithDriveLetter() const
{ {
const QStringView p = pathView(); QStringView p = pathView();
return !needsDevice() && p.size() >= 2 && isWindowsDriveLetter(p[0]) && p.at(1) == ':'; 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) if (!project)
return {}; return {};
const ProjectExplorer::Target *target = project->targets().value(0); const ProjectExplorer::Target *target = ProjectExplorer::ProjectManager::startupTarget();
if (!target) if (!target)
return {}; return {};

View File

@@ -14,6 +14,8 @@
#include <android/androidconstants.h> #include <android/androidconstants.h>
#include <baremetal/baremetalconstants.h>
#include <ios/iosconstants.h> #include <ios/iosconstants.h>
#include <webassembly/webassemblyconstants.h> #include <webassembly/webassemblyconstants.h>
@@ -202,6 +204,8 @@ static bool supportsStageForInstallation(const Kit *kit)
return runDevice->id() != buildDevice->id() return runDevice->id() != buildDevice->id()
&& runDevice->type() != Android::Constants::ANDROID_DEVICE_TYPE && runDevice->type() != Android::Constants::ANDROID_DEVICE_TYPE
&& runDevice->type() != Ios::Constants::IOS_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; && 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) 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); const bool success = saveImpl(errorString, filePath, autoSave);
if (success) if (success)
emit saved(filePath, autoSave); emit saved(filePath.isEmpty() ? this->filePath() : filePath, autoSave);
return success; return success;
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -113,6 +113,13 @@ void TerminalWidget::setupPty()
Environment env = m_openParameters.environment.value_or(Environment{}) Environment env = m_openParameters.environment.value_or(Environment{})
.appliedToEnvironment(shellCommand.executable().deviceEnvironment()); .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 // For git bash on Windows
env.prependOrSetPath(shellCommand.executable().parentDir()); env.prependOrSetPath(shellCommand.executable().parentDir());
if (env.hasKey("CLINK_NOAUTORUN")) if (env.hasKey("CLINK_NOAUTORUN"))

View File

@@ -24,6 +24,7 @@
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <sys/wait.h>
#endif #endif
#include <iostream> #include <iostream>
@@ -221,7 +222,25 @@ void onInferiorStarted()
if (!debugMode) if (!debugMode)
sendPid(inferiorId); sendPid(inferiorId);
#else #else
if (debugMode) {
qCInfo(log) << "Detaching ...";
ptrace(PTRACE_DETACH, inferiorId, 0, SIGSTOP); 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); sendPid(inferiorId);
#endif #endif
} }

View File

@@ -190,6 +190,7 @@ private slots:
void enumDeclaration(); void enumDeclaration();
void invalidEnumClassDeclaration(); void invalidEnumClassDeclaration();
void invalidEnumWithDestructorId(); void invalidEnumWithDestructorId();
void invalidFunctionInitializer();
}; };
void tst_AST::gcc_attributes_1() void tst_AST::gcc_attributes_1()
@@ -2052,6 +2053,14 @@ void tst_AST::invalidEnumWithDestructorId()
QVERIFY(diag.errorCount != 0); 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() void tst_AST::initTestCase()
{ {
control.setDiagnosticClient(&diag); control.setDiagnosticClient(&diag);

View File

@@ -115,6 +115,8 @@ private slots:
void sort(); void sort();
void sort_data(); void sort_data();
void isRootPath();
private: private:
QTemporaryDir tempDir; QTemporaryDir tempDir;
QString rootPath; QString rootPath;
@@ -1308,6 +1310,14 @@ void tst_filepath::startsWithDriveLetter_data()
QTest::newRow("simple-win") << FilePath::fromString("c:/a") << true; QTest::newRow("simple-win") << FilePath::fromString("c:/a") << true;
QTest::newRow("simple-linux") << FilePath::fromString("/c:/a") << false; QTest::newRow("simple-linux") << FilePath::fromString("/c:/a") << false;
QTest::newRow("relative") << FilePath("a/b") << 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() void tst_filepath::startsWithDriveLetter()
@@ -1656,6 +1666,31 @@ void tst_filepath::sort()
QCOMPARE(sortedPaths, sorted); 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() void tst_filepath::sort_data()
{ {
QTest::addColumn<QStringList>("input"); QTest::addColumn<QStringList>("input");