forked from qt-creator/qt-creator
Debugger: add python debugger setting in run configuration
Change-Id: Ifa5d72566007e0bb006523433dcef97689677fbf Reviewed-by: hjk <hjk@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -395,6 +395,12 @@ bool allOf(const T &container, F predicate)
|
|||||||
return std::all_of(std::begin(container), std::end(container), predicate);
|
return std::all_of(std::begin(container), std::end(container), predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, typename F>
|
||||||
|
bool allOf(const std::initializer_list<T> &initializerList, F predicate)
|
||||||
|
{
|
||||||
|
return std::all_of(std::begin(initializerList), std::end(initializerList), predicate);
|
||||||
|
}
|
||||||
|
|
||||||
// allOf taking a member function pointer
|
// allOf taking a member function pointer
|
||||||
template<typename T, typename R, typename S>
|
template<typename T, typename R, typename S>
|
||||||
bool allOf(const T &container, R (S::*predicate)() const)
|
bool allOf(const T &container, R (S::*predicate)() const)
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ enum DebuggerEngineType
|
|||||||
NoEngineType = 0,
|
NoEngineType = 0,
|
||||||
GdbEngineType = 0x001,
|
GdbEngineType = 0x001,
|
||||||
CdbEngineType = 0x004,
|
CdbEngineType = 0x004,
|
||||||
PdbEngineType = 0x008,
|
|
||||||
LldbEngineType = 0x100,
|
LldbEngineType = 0x100,
|
||||||
UvscEngineType = 0x1000
|
UvscEngineType = 0x1000
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -267,8 +267,8 @@ public:
|
|||||||
|
|
||||||
connect(&settings().enableReverseDebugging, &BaseAspect::changed, this, [this] {
|
connect(&settings().enableReverseDebugging, &BaseAspect::changed, this, [this] {
|
||||||
updateState();
|
updateState();
|
||||||
if (m_companionEngine)
|
for (const QPointer<DebuggerEngine> &companion : std::as_const(m_companionEngines))
|
||||||
m_companionEngine->d->updateState();
|
companion->d->updateState();
|
||||||
});
|
});
|
||||||
static int contextCount = 0;
|
static int contextCount = 0;
|
||||||
m_context = Context(Id("Debugger.Engine.").withSuffix(++contextCount));
|
m_context = Context(Id("Debugger.Engine.").withSuffix(++contextCount));
|
||||||
@@ -445,7 +445,7 @@ public:
|
|||||||
DebuggerRunParameters m_runParameters;
|
DebuggerRunParameters m_runParameters;
|
||||||
IDevice::ConstPtr m_device;
|
IDevice::ConstPtr m_device;
|
||||||
|
|
||||||
QPointer<DebuggerEngine> m_companionEngine;
|
QList<QPointer<DebuggerEngine>> m_companionEngines;
|
||||||
bool m_isPrimaryEngine = true;
|
bool m_isPrimaryEngine = true;
|
||||||
|
|
||||||
// The current state.
|
// The current state.
|
||||||
@@ -1134,9 +1134,9 @@ IDevice::ConstPtr DebuggerEngine::device() const
|
|||||||
return d->m_device;
|
return d->m_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerEngine *DebuggerEngine::companionEngine() const
|
QList<DebuggerEngine *> DebuggerEngine::companionEngines() const
|
||||||
{
|
{
|
||||||
return d->m_companionEngine;
|
return Utils::transform(d->m_companionEngines, &QPointer<DebuggerEngine>::get);
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerState DebuggerEngine::state() const
|
DebuggerState DebuggerEngine::state() const
|
||||||
@@ -1849,8 +1849,8 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
|
|||||||
showMessage(msg, LogDebug);
|
showMessage(msg, LogDebug);
|
||||||
|
|
||||||
d->updateState();
|
d->updateState();
|
||||||
if (d->m_companionEngine)
|
for (const QPointer<DebuggerEngine> &companion : std::as_const(d->m_companionEngines))
|
||||||
d->m_companionEngine->d->updateState();
|
companion->d->updateState();
|
||||||
|
|
||||||
if (oldState != d->m_state)
|
if (oldState != d->m_state)
|
||||||
emit EngineManager::instance()->engineStateChanged(this);
|
emit EngineManager::instance()->engineStateChanged(this);
|
||||||
@@ -2037,9 +2037,9 @@ void DebuggerEngine::progressPing()
|
|||||||
d->m_progress.setProgressValue(progress);
|
d->m_progress.setProgressValue(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEngine::setCompanionEngine(DebuggerEngine *engine)
|
void DebuggerEngine::addCompanionEngine(DebuggerEngine *engine)
|
||||||
{
|
{
|
||||||
d->m_companionEngine = engine;
|
d->m_companionEngines << engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEngine::setSecondaryEngine()
|
void DebuggerEngine::setSecondaryEngine()
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ public:
|
|||||||
QString version;
|
QString version;
|
||||||
|
|
||||||
bool isQmlDebugging = false;
|
bool isQmlDebugging = false;
|
||||||
|
bool isPythonDebugging = false;
|
||||||
bool breakOnMain = false;
|
bool breakOnMain = false;
|
||||||
bool multiProcess = false; // Whether to set detach-on-fork off.
|
bool multiProcess = false; // Whether to set detach-on-fork off.
|
||||||
bool useTerminal = false;
|
bool useTerminal = false;
|
||||||
@@ -269,7 +270,7 @@ public:
|
|||||||
QString runId() const;
|
QString runId() const;
|
||||||
|
|
||||||
const DebuggerRunParameters &runParameters() const;
|
const DebuggerRunParameters &runParameters() const;
|
||||||
void setCompanionEngine(DebuggerEngine *engine);
|
void addCompanionEngine(DebuggerEngine *engine);
|
||||||
void setSecondaryEngine();
|
void setSecondaryEngine();
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
@@ -553,7 +554,7 @@ protected:
|
|||||||
void startDying() const;
|
void startDying() const;
|
||||||
|
|
||||||
ProjectExplorer::IDeviceConstPtr device() const;
|
ProjectExplorer::IDeviceConstPtr device() const;
|
||||||
DebuggerEngine *companionEngine() const;
|
QList<DebuggerEngine *> companionEngines() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class DebuggerPluginPrivate;
|
friend class DebuggerPluginPrivate;
|
||||||
|
|||||||
@@ -243,10 +243,6 @@ void DebuggerItem::reinitializeFromFile(QString *error, Utils::Environment *cust
|
|||||||
m_version = output.section(' ', 2);
|
m_version = output.section(' ', 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (output.startsWith("Python")) {
|
|
||||||
m_engineType = PdbEngineType;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (error)
|
if (error)
|
||||||
*error = output;
|
*error = output;
|
||||||
m_engineType = NoEngineType;
|
m_engineType = NoEngineType;
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ namespace Debugger {
|
|||||||
\class Debugger::DebuggerRunConfigurationAspect
|
\class Debugger::DebuggerRunConfigurationAspect
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static bool isDisabled(TriStateAspect *aspect)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(aspect, return false);
|
||||||
|
return aspect->value() == TriState::Disabled;
|
||||||
|
}
|
||||||
|
|
||||||
DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
|
DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
|
||||||
: m_target(target)
|
: m_target(target)
|
||||||
{
|
{
|
||||||
@@ -49,6 +55,7 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
|
|||||||
setConfigWidgetCreator([this] {
|
setConfigWidgetCreator([this] {
|
||||||
Layouting::Grid builder;
|
Layouting::Grid builder;
|
||||||
builder.addRow({m_cppAspect});
|
builder.addRow({m_cppAspect});
|
||||||
|
builder.addRow({m_pythonAspect});
|
||||||
auto info = new QLabel(
|
auto info = new QLabel(
|
||||||
Tr::tr("<a href=\""
|
Tr::tr("<a href=\""
|
||||||
"qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html"
|
"qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html"
|
||||||
@@ -98,6 +105,7 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
|
|||||||
|
|
||||||
addDataExtractor(this, &DebuggerRunConfigurationAspect::useCppDebugger, &Data::useCppDebugger);
|
addDataExtractor(this, &DebuggerRunConfigurationAspect::useCppDebugger, &Data::useCppDebugger);
|
||||||
addDataExtractor(this, &DebuggerRunConfigurationAspect::useQmlDebugger, &Data::useQmlDebugger);
|
addDataExtractor(this, &DebuggerRunConfigurationAspect::useQmlDebugger, &Data::useQmlDebugger);
|
||||||
|
addDataExtractor(this, &DebuggerRunConfigurationAspect::usePythonDebugger, &Data::usePythonDebugger);
|
||||||
addDataExtractor(this, &DebuggerRunConfigurationAspect::useMultiProcess, &Data::useMultiProcess);
|
addDataExtractor(this, &DebuggerRunConfigurationAspect::useMultiProcess, &Data::useMultiProcess);
|
||||||
addDataExtractor(this, &DebuggerRunConfigurationAspect::overrideStartup, &Data::overrideStartup);
|
addDataExtractor(this, &DebuggerRunConfigurationAspect::overrideStartup, &Data::overrideStartup);
|
||||||
|
|
||||||
@@ -109,16 +117,23 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
|
|||||||
m_qmlAspect->setLabelText(Tr::tr("QML debugger:"));
|
m_qmlAspect->setLabelText(Tr::tr("QML debugger:"));
|
||||||
m_qmlAspect->setSettingsKey("RunConfiguration.UseQmlDebugger");
|
m_qmlAspect->setSettingsKey("RunConfiguration.UseQmlDebugger");
|
||||||
|
|
||||||
|
m_pythonAspect = new TriStateAspect(nullptr, Tr::tr("Enabled"), Tr::tr("Disabled"), Tr::tr("Automatic"));
|
||||||
|
m_pythonAspect->setLabelText(Tr::tr("Python debugger:"));
|
||||||
|
m_pythonAspect->setSettingsKey("RunConfiguration.UsePythonDebugger");
|
||||||
|
|
||||||
// Make sure at least one of the debuggers is set to be active.
|
// Make sure at least one of the debuggers is set to be active.
|
||||||
connect(m_cppAspect, &TriStateAspect::changed, this, [this]{
|
connect(m_cppAspect, &TriStateAspect::changed, this, [this]{
|
||||||
if (m_cppAspect->value() == TriState::Disabled && m_qmlAspect->value() == TriState::Disabled)
|
if (Utils::allOf({m_cppAspect, m_qmlAspect, m_pythonAspect}, &isDisabled))
|
||||||
m_qmlAspect->setValue(TriState::Default);
|
m_qmlAspect->setValue(TriState::Default);
|
||||||
});
|
});
|
||||||
connect(m_qmlAspect, &TriStateAspect::changed, this, [this]{
|
connect(m_qmlAspect, &TriStateAspect::changed, this, [this]{
|
||||||
if (m_qmlAspect->value() == TriState::Disabled && m_cppAspect->value() == TriState::Disabled)
|
if (Utils::allOf({m_cppAspect, m_qmlAspect, m_pythonAspect}, &isDisabled))
|
||||||
|
m_cppAspect->setValue(TriState::Default);
|
||||||
|
});
|
||||||
|
connect(m_qmlAspect, &TriStateAspect::changed, this, [this] {
|
||||||
|
if (Utils::allOf({m_cppAspect, m_qmlAspect, m_pythonAspect}, &isDisabled))
|
||||||
m_cppAspect->setValue(TriState::Default);
|
m_cppAspect->setValue(TriState::Default);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
m_multiProcessAspect = new BoolAspect;
|
m_multiProcessAspect = new BoolAspect;
|
||||||
m_multiProcessAspect->setSettingsKey("RunConfiguration.UseMultiProcess");
|
m_multiProcessAspect->setSettingsKey("RunConfiguration.UseMultiProcess");
|
||||||
@@ -177,8 +192,8 @@ bool DebuggerRunConfigurationAspect::useQmlDebugger() const
|
|||||||
//
|
//
|
||||||
// Try to find a build configuration to check whether qml debugging is enabled there
|
// Try to find a build configuration to check whether qml debugging is enabled there
|
||||||
if (BuildConfiguration *bc = m_target->activeBuildConfiguration()) {
|
if (BuildConfiguration *bc = m_target->activeBuildConfiguration()) {
|
||||||
const auto aspect = bc->aspect<QtSupport::QmlDebuggingAspect>();
|
if (const auto aspect = bc->aspect<QtSupport::QmlDebuggingAspect>())
|
||||||
return aspect && aspect->value() == TriState::Enabled;
|
return aspect->value() == TriState::Enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !languages.contains(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
return !languages.contains(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
||||||
@@ -186,6 +201,15 @@ bool DebuggerRunConfigurationAspect::useQmlDebugger() const
|
|||||||
return m_qmlAspect->value() == TriState::Enabled;
|
return m_qmlAspect->value() == TriState::Enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DebuggerRunConfigurationAspect::usePythonDebugger() const
|
||||||
|
{
|
||||||
|
if (m_pythonAspect->value() == TriState::Default) {
|
||||||
|
const Core::Context languages = m_target->project()->projectLanguages();
|
||||||
|
return languages.contains(ProjectExplorer::Constants::PYTHON_LANGUAGE_ID);
|
||||||
|
}
|
||||||
|
return m_pythonAspect->value() == TriState::Enabled;
|
||||||
|
}
|
||||||
|
|
||||||
bool DebuggerRunConfigurationAspect::useMultiProcess() const
|
bool DebuggerRunConfigurationAspect::useMultiProcess() const
|
||||||
{
|
{
|
||||||
return m_multiProcessAspect->value();
|
return m_multiProcessAspect->value();
|
||||||
@@ -215,6 +239,7 @@ void DebuggerRunConfigurationAspect::toMap(Store &map) const
|
|||||||
{
|
{
|
||||||
m_cppAspect->toMap(map);
|
m_cppAspect->toMap(map);
|
||||||
m_qmlAspect->toMap(map);
|
m_qmlAspect->toMap(map);
|
||||||
|
m_pythonAspect->toMap(map);
|
||||||
m_multiProcessAspect->toMap(map);
|
m_multiProcessAspect->toMap(map);
|
||||||
m_overrideStartupAspect->toMap(map);
|
m_overrideStartupAspect->toMap(map);
|
||||||
|
|
||||||
@@ -227,6 +252,7 @@ void DebuggerRunConfigurationAspect::fromMap(const Store &map)
|
|||||||
{
|
{
|
||||||
m_cppAspect->fromMap(map);
|
m_cppAspect->fromMap(map);
|
||||||
m_qmlAspect->fromMap(map);
|
m_qmlAspect->fromMap(map);
|
||||||
|
m_pythonAspect->fromMap(map);
|
||||||
|
|
||||||
// respect old project settings
|
// respect old project settings
|
||||||
if (map.value("RunConfiguration.UseCppDebuggerAuto", false).toBool())
|
if (map.value("RunConfiguration.UseCppDebuggerAuto", false).toBool())
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public:
|
|||||||
|
|
||||||
bool useCppDebugger() const;
|
bool useCppDebugger() const;
|
||||||
bool useQmlDebugger() const;
|
bool useQmlDebugger() const;
|
||||||
|
bool usePythonDebugger() const;
|
||||||
void setUseQmlDebugger(bool value);
|
void setUseQmlDebugger(bool value);
|
||||||
bool useMultiProcess() const;
|
bool useMultiProcess() const;
|
||||||
void setUseMultiProcess(bool on);
|
void setUseMultiProcess(bool on);
|
||||||
@@ -33,6 +34,7 @@ public:
|
|||||||
{
|
{
|
||||||
bool useCppDebugger;
|
bool useCppDebugger;
|
||||||
bool useQmlDebugger;
|
bool useQmlDebugger;
|
||||||
|
bool usePythonDebugger;
|
||||||
bool useMultiProcess;
|
bool useMultiProcess;
|
||||||
QString overrideStartup;
|
QString overrideStartup;
|
||||||
};
|
};
|
||||||
@@ -40,6 +42,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
Utils::TriStateAspect *m_cppAspect;
|
Utils::TriStateAspect *m_cppAspect;
|
||||||
Utils::TriStateAspect *m_qmlAspect;
|
Utils::TriStateAspect *m_qmlAspect;
|
||||||
|
Utils::TriStateAspect *m_pythonAspect;
|
||||||
Utils::BoolAspect *m_multiProcessAspect;
|
Utils::BoolAspect *m_multiProcessAspect;
|
||||||
Utils::StringAspect *m_overrideStartupAspect;
|
Utils::StringAspect *m_overrideStartupAspect;
|
||||||
ProjectExplorer::Target *m_target;
|
ProjectExplorer::Target *m_target;
|
||||||
|
|||||||
@@ -481,31 +481,27 @@ void DebuggerRunTool::start()
|
|||||||
|
|
||||||
runControl()->setDisplayName(m_runParameters.displayName);
|
runControl()->setDisplayName(m_runParameters.displayName);
|
||||||
|
|
||||||
if (!m_engine)
|
if (auto dapEngine = createDapEngine(runControl()->runMode()))
|
||||||
m_engine = createDapEngine(runControl()->runMode());
|
m_engines << dapEngine;
|
||||||
|
|
||||||
if (!m_engine) {
|
if (m_engines.isEmpty()) {
|
||||||
if (m_runParameters.isCppDebugging()) {
|
if (m_runParameters.isCppDebugging()) {
|
||||||
switch (m_runParameters.cppEngineType) {
|
switch (m_runParameters.cppEngineType) {
|
||||||
case GdbEngineType:
|
case GdbEngineType:
|
||||||
m_engine = createGdbEngine();
|
m_engines << createGdbEngine();
|
||||||
break;
|
break;
|
||||||
case CdbEngineType:
|
case CdbEngineType:
|
||||||
if (!HostOsInfo::isWindowsHost()) {
|
if (!HostOsInfo::isWindowsHost()) {
|
||||||
reportFailure(Tr::tr("Unsupported CDB host system."));
|
reportFailure(Tr::tr("Unsupported CDB host system."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_engine = createCdbEngine();
|
m_engines << createCdbEngine();
|
||||||
break;
|
break;
|
||||||
case LldbEngineType:
|
case LldbEngineType:
|
||||||
m_engine = createLldbEngine();
|
m_engines << createLldbEngine();
|
||||||
break;
|
|
||||||
case PdbEngineType: // FIXME: Yes, Python counts as C++...
|
|
||||||
QTC_CHECK(false); // Called from DebuggerRunTool constructor already.
|
|
||||||
// m_engine = createPdbEngine();
|
|
||||||
break;
|
break;
|
||||||
case UvscEngineType:
|
case UvscEngineType:
|
||||||
m_engine = createUvscEngine();
|
m_engines << createUvscEngine();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!m_runParameters.isQmlDebugging) {
|
if (!m_runParameters.isQmlDebugging) {
|
||||||
@@ -518,16 +514,14 @@ void DebuggerRunTool::start()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_runParameters.isQmlDebugging) {
|
if (m_runParameters.isPythonDebugging)
|
||||||
if (m_engine) {
|
m_engines << createPdbEngine();
|
||||||
m_engine2 = createQmlEngine();
|
|
||||||
} else {
|
if (m_runParameters.isQmlDebugging)
|
||||||
m_engine = createQmlEngine();
|
m_engines << createQmlEngine();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_engine) {
|
if (m_engines.isEmpty()) {
|
||||||
QString msg = noEngineMessage();
|
QString msg = noEngineMessage();
|
||||||
if (!DebuggerKitAspect::debugger(runControl()->kit()))
|
if (!DebuggerKitAspect::debugger(runControl()->kit()))
|
||||||
msg += '\n' + noDebuggerInKitMessage();
|
msg += '\n' + noDebuggerInKitMessage();
|
||||||
@@ -535,26 +529,47 @@ void DebuggerRunTool::start()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_engine->setRunParameters(m_runParameters);
|
if (auto interpreterAspect = runControl()->aspect<FilePathAspect>()) {
|
||||||
m_engine->setRunId(d->runId);
|
if (auto mainScriptAspect = runControl()->aspect<MainScriptAspect>()) {
|
||||||
m_engine->setRunTool(this);
|
const FilePath mainScript = mainScriptAspect->filePath;
|
||||||
m_engine->setCompanionEngine(m_engine2);
|
const FilePath interpreter = interpreterAspect->filePath;
|
||||||
|
if (!interpreter.isEmpty() && mainScript.endsWith(".py")) {
|
||||||
|
m_runParameters.mainScript = mainScript;
|
||||||
|
m_runParameters.interpreter = interpreter;
|
||||||
|
if (auto args = runControl()->aspect<ArgumentsAspect>())
|
||||||
|
m_runParameters.inferior.command.addArgs(args->arguments, CommandLine::Raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
for (auto engine : m_engines) {
|
||||||
|
engine->setRunParameters(m_runParameters);
|
||||||
|
engine->setRunId(d->runId);
|
||||||
|
engine->setRunTool(this);
|
||||||
|
for (auto companion : m_engines) {
|
||||||
|
if (companion != engine)
|
||||||
|
engine->addCompanionEngine(companion);
|
||||||
|
}
|
||||||
|
if (!first)
|
||||||
|
engine->setSecondaryEngine();
|
||||||
auto rc = runControl();
|
auto rc = runControl();
|
||||||
connect(m_engine, &DebuggerEngine::requestRunControlFinish, rc, [rc] {
|
connect(engine, &DebuggerEngine::requestRunControlFinish, rc, [rc] {
|
||||||
rc->setAutoDeleteOnStop(true);
|
rc->setAutoDeleteOnStop(true);
|
||||||
rc->initiateStop();
|
rc->initiateStop();
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
connect(m_engine, &DebuggerEngine::requestRunControlStop, rc, &RunControl::initiateStop);
|
connect(engine, &DebuggerEngine::requestRunControlStop, rc, &RunControl::initiateStop);
|
||||||
connect(m_engine, &DebuggerEngine::engineStarted,
|
connect(engine, &DebuggerEngine::engineStarted,
|
||||||
this, [this] { handleEngineStarted(m_engine); });
|
this, [this, engine] { handleEngineStarted(engine); });
|
||||||
connect(m_engine, &DebuggerEngine::engineFinished,
|
connect(engine, &DebuggerEngine::engineFinished,
|
||||||
this, [this] { handleEngineFinished(m_engine); });
|
this, [this, engine] { handleEngineFinished(engine); });
|
||||||
connect(m_engine, &DebuggerEngine::appendMessageRequested,
|
connect(engine, &DebuggerEngine::appendMessageRequested,
|
||||||
this, &DebuggerRunTool::appendMessage);
|
this, &DebuggerRunTool::appendMessage);
|
||||||
++d->engineStartsNeeded;
|
++d->engineStartsNeeded;
|
||||||
++d->engineStopsNeeded;
|
++d->engineStopsNeeded;
|
||||||
|
|
||||||
connect(m_engine, &DebuggerEngine::attachToCoreRequested, this, [this](const QString &coreFile) {
|
if (first) {
|
||||||
|
connect(engine, &DebuggerEngine::attachToCoreRequested, this, [this](const QString &coreFile) {
|
||||||
auto rc = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
auto rc = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
||||||
rc->copyDataFromRunControl(runControl());
|
rc->copyDataFromRunControl(runControl());
|
||||||
auto name = QString(Tr::tr("%1 - Snapshot %2").arg(runControl()->displayName()).arg(++d->snapshotCounter));
|
auto name = QString(Tr::tr("%1 - Snapshot %2").arg(runControl()->displayName()).arg(++d->snapshotCounter));
|
||||||
@@ -565,25 +580,8 @@ void DebuggerRunTool::start()
|
|||||||
debugger->startRunControl();
|
debugger->startRunControl();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (m_engine2) {
|
first = false;
|
||||||
m_engine2->setRunParameters(m_runParameters);
|
}
|
||||||
m_engine2->setRunId(d->runId);
|
|
||||||
m_engine2->setRunTool(this);
|
|
||||||
m_engine2->setCompanionEngine(m_engine);
|
|
||||||
m_engine2->setSecondaryEngine();
|
|
||||||
connect(m_engine2, &DebuggerEngine::requestRunControlFinish, rc, [rc] {
|
|
||||||
rc->setAutoDeleteOnStop(true);
|
|
||||||
rc->initiateStop();
|
|
||||||
}, Qt::QueuedConnection);
|
|
||||||
connect(m_engine2, &DebuggerEngine::requestRunControlStop, rc, &RunControl::initiateStop);
|
|
||||||
connect(m_engine2, &DebuggerEngine::engineStarted,
|
|
||||||
this, [this] { handleEngineStarted(m_engine2); });
|
|
||||||
connect(m_engine2, &DebuggerEngine::engineFinished,
|
|
||||||
this, [this] { handleEngineFinished(m_engine2); });
|
|
||||||
connect(m_engine2, &DebuggerEngine::appendMessageRequested,
|
|
||||||
this, &DebuggerRunTool::appendMessage);
|
|
||||||
++d->engineStartsNeeded;
|
|
||||||
++d->engineStopsNeeded;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_runParameters.startMode != AttachToCore) {
|
if (m_runParameters.startMode != AttachToCore) {
|
||||||
@@ -593,12 +591,13 @@ void DebuggerRunTool::start()
|
|||||||
if (gbp->isEnabled()) {
|
if (gbp->isEnabled()) {
|
||||||
const BreakpointParameters &bp = gbp->requestedParameters();
|
const BreakpointParameters &bp = gbp->requestedParameters();
|
||||||
hasQmlBreakpoints = hasQmlBreakpoints || bp.isQmlFileAndLineBreakpoint();
|
hasQmlBreakpoints = hasQmlBreakpoints || bp.isQmlFileAndLineBreakpoint();
|
||||||
if (!m_engine->acceptsBreakpoint(bp)) {
|
auto engineAcceptsBp = [bp](const DebuggerEngine *engine) {
|
||||||
if (!m_engine2 || !m_engine2->acceptsBreakpoint(bp))
|
return engine->acceptsBreakpoint(bp);
|
||||||
|
};
|
||||||
|
if (!Utils::anyOf(m_engines, engineAcceptsBp))
|
||||||
unhandledIds.append(gbp->displayName());
|
unhandledIds.append(gbp->displayName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!unhandledIds.isEmpty()) {
|
if (!unhandledIds.isEmpty()) {
|
||||||
QString warningMessage = Tr::tr("Some breakpoints cannot be handled by the debugger "
|
QString warningMessage = Tr::tr("Some breakpoints cannot be handled by the debugger "
|
||||||
"languages currently active, and will be ignored.<p>"
|
"languages currently active, and will be ignored.<p>"
|
||||||
@@ -624,28 +623,22 @@ void DebuggerRunTool::start()
|
|||||||
|
|
||||||
appendMessage(Tr::tr("Debugging %1 ...").arg(m_runParameters.inferior.command.toUserOutput()),
|
appendMessage(Tr::tr("Debugging %1 ...").arg(m_runParameters.inferior.command.toUserOutput()),
|
||||||
NormalMessageFormat);
|
NormalMessageFormat);
|
||||||
QString debuggerName = m_engine->objectName();
|
const QString debuggerName = Utils::transform<QStringList>(m_engines, &DebuggerEngine::objectName).join(" ");
|
||||||
if (m_engine2)
|
|
||||||
debuggerName += ' ' + m_engine2->objectName();
|
|
||||||
|
|
||||||
const QString message = Tr::tr("Starting debugger \"%1\" for ABI \"%2\"...")
|
const QString message = Tr::tr("Starting debugger \"%1\" for ABI \"%2\"...")
|
||||||
.arg(debuggerName).arg(m_runParameters.toolChainAbi.toString());
|
.arg(debuggerName).arg(m_runParameters.toolChainAbi.toString());
|
||||||
DebuggerMainWindow::showStatusMessage(message, 10000);
|
DebuggerMainWindow::showStatusMessage(message, 10000);
|
||||||
|
|
||||||
showMessage(m_engine->formatStartParameters(), LogDebug);
|
showMessage(m_engines.first()->formatStartParameters(), LogDebug);
|
||||||
showMessage(DebuggerSettings::dump(), LogDebug);
|
showMessage(DebuggerSettings::dump(), LogDebug);
|
||||||
|
|
||||||
if (m_engine2)
|
Utils::reverseForeach(m_engines, [](DebuggerEngine *engine) { engine->start(); });
|
||||||
m_engine2->start();
|
|
||||||
m_engine->start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerRunTool::stop()
|
void DebuggerRunTool::stop()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_engine, reportStopped(); return);
|
QTC_ASSERT(!m_engines.isEmpty(), reportStopped(); return);
|
||||||
if (m_engine2)
|
Utils::reverseForeach(m_engines, [](DebuggerEngine *engine) { engine->quitDebugger(); });
|
||||||
m_engine2->quitDebugger();
|
|
||||||
m_engine->quitDebugger();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerRunTool::handleEngineStarted(DebuggerEngine *engine)
|
void DebuggerRunTool::handleEngineStarted(DebuggerEngine *engine)
|
||||||
@@ -657,7 +650,7 @@ void DebuggerRunTool::handleEngineStarted(DebuggerEngine *engine)
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// Feels better, as the QML Engine might attach late or not at all.
|
// Feels better, as the QML Engine might attach late or not at all.
|
||||||
if (engine == m_engine) {
|
if (engine == m_engines.first()) {
|
||||||
EngineManager::activateDebugMode();
|
EngineManager::activateDebugMode();
|
||||||
reportStarted();
|
reportStarted();
|
||||||
}
|
}
|
||||||
@@ -865,6 +858,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
|
|||||||
if (!aspect->useCppDebugger)
|
if (!aspect->useCppDebugger)
|
||||||
m_runParameters.cppEngineType = NoEngineType;
|
m_runParameters.cppEngineType = NoEngineType;
|
||||||
m_runParameters.isQmlDebugging = aspect->useQmlDebugger;
|
m_runParameters.isQmlDebugging = aspect->useQmlDebugger;
|
||||||
|
m_runParameters.isPythonDebugging = aspect->usePythonDebugger;
|
||||||
m_runParameters.multiProcess = aspect->useMultiProcess;
|
m_runParameters.multiProcess = aspect->useMultiProcess;
|
||||||
m_runParameters.additionalStartupCommands = aspect->overrideStartup;
|
m_runParameters.additionalStartupCommands = aspect->overrideStartup;
|
||||||
|
|
||||||
@@ -907,22 +901,6 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
|
|||||||
if (ok)
|
if (ok)
|
||||||
m_runParameters.nativeMixedEnabled = bool(nativeMixedOverride);
|
m_runParameters.nativeMixedEnabled = bool(nativeMixedOverride);
|
||||||
|
|
||||||
|
|
||||||
if (auto interpreterAspect = runControl->aspect<FilePathAspect>()) {
|
|
||||||
if (auto mainScriptAspect = runControl->aspect<MainScriptAspect>()) {
|
|
||||||
const FilePath mainScript = mainScriptAspect->filePath;
|
|
||||||
const FilePath interpreter = interpreterAspect->filePath;
|
|
||||||
if (!interpreter.isEmpty() && mainScript.endsWith(".py")) {
|
|
||||||
m_runParameters.mainScript = mainScript;
|
|
||||||
m_runParameters.interpreter = interpreter;
|
|
||||||
if (auto args = runControl->aspect<ArgumentsAspect>())
|
|
||||||
m_runParameters.inferior.command.addArgs(args->arguments, CommandLine::Raw);
|
|
||||||
if (runControl->runMode() == ProjectExplorer::Constants::DEBUG_RUN_MODE)
|
|
||||||
m_engine = createPdbEngine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (QtSupport::QtVersion *baseQtVersion = QtSupport::QtKitAspect::qtVersion(kit)) {
|
if (QtSupport::QtVersion *baseQtVersion = QtSupport::QtKitAspect::qtVersion(kit)) {
|
||||||
const QVersionNumber qtVersion = baseQtVersion->qtVersion();
|
const QVersionNumber qtVersion = baseQtVersion->qtVersion();
|
||||||
m_runParameters.fallbackQtVersion = 0x10000 * qtVersion.majorVersion()
|
m_runParameters.fallbackQtVersion = 0x10000 * qtVersion.majorVersion()
|
||||||
@@ -948,10 +926,8 @@ DebuggerRunTool::~DebuggerRunTool()
|
|||||||
if (m_runParameters.isSnapshot && !m_runParameters.coreFile.isEmpty())
|
if (m_runParameters.isSnapshot && !m_runParameters.coreFile.isEmpty())
|
||||||
m_runParameters.coreFile.removeFile();
|
m_runParameters.coreFile.removeFile();
|
||||||
|
|
||||||
delete m_engine2;
|
qDeleteAll(m_engines);
|
||||||
m_engine2 = nullptr;
|
m_engines.clear();
|
||||||
delete m_engine;
|
|
||||||
m_engine = nullptr;
|
|
||||||
|
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
@@ -961,11 +937,10 @@ void DebuggerRunTool::showMessage(const QString &msg, int channel, int timeout)
|
|||||||
if (channel == ConsoleOutput)
|
if (channel == ConsoleOutput)
|
||||||
debuggerConsole()->printItem(ConsoleItem::DefaultType, msg);
|
debuggerConsole()->printItem(ConsoleItem::DefaultType, msg);
|
||||||
|
|
||||||
QTC_ASSERT(m_engine, qDebug() << msg; return);
|
QTC_ASSERT(!m_engines.isEmpty(), qDebug() << msg; return);
|
||||||
|
|
||||||
m_engine->showMessage(msg, channel, timeout);
|
for (auto engine : m_engines)
|
||||||
if (m_engine2)
|
engine->showMessage(msg, channel, timeout);
|
||||||
m_engine->showMessage(msg, channel, timeout);
|
|
||||||
switch (channel) {
|
switch (channel) {
|
||||||
case AppOutput:
|
case AppOutput:
|
||||||
appendMessage(msg, StdOutFormat);
|
appendMessage(msg, StdOutFormat);
|
||||||
|
|||||||
@@ -115,8 +115,7 @@ private:
|
|||||||
void handleEngineFinished(Internal::DebuggerEngine *engine);
|
void handleEngineFinished(Internal::DebuggerEngine *engine);
|
||||||
|
|
||||||
Internal::DebuggerRunToolPrivate *d;
|
Internal::DebuggerRunToolPrivate *d;
|
||||||
QPointer<Internal::DebuggerEngine> m_engine;
|
QList<QPointer<Internal::DebuggerEngine>> m_engines;
|
||||||
QPointer<Internal::DebuggerEngine> m_engine2;
|
|
||||||
Internal::DebuggerRunParameters m_runParameters;
|
Internal::DebuggerRunParameters m_runParameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -405,7 +405,9 @@ void QmlEngine::appStartupFailed(const QString &errorMessage)
|
|||||||
{
|
{
|
||||||
QString error = Tr::tr("Could not connect to the in-process QML debugger. %1").arg(errorMessage);
|
QString error = Tr::tr("Could not connect to the in-process QML debugger. %1").arg(errorMessage);
|
||||||
|
|
||||||
if (companionEngine()) {
|
if (companionEngines().isEmpty()) {
|
||||||
|
debuggerConsole()->printItem(ConsoleItem::WarningType, error);
|
||||||
|
} else {
|
||||||
auto infoBox = new QMessageBox(ICore::dialogParent());
|
auto infoBox = new QMessageBox(ICore::dialogParent());
|
||||||
infoBox->setIcon(QMessageBox::Critical);
|
infoBox->setIcon(QMessageBox::Critical);
|
||||||
infoBox->setWindowTitle(QGuiApplication::applicationDisplayName());
|
infoBox->setWindowTitle(QGuiApplication::applicationDisplayName());
|
||||||
@@ -415,8 +417,6 @@ void QmlEngine::appStartupFailed(const QString &errorMessage)
|
|||||||
connect(infoBox, &QDialog::finished,
|
connect(infoBox, &QDialog::finished,
|
||||||
this, &QmlEngine::errorMessageBoxFinished);
|
this, &QmlEngine::errorMessageBoxFinished);
|
||||||
infoBox->show();
|
infoBox->show();
|
||||||
} else {
|
|
||||||
debuggerConsole()->printItem(ConsoleItem::WarningType, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyEngineRunFailed();
|
notifyEngineRunFailed();
|
||||||
@@ -1029,7 +1029,7 @@ bool QmlEngine::companionPreventsActions() const
|
|||||||
{
|
{
|
||||||
// We need a C++ Engine in a Running state to do anything sensible
|
// We need a C++ Engine in a Running state to do anything sensible
|
||||||
// as otherwise the debugger services in the debuggee are unresponsive.
|
// as otherwise the debugger services in the debuggee are unresponsive.
|
||||||
if (DebuggerEngine *companion = companionEngine())
|
if (DebuggerEngine *companion = companionEngines().value(0))
|
||||||
return companion->state() != InferiorRunOk;
|
return companion->state() != InferiorRunOk;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
|
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
|
||||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||||
|
|
||||||
@@ -186,10 +187,14 @@ void PythonBuildSystem::triggerParsing()
|
|||||||
newRoot->addNestedNode(
|
newRoot->addNestedNode(
|
||||||
std::make_unique<PythonFileNode>(projectFile, displayName, FileType::Project));
|
std::make_unique<PythonFileNode>(projectFile, displayName, FileType::Project));
|
||||||
|
|
||||||
|
bool hasQmlFiles = false;
|
||||||
|
|
||||||
for (const FileEntry &entry : std::as_const(m_files)) {
|
for (const FileEntry &entry : std::as_const(m_files)) {
|
||||||
const QString displayName = entry.filePath.relativePathFrom(projectDirectory()).toUserOutput();
|
const QString displayName = entry.filePath.relativePathFrom(projectDirectory()).toUserOutput();
|
||||||
const FileType fileType = getFileType(entry.filePath);
|
const FileType fileType = getFileType(entry.filePath);
|
||||||
|
|
||||||
|
hasQmlFiles |= fileType == FileType::QML;
|
||||||
|
|
||||||
newRoot->addNestedNode(std::make_unique<PythonFileNode>(entry.filePath, displayName, fileType));
|
newRoot->addNestedNode(std::make_unique<PythonFileNode>(entry.filePath, displayName, fileType));
|
||||||
const MimeType mt = mimeTypeForFile(entry.filePath, MimeMatchMode::MatchExtension);
|
const MimeType mt = mimeTypeForFile(entry.filePath, MimeMatchMode::MatchExtension);
|
||||||
if (mt.matchesName(Constants::C_PY_MIMETYPE) || mt.matchesName(Constants::C_PY3_MIMETYPE)
|
if (mt.matchesName(Constants::C_PY_MIMETYPE) || mt.matchesName(Constants::C_PY3_MIMETYPE)
|
||||||
@@ -204,6 +209,8 @@ void PythonBuildSystem::triggerParsing()
|
|||||||
appTargets.append(bti);
|
appTargets.append(bti);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
project()->setProjectLanguage(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID, hasQmlFiles);
|
||||||
|
|
||||||
setRootProjectNode(std::move(newRoot));
|
setRootProjectNode(std::move(newRoot));
|
||||||
|
|
||||||
setApplicationTargets(appTargets);
|
setApplicationTargets(appTargets);
|
||||||
|
|||||||
Reference in New Issue
Block a user