LanguageClient: reset all assist providers

Instead of just unsetting the function assist provider and quick fix
assist provider reset it to the previous provider.

Change-Id: I46c5c2f14234e3da08480dd103e4634859447d57
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2019-09-10 08:03:36 +02:00
parent cd6b37d905
commit f0a3779513
7 changed files with 70 additions and 36 deletions

View File

@@ -95,13 +95,14 @@ private:
Client::Client(BaseClientInterface *clientInterface) Client::Client(BaseClientInterface *clientInterface)
: m_id(Core::Id::fromString(QUuid::createUuid().toString())) : m_id(Core::Id::fromString(QUuid::createUuid().toString()))
, m_completionProvider(this)
, m_functionHintProvider(this)
, m_quickFixProvider(this)
, m_clientInterface(clientInterface) , m_clientInterface(clientInterface)
, m_documentSymbolCache(this) , m_documentSymbolCache(this)
, m_hoverHandler(this) , m_hoverHandler(this)
{ {
m_clientProviders.completionAssistProvider = new LanguageClientCompletionAssistProvider(this);
m_clientProviders.functionHintProvider = new FunctionHintAssistProvider(this);
m_clientProviders.quickFixAssistProvider = new LanguageClientQuickFixProvider(this);
m_contentHandler.insert(JsonRpcMessageHandler::jsonRpcMimeType(), m_contentHandler.insert(JsonRpcMessageHandler::jsonRpcMimeType(),
&JsonRpcMessageHandler::parseContent); &JsonRpcMessageHandler::parseContent);
QTC_ASSERT(clientInterface, return); QTC_ASSERT(clientInterface, return);
@@ -129,12 +130,8 @@ Client::~Client()
using namespace TextEditor; using namespace TextEditor;
// FIXME: instead of replacing the completion provider in the text document store the // FIXME: instead of replacing the completion provider in the text document store the
// completion provider as a prioritised list in the text document // completion provider as a prioritised list in the text document
for (TextDocument *document : m_resetAssistProvider.keys()) { for (TextDocument *document : m_resetAssistProvider.keys())
if (document->completionAssistProvider() == &m_completionProvider) resetAssistProviders(document);
document->setCompletionAssistProvider(m_resetAssistProvider[document]);
document->setFunctionHintAssistProvider(nullptr);
document->setQuickFixAssistProvider(nullptr);
}
for (Core::IEditor * editor : Core::DocumentModel::editorsForOpenedDocuments()) { for (Core::IEditor * editor : Core::DocumentModel::editorsForOpenedDocuments()) {
if (auto textEditor = qobject_cast<BaseTextEditor *>(editor)) { if (auto textEditor = qobject_cast<BaseTextEditor *>(editor)) {
TextEditorWidget *widget = textEditor->editorWidget(); TextEditorWidget *widget = textEditor->editorWidget();
@@ -317,31 +314,39 @@ bool Client::openDocument(Core::IDocument *document)
if (textDocument) { if (textDocument) {
connect(textDocument, connect(textDocument,
&TextEditor::TextDocument::contentsChangedWithPosition, &TextDocument::contentsChangedWithPosition,
this, this,
[this, textDocument](int position, int charsRemoved, int charsAdded) { [this, textDocument](int position, int charsRemoved, int charsAdded) {
documentContentsChanged(textDocument, position, charsRemoved, charsAdded); documentContentsChanged(textDocument, position, charsRemoved, charsAdded);
}); });
auto *oldCompletionProvider = qobject_cast<TextEditor::DocumentContentCompletionProvider *>(
textDocument->completionAssistProvider()); if (auto completionProvider = qobject_cast<LanguageClientCompletionAssistProvider *>(
if (oldCompletionProvider || !textDocument->completionAssistProvider()) { m_clientProviders.completionAssistProvider)) {
// only replace the completion assist provider if it is the default one or null completionProvider->setTriggerCharacters(
m_completionProvider.setTriggerCharacters(
m_serverCapabilities.completionProvider() m_serverCapabilities.completionProvider()
.value_or(ServerCapabilities::CompletionOptions()) .value_or(ServerCapabilities::CompletionOptions())
.triggerCharacters() .triggerCharacters()
.value_or(QList<QString>())); .value_or(QList<QString>()));
textDocument->setCompletionAssistProvider(&m_completionProvider);
} }
m_resetAssistProvider[textDocument] = oldCompletionProvider; if (auto functionHintAssistProvider = qobject_cast<FunctionHintAssistProvider *>(
m_functionHintProvider.setTriggerCharacters( m_clientProviders.completionAssistProvider)) {
functionHintAssistProvider->setTriggerCharacters(
m_serverCapabilities.signatureHelpProvider() m_serverCapabilities.signatureHelpProvider()
.value_or(ServerCapabilities::SignatureHelpOptions()) .value_or(ServerCapabilities::SignatureHelpOptions())
.triggerCharacters() .triggerCharacters()
.value_or(QList<QString>())); .value_or(QList<QString>()));
textDocument->setCompletionAssistProvider(&m_completionProvider); }
textDocument->setFunctionHintAssistProvider(&m_functionHintProvider);
textDocument->setQuickFixAssistProvider(&m_quickFixProvider); auto *oldCompletionProvider = qobject_cast<DocumentContentCompletionProvider *>(
textDocument->completionAssistProvider());
// only replace the completion assist provider if it is the default one or null
if (oldCompletionProvider || !textDocument->completionAssistProvider())
textDocument->setCompletionAssistProvider(m_clientProviders.completionAssistProvider);
m_resetAssistProvider[textDocument] = {oldCompletionProvider,
textDocument->functionHintAssistProvider(),
textDocument->quickFixAssistProvider()};
textDocument->setFunctionHintAssistProvider(m_clientProviders.functionHintProvider);
textDocument->setQuickFixAssistProvider(m_clientProviders.quickFixAssistProvider);
connect(textDocument, &QObject::destroyed, this, [this, textDocument]{ connect(textDocument, &QObject::destroyed, this, [this, textDocument]{
m_resetAssistProvider.remove(textDocument); m_resetAssistProvider.remove(textDocument);
}); });
@@ -388,10 +393,8 @@ void Client::closeDocument(Core::IDocument *document)
const DidCloseTextDocumentParams params(TextDocumentIdentifier{uri}); const DidCloseTextDocumentParams params(TextDocumentIdentifier{uri});
m_highlights[uri].clear(); m_highlights[uri].clear();
sendContent(uri, DidCloseTextDocumentNotification(params)); sendContent(uri, DidCloseTextDocumentNotification(params));
auto textDocument = qobject_cast<TextEditor::TextDocument *>(document); if (auto textDocument = qobject_cast<TextEditor::TextDocument *>(document))
if (!textDocument) resetAssistProviders(textDocument);
return;
textDocument->setCompletionAssistProvider(m_resetAssistProvider.take(textDocument));
} }
bool Client::documentOpen(const Core::IDocument *document) const bool Client::documentOpen(const Core::IDocument *document) const
@@ -1034,6 +1037,23 @@ void Client::removeDiagnostics(const DocumentUri &uri)
} }
} }
void Client::resetAssistProviders(TextEditor::TextDocument *document)
{
const AssistProviders providers = m_resetAssistProvider.take(document);
if (providers.completionAssistProvider
&& document->completionAssistProvider() == m_clientProviders.completionAssistProvider) {
document->setCompletionAssistProvider(providers.completionAssistProvider);
}
if (providers.functionHintProvider
&& document->functionHintAssistProvider() == m_clientProviders.functionHintProvider) {
document->setFunctionHintAssistProvider(providers.functionHintProvider);
}
if (providers.quickFixAssistProvider
&& document->quickFixAssistProvider() == m_clientProviders.quickFixAssistProvider) {
document->setQuickFixAssistProvider(providers.quickFixAssistProvider);
}
}
void Client::handleResponse(const MessageId &id, const QByteArray &content, QTextCodec *codec) void Client::handleResponse(const MessageId &id, const QByteArray &content, QTextCodec *codec)
{ {
if (auto handler = m_responseHandlers[id]) if (auto handler = m_responseHandlers[id])

View File

@@ -193,6 +193,7 @@ private:
void showDiagnostics(const LanguageServerProtocol::DocumentUri &uri); void showDiagnostics(const LanguageServerProtocol::DocumentUri &uri);
void removeDiagnostics(const LanguageServerProtocol::DocumentUri &uri); void removeDiagnostics(const LanguageServerProtocol::DocumentUri &uri);
void resetAssistProviders(TextEditor::TextDocument *document);
using ContentHandler = std::function<void(const QByteArray &, QTextCodec *, QString &, using ContentHandler = std::function<void(const QByteArray &, QTextCodec *, QString &,
LanguageServerProtocol::ResponseHandlers, LanguageServerProtocol::ResponseHandlers,
@@ -207,10 +208,15 @@ private:
Core::Id m_id; Core::Id m_id;
LanguageServerProtocol::ServerCapabilities m_serverCapabilities; LanguageServerProtocol::ServerCapabilities m_serverCapabilities;
DynamicCapabilities m_dynamicCapabilities; DynamicCapabilities m_dynamicCapabilities;
LanguageClientCompletionAssistProvider m_completionProvider; struct AssistProviders
FunctionHintAssistProvider m_functionHintProvider; {
LanguageClientQuickFixProvider m_quickFixProvider; QPointer<TextEditor::CompletionAssistProvider> completionAssistProvider;
QMap<TextEditor::TextDocument *, QPointer<TextEditor::CompletionAssistProvider>> m_resetAssistProvider; QPointer<TextEditor::CompletionAssistProvider> functionHintProvider;
QPointer<TextEditor::IAssistProvider> quickFixAssistProvider;
};
AssistProviders m_clientProviders;
QMap<TextEditor::TextDocument *, AssistProviders> m_resetAssistProvider;
QHash<LanguageServerProtocol::DocumentUri, LanguageServerProtocol::MessageId> m_highlightRequests; QHash<LanguageServerProtocol::DocumentUri, LanguageServerProtocol::MessageId> m_highlightRequests;
int m_restartsLeft = 5; int m_restartsLeft = 5;
QScopedPointer<BaseClientInterface> m_clientInterface; QScopedPointer<BaseClientInterface> m_clientInterface;

View File

@@ -385,7 +385,8 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse(
} }
LanguageClientCompletionAssistProvider::LanguageClientCompletionAssistProvider(Client *client) LanguageClientCompletionAssistProvider::LanguageClientCompletionAssistProvider(Client *client)
: m_client(client) : CompletionAssistProvider(client)
, m_client(client)
{ } { }
IAssistProcessor *LanguageClientCompletionAssistProvider::createProcessor() const IAssistProcessor *LanguageClientCompletionAssistProvider::createProcessor() const

View File

@@ -33,6 +33,8 @@ class Client;
class LanguageClientCompletionAssistProvider : public TextEditor::CompletionAssistProvider class LanguageClientCompletionAssistProvider : public TextEditor::CompletionAssistProvider
{ {
Q_OBJECT
public: public:
LanguageClientCompletionAssistProvider(Client *client); LanguageClientCompletionAssistProvider(Client *client);

View File

@@ -102,7 +102,8 @@ void FunctionHintProcessor::handleSignatureResponse(const SignatureHelpRequest::
} }
FunctionHintAssistProvider::FunctionHintAssistProvider(Client *client) FunctionHintAssistProvider::FunctionHintAssistProvider(Client *client)
: m_client(client) : CompletionAssistProvider(client)
, m_client(client)
{} {}
TextEditor::IAssistProcessor *FunctionHintAssistProvider::createProcessor() const TextEditor::IAssistProcessor *FunctionHintAssistProvider::createProcessor() const

View File

@@ -33,6 +33,8 @@ class Client;
class FunctionHintAssistProvider : public TextEditor::CompletionAssistProvider class FunctionHintAssistProvider : public TextEditor::CompletionAssistProvider
{ {
Q_OBJECT
public: public:
explicit FunctionHintAssistProvider(Client *client); explicit FunctionHintAssistProvider(Client *client);

View File

@@ -148,7 +148,9 @@ void LanguageClientQuickFixAssistProcessor::handleCodeActionResponse(
setAsyncProposalAvailable(GenericProposal::createProposal(m_assistInterface.data(), ops)); setAsyncProposalAvailable(GenericProposal::createProposal(m_assistInterface.data(), ops));
} }
LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client) : m_client(client) LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client)
: IAssistProvider(client)
, m_client(client)
{ {
QTC_CHECK(client); QTC_CHECK(client);
} }