forked from qt-creator/qt-creator
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:
@@ -207,8 +207,9 @@ void PyLSClient::openDocument(TextEditor::TextDocument *document)
|
|||||||
const FilePath documentPath = document->filePath();
|
const FilePath documentPath = document->filePath();
|
||||||
if (PythonProject *project = pythonProjectForFile(documentPath)) {
|
if (PythonProject *project = pythonProjectForFile(documentPath)) {
|
||||||
if (Target *target = project->activeTarget()) {
|
if (Target *target = project->activeTarget()) {
|
||||||
if (auto rc = qobject_cast<PythonRunConfiguration *>(target->activeRunConfiguration()))
|
if (RunConfiguration *rc = target->activeRunConfiguration())
|
||||||
updateExtraCompilers(project, rc->extraCompilers());
|
if (auto aspect = rc->aspect<PythonInterpreterAspect>())
|
||||||
|
updateExtraCompilers(project, aspect->extraCompilers());
|
||||||
}
|
}
|
||||||
} else if (isSupportedDocument(document)) {
|
} else if (isSupportedDocument(document)) {
|
||||||
const FilePath workspacePath = documentPath.parentDir();
|
const FilePath workspacePath = documentPath.parentDir();
|
||||||
|
|||||||
@@ -119,28 +119,25 @@ private:
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class PythonInterpreterAspect final : public InterpreterAspect
|
class PythonInterpreterAspectPrivate : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PythonInterpreterAspect(PythonRunConfiguration *rc)
|
PythonInterpreterAspectPrivate(PythonInterpreterAspect *parent, PythonRunConfiguration *rc)
|
||||||
: q(rc)
|
: q(parent), rc(rc)
|
||||||
{
|
{
|
||||||
connect(this, &InterpreterAspect::changed,
|
connect(q, &InterpreterAspect::changed,
|
||||||
this, &PythonInterpreterAspect::currentInterpreterChanged);
|
this, &PythonInterpreterAspectPrivate::currentInterpreterChanged);
|
||||||
currentInterpreterChanged();
|
currentInterpreterChanged();
|
||||||
|
|
||||||
connect(PySideInstaller::instance(), &PySideInstaller::pySideInstalled, this,
|
connect(PySideInstaller::instance(), &PySideInstaller::pySideInstalled, this,
|
||||||
[this](const FilePath &python) {
|
[this](const FilePath &python) {
|
||||||
if (python == currentInterpreter().command)
|
if (python == q->currentInterpreter().command)
|
||||||
checkForPySide(python);
|
checkForPySide(python);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
~PythonInterpreterAspect()
|
~PythonInterpreterAspectPrivate() { qDeleteAll(m_extraCompilers); }
|
||||||
{
|
|
||||||
qDeleteAll(m_extraCompilers);
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkForPySide(const FilePath &python);
|
void checkForPySide(const FilePath &python);
|
||||||
void checkForPySide(const FilePath &python, const QString &pySidePackageName);
|
void checkForPySide(const FilePath &python, const QString &pySidePackageName);
|
||||||
@@ -152,12 +149,28 @@ public:
|
|||||||
|
|
||||||
FilePath m_pySideUicPath;
|
FilePath m_pySideUicPath;
|
||||||
|
|
||||||
PythonRunConfiguration *q;
|
PythonInterpreterAspect *q;
|
||||||
|
PythonRunConfiguration *rc;
|
||||||
QList<PySideUicExtraCompiler *> m_extraCompilers;
|
QList<PySideUicExtraCompiler *> m_extraCompilers;
|
||||||
QFutureWatcher<PipPackageInfo> m_watcher;
|
QFutureWatcher<PipPackageInfo> m_watcher;
|
||||||
QMetaObject::Connection m_watcherConnection;
|
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)
|
PythonRunConfiguration::PythonRunConfiguration(Target *target, Id id)
|
||||||
: RunConfiguration(target, 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, &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 PythonInterpreterAspectPrivate::checkForPySide(const FilePath &python)
|
||||||
|
|
||||||
void PythonInterpreterAspect::checkForPySide(const FilePath &python)
|
|
||||||
{
|
{
|
||||||
checkForPySide(python, "PySide6-Essentials");
|
checkForPySide(python, "PySide6-Essentials");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PythonInterpreterAspect::checkForPySide(const FilePath &python,
|
void PythonInterpreterAspectPrivate::checkForPySide(const FilePath &python,
|
||||||
const QString &pySidePackageName)
|
const QString &pySidePackageName)
|
||||||
{
|
{
|
||||||
const PipPackage package(pySidePackageName);
|
const PipPackage package(pySidePackageName);
|
||||||
QObject::disconnect(m_watcherConnection);
|
QObject::disconnect(m_watcherConnection);
|
||||||
@@ -255,9 +268,9 @@ void PythonInterpreterAspect::checkForPySide(const FilePath &python,
|
|||||||
ExtensionSystem::PluginManager::futureSynchronizer()->addFuture(future);
|
ExtensionSystem::PluginManager::futureSynchronizer()->addFuture(future);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PythonInterpreterAspect::handlePySidePackageInfo(const PipPackageInfo &pySideInfo,
|
void PythonInterpreterAspectPrivate::handlePySidePackageInfo(const PipPackageInfo &pySideInfo,
|
||||||
const Utils::FilePath &python,
|
const FilePath &python,
|
||||||
const QString &requestedPackageName)
|
const QString &requestedPackageName)
|
||||||
{
|
{
|
||||||
struct PythonTools
|
struct PythonTools
|
||||||
{
|
{
|
||||||
@@ -266,7 +279,7 @@ void PythonInterpreterAspect::handlePySidePackageInfo(const PipPackageInfo &pySi
|
|||||||
};
|
};
|
||||||
|
|
||||||
BuildStepList *buildSteps = nullptr;
|
BuildStepList *buildSteps = nullptr;
|
||||||
if (Target *target = q->target()) {
|
if (Target *target = rc->target()) {
|
||||||
if (auto buildConfiguration = target->activeBuildConfiguration())
|
if (auto buildConfiguration = target->activeBuildConfiguration())
|
||||||
buildSteps = buildConfiguration->buildSteps();
|
buildSteps = buildConfiguration->buildSteps();
|
||||||
}
|
}
|
||||||
@@ -311,12 +324,12 @@ void PythonInterpreterAspect::handlePySidePackageInfo(const PipPackageInfo &pySi
|
|||||||
pySideBuildStep->updatePySideProjectPath(pythonTools.pySideProjectPath);
|
pySideBuildStep->updatePySideProjectPath(pythonTools.pySideProjectPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PythonInterpreterAspect::currentInterpreterChanged()
|
void PythonInterpreterAspectPrivate::currentInterpreterChanged()
|
||||||
{
|
{
|
||||||
const FilePath python = currentInterpreter().command;
|
const FilePath python = q->currentInterpreter().command;
|
||||||
checkForPySide(python);
|
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 (auto document = TextEditor::TextDocument::textDocumentForFilePath(file)) {
|
||||||
if (document->mimeType() == Constants::C_PY_MIMETYPE
|
if (document->mimeType() == Constants::C_PY_MIMETYPE
|
||||||
|| document->mimeType() == Constants::C_PY3_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;
|
QList<PySideUicExtraCompiler *> oldCompilers = m_extraCompilers;
|
||||||
m_extraCompilers.clear();
|
m_extraCompilers.clear();
|
||||||
@@ -343,21 +356,21 @@ void PythonInterpreterAspect::updateExtraCompilers()
|
|||||||
return fileNode->fileType() == ProjectExplorer::FileType::Form;
|
return fileNode->fileType() == ProjectExplorer::FileType::Form;
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
const FilePaths uiFiles = q->project()->files(uiMatcher);
|
const FilePaths uiFiles = rc->project()->files(uiMatcher);
|
||||||
for (const FilePath &uiFile : uiFiles) {
|
for (const FilePath &uiFile : uiFiles) {
|
||||||
FilePath generated = uiFile.parentDir();
|
FilePath generated = uiFile.parentDir();
|
||||||
generated = generated.pathAppended("/ui_" + uiFile.baseName() + ".py");
|
generated = generated.pathAppended("/ui_" + uiFile.baseName() + ".py");
|
||||||
int index = Utils::indexOf(oldCompilers, [&](PySideUicExtraCompiler *oldCompiler) {
|
int index = Utils::indexOf(oldCompilers, [&](PySideUicExtraCompiler *oldCompiler) {
|
||||||
return oldCompiler->pySideUicPath() == m_pySideUicPath
|
return oldCompiler->pySideUicPath() == m_pySideUicPath
|
||||||
&& oldCompiler->project() == q->project() && oldCompiler->source() == uiFile
|
&& oldCompiler->project() == rc->project() && oldCompiler->source() == uiFile
|
||||||
&& oldCompiler->targets() == FilePaths{generated};
|
&& oldCompiler->targets() == FilePaths{generated};
|
||||||
});
|
});
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
m_extraCompilers << new PySideUicExtraCompiler(m_pySideUicPath,
|
m_extraCompilers << new PySideUicExtraCompiler(m_pySideUicPath,
|
||||||
q->project(),
|
rc->project(),
|
||||||
uiFile,
|
uiFile,
|
||||||
{generated},
|
{generated},
|
||||||
q);
|
this);
|
||||||
} else {
|
} else {
|
||||||
m_extraCompilers << oldCompilers.takeAt(index);
|
m_extraCompilers << oldCompilers.takeAt(index);
|
||||||
}
|
}
|
||||||
@@ -365,11 +378,13 @@ void PythonInterpreterAspect::updateExtraCompilers()
|
|||||||
}
|
}
|
||||||
for (LanguageClient::Client *client : LanguageClient::LanguageClientManager::clients()) {
|
for (LanguageClient::Client *client : LanguageClient::LanguageClientManager::clients()) {
|
||||||
if (auto pylsClient = qobject_cast<PyLSClient *>(client))
|
if (auto pylsClient = qobject_cast<PyLSClient *>(client))
|
||||||
pylsClient->updateExtraCompilers(q->project(), m_extraCompilers);
|
pylsClient->updateExtraCompilers(rc->project(), m_extraCompilers);
|
||||||
}
|
}
|
||||||
qDeleteAll(oldCompilers);
|
qDeleteAll(oldCompilers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Factories
|
||||||
|
|
||||||
PythonRunConfigurationFactory::PythonRunConfigurationFactory()
|
PythonRunConfigurationFactory::PythonRunConfigurationFactory()
|
||||||
{
|
{
|
||||||
registerRunConfiguration<PythonRunConfiguration>(Constants::C_PYTHONRUNCONFIGURATION_ID);
|
registerRunConfiguration<PythonRunConfiguration>(Constants::C_PYTHONRUNCONFIGURATION_ID);
|
||||||
|
|||||||
@@ -4,21 +4,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <projectexplorer/runconfiguration.h>
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
#include <projectexplorer/runconfigurationaspects.h>
|
||||||
#include <projectexplorer/runcontrol.h>
|
#include <projectexplorer/runcontrol.h>
|
||||||
|
|
||||||
namespace Python::Internal {
|
namespace Python::Internal {
|
||||||
|
|
||||||
class PySideUicExtraCompiler;
|
class PySideUicExtraCompiler;
|
||||||
|
class PythonRunConfiguration;
|
||||||
|
|
||||||
class PythonRunConfiguration : public ProjectExplorer::RunConfiguration
|
class PythonInterpreterAspect final : public ProjectExplorer::InterpreterAspect
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PythonRunConfiguration(ProjectExplorer::Target *target, Utils::Id id);
|
explicit PythonInterpreterAspect(PythonRunConfiguration *rc);
|
||||||
~PythonRunConfiguration() override;
|
~PythonInterpreterAspect() final;
|
||||||
|
|
||||||
QList<PySideUicExtraCompiler *> extraCompilers() const;
|
QList<PySideUicExtraCompiler *> extraCompilers() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class PythonRunConfiguration;
|
||||||
|
class PythonInterpreterAspectPrivate *d = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PythonRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
|
class PythonRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
|
||||||
|
|||||||
Reference in New Issue
Block a user