Python: ensure opened file is inside a workspace

The Python language server seems to dislike files that are not part of a
workspace resulting in very long lookup times for specific symbols.

Fixes: QTCREATORBUG-26230
Fixes: QTCREATORBUG-24704
Fixes: QTCREATORBUG-24140
Change-Id: Iceb7a2b3d57aea6554225a74587f619e530e10c9
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2022-03-14 10:09:55 +01:00
parent d824c276df
commit 9d1fe1df14
2 changed files with 46 additions and 5 deletions

View File

@@ -143,7 +143,7 @@ public:
bool isSupportedDocument(const TextEditor::TextDocument *document) const; bool isSupportedDocument(const TextEditor::TextDocument *document) const;
bool isSupportedFile(const Utils::FilePath &filePath, const QString &mimeType) const; bool isSupportedFile(const Utils::FilePath &filePath, const QString &mimeType) const;
bool isSupportedUri(const LanguageServerProtocol::DocumentUri &uri) const; bool isSupportedUri(const LanguageServerProtocol::DocumentUri &uri) const;
void openDocument(TextEditor::TextDocument *document); virtual void openDocument(TextEditor::TextDocument *document);
void closeDocument(TextEditor::TextDocument *document); void closeDocument(TextEditor::TextDocument *document);
void activateDocument(TextEditor::TextDocument *document); void activateDocument(TextEditor::TextDocument *document);
void deactivateDocument(TextEditor::TextDocument *document); void deactivateDocument(TextEditor::TextDocument *document);

View File

@@ -27,18 +27,18 @@
#include "pythonconstants.h" #include "pythonconstants.h"
#include "pythonplugin.h" #include "pythonplugin.h"
#include "pythonproject.h"
#include "pythonsettings.h" #include "pythonsettings.h"
#include "pythonutils.h" #include "pythonutils.h"
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <languageclient/languageclientmanager.h> #include <languageclient/languageclientmanager.h>
#include <languageserverprotocol/workspace.h>
#include <projectexplorer/session.h>
#include <texteditor/textdocument.h> #include <texteditor/textdocument.h>
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>
#include <utils/infobar.h> #include <utils/infobar.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/runextensions.h> #include <utils/runextensions.h>
@@ -471,9 +471,50 @@ void PyLSSettings::setInterpreter(const QString &interpreterId)
m_executable = interpreter.command; m_executable = interpreter.command;
} }
static PythonProject *projectForFile(const FilePath &pythonFile)
{
for (ProjectExplorer::Project *project : ProjectExplorer::SessionManager::projects()) {
if (auto pythonProject = qobject_cast<PythonProject *>(project)) {
if (pythonProject->isKnownFile(pythonFile))
return pythonProject;
}
}
return nullptr;
}
class PyLSClient : public Client
{
public:
using Client::Client;
void openDocument(TextEditor::TextDocument *document) override
{
using namespace LanguageServerProtocol;
if (reachable()) {
const FilePath documentPath = document->filePath();
if (isSupportedDocument(document) && !projectForFile(documentPath)) {
const FilePath workspacePath = documentPath.parentDir();
if (!extraWorkspaceDirs.contains(workspacePath)) {
WorkspaceFoldersChangeEvent event;
event.setAdded({WorkSpaceFolder(DocumentUri::fromFilePath(workspacePath),
workspacePath.fileName())});
DidChangeWorkspaceFoldersParams params;
params.setEvent(event);
DidChangeWorkspaceFoldersNotification change(params);
sendContent(change);
extraWorkspaceDirs.append(workspacePath);
}
}
}
Client::openDocument(document);
}
private:
FilePaths extraWorkspaceDirs;
};
Client *PyLSSettings::createClient(BaseClientInterface *interface) const Client *PyLSSettings::createClient(BaseClientInterface *interface) const
{ {
return new Client(interface); return new PyLSClient(interface);
} }
QJsonObject PyLSSettings::defaultConfiguration() QJsonObject PyLSSettings::defaultConfiguration()