Commit ee27248a authored by hjk's avatar hjk

Debugger: Streamline DebuggerRun{Control,Tool}Setup

Only one code path needed once we have a RunConfiguration.

Change-Id: Ib65f471a929a0c70694dd142b4f83be7eebbe151
Reviewed-by: Christian Stenger's avatarChristian Stenger <christian.stenger@qt.io>
parent cd47065b
......@@ -476,19 +476,21 @@ private:
class DebuggerRunTool : public ProjectExplorer::ToolRunner
{
public:
DebuggerRunTool(ProjectExplorer::RunControl *runControl, const DebuggerRunParameters &rp);
DebuggerRunTool(ProjectExplorer::RunControl *runControl,
const DebuggerRunParameters &rp,
QString *errorMessage = nullptr);
~DebuggerRunTool();
DebuggerEngine *engine() const { return m_engine; }
DebuggerRunControl *runControl() const;
QStringList errors() const { return m_errors; }
void showMessage(const QString &msg, int channel, int timeout = -1);
void handleFinished();
private:
bool fixup();
DebuggerRunParameters m_rp;
DebuggerEngine *m_engine = nullptr; // Master engine
QStringList m_errors;
......@@ -508,8 +510,7 @@ private:
};
DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters &rp, QStringList *errors);
DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp, const ProjectExplorer::Kit *kit);
ProjectExplorer::RunControl *createAndScheduleRun(const DebuggerRunParameters &rp, ProjectExplorer::Kit *kit);
} // namespace Internal
} // namespace Debugger
......
......@@ -661,7 +661,7 @@ public:
m_threadBox->blockSignals(state);
}
DebuggerRunControl *attachToRunningProcess(Kit *kit, DeviceProcessItem process, bool contAfterAttach);
RunControl *attachToRunningProcess(Kit *kit, DeviceProcessItem process, bool contAfterAttach);
void writeSettings()
{
......@@ -2067,9 +2067,9 @@ void DebuggerPluginPrivate::attachToUnstartedApplicationDialog()
connect(dlg, &QDialog::finished, dlg, &QObject::deleteLater);
connect(dlg, &UnstartedAppWatcherDialog::processFound, this, [this, dlg] {
DebuggerRunControl *rc = attachToRunningProcess(dlg->currentKit(),
dlg->currentProcess(),
dlg->continueOnAttach());
RunControl *rc = attachToRunningProcess(dlg->currentKit(),
dlg->currentProcess(),
dlg->continueOnAttach());
if (!rc)
return;
......@@ -2080,7 +2080,7 @@ void DebuggerPluginPrivate::attachToUnstartedApplicationDialog()
dlg->show();
}
DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
RunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
DeviceProcessItem process, bool contAfterAttach)
{
QTC_ASSERT(kit, return 0);
......@@ -2124,13 +2124,13 @@ void DebuggerPlugin::attachExternalApplication(RunControl *rc)
rp.startMode = AttachExternal;
rp.closeMode = DetachAtClose;
rp.toolChainAbi = rc->abi();
Kit *kit = 0;
if (const RunConfiguration *runConfiguration = rc->runConfiguration())
if (const Target *target = runConfiguration->target())
kit = target->kit();
if (!kit)
kit = guessKitFromParameters(rp);
createAndScheduleRun(rp, kit);
if (RunConfiguration *runConfig = rc->runConfiguration()) {
auto runControl = new DebuggerRunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE);
(void) new DebuggerRunTool(runControl, rp);
ProjectExplorerPlugin::startRunControl(runControl, ProjectExplorer::Constants::DEBUG_RUN_MODE);
} else {
createAndScheduleRun(rp, guessKitFromParameters(rp));
}
}
void DebuggerPlugin::getEnginesState(QByteArray *json) const
......@@ -2223,8 +2223,8 @@ void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &valu
void DebuggerPluginPrivate::runScheduled()
{
for (int i = 0, n = m_scheduledStarts.size(); i != n; ++i)
createAndScheduleRun(m_scheduledStarts.at(i).first, m_scheduledStarts.at(i).second);
for (const QPair<DebuggerRunParameters, Kit *> pair : m_scheduledStarts)
createAndScheduleRun(pair.first, pair.second);
}
void DebuggerPluginPrivate::editorOpened(IEditor *editor)
......@@ -3705,13 +3705,14 @@ void DebuggerUnitTests::testStateMachine()
DebuggerRunParameters rp;
Target *t = SessionManager::startupProject()->activeTarget();
QVERIFY(t);
Kit *kit = t->kit();
QVERIFY(kit);
RunConfiguration *rc = t->activeRunConfiguration();
QVERIFY(rc);
rp.inferior = rc->runnable().as<StandardRunnable>();
rp.testCase = TestNoBoundsOfCurrentFunction;
DebuggerRunControl *runControl = createAndScheduleRun(rp, kit);
auto runControl = new DebuggerRunControl(rc, ProjectExplorer::Constants::DEBUG_RUN_MODE);
(void) new DebuggerRunTool(runControl, rp);
ProjectExplorerPlugin::startRunControl(runControl, ProjectExplorer::Constants::DEBUG_RUN_MODE);
connect(runControl, &RunControl::finished, this, [this] {
QTestEventLoop::instance().exitLoop();
......
......@@ -45,6 +45,7 @@
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorericons.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
#include <projectexplorer/taskhub.h>
#include <projectexplorer/toolchain.h>
......@@ -292,9 +293,13 @@ DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters
return engine;
}
static bool fixup(DebuggerRunParameters &rp, RunConfiguration *const runConfig,
const Kit *kit, Core::Id runMode, QStringList *errors)
bool DebuggerRunTool::fixup()
{
DebuggerRunParameters &rp = m_rp;
RunConfiguration *const runConfig = runControl()->runConfiguration();
Core::Id runMode = runControl()->runMode();
const Kit *kit = runConfig->target()->kit();
QTC_ASSERT(kit, return false);
// Extract as much as possible from available RunConfiguration.
......@@ -403,9 +408,9 @@ static bool fixup(DebuggerRunParameters &rp, RunConfiguration *const runConfig,
foreach (const Task &t, tasks) {
if (t.type == Task::Warning)
continue;
errors->append(t.description);
m_errors.append(t.description);
}
if (!errors->isEmpty())
if (!m_errors.isEmpty())
return false;
}
}
......@@ -417,7 +422,7 @@ static bool fixup(DebuggerRunParameters &rp, RunConfiguration *const runConfig,
const bool canListen = server.listen(QHostAddress::LocalHost)
|| server.listen(QHostAddress::LocalHostIPv6);
if (!canListen) {
errors->append(DebuggerPlugin::tr("Not enough free ports for QML debugging.") + ' ');
m_errors.append(DebuggerPlugin::tr("Not enough free ports for QML debugging.") + ' ');
return false;
}
TcpServerConnection conn;
......@@ -503,14 +508,23 @@ static bool isDebuggableScript(RunConfiguration *runConfig)
/// DebuggerRunTool
DebuggerRunTool::DebuggerRunTool(RunControl *runControl, const DebuggerRunParameters &rp)
DebuggerRunTool::DebuggerRunTool(RunControl *runControl, const DebuggerRunParameters &rp, QString *errorMessage)
: ToolRunner(runControl), m_rp(rp)
{
runControl->setDisplayName(m_rp.displayName);
// QML and/or mixed are not prepared for it.
runControl->setSupportsReRunning(!(m_rp.languages & QmlLanguage));
m_engine = createEngine(m_rp.masterEngineType, m_rp, &m_errors);
if (fixup()) {
m_engine = createEngine(m_rp.masterEngineType, m_rp, &m_errors);
if (!m_engine) {
QString msg = m_errors.join('\n');
if (errorMessage)
*errorMessage = msg;
return;
}
}
connect(runControl, &RunControl::finished,
this, &DebuggerRunTool::handleFinished);
connect(m_engine, &DebuggerEngine::requestRemoteSetup,
......@@ -587,19 +601,9 @@ public:
QTC_ASSERT(runConfig, return 0);
QTC_ASSERT(mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain, return 0);
// We cover only local setup here. Remote setups are handled by the
// RunControl factories in the target specific plugins.
QStringList errors;
auto runControl = new DebuggerRunControl(runConfig, mode);
DebuggerRunParameters rp;
if (fixup(rp, runConfig, runConfig->target()->kit(), mode, &errors)) {
(void) new DebuggerRunTool(runControl, rp);
return runControl;
}
if (errorMessage)
*errorMessage = errors.join('\n');
delete runControl;
return nullptr;
(void) new DebuggerRunTool(runControl, DebuggerStartParameters(), errorMessage);
return runControl;
}
bool canRun(RunConfiguration *runConfig, Core::Id mode) const override
......@@ -639,21 +643,39 @@ QObject *createDebuggerRunControlFactory(QObject *parent)
/**
* Used for direct "special" starts from actions in the debugger plugin.
*/
DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp0, const Kit *kit)
class DummyProject : public Project
{
public:
DummyProject() : Project(QString(""), FileName::fromString("")) {}
QString displayName() const final { return QString(); }
};
RunConfiguration *dummyRunConfigForKit(ProjectExplorer::Kit *kit)
{
QTC_ASSERT(kit, return nullptr); // Caller needs to look for a suitable kit.
auto runControl = new DebuggerRunControl(nullptr, DebugRunMode);
QStringList errors;
DebuggerRunParameters rp = rp0;
if (fixup(rp, nullptr, kit, DebugRunMode, &errors)) {
(void) new DebuggerRunTool(runControl, rp);
showMessage(rp.startMessage, 0);
ProjectExplorerPlugin::startRunControl(runControl, DebugRunMode);
return runControl; // Only used for tests.
Project *project = SessionManager::startupProject();
Target *target = nullptr;
if (project) {
target = project->target(kit);
} else {
project = new DummyProject;
target = project->createTarget(kit);
}
ProjectExplorerPlugin::showRunErrorMessage(errors.join('\n'));
delete runControl;
return nullptr;
QTC_ASSERT(target, return nullptr);
auto runConfig = target->activeRunConfiguration();
return runConfig;
}
RunControl *createAndScheduleRun(const DebuggerRunParameters &rp, Kit *kit)
{
RunConfiguration *runConfig = dummyRunConfigForKit(kit);
QTC_ASSERT(runConfig, return nullptr);
auto runControl = new DebuggerRunControl(runConfig, DebugRunMode);
(void) new DebuggerRunTool(runControl, rp);
QTC_ASSERT(runControl, return nullptr);
ProjectExplorerPlugin::startRunControl(runControl, ProjectExplorer::Constants::DEBUG_RUN_MODE);
return runControl;
}
} // Internal
......@@ -669,18 +691,8 @@ DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp,
{
QTC_ASSERT(runConfig, return nullptr);
auto runControl = new DebuggerRunControl(runConfig, runMode);
QStringList errors;
DebuggerRunParameters rp = sp;
if (fixup(rp, runConfig, runConfig->target()->kit(), runMode, &errors)) {
(void) new Internal::DebuggerRunTool(runControl, rp);
return runControl;
}
QString msg = errors.join('\n');
if (errorMessage)
*errorMessage = msg;
Core::ICore::showWarningWithOptions(DebuggerRunControl::tr("Debugger"), msg);
delete runControl;
return nullptr;
(void) new Internal::DebuggerRunTool(runControl, sp, errorMessage);
return runControl;
}
} // namespace Debugger
......@@ -63,6 +63,7 @@
#include <projectexplorer/devicesupport/deviceprocess.h>
#include <projectexplorer/itaskhandler.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/taskhub.h>
#include <utils/algorithm.h>
......@@ -3327,7 +3328,9 @@ void GdbEngine::handleMakeSnapshot(const DebuggerResponse &response, const QStri
}
rp.displayName = function + ": " + QDateTime::currentDateTime().toString();
rp.isSnapshot = true;
createAndScheduleRun(rp, 0);
auto rc = new DebuggerRunControl(runControl()->runConfiguration(), ProjectExplorer::Constants::DEBUG_RUN_MODE);
(void) new DebuggerRunTool(rc, rp);
ProjectExplorerPlugin::startRunControl(rc, ProjectExplorer::Constants::DEBUG_RUN_MODE);
} else {
QString msg = response.data["msg"].data();
AsynchronousMessageBox::critical(tr("Snapshot Creation Error"),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment