Python: Centralize interpreter specific function in the aspect

... and expose that instead of the PythonRunConfiguration.

This makes the PythonRunConfiguration more the container of aspects,
similar to where the other runconfigs move.

Change-Id: Ibc76b706f2d4d334640ea8f3b91343f9e7c0f566
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2023-07-05 09:30:51 +02:00
parent 7a28ed76b8
commit b3df9a4fcf
3 changed files with 59 additions and 37 deletions

View File

@@ -207,8 +207,9 @@ void PyLSClient::openDocument(TextEditor::TextDocument *document)
const FilePath documentPath = document->filePath();
if (PythonProject *project = pythonProjectForFile(documentPath)) {
if (Target *target = project->activeTarget()) {
if (auto rc = qobject_cast<PythonRunConfiguration *>(target->activeRunConfiguration()))
updateExtraCompilers(project, rc->extraCompilers());
if (RunConfiguration *rc = target->activeRunConfiguration())
if (auto aspect = rc->aspect<PythonInterpreterAspect>())
updateExtraCompilers(project, aspect->extraCompilers());
}
} else if (isSupportedDocument(document)) {
const FilePath workspacePath = documentPath.parentDir();

View File

@@ -119,28 +119,25 @@ private:
////////////////////////////////////////////////////////////////
class PythonInterpreterAspect final : public InterpreterAspect
class PythonInterpreterAspectPrivate : public QObject
{
public:
PythonInterpreterAspect(PythonRunConfiguration *rc)
: q(rc)
PythonInterpreterAspectPrivate(PythonInterpreterAspect *parent, PythonRunConfiguration *rc)
: q(parent), rc(rc)
{
connect(this, &InterpreterAspect::changed,
this, &PythonInterpreterAspect::currentInterpreterChanged);
connect(q, &InterpreterAspect::changed,
this, &PythonInterpreterAspectPrivate::currentInterpreterChanged);
currentInterpreterChanged();
connect(PySideInstaller::instance(), &PySideInstaller::pySideInstalled, this,
[this](const FilePath &python) {
if (python == currentInterpreter().command)
if (python == q->currentInterpreter().command)
checkForPySide(python);
}
);
}
~PythonInterpreterAspect()
{
qDeleteAll(m_extraCompilers);
}
~PythonInterpreterAspectPrivate() { qDeleteAll(m_extraCompilers); }
void checkForPySide(const FilePath &python);
void checkForPySide(const FilePath &python, const QString &pySidePackageName);
@@ -152,12 +149,28 @@ public:
FilePath m_pySideUicPath;
PythonRunConfiguration *q;
PythonInterpreterAspect *q;
PythonRunConfiguration *rc;
QList<PySideUicExtraCompiler *> m_extraCompilers;
QFutureWatcher<PipPackageInfo> m_watcher;
QMetaObject::Connection m_watcherConnection;
};
PythonInterpreterAspect::PythonInterpreterAspect(PythonRunConfiguration *rc)
: d(new PythonInterpreterAspectPrivate(this, rc))
{}
PythonInterpreterAspect::~PythonInterpreterAspect()
{
delete d;
}
class PythonRunConfiguration : public ProjectExplorer::RunConfiguration
{
public:
PythonRunConfiguration(ProjectExplorer::Target *target, Utils::Id id);
};
PythonRunConfiguration::PythonRunConfiguration(Target *target, Id id)
: RunConfiguration(target, id)
{
@@ -232,18 +245,18 @@ PythonRunConfiguration::PythonRunConfiguration(Target *target, Id id)
});
connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update);
connect(target, &Target::buildSystemUpdated, this, [this, interpreterAspect] { interpreterAspect->updateExtraCompilers(); });
connect(target, &Target::buildSystemUpdated, this, [this, interpreterAspect] {
interpreterAspect->d->updateExtraCompilers();
});
}
PythonRunConfiguration::~PythonRunConfiguration() = default;
void PythonInterpreterAspect::checkForPySide(const FilePath &python)
void PythonInterpreterAspectPrivate::checkForPySide(const FilePath &python)
{
checkForPySide(python, "PySide6-Essentials");
}
void PythonInterpreterAspect::checkForPySide(const FilePath &python,
const QString &pySidePackageName)
void PythonInterpreterAspectPrivate::checkForPySide(const FilePath &python,
const QString &pySidePackageName)
{
const PipPackage package(pySidePackageName);
QObject::disconnect(m_watcherConnection);
@@ -255,9 +268,9 @@ void PythonInterpreterAspect::checkForPySide(const FilePath &python,
ExtensionSystem::PluginManager::futureSynchronizer()->addFuture(future);
}
void PythonInterpreterAspect::handlePySidePackageInfo(const PipPackageInfo &pySideInfo,
const Utils::FilePath &python,
const QString &requestedPackageName)
void PythonInterpreterAspectPrivate::handlePySidePackageInfo(const PipPackageInfo &pySideInfo,
const FilePath &python,
const QString &requestedPackageName)
{
struct PythonTools
{
@@ -266,7 +279,7 @@ void PythonInterpreterAspect::handlePySidePackageInfo(const PipPackageInfo &pySi
};
BuildStepList *buildSteps = nullptr;
if (Target *target = q->target()) {
if (Target *target = rc->target()) {
if (auto buildConfiguration = target->activeBuildConfiguration())
buildSteps = buildConfiguration->buildSteps();
}
@@ -311,12 +324,12 @@ void PythonInterpreterAspect::handlePySidePackageInfo(const PipPackageInfo &pySi
pySideBuildStep->updatePySideProjectPath(pythonTools.pySideProjectPath);
}
void PythonInterpreterAspect::currentInterpreterChanged()
void PythonInterpreterAspectPrivate::currentInterpreterChanged()
{
const FilePath python = currentInterpreter().command;
const FilePath python = q->currentInterpreter().command;
checkForPySide(python);
for (FilePath &file : q->project()->files(Project::AllFiles)) {
for (FilePath &file : rc->project()->files(Project::AllFiles)) {
if (auto document = TextEditor::TextDocument::textDocumentForFilePath(file)) {
if (document->mimeType() == Constants::C_PY_MIMETYPE
|| document->mimeType() == Constants::C_PY3_MIMETYPE) {
@@ -327,12 +340,12 @@ void PythonInterpreterAspect::currentInterpreterChanged()
}
}
QList<PySideUicExtraCompiler *> PythonRunConfiguration::extraCompilers() const
QList<PySideUicExtraCompiler *> PythonInterpreterAspect::extraCompilers() const
{
return static_cast<PythonInterpreterAspect *>(aspect<InterpreterAspect>())->m_extraCompilers;
return d->m_extraCompilers;
}
void PythonInterpreterAspect::updateExtraCompilers()
void PythonInterpreterAspectPrivate::updateExtraCompilers()
{
QList<PySideUicExtraCompiler *> oldCompilers = m_extraCompilers;
m_extraCompilers.clear();
@@ -343,21 +356,21 @@ void PythonInterpreterAspect::updateExtraCompilers()
return fileNode->fileType() == ProjectExplorer::FileType::Form;
return false;
};
const FilePaths uiFiles = q->project()->files(uiMatcher);
const FilePaths uiFiles = rc->project()->files(uiMatcher);
for (const FilePath &uiFile : uiFiles) {
FilePath generated = uiFile.parentDir();
generated = generated.pathAppended("/ui_" + uiFile.baseName() + ".py");
int index = Utils::indexOf(oldCompilers, [&](PySideUicExtraCompiler *oldCompiler) {
return oldCompiler->pySideUicPath() == m_pySideUicPath
&& oldCompiler->project() == q->project() && oldCompiler->source() == uiFile
&& oldCompiler->project() == rc->project() && oldCompiler->source() == uiFile
&& oldCompiler->targets() == FilePaths{generated};
});
if (index < 0) {
m_extraCompilers << new PySideUicExtraCompiler(m_pySideUicPath,
q->project(),
rc->project(),
uiFile,
{generated},
q);
this);
} else {
m_extraCompilers << oldCompilers.takeAt(index);
}
@@ -365,11 +378,13 @@ void PythonInterpreterAspect::updateExtraCompilers()
}
for (LanguageClient::Client *client : LanguageClient::LanguageClientManager::clients()) {
if (auto pylsClient = qobject_cast<PyLSClient *>(client))
pylsClient->updateExtraCompilers(q->project(), m_extraCompilers);
pylsClient->updateExtraCompilers(rc->project(), m_extraCompilers);
}
qDeleteAll(oldCompilers);
}
// Factories
PythonRunConfigurationFactory::PythonRunConfigurationFactory()
{
registerRunConfiguration<PythonRunConfiguration>(Constants::C_PYTHONRUNCONFIGURATION_ID);

View File

@@ -4,21 +4,27 @@
#pragma once
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/runcontrol.h>
namespace Python::Internal {
class PySideUicExtraCompiler;
class PythonRunConfiguration;
class PythonRunConfiguration : public ProjectExplorer::RunConfiguration
class PythonInterpreterAspect final : public ProjectExplorer::InterpreterAspect
{
Q_OBJECT
public:
PythonRunConfiguration(ProjectExplorer::Target *target, Utils::Id id);
~PythonRunConfiguration() override;
explicit PythonInterpreterAspect(PythonRunConfiguration *rc);
~PythonInterpreterAspect() final;
QList<PySideUicExtraCompiler *> extraCompilers() const;
private:
friend class PythonRunConfiguration;
class PythonInterpreterAspectPrivate *d = nullptr;
};
class PythonRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory