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:
David Schulz
2023-11-29 15:08:48 +01:00
committed by hjk
parent 5034936333
commit eb740bdd95
11 changed files with 143 additions and 131 deletions

View File

@@ -395,6 +395,12 @@ bool allOf(const T &container, F 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
template<typename T, typename R, typename S>
bool allOf(const T &container, R (S::*predicate)() const)

View File

@@ -97,7 +97,6 @@ enum DebuggerEngineType
NoEngineType = 0,
GdbEngineType = 0x001,
CdbEngineType = 0x004,
PdbEngineType = 0x008,
LldbEngineType = 0x100,
UvscEngineType = 0x1000
};

View File

@@ -267,8 +267,8 @@ public:
connect(&settings().enableReverseDebugging, &BaseAspect::changed, this, [this] {
updateState();
if (m_companionEngine)
m_companionEngine->d->updateState();
for (const QPointer<DebuggerEngine> &companion : std::as_const(m_companionEngines))
companion->d->updateState();
});
static int contextCount = 0;
m_context = Context(Id("Debugger.Engine.").withSuffix(++contextCount));
@@ -445,7 +445,7 @@ public:
DebuggerRunParameters m_runParameters;
IDevice::ConstPtr m_device;
QPointer<DebuggerEngine> m_companionEngine;
QList<QPointer<DebuggerEngine>> m_companionEngines;
bool m_isPrimaryEngine = true;
// The current state.
@@ -1134,9 +1134,9 @@ IDevice::ConstPtr DebuggerEngine::device() const
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
@@ -1849,8 +1849,8 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
showMessage(msg, LogDebug);
d->updateState();
if (d->m_companionEngine)
d->m_companionEngine->d->updateState();
for (const QPointer<DebuggerEngine> &companion : std::as_const(d->m_companionEngines))
companion->d->updateState();
if (oldState != d->m_state)
emit EngineManager::instance()->engineStateChanged(this);
@@ -2037,9 +2037,9 @@ void DebuggerEngine::progressPing()
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()

View File

@@ -149,6 +149,7 @@ public:
QString version;
bool isQmlDebugging = false;
bool isPythonDebugging = false;
bool breakOnMain = false;
bool multiProcess = false; // Whether to set detach-on-fork off.
bool useTerminal = false;
@@ -269,7 +270,7 @@ public:
QString runId() const;
const DebuggerRunParameters &runParameters() const;
void setCompanionEngine(DebuggerEngine *engine);
void addCompanionEngine(DebuggerEngine *engine);
void setSecondaryEngine();
void start();
@@ -553,7 +554,7 @@ protected:
void startDying() const;
ProjectExplorer::IDeviceConstPtr device() const;
DebuggerEngine *companionEngine() const;
QList<DebuggerEngine *> companionEngines() const;
private:
friend class DebuggerPluginPrivate;

View File

@@ -243,10 +243,6 @@ void DebuggerItem::reinitializeFromFile(QString *error, Utils::Environment *cust
m_version = output.section(' ', 2);
return;
}
if (output.startsWith("Python")) {
m_engineType = PdbEngineType;
return;
}
if (error)
*error = output;
m_engineType = NoEngineType;

View File

@@ -40,6 +40,12 @@ namespace Debugger {
\class Debugger::DebuggerRunConfigurationAspect
*/
static bool isDisabled(TriStateAspect *aspect)
{
QTC_ASSERT(aspect, return false);
return aspect->value() == TriState::Disabled;
}
DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
: m_target(target)
{
@@ -49,6 +55,7 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
setConfigWidgetCreator([this] {
Layouting::Grid builder;
builder.addRow({m_cppAspect});
builder.addRow({m_pythonAspect});
auto info = new QLabel(
Tr::tr("<a href=\""
"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::useQmlDebugger, &Data::useQmlDebugger);
addDataExtractor(this, &DebuggerRunConfigurationAspect::usePythonDebugger, &Data::usePythonDebugger);
addDataExtractor(this, &DebuggerRunConfigurationAspect::useMultiProcess, &Data::useMultiProcess);
addDataExtractor(this, &DebuggerRunConfigurationAspect::overrideStartup, &Data::overrideStartup);
@@ -109,16 +117,23 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
m_qmlAspect->setLabelText(Tr::tr("QML debugger:"));
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.
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);
});
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_multiProcessAspect = new BoolAspect;
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
if (BuildConfiguration *bc = m_target->activeBuildConfiguration()) {
const auto aspect = bc->aspect<QtSupport::QmlDebuggingAspect>();
return aspect && aspect->value() == TriState::Enabled;
if (const auto aspect = bc->aspect<QtSupport::QmlDebuggingAspect>())
return aspect->value() == TriState::Enabled;
}
return !languages.contains(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
@@ -186,6 +201,15 @@ bool DebuggerRunConfigurationAspect::useQmlDebugger() const
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
{
return m_multiProcessAspect->value();
@@ -215,6 +239,7 @@ void DebuggerRunConfigurationAspect::toMap(Store &map) const
{
m_cppAspect->toMap(map);
m_qmlAspect->toMap(map);
m_pythonAspect->toMap(map);
m_multiProcessAspect->toMap(map);
m_overrideStartupAspect->toMap(map);
@@ -227,6 +252,7 @@ void DebuggerRunConfigurationAspect::fromMap(const Store &map)
{
m_cppAspect->fromMap(map);
m_qmlAspect->fromMap(map);
m_pythonAspect->fromMap(map);
// respect old project settings
if (map.value("RunConfiguration.UseCppDebuggerAuto", false).toBool())

View File

@@ -22,6 +22,7 @@ public:
bool useCppDebugger() const;
bool useQmlDebugger() const;
bool usePythonDebugger() const;
void setUseQmlDebugger(bool value);
bool useMultiProcess() const;
void setUseMultiProcess(bool on);
@@ -33,6 +34,7 @@ public:
{
bool useCppDebugger;
bool useQmlDebugger;
bool usePythonDebugger;
bool useMultiProcess;
QString overrideStartup;
};
@@ -40,6 +42,7 @@ public:
private:
Utils::TriStateAspect *m_cppAspect;
Utils::TriStateAspect *m_qmlAspect;
Utils::TriStateAspect *m_pythonAspect;
Utils::BoolAspect *m_multiProcessAspect;
Utils::StringAspect *m_overrideStartupAspect;
ProjectExplorer::Target *m_target;

View File

@@ -481,31 +481,27 @@ void DebuggerRunTool::start()
runControl()->setDisplayName(m_runParameters.displayName);
if (!m_engine)
m_engine = createDapEngine(runControl()->runMode());
if (auto dapEngine = createDapEngine(runControl()->runMode()))
m_engines << dapEngine;
if (!m_engine) {
if (m_engines.isEmpty()) {
if (m_runParameters.isCppDebugging()) {
switch (m_runParameters.cppEngineType) {
case GdbEngineType:
m_engine = createGdbEngine();
m_engines << createGdbEngine();
break;
case CdbEngineType:
if (!HostOsInfo::isWindowsHost()) {
reportFailure(Tr::tr("Unsupported CDB host system."));
return;
}
m_engine = createCdbEngine();
m_engines << createCdbEngine();
break;
case LldbEngineType:
m_engine = createLldbEngine();
break;
case PdbEngineType: // FIXME: Yes, Python counts as C++...
QTC_CHECK(false); // Called from DebuggerRunTool constructor already.
// m_engine = createPdbEngine();
m_engines << createLldbEngine();
break;
case UvscEngineType:
m_engine = createUvscEngine();
m_engines << createUvscEngine();
break;
default:
if (!m_runParameters.isQmlDebugging) {
@@ -518,16 +514,14 @@ void DebuggerRunTool::start()
}
}
if (m_runParameters.isQmlDebugging) {
if (m_engine) {
m_engine2 = createQmlEngine();
} else {
m_engine = createQmlEngine();
}
}
if (m_runParameters.isPythonDebugging)
m_engines << createPdbEngine();
if (m_runParameters.isQmlDebugging)
m_engines << createQmlEngine();
}
if (!m_engine) {
if (m_engines.isEmpty()) {
QString msg = noEngineMessage();
if (!DebuggerKitAspect::debugger(runControl()->kit()))
msg += '\n' + noDebuggerInKitMessage();
@@ -535,55 +529,59 @@ void DebuggerRunTool::start()
return;
}
m_engine->setRunParameters(m_runParameters);
m_engine->setRunId(d->runId);
m_engine->setRunTool(this);
m_engine->setCompanionEngine(m_engine2);
auto rc = runControl();
connect(m_engine, &DebuggerEngine::requestRunControlFinish, rc, [rc] {
rc->setAutoDeleteOnStop(true);
rc->initiateStop();
}, Qt::QueuedConnection);
connect(m_engine, &DebuggerEngine::requestRunControlStop, rc, &RunControl::initiateStop);
connect(m_engine, &DebuggerEngine::engineStarted,
this, [this] { handleEngineStarted(m_engine); });
connect(m_engine, &DebuggerEngine::engineFinished,
this, [this] { handleEngineFinished(m_engine); });
connect(m_engine, &DebuggerEngine::appendMessageRequested,
this, &DebuggerRunTool::appendMessage);
++d->engineStartsNeeded;
++d->engineStopsNeeded;
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);
}
}
}
connect(m_engine, &DebuggerEngine::attachToCoreRequested, this, [this](const QString &coreFile) {
auto rc = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
rc->copyDataFromRunControl(runControl());
auto name = QString(Tr::tr("%1 - Snapshot %2").arg(runControl()->displayName()).arg(++d->snapshotCounter));
auto debugger = new DebuggerRunTool(rc);
debugger->setStartMode(AttachToCore);
debugger->setRunControlName(name);
debugger->setCoreFilePath(FilePath::fromString(coreFile), true);
debugger->startRunControl();
});
if (m_engine2) {
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,
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();
connect(engine, &DebuggerEngine::requestRunControlFinish, rc, [rc] {
rc->setAutoDeleteOnStop(true);
rc->initiateStop();
}, Qt::QueuedConnection);
connect(engine, &DebuggerEngine::requestRunControlStop, rc, &RunControl::initiateStop);
connect(engine, &DebuggerEngine::engineStarted,
this, [this, engine] { handleEngineStarted(engine); });
connect(engine, &DebuggerEngine::engineFinished,
this, [this, engine] { handleEngineFinished(engine); });
connect(engine, &DebuggerEngine::appendMessageRequested,
this, &DebuggerRunTool::appendMessage);
++d->engineStartsNeeded;
++d->engineStopsNeeded;
if (first) {
connect(engine, &DebuggerEngine::attachToCoreRequested, this, [this](const QString &coreFile) {
auto rc = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
rc->copyDataFromRunControl(runControl());
auto name = QString(Tr::tr("%1 - Snapshot %2").arg(runControl()->displayName()).arg(++d->snapshotCounter));
auto debugger = new DebuggerRunTool(rc);
debugger->setStartMode(AttachToCore);
debugger->setRunControlName(name);
debugger->setCoreFilePath(FilePath::fromString(coreFile), true);
debugger->startRunControl();
});
first = false;
}
}
if (m_runParameters.startMode != AttachToCore) {
@@ -593,10 +591,11 @@ void DebuggerRunTool::start()
if (gbp->isEnabled()) {
const BreakpointParameters &bp = gbp->requestedParameters();
hasQmlBreakpoints = hasQmlBreakpoints || bp.isQmlFileAndLineBreakpoint();
if (!m_engine->acceptsBreakpoint(bp)) {
if (!m_engine2 || !m_engine2->acceptsBreakpoint(bp))
unhandledIds.append(gbp->displayName());
}
auto engineAcceptsBp = [bp](const DebuggerEngine *engine) {
return engine->acceptsBreakpoint(bp);
};
if (!Utils::anyOf(m_engines, engineAcceptsBp))
unhandledIds.append(gbp->displayName());
}
}
if (!unhandledIds.isEmpty()) {
@@ -624,28 +623,22 @@ void DebuggerRunTool::start()
appendMessage(Tr::tr("Debugging %1 ...").arg(m_runParameters.inferior.command.toUserOutput()),
NormalMessageFormat);
QString debuggerName = m_engine->objectName();
if (m_engine2)
debuggerName += ' ' + m_engine2->objectName();
const QString debuggerName = Utils::transform<QStringList>(m_engines, &DebuggerEngine::objectName).join(" ");
const QString message = Tr::tr("Starting debugger \"%1\" for ABI \"%2\"...")
.arg(debuggerName).arg(m_runParameters.toolChainAbi.toString());
DebuggerMainWindow::showStatusMessage(message, 10000);
showMessage(m_engine->formatStartParameters(), LogDebug);
showMessage(m_engines.first()->formatStartParameters(), LogDebug);
showMessage(DebuggerSettings::dump(), LogDebug);
if (m_engine2)
m_engine2->start();
m_engine->start();
Utils::reverseForeach(m_engines, [](DebuggerEngine *engine) { engine->start(); });
}
void DebuggerRunTool::stop()
{
QTC_ASSERT(m_engine, reportStopped(); return);
if (m_engine2)
m_engine2->quitDebugger();
m_engine->quitDebugger();
QTC_ASSERT(!m_engines.isEmpty(), reportStopped(); return);
Utils::reverseForeach(m_engines, [](DebuggerEngine *engine) { engine->quitDebugger(); });
}
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.
if (engine == m_engine) {
if (engine == m_engines.first()) {
EngineManager::activateDebugMode();
reportStarted();
}
@@ -865,6 +858,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
if (!aspect->useCppDebugger)
m_runParameters.cppEngineType = NoEngineType;
m_runParameters.isQmlDebugging = aspect->useQmlDebugger;
m_runParameters.isPythonDebugging = aspect->usePythonDebugger;
m_runParameters.multiProcess = aspect->useMultiProcess;
m_runParameters.additionalStartupCommands = aspect->overrideStartup;
@@ -907,22 +901,6 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
if (ok)
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)) {
const QVersionNumber qtVersion = baseQtVersion->qtVersion();
m_runParameters.fallbackQtVersion = 0x10000 * qtVersion.majorVersion()
@@ -948,10 +926,8 @@ DebuggerRunTool::~DebuggerRunTool()
if (m_runParameters.isSnapshot && !m_runParameters.coreFile.isEmpty())
m_runParameters.coreFile.removeFile();
delete m_engine2;
m_engine2 = nullptr;
delete m_engine;
m_engine = nullptr;
qDeleteAll(m_engines);
m_engines.clear();
delete d;
}
@@ -961,11 +937,10 @@ void DebuggerRunTool::showMessage(const QString &msg, int channel, int timeout)
if (channel == ConsoleOutput)
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);
if (m_engine2)
m_engine->showMessage(msg, channel, timeout);
for (auto engine : m_engines)
engine->showMessage(msg, channel, timeout);
switch (channel) {
case AppOutput:
appendMessage(msg, StdOutFormat);

View File

@@ -115,8 +115,7 @@ private:
void handleEngineFinished(Internal::DebuggerEngine *engine);
Internal::DebuggerRunToolPrivate *d;
QPointer<Internal::DebuggerEngine> m_engine;
QPointer<Internal::DebuggerEngine> m_engine2;
QList<QPointer<Internal::DebuggerEngine>> m_engines;
Internal::DebuggerRunParameters m_runParameters;
};

View File

@@ -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);
if (companionEngine()) {
if (companionEngines().isEmpty()) {
debuggerConsole()->printItem(ConsoleItem::WarningType, error);
} else {
auto infoBox = new QMessageBox(ICore::dialogParent());
infoBox->setIcon(QMessageBox::Critical);
infoBox->setWindowTitle(QGuiApplication::applicationDisplayName());
@@ -415,8 +417,6 @@ void QmlEngine::appStartupFailed(const QString &errorMessage)
connect(infoBox, &QDialog::finished,
this, &QmlEngine::errorMessageBoxFinished);
infoBox->show();
} else {
debuggerConsole()->printItem(ConsoleItem::WarningType, error);
}
notifyEngineRunFailed();
@@ -1029,7 +1029,7 @@ bool QmlEngine::companionPreventsActions() const
{
// We need a C++ Engine in a Running state to do anything sensible
// 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 false;

View File

@@ -13,6 +13,7 @@
#include <coreplugin/messagemanager.h>
#include <projectexplorer/target.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <qmljs/qmljsmodelmanagerinterface.h>
@@ -186,10 +187,14 @@ void PythonBuildSystem::triggerParsing()
newRoot->addNestedNode(
std::make_unique<PythonFileNode>(projectFile, displayName, FileType::Project));
bool hasQmlFiles = false;
for (const FileEntry &entry : std::as_const(m_files)) {
const QString displayName = entry.filePath.relativePathFrom(projectDirectory()).toUserOutput();
const FileType fileType = getFileType(entry.filePath);
hasQmlFiles |= fileType == FileType::QML;
newRoot->addNestedNode(std::make_unique<PythonFileNode>(entry.filePath, displayName, fileType));
const MimeType mt = mimeTypeForFile(entry.filePath, MimeMatchMode::MatchExtension);
if (mt.matchesName(Constants::C_PY_MIMETYPE) || mt.matchesName(Constants::C_PY3_MIMETYPE)
@@ -204,6 +209,8 @@ void PythonBuildSystem::triggerParsing()
appTargets.append(bti);
}
}
project()->setProjectLanguage(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID, hasQmlFiles);
setRootProjectNode(std::move(newRoot));
setApplicationTargets(appTargets);