Merge remote-tracking branch 'origin/15.0'

Change-Id: I13e6beb4741be5aa79b2798aa6b674e45ad109f2
This commit is contained in:
Eike Ziller
2024-12-02 13:19:27 +01:00
27 changed files with 345 additions and 239 deletions

View File

@@ -45,5 +45,6 @@
{#qt-creator} channel on Libera.Chat IRC, go to \uicontrol Help >
\uicontrol Contact.
\sa {Paste and fetch code snippets}, {Technical Support}
\sa {Paste and fetch code snippets}, {Technical Support},
{Turn on crash reports}
*/

View File

@@ -24,6 +24,20 @@
\li Select \uicontrol {Enable crash reporting}.
\endlist
Crash reports are sent automatically if they don't exceed the file size
limit that Sentry sets for accepting them. You are not notified about
sending the reports or whether it succeeded or failed.
\section1 Clear local crash reports
\QC stores crash reports on the computer in the following directories:
\list
\li On Windows: \c {%APPDATA%\QtProject\qtcreator\crashpad_reports}
\li On Linux and \macos:
\c {$HOME/.config/QtProject/qtcreator/crashpad_reports}
\endlist
To free up disk space that crash reports reserve on the computer,
select \uicontrol {Clear Local Crash Reports}. You can see the
size of the crash reports next to the button.
@@ -31,5 +45,8 @@
Select \uicontrol ? to view more information about Crashpad and the security
policy.
\note The best way to report a crash is to create a bug report where you
paste the corresponding stack trace.
\sa {Contact Qt}
*/

View File

@@ -487,15 +487,17 @@ int Parser::find(int token, int stopAt)
return 0;
}
void Parser::match(int kind, int *token)
bool Parser::match(int kind, int *token)
{
if (LA() == kind)
if (LA() == kind) {
*token = consumeToken();
else {
*token = 0;
error(_tokenIndex, "expected token `%s' got `%s'",
Token::name(kind), tok().spell());
return true;
}
*token = 0;
error(_tokenIndex, "expected token `%s' got `%s'",
Token::name(kind), tok().spell());
return false;
}
bool Parser::parseClassOrNamespaceName(NameAST *&node)
@@ -3503,7 +3505,8 @@ bool Parser::parseExpressionStatement(StatementAST *&node)
DEBUG_THIS_RULE();
if (LA() == T_SEMICOLON) {
ExpressionStatementAST *ast = new (_pool) ExpressionStatementAST;
match(T_SEMICOLON, &ast->semicolon_token);
if (!match(T_SEMICOLON, &ast->semicolon_token))
return false;
node = ast;
return true;
}
@@ -3524,9 +3527,10 @@ bool Parser::parseExpressionStatement(StatementAST *&node)
ExpressionStatementAST *ast = new (previousPool) ExpressionStatementAST;
if (expression)
ast->expression = expression->clone(previousPool);
match(T_SEMICOLON, &ast->semicolon_token);
node = ast;
parsed = true;
if (match(T_SEMICOLON, &ast->semicolon_token)) {
node = ast;
parsed = true;
}
}
_inExpressionStatement = wasInExpressionStatement;

View File

@@ -273,7 +273,7 @@ public:
const Identifier *className(ClassSpecifierAST *ast) const;
const Identifier *identifier(NameAST *name) const;
void match(int kind, int *token);
bool match(int kind, int *token);
bool maybeAmbiguousStatement(DeclarationStatementAST *ast, StatementAST *&node);
bool maybeForwardOrClassDeclaration(SpecifierListAST *decl_specifier_seq) const;

View File

@@ -120,6 +120,7 @@ struct TerminalSurfacePrivate
};
m_vtermScreenCallbacks.sb_clear = [](void *user) {
auto p = static_cast<TerminalSurfacePrivate *>(user);
emit p->q->cleared();
return p->sb_clear();
};
m_vtermScreenCallbacks.bell = [](void *user) {

View File

@@ -111,6 +111,7 @@ signals:
void cursorChanged(Cursor oldCursor, Cursor newCursor);
void altscreenChanged(bool altScreen);
void unscroll();
void cleared();
private:
std::unique_ptr<TerminalSurfacePrivate> d;

View File

@@ -176,6 +176,7 @@ TerminalSurface *TerminalView::surface() const
void TerminalView::setupSurface()
{
d->m_surface = std::make_unique<TerminalSurface>(QSize{80, 60});
connect(d->m_surface.get(), &TerminalSurface::cleared, this, &TerminalView::cleared);
if (d->m_surfaceIntegration)
d->m_surface->setSurfaceIntegration(d->m_surfaceIntegration);

View File

@@ -224,6 +224,9 @@ protected:
private:
void scheduleViewportUpdate();
signals:
void cleared();
private:
std::unique_ptr<TerminalViewPrivate> d;
};

View File

@@ -228,6 +228,9 @@ QTCREATOR_UTILS_EXPORT int parseUsedPortFromNetstatOutput(const QByteArray &line
return -1;
}
if (columnToParse.size() > 0 && columnToParse.back() == '*')
return -1; // Valid case, no warning. See QNX udp case.
const int port = trailingNumber(columnToParse, base);
if (port == -1) {
qWarning("%s: Unexpected string '%s' is not a port. Tried to read from '%s'",

View File

@@ -5,6 +5,7 @@
#include "tooltip.h"
#include "../qtcassert.h"
#include "../hostosinfo.h"
#include <QColor>
#include <QFontMetrics>
@@ -249,7 +250,8 @@ void WidgetTip::configure(const QPoint &pos)
move(pos);
m_layout->addWidget(m_widget);
m_layout->setSizeConstraint(QLayout::SetFixedSize);
adjustSize();
if (!HostOsInfo::isMacHost()) // work around QTBUG-131479
adjustSize();
}
void WidgetTip::pinToolTipWidget(QWidget *parent)

View File

@@ -25,5 +25,29 @@
],
"Url" : "https://www.qt.io",
"DocumentationUrl" : "https://doc.qt.io/qtcreator/creator-projects-autotools.html",
${IDE_PLUGIN_DEPENDENCIES}
${IDE_PLUGIN_DEPENDENCIES},
"Mimetypes" : [
"<?xml version='1.0' encoding='UTF-8'?>",
"<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>",
" <mime-type type='text/x-makefile'>",
" <comment>Makefile build file</comment>",
" <magic priority='20'>",
" <!-- Only magic for default autoconf/automake produced ones -->",
" <match value='# Makefile.in generated by' type='string' offset='0'/>",
" <!-- Not exhaustive, and most people don't set this! -->",
" <match value='#!make' type='string' offset='0'/>",
" <match value='#!/usr/bin/make' type='string' offset='0'/>",
" <match value='#!/usr/local/bin/make' type='string' offset='0'/>",
" <match value='#!/usr/bin/env make' type='string' offset='0'/>",
" </magic>",
" <glob pattern='Makefile'/>",
" <glob pattern='GNUMakefile'/>",
" <glob pattern='*.mk'/>",
" <glob pattern='*.mak'/>",
" <glob weight='10' pattern='Makefile.*'/>",
" <sub-class-of type='text/plain'/>",
" </mime-type>",
"</mime-info>"
]
}

View File

@@ -5,7 +5,6 @@ add_qtc_plugin(AutotoolsProjectManager
autogenstep.cpp autogenstep.h
autoreconfstep.cpp autoreconfstep.h
autotoolsbuildconfiguration.cpp autotoolsbuildconfiguration.h
autotoolsbuildsystem.cpp autotoolsbuildsystem.h
autotoolsprojectconstants.h
autotoolsprojectmanagertr.h
autotoolsprojectplugin.cpp

View File

@@ -5,29 +5,191 @@
#include "autotoolsprojectconstants.h"
#include "autotoolsprojectmanagertr.h"
#include "makefileparser.h"
#include <projectexplorer/buildinfo.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorertr.h>
#include <projectexplorer/projectupdater.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtcppkitinfo.h>
#include <solutions/tasking/tasktreerunner.h>
#include <utils/async.h>
#include <utils/mimeconstants.h>
using namespace ProjectExplorer;
using namespace Tasking;
using namespace Utils;
namespace AutotoolsProjectManager::Internal {
// AutotoolsBuildConfiguration
// AutotoolsBuildSystem
class AutotoolsBuildSystem final : public BuildSystem
{
public:
explicit AutotoolsBuildSystem(BuildConfiguration *bc);
private:
void triggerParsing() final;
QString name() const final { return QLatin1String("autotools"); }
/**
* Is invoked when the makefile parsing by m_makefileParserThread has
* been finished. Adds all sources and files into the project tree and
* takes care listen to file changes for Makefile.am and configure.ac
* files.
*/
void makefileParsingFinished(const MakefileParserOutputData &outputData);
/// Return value for AutotoolsProject::files()
QStringList m_files;
/// Responsible for parsing the makefiles asynchronously in a thread
Tasking::TaskTreeRunner m_parserRunner;
std::unique_ptr<ProjectUpdater> m_cppCodeModelUpdater;
};
AutotoolsBuildSystem::AutotoolsBuildSystem(BuildConfiguration *bc)
: BuildSystem(bc)
, m_cppCodeModelUpdater(ProjectUpdaterFactory::createCppProjectUpdater())
{
connect(project(), &Project::projectFileIsDirty, this, [this] { requestParse(); });
}
static void parseMakefileImpl(QPromise<MakefileParserOutputData> &promise, const QString &makefile)
{
const auto result = parseMakefile(makefile, QFuture<void>(promise.future()));
if (result)
promise.addResult(*result);
else
promise.future().cancel();
}
void AutotoolsBuildSystem::triggerParsing()
{
const Storage<std::optional<ParseGuard>> storage;
const auto onSetup = [this, storage](Async<MakefileParserOutputData> &async) {
*storage = guardParsingRun();
async.setConcurrentCallData(parseMakefileImpl, projectFilePath().path());
};
const auto onDone = [this, storage](const Async<MakefileParserOutputData> &async) {
(*storage)->markAsSuccess();
makefileParsingFinished(async.result());
};
const Group recipe {
storage,
AsyncTask<MakefileParserOutputData>(onSetup, onDone, CallDoneIf::Success)
};
m_parserRunner.start(recipe);
}
static QStringList filterIncludes(const QString &absSrc, const QString &absBuild,
const QStringList &in)
{
QStringList result;
for (const QString &i : in) {
QString out = i;
out.replace(QLatin1String("$(top_srcdir)"), absSrc);
out.replace(QLatin1String("$(abs_top_srcdir)"), absSrc);
out.replace(QLatin1String("$(top_builddir)"), absBuild);
out.replace(QLatin1String("$(abs_top_builddir)"), absBuild);
result << out;
}
return result;
}
void AutotoolsBuildSystem::makefileParsingFinished(const MakefileParserOutputData &outputData)
{
m_files.clear();
QSet<FilePath> filesToWatch;
// Apply sources to m_files, which are returned at AutotoolsBuildSystem::files()
const QFileInfo fileInfo = projectFilePath().toFileInfo();
const QDir dir = fileInfo.absoluteDir();
const QStringList files = outputData.m_sources;
for (const QString& file : files)
m_files.append(dir.absoluteFilePath(file));
// Watch for changes of Makefile.am files. If a Makefile.am file
// has been changed, the project tree must be reparsed.
const QStringList makefiles = outputData.m_makefiles;
for (const QString &makefile : makefiles) {
const QString absMakefile = dir.absoluteFilePath(makefile);
m_files.append(absMakefile);
filesToWatch.insert(FilePath::fromString(absMakefile));
}
// Add configure.ac file to project and watch for changes.
const QLatin1String configureAc(QLatin1String("configure.ac"));
const QFile configureAcFile(fileInfo.absolutePath() + QLatin1Char('/') + configureAc);
if (configureAcFile.exists()) {
const QString absConfigureAc = dir.absoluteFilePath(configureAc);
m_files.append(absConfigureAc);
filesToWatch.insert(FilePath::fromString(absConfigureAc));
}
auto newRoot = std::make_unique<ProjectNode>(project()->projectDirectory());
for (const QString &f : std::as_const(m_files)) {
const FilePath path = FilePath::fromString(f);
newRoot->addNestedNode(std::make_unique<FileNode>(path,
FileNode::fileTypeForFileName(path)));
}
setRootProjectNode(std::move(newRoot));
project()->setExtraProjectFiles(filesToWatch);
QtSupport::CppKitInfo kitInfo(kit());
QTC_ASSERT(kitInfo.isValid(), return );
RawProjectPart rpp;
rpp.setDisplayName(project()->displayName());
rpp.setProjectFileLocation(projectFilePath());
rpp.setQtVersion(kitInfo.projectPartQtVersion);
const QStringList cflags = outputData.m_cflags;
QStringList cxxflags = outputData.m_cxxflags;
if (cxxflags.isEmpty())
cxxflags = cflags;
const FilePath includeFileBaseDir = projectDirectory();
rpp.setFlagsForC({kitInfo.cToolchain, cflags, includeFileBaseDir});
rpp.setFlagsForCxx({kitInfo.cxxToolchain, cxxflags, includeFileBaseDir});
const QString absSrc = project()->projectDirectory().path();
BuildConfiguration *bc = target()->activeBuildConfiguration();
const QString absBuild = bc ? bc->buildDirectory().path() : QString();
rpp.setIncludePaths(filterIncludes(absSrc, absBuild, outputData.m_includePaths));
rpp.setMacros(outputData.m_macros);
rpp.setFiles(m_files);
m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), {rpp}});
emitBuildSystemUpdated();
}
// AutotoolsBuildConfiguration
class AutotoolsBuildConfiguration final : public BuildConfiguration
{
public:
AutotoolsBuildConfiguration(Target *target, Id id)
: BuildConfiguration(target, id)
, m_buildSystem(new AutotoolsBuildSystem(this))
{
// /<foobar> is used so the un-changed check in setBuildDirectory() works correctly.
// The leading / is to avoid the relative the path expansion in BuildConfiguration::buildDirectory.
@@ -48,6 +210,13 @@ public:
// ### Build Steps Clean ###
appendInitialCleanStep(Constants::MAKE_STEP_ID); // make clean
}
~AutotoolsBuildConfiguration() override { delete m_buildSystem; }
private:
BuildSystem *buildSystem() const override { return m_buildSystem; }
AutotoolsBuildSystem * const m_buildSystem;
};
class AutotoolsBuildConfigurationFactory final : public BuildConfigurationFactory

View File

@@ -1,187 +0,0 @@
// Copyright (C) 2016 Openismus GmbH.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "autotoolsbuildsystem.h"
#include "makefileparser.h"
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/projectupdater.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtcppkitinfo.h>
#include <solutions/tasking/tasktreerunner.h>
#include <utils/async.h>
#include <utils/qtcassert.h>
using namespace ProjectExplorer;
using namespace Tasking;
using namespace Utils;
namespace AutotoolsProjectManager::Internal {
class AutotoolsBuildSystem final : public BuildSystem
{
public:
explicit AutotoolsBuildSystem(Target *target);
~AutotoolsBuildSystem() final;
private:
void triggerParsing() final;
QString name() const final { return QLatin1String("autotools"); }
/**
* Is invoked when the makefile parsing by m_makefileParserThread has
* been finished. Adds all sources and files into the project tree and
* takes care listen to file changes for Makefile.am and configure.ac
* files.
*/
void makefileParsingFinished(const MakefileParserOutputData &outputData);
/// Return value for AutotoolsProject::files()
QStringList m_files;
/// Responsible for parsing the makefiles asynchronously in a thread
Tasking::TaskTreeRunner m_parserRunner;
std::unique_ptr<ProjectUpdater> m_cppCodeModelUpdater;
};
AutotoolsBuildSystem::AutotoolsBuildSystem(Target *target)
: BuildSystem(target)
, m_cppCodeModelUpdater(ProjectUpdaterFactory::createCppProjectUpdater())
{
connect(target, &Target::activeBuildConfigurationChanged, this, [this] { requestParse(); });
connect(target->project(), &Project::projectFileIsDirty, this, [this] { requestParse(); });
}
AutotoolsBuildSystem::~AutotoolsBuildSystem() = default;
static void parseMakefileImpl(QPromise<MakefileParserOutputData> &promise, const QString &makefile)
{
const auto result = parseMakefile(makefile, QFuture<void>(promise.future()));
if (result)
promise.addResult(*result);
else
promise.future().cancel();
}
void AutotoolsBuildSystem::triggerParsing()
{
const Storage<std::optional<ParseGuard>> storage;
const auto onSetup = [this, storage](Async<MakefileParserOutputData> &async) {
*storage = guardParsingRun();
async.setConcurrentCallData(parseMakefileImpl, projectFilePath().path());
};
const auto onDone = [this, storage](const Async<MakefileParserOutputData> &async) {
(*storage)->markAsSuccess();
makefileParsingFinished(async.result());
};
const Group recipe {
storage,
AsyncTask<MakefileParserOutputData>(onSetup, onDone, CallDoneIf::Success)
};
m_parserRunner.start(recipe);
}
static QStringList filterIncludes(const QString &absSrc, const QString &absBuild,
const QStringList &in)
{
QStringList result;
for (const QString &i : in) {
QString out = i;
out.replace(QLatin1String("$(top_srcdir)"), absSrc);
out.replace(QLatin1String("$(abs_top_srcdir)"), absSrc);
out.replace(QLatin1String("$(top_builddir)"), absBuild);
out.replace(QLatin1String("$(abs_top_builddir)"), absBuild);
result << out;
}
return result;
}
void AutotoolsBuildSystem::makefileParsingFinished(const MakefileParserOutputData &outputData)
{
m_files.clear();
QSet<FilePath> filesToWatch;
// Apply sources to m_files, which are returned at AutotoolsBuildSystem::files()
const QFileInfo fileInfo = projectFilePath().toFileInfo();
const QDir dir = fileInfo.absoluteDir();
const QStringList files = outputData.m_sources;
for (const QString& file : files)
m_files.append(dir.absoluteFilePath(file));
// Watch for changes of Makefile.am files. If a Makefile.am file
// has been changed, the project tree must be reparsed.
const QStringList makefiles = outputData.m_makefiles;
for (const QString &makefile : makefiles) {
const QString absMakefile = dir.absoluteFilePath(makefile);
m_files.append(absMakefile);
filesToWatch.insert(FilePath::fromString(absMakefile));
}
// Add configure.ac file to project and watch for changes.
const QLatin1String configureAc(QLatin1String("configure.ac"));
const QFile configureAcFile(fileInfo.absolutePath() + QLatin1Char('/') + configureAc);
if (configureAcFile.exists()) {
const QString absConfigureAc = dir.absoluteFilePath(configureAc);
m_files.append(absConfigureAc);
filesToWatch.insert(FilePath::fromString(absConfigureAc));
}
auto newRoot = std::make_unique<ProjectNode>(project()->projectDirectory());
for (const QString &f : std::as_const(m_files)) {
const FilePath path = FilePath::fromString(f);
newRoot->addNestedNode(std::make_unique<FileNode>(path,
FileNode::fileTypeForFileName(path)));
}
setRootProjectNode(std::move(newRoot));
project()->setExtraProjectFiles(filesToWatch);
QtSupport::CppKitInfo kitInfo(kit());
QTC_ASSERT(kitInfo.isValid(), return );
RawProjectPart rpp;
rpp.setDisplayName(project()->displayName());
rpp.setProjectFileLocation(projectFilePath());
rpp.setQtVersion(kitInfo.projectPartQtVersion);
const QStringList cflags = outputData.m_cflags;
QStringList cxxflags = outputData.m_cxxflags;
if (cxxflags.isEmpty())
cxxflags = cflags;
const FilePath includeFileBaseDir = projectDirectory();
rpp.setFlagsForC({kitInfo.cToolchain, cflags, includeFileBaseDir});
rpp.setFlagsForCxx({kitInfo.cxxToolchain, cxxflags, includeFileBaseDir});
const QString absSrc = project()->projectDirectory().path();
BuildConfiguration *bc = target()->activeBuildConfiguration();
const QString absBuild = bc ? bc->buildDirectory().path() : QString();
rpp.setIncludePaths(filterIncludes(absSrc, absBuild, outputData.m_includePaths));
rpp.setMacros(outputData.m_macros);
rpp.setFiles(m_files);
m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), {rpp}});
emitBuildSystemUpdated();
}
BuildSystem *createAutotoolsBuildSystem(Target *target)
{
return new AutotoolsBuildSystem(target);
}
} // AutotoolsProjectManager::Internal

View File

@@ -1,12 +0,0 @@
// Copyright (C) 2016 Openismus GmbH.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <projectexplorer/buildsystem.h>
namespace AutotoolsProjectManager::Internal {
ProjectExplorer::BuildSystem *createAutotoolsBuildSystem(ProjectExplorer::Target *target);
} // AutotoolsProjectManager::Internal

View File

@@ -17,8 +17,6 @@ QtcPlugin {
"autoreconfstep.h",
"autotoolsbuildconfiguration.cpp",
"autotoolsbuildconfiguration.h",
"autotoolsbuildsystem.cpp",
"autotoolsbuildsystem.h",
"autotoolsprojectconstants.h",
"autotoolsprojectmanagertr.h",
"autotoolsprojectplugin.cpp",

View File

@@ -4,7 +4,6 @@
#include "autogenstep.h"
#include "autoreconfstep.h"
#include "autotoolsbuildconfiguration.h"
#include "autotoolsbuildsystem.h"
#include "autotoolsprojectconstants.h"
#include "configurestep.h"
#include "makestep.h"
@@ -41,7 +40,6 @@ public:
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setDisplayName(projectDirectory().fileName());
setHasMakeInstallEquivalent(true);
setBuildSystemCreator(&createAutotoolsBuildSystem);
}
};

View File

@@ -47,6 +47,18 @@ void TerminalSearch::setSearchString(const QString &searchString, FindFlags find
}
}
void TerminalSearch::clearAndSearchAgain()
{
if (!m_hits.isEmpty()) {
m_hits.clear();
m_currentHit = -1;
emit hitsChanged();
emit currentHitChanged();
}
m_debounceTimer.start();
}
void TerminalSearch::nextHit()
{
if (m_hits.isEmpty())
@@ -67,13 +79,6 @@ void TerminalSearch::previousHit()
void TerminalSearch::updateHits()
{
if (!m_hits.isEmpty()) {
m_hits.clear();
m_currentHit = -1;
emit hitsChanged();
emit currentHitChanged();
}
m_debounceTimer.start();
}
@@ -282,6 +287,10 @@ SearchableTerminal::SearchableTerminal(QWidget *parent)
m_aggregate->add(this);
surfaceChanged();
connect(this, &TerminalSolution::TerminalView::cleared, this, [this] {
m_search->clearAndSearchAgain();
});
}
SearchableTerminal::~SearchableTerminal() = default;

View File

@@ -25,6 +25,7 @@ public:
void setCurrentSelection(std::optional<SearchHitWithText> selection);
void setSearchString(const QString &searchString, Utils::FindFlags findFlags);
void clearAndSearchAgain();
void nextHit();
void previousHit();

View File

@@ -54,6 +54,7 @@
#include <qtsupport/qtkitaspect.h>
#include <QTcpServer>
#include <QTextCodec>
#include <QTimer>
using namespace Core;
@@ -104,6 +105,9 @@ public:
// DebugServer
Process debuggerServerProc;
QTextCodec *debuggerServerCodec = QTextCodec::codecForName("utf8");
QTextCodec::ConverterState outputCodecState; // FIXME: Handle on Process side.
QTextCodec::ConverterState errorCodecState;
ProcessHandle serverAttachPid;
bool serverUseMulti = true;
bool serverEssential = true;
@@ -1142,8 +1146,29 @@ void DebuggerRunTool::startDebugServerIfNeededAndContinueStartup()
}
}
if (auto terminalAspect = runControl()->aspectData<TerminalAspect>()) {
const bool useTerminal = terminalAspect->useTerminal;
d->debuggerServerProc.setTerminalMode(useTerminal ? TerminalMode::Run : TerminalMode::Off);
}
d->debuggerServerProc.setCommand(cmd);
connect(&d->debuggerServerProc, &Process::readyReadStandardOutput,
this, [this] {
const QByteArray data = d->debuggerServerProc.readAllRawStandardOutput();
const QString msg = d->debuggerServerCodec->toUnicode(
data.constData(), data.length(), &d->outputCodecState);
runControl()->postMessage(msg, StdOutFormat, false);
});
connect(&d->debuggerServerProc, &Process::readyReadStandardError,
this, [this] {
const QByteArray data = d->debuggerServerProc.readAllRawStandardError();
const QString msg = d->debuggerServerCodec->toUnicode(
data.constData(), data.length(), &d->errorCodecState);
runControl()->postMessage(msg, StdErrFormat, false);
});
connect(&d->debuggerServerProc, &Process::started, this, [this] {
continueAfterDebugServerStart();
});

View File

@@ -464,6 +464,7 @@ DebuggerToolTipWidget::DebuggerToolTipWidget(DebuggerEngine *engine,
auto mainLayout = new QVBoxLayout(this);
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
mainLayout->addWidget(toolBar);
mainLayout->addWidget(treeView);

View File

@@ -87,6 +87,22 @@ void LanguageClientQuickFixAssistProcessor::cancel()
}
}
QuickFixOperations LanguageClientQuickFixAssistProcessor::resultToOperations(const LanguageServerProtocol::CodeActionResult &result)
{
auto list = std::get_if<QList<std::variant<Command, CodeAction>>>(&result);
if (!list)
return {};
QuickFixOperations ops;
for (const std::variant<Command, CodeAction> &item : *list) {
if (auto action = std::get_if<CodeAction>(&item))
ops << new CodeActionQuickFixOperation(*action, m_client);
else if (auto command = std::get_if<Command>(&item))
ops << new CommandQuickFixOperation(*command, m_client);
}
return ops;
}
void LanguageClientQuickFixAssistProcessor::handleCodeActionResponse(const CodeActionRequest::Response &response)
{
m_currentRequest.reset();
@@ -101,17 +117,7 @@ void LanguageClientQuickFixAssistProcessor::handleCodeActionResponse(const CodeA
GenericProposal *LanguageClientQuickFixAssistProcessor::handleCodeActionResult(const CodeActionResult &result)
{
if (auto list = std::get_if<QList<std::variant<Command, CodeAction>>>(&result)) {
QuickFixOperations ops;
for (const std::variant<Command, CodeAction> &item : *list) {
if (auto action = std::get_if<CodeAction>(&item))
ops << new CodeActionQuickFixOperation(*action, m_client);
else if (auto command = std::get_if<Command>(&item))
ops << new CommandQuickFixOperation(*command, m_client);
}
return GenericProposal::createProposal(interface(), ops);
}
return nullptr;
return GenericProposal::createProposal(interface(), resultToOperations(result));
}
LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client)

View File

@@ -67,6 +67,8 @@ public:
void cancel() override;
protected:
TextEditor::QuickFixOperations resultToOperations(
const LanguageServerProtocol::CodeActionResult &result);
void setOnlyKinds(const QList<LanguageServerProtocol::CodeActionKind> &only);
Client *client() { return m_client; }

View File

@@ -490,7 +490,6 @@ public:
m_initializationOptions = options.as<QString>();
emit optionsChanged();
LanguageClientManager::applySettings();
m_isUpdatingAsyncOptions = false;
});

View File

@@ -242,6 +242,7 @@ ExtraCompiler *BuildSystem::extraCompilerForTarget(const Utils::FilePath &target
MakeInstallCommand BuildSystem::makeInstallCommand(const FilePath &installRoot) const
{
QTC_ASSERT(target()->project()->hasMakeInstallEquivalent(), return {});
QTC_ASSERT(buildConfiguration(), return {});
BuildStepList *buildSteps = buildConfiguration()->buildSteps();
QTC_ASSERT(buildSteps, return {});

View File

@@ -6,12 +6,16 @@
#include "qmljseditorconstants.h"
#include "qmljseditortr.h"
#include "qmljseditorsettings.h"
#include "qmljsquickfix.h"
#include <languageclient/languageclientinterface.h>
#include <languageclient/languageclientmanager.h>
#include <languageclient/languageclientquickfix.h>
#include <projectexplorer/buildmanager.h>
#include <texteditor/codeassist/genericproposal.h>
#include <texteditor/codeassist/iassistprovider.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditor.h>
#include <texteditor/texteditorconstants.h>
@@ -107,6 +111,41 @@ void QmllsClient::updateQmllsSemanticHighlightingCapability()
}
}
class QmllsQuickFixAssistProcessor : public LanguageClientQuickFixAssistProcessor
{
public:
using LanguageClientQuickFixAssistProcessor::LanguageClientQuickFixAssistProcessor;
private:
TextEditor::GenericProposal *perform() override
{
// Step 1: Collect qmlls code actions asynchronously
LanguageClientQuickFixAssistProcessor::perform();
// Step 2: Collect built-in quickfixes synchronously
m_builtinOps = findQmlJSQuickFixes(interface());
return nullptr;
}
TextEditor::GenericProposal *handleCodeActionResult(const LanguageServerProtocol::CodeActionResult &result) override
{
return TextEditor::GenericProposal::createProposal(
interface(), resultToOperations(result) + m_builtinOps);
}
QuickFixOperations m_builtinOps;
};
class QmllsQuickFixAssistProvider : public LanguageClientQuickFixProvider
{
public:
using LanguageClientQuickFixProvider::LanguageClientQuickFixProvider;
TextEditor::IAssistProcessor *createProcessor(const TextEditor::AssistInterface *) const override
{
return new QmllsQuickFixAssistProcessor(client());
}
};
QmllsClient::QmllsClient(StdIOClientInterface *interface)
: Client(interface)
{
@@ -178,6 +217,7 @@ QmllsClient::QmllsClient(StdIOClientInterface *interface)
}
return std::nullopt;
});
setQuickFixAssistProvider(new QmllsQuickFixAssistProvider(this));
}
QmllsClient::~QmllsClient()

View File

@@ -70,7 +70,7 @@ WebAssemblySettings::WebAssemblySettings()
"or %3 version that you plan to develop against.")
.arg(R"(<a href="https://emscripten.org/docs/getting_started/downloads.html">Emscripten SDK</a>)")
.arg(R"(<a href="https://doc.qt.io/qt-5/wasm.html#install-emscripten">Qt 5</a>)")
.arg(R"(<a href="https://doc.qt.io/qt-6/wasm.html#install-emscripten">Qt 6</a>)"));
.arg(R"(<a href="https://doc.qt.io/qt-6/wasm.html#installing-emscripten">Qt 6</a>)"));
instruction->setOpenExternalLinks(true);
instruction->setWordWrap(true);