LanguageClient: remove codeassist proposal handler

Removes noise from the interface. Using specialized clangd processors
that redirect the proposals for testing purposes is an overall cleaner
solution.

Change-Id: Ia4f3d4720765f0533c5530a2a5c7db3cc971e0be
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2021-09-15 11:35:19 +02:00
parent bd39697ca4
commit e7f6abc084
9 changed files with 134 additions and 115 deletions

View File

@@ -681,9 +681,11 @@ public:
class DoxygenAssistProcessor : public TextEditor::IAssistProcessor class DoxygenAssistProcessor : public TextEditor::IAssistProcessor
{ {
public: public:
DoxygenAssistProcessor(int position, unsigned completionOperator, DoxygenAssistProcessor(ClangdClient *client, int position, unsigned completionOperator)
const ProposalHandler &handler) : m_client(client)
: m_position(position), m_completionOperator(completionOperator), m_handler(handler) {} , m_position(position)
, m_completionOperator(completionOperator)
{}
private: private:
TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *) override TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *) override
@@ -699,16 +701,16 @@ private:
TextEditor::GenericProposalModelPtr model(new TextEditor::GenericProposalModel); TextEditor::GenericProposalModelPtr model(new TextEditor::GenericProposalModel);
model->loadContent(completions); model->loadContent(completions);
const auto proposal = new TextEditor::GenericProposal(m_position, model); const auto proposal = new TextEditor::GenericProposal(m_position, model);
if (m_handler) { if (m_client->testingEnabled()) {
m_handler(proposal); emit m_client->proposalReady(proposal);
return nullptr; return nullptr;
} }
return proposal; return proposal;
} }
ClangdClient * const m_client;
const int m_position; const int m_position;
const unsigned m_completionOperator; const unsigned m_completionOperator;
const ProposalHandler m_handler;
}; };
class ClangdClient::Private class ClangdClient::Private
@@ -770,6 +772,67 @@ public:
} }
}; };
QList<LanguageServerProtocol::CompletionItem> completionItemsTransformer(
const Utils::FilePath &filePath,
const QString &content,
int pos,
const QList<CompletionItem> &items)
{
qCDebug(clangdLog) << "received" << items.count() << "completions";
// If there are signals among the candidates, we employ the built-in code model to find out
// whether the cursor was on the second argument of a (dis)connect() call.
// If so, we offer only signals, as nothing else makes sense in that context.
static const auto criterion = [](const CompletionItem &ci) {
const Utils::optional<MarkupOrString> doc = ci.documentation();
if (!doc)
return false;
QString docText;
if (Utils::holds_alternative<QString>(*doc))
docText = Utils::get<QString>(*doc);
else if (Utils::holds_alternative<MarkupContent>(*doc))
docText = Utils::get<MarkupContent>(*doc).content();
return docText.contains("Annotation: qt_signal");
};
if (pos != -1 && Utils::anyOf(items, criterion)
&& CppEditor::CppModelManager::instance()->positionRequiresSignal(filePath.toString(),
content.toUtf8(),
pos)) {
return Utils::filtered(items, criterion);
}
return items;
};
class ClangdClient::ClangdCompletionAssistProcessor : public LanguageClientCompletionAssistProcessor
{
public:
ClangdCompletionAssistProcessor(ClangdClient *client, const QString &snippetsGroup)
: LanguageClientCompletionAssistProcessor(client,
&completionItemsTransformer,
&applyCompletionItem,
snippetsGroup)
, m_client(client)
{
}
private:
TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *interface) override
{
if (m_client->d->isTesting) {
setAsyncCompletionAvailableHandler([this](TextEditor::IAssistProposal *proposal) {
emit m_client->proposalReady(proposal);
});
}
return LanguageClientCompletionAssistProcessor::perform(interface);
}
static void applyCompletionItem(const CompletionItem &item,
TextEditor::TextDocumentManipulatorInterface &manipulator,
QChar typedChar);
ClangdClient * const m_client;
};
class ClangdClient::ClangdCompletionAssistProvider : public LanguageClientCompletionAssistProvider class ClangdClient::ClangdCompletionAssistProvider : public LanguageClientCompletionAssistProvider
{ {
public: public:
@@ -783,9 +846,7 @@ private:
bool isActivationCharSequence(const QString &sequence) const override; bool isActivationCharSequence(const QString &sequence) const override;
bool isContinuationChar(const QChar &c) const override; bool isContinuationChar(const QChar &c) const override;
void applyCompletionItem(const CompletionItem &item, ClangdClient * const m_client;
TextEditor::TextDocumentManipulatorInterface &manipulator,
QChar typedChar);
}; };
ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir) ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
@@ -1081,13 +1142,11 @@ void ClangdClient::Private::findUsages(TextEditor::TextDocument *document,
void ClangdClient::enableTesting() void ClangdClient::enableTesting()
{ {
d->isTesting = true; d->isTesting = true;
setCompletionProposalHandler([this](TextEditor::IAssistProposal *proposal) { }
QMetaObject::invokeMethod(this, [this, proposal] { emit proposalReady(proposal); },
Qt::QueuedConnection); bool ClangdClient::testingEnabled() const
}); {
setFunctionHintProposalHandler([this](TextEditor::IAssistProposal *proposal) { return d->isTesting;
emit proposalReady(proposal);
});
} }
void ClangdClient::Private::handleFindUsagesResult(quint64 key, const QList<Location> &locations) void ClangdClient::Private::handleFindUsagesResult(quint64 key, const QList<Location> &locations)
@@ -2664,39 +2723,32 @@ QString ClangdDiagnostic::category() const
return typedValue<QString>("category"); return typedValue<QString>("category");
} }
class ClangdClient::ClangdFunctionHintProcessor : public FunctionHintProcessor
{
public:
ClangdFunctionHintProcessor(ClangdClient *client)
: FunctionHintProcessor(client)
, m_client(client)
{}
private:
TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *interface) override
{
if (m_client->d->isTesting) {
setAsyncCompletionAvailableHandler([this](TextEditor::IAssistProposal *proposal) {
emit m_client->proposalReady(proposal);
});
}
return FunctionHintProcessor::perform(interface);
}
ClangdClient * const m_client;
};
ClangdClient::ClangdCompletionAssistProvider::ClangdCompletionAssistProvider(ClangdClient *client) ClangdClient::ClangdCompletionAssistProvider::ClangdCompletionAssistProvider(ClangdClient *client)
: LanguageClientCompletionAssistProvider(client) : LanguageClientCompletionAssistProvider(client)
{ , m_client(client)
setItemsTransformer([](const Utils::FilePath &filePath, const QString &content, {}
int pos, const QList<CompletionItem> &items) {
qCDebug(clangdLog) << "received" << items.count() << "completions";
// If there are signals among the candidates, we employ the built-in code model to find out
// whether the cursor was on the second argument of a (dis)connect() call.
// If so, we offer only signals, as nothing else makes sense in that context.
static const auto criterion = [](const CompletionItem &ci) {
const Utils::optional<MarkupOrString> doc = ci.documentation();
if (!doc)
return false;
QString docText;
if (Utils::holds_alternative<QString>(*doc))
docText = Utils::get<QString>(*doc);
else if (Utils::holds_alternative<MarkupContent>(*doc))
docText = Utils::get<MarkupContent>(*doc).content();
return docText.contains("Annotation: qt_signal");
};
if (pos != -1 && Utils::anyOf(items, criterion) && CppEditor::CppModelManager::instance()
->positionRequiresSignal(filePath.toString(), content.toUtf8(), pos)) {
return Utils::filtered(items, criterion);
}
return items;
});
setApplyHelper([this](const CompletionItem &item,
TextEditor::TextDocumentManipulatorInterface &manipulator, QChar typedChar) {
applyCompletionItem(item, manipulator, typedChar);
});
}
TextEditor::IAssistProcessor *ClangdClient::ClangdCompletionAssistProvider::createProcessor( TextEditor::IAssistProcessor *ClangdClient::ClangdCompletionAssistProvider::createProcessor(
const TextEditor::AssistInterface *assistInterface) const const TextEditor::AssistInterface *assistInterface) const
@@ -2704,20 +2756,21 @@ TextEditor::IAssistProcessor *ClangdClient::ClangdCompletionAssistProvider::crea
ClangCompletionContextAnalyzer contextAnalyzer(assistInterface->textDocument(), ClangCompletionContextAnalyzer contextAnalyzer(assistInterface->textDocument(),
assistInterface->position(), false, {}); assistInterface->position(), false, {});
contextAnalyzer.analyze(); contextAnalyzer.analyze();
client()->setSnippetsGroup(
contextAnalyzer.addSnippets() ? CppEditor::Constants::CPP_SNIPPETS_GROUP_ID : QString());
switch (contextAnalyzer.completionAction()) { switch (contextAnalyzer.completionAction()) {
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen:
qCDebug(clangdLog) << "completion changed to function hint"; qCDebug(clangdLog) << "completion changed to function hint";
return new FunctionHintProcessor(client(), proposalHandler()); return new ClangdFunctionHintProcessor(m_client);
case ClangCompletionContextAnalyzer::CompleteDoxygenKeyword: case ClangCompletionContextAnalyzer::CompleteDoxygenKeyword:
return new DoxygenAssistProcessor(contextAnalyzer.positionForProposal(), return new DoxygenAssistProcessor(m_client,
contextAnalyzer.completionOperator(), contextAnalyzer.positionForProposal(),
proposalHandler()); contextAnalyzer.completionOperator());
default: default:
break; break;
} }
return LanguageClientCompletionAssistProvider::createProcessor(assistInterface); const QString snippetsGroup = contextAnalyzer.addSnippets()
? CppEditor::Constants::CPP_SNIPPETS_GROUP_ID
: QString();
return new ClangdCompletionAssistProcessor(m_client, snippetsGroup);
} }
bool ClangdClient::ClangdCompletionAssistProvider::isActivationCharSequence(const QString &sequence) const bool ClangdClient::ClangdCompletionAssistProvider::isActivationCharSequence(const QString &sequence) const
@@ -2747,7 +2800,7 @@ bool ClangdClient::ClangdCompletionAssistProvider::isContinuationChar(const QCha
return CppEditor::isValidIdentifierChar(c); return CppEditor::isValidIdentifierChar(c);
} }
void ClangdClient::ClangdCompletionAssistProvider::applyCompletionItem( void ClangdClient::ClangdCompletionAssistProcessor::applyCompletionItem(
const CompletionItem &item, TextEditor::TextDocumentManipulatorInterface &manipulator, const CompletionItem &item, TextEditor::TextDocumentManipulatorInterface &manipulator,
QChar typedChar) QChar typedChar)
{ {

View File

@@ -77,6 +77,7 @@ public:
const LanguageServerProtocol::DocumentUri &uri); const LanguageServerProtocol::DocumentUri &uri);
void enableTesting(); void enableTesting();
bool testingEnabled() const;
signals: signals:
void indexingFinished(); void indexingFinished();
@@ -96,6 +97,8 @@ private:
class FollowSymbolData; class FollowSymbolData;
class VirtualFunctionAssistProcessor; class VirtualFunctionAssistProcessor;
class VirtualFunctionAssistProvider; class VirtualFunctionAssistProvider;
class ClangdFunctionHintProcessor;
class ClangdCompletionAssistProcessor;
class ClangdCompletionAssistProvider; class ClangdCompletionAssistProvider;
Private * const d; Private * const d;
}; };

View File

@@ -77,6 +77,7 @@ using Range = std::tuple<int, int, int>;
} // namespace ClangCodeModel } // namespace ClangCodeModel
Q_DECLARE_METATYPE(ClangCodeModel::Internal::Tests::Range) Q_DECLARE_METATYPE(ClangCodeModel::Internal::Tests::Range)
Q_DECLARE_METATYPE(IAssistProposal *)
namespace ClangCodeModel { namespace ClangCodeModel {
namespace Internal { namespace Internal {
@@ -1885,7 +1886,7 @@ void ClangdTestCompletion::getProposal(const QString &fileName,
connect(client(), &ClangdClient::proposalReady, &loop, [&proposal, &loop](IAssistProposal *p) { connect(client(), &ClangdClient::proposalReady, &loop, [&proposal, &loop](IAssistProposal *p) {
proposal = p; proposal = p;
loop.quit(); loop.quit();
}); }, Qt::QueuedConnection);
editor->editorWidget()->invokeAssist(Completion, nullptr); editor->editorWidget()->invokeAssist(Completion, nullptr);
timer.start(5000); timer.start(5000);
loop.exec(); loop.exec();

View File

@@ -1047,22 +1047,6 @@ SymbolStringifier Client::symbolStringifier() const
return m_symbolStringifier; return m_symbolStringifier;
} }
void Client::setCompletionProposalHandler(const ProposalHandler &handler)
{
if (const auto provider = qobject_cast<LanguageClientCompletionAssistProvider *>(
m_clientProviders.completionAssistProvider)) {
provider->setProposalHandler(handler);
}
}
void Client::setFunctionHintProposalHandler(const ProposalHandler &handler)
{
if (const auto provider = qobject_cast<FunctionHintAssistProvider *>(
m_clientProviders.functionHintProvider)) {
provider->setProposalHandler(handler);
}
}
void Client::setSnippetsGroup(const QString &group) void Client::setSnippetsGroup(const QString &group)
{ {
if (const auto provider = qobject_cast<LanguageClientCompletionAssistProvider *>( if (const auto provider = qobject_cast<LanguageClientCompletionAssistProvider *>(

View File

@@ -185,8 +185,6 @@ public:
void setSemanticTokensHandler(const SemanticTokensHandler &handler); void setSemanticTokensHandler(const SemanticTokensHandler &handler);
void setSymbolStringifier(const LanguageServerProtocol::SymbolStringifier &stringifier); void setSymbolStringifier(const LanguageServerProtocol::SymbolStringifier &stringifier);
LanguageServerProtocol::SymbolStringifier symbolStringifier() const; LanguageServerProtocol::SymbolStringifier symbolStringifier() const;
void setCompletionProposalHandler(const ProposalHandler &handler);
void setFunctionHintProposalHandler(const ProposalHandler &handler);
void setSnippetsGroup(const QString &group); void setSnippetsGroup(const QString &group);
void setCompletionAssistProvider(LanguageClientCompletionAssistProvider *provider); void setCompletionAssistProvider(LanguageClientCompletionAssistProvider *provider);

View File

@@ -287,12 +287,15 @@ public:
int m_pos = -1; int m_pos = -1;
}; };
LanguageClientCompletionAssistProcessor::LanguageClientCompletionAssistProcessor(
LanguageClientCompletionAssistProcessor::LanguageClientCompletionAssistProcessor(Client *client, Client *client,
const CompletionItemsTransformer &itemsTransformer, const CompletionApplyHelper &applyHelper, const CompletionItemsTransformer &itemsTransformer,
const ProposalHandler &proposalHandler, const QString &snippetsGroup) const CompletionApplyHelper &applyHelper,
: m_client(client), m_itemsTransformer(itemsTransformer), m_applyHelper(applyHelper), const QString &snippetsGroup)
m_proposalHandler(proposalHandler), m_snippetsGroup(snippetsGroup) : m_client(client)
, m_itemsTransformer(itemsTransformer)
, m_applyHelper(applyHelper)
, m_snippetsGroup(snippetsGroup)
{} {}
LanguageClientCompletionAssistProcessor::~LanguageClientCompletionAssistProcessor() LanguageClientCompletionAssistProcessor::~LanguageClientCompletionAssistProcessor()
@@ -427,9 +430,6 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse(
proposal->m_pos = m_pos; proposal->m_pos = m_pos;
proposal->setFragile(true); proposal->setFragile(true);
proposal->setSupportsPrefix(false); proposal->setSupportsPrefix(false);
if (m_proposalHandler)
m_proposalHandler(proposal);
else
setAsyncProposalAvailable(proposal); setAsyncProposalAvailable(proposal);
m_client->removeAssistProcessor(this); m_client->removeAssistProcessor(this);
qCDebug(LOGLSPCOMPLETION) << QTime::currentTime() << " : " qCDebug(LOGLSPCOMPLETION) << QTime::currentTime() << " : "
@@ -444,8 +444,10 @@ LanguageClientCompletionAssistProvider::LanguageClientCompletionAssistProvider(C
IAssistProcessor *LanguageClientCompletionAssistProvider::createProcessor( IAssistProcessor *LanguageClientCompletionAssistProvider::createProcessor(
const AssistInterface *) const const AssistInterface *) const
{ {
return new LanguageClientCompletionAssistProcessor(m_client, m_itemsTransformer, m_applyHelper, return new LanguageClientCompletionAssistProcessor(m_client,
m_proposalHandler, m_snippetsGroup); m_itemsTransformer,
m_applyHelper,
m_snippetsGroup);
} }
IAssistProvider::RunType LanguageClientCompletionAssistProvider::runType() const IAssistProvider::RunType LanguageClientCompletionAssistProvider::runType() const

View File

@@ -53,7 +53,6 @@ using CompletionItemsTransformer = std::function<QList<LanguageServerProtocol::C
using CompletionApplyHelper = std::function<void( using CompletionApplyHelper = std::function<void(
const LanguageServerProtocol::CompletionItem &, const LanguageServerProtocol::CompletionItem &,
TextEditor::TextDocumentManipulatorInterface &, QChar)>; TextEditor::TextDocumentManipulatorInterface &, QChar)>;
using ProposalHandler = std::function<void(TextEditor::IAssistProposal *)>;
class LANGUAGECLIENT_EXPORT LanguageClientCompletionAssistProvider class LANGUAGECLIENT_EXPORT LanguageClientCompletionAssistProvider
: public TextEditor::CompletionAssistProvider : public TextEditor::CompletionAssistProvider
@@ -72,20 +71,17 @@ public:
void setTriggerCharacters(const Utils::optional<QList<QString>> triggerChars); void setTriggerCharacters(const Utils::optional<QList<QString>> triggerChars);
void setProposalHandler(const ProposalHandler &handler) { m_proposalHandler = handler; }
void setSnippetsGroup(const QString &group) { m_snippetsGroup = group; } void setSnippetsGroup(const QString &group) { m_snippetsGroup = group; }
protected: protected:
void setItemsTransformer(const CompletionItemsTransformer &transformer); void setItemsTransformer(const CompletionItemsTransformer &transformer);
void setApplyHelper(const CompletionApplyHelper &applyHelper); void setApplyHelper(const CompletionApplyHelper &applyHelper);
Client *client() const { return m_client; } Client *client() const { return m_client; }
const ProposalHandler &proposalHandler() const { return m_proposalHandler; }
private: private:
QList<QString> m_triggerChars; QList<QString> m_triggerChars;
CompletionItemsTransformer m_itemsTransformer; CompletionItemsTransformer m_itemsTransformer;
CompletionApplyHelper m_applyHelper; CompletionApplyHelper m_applyHelper;
ProposalHandler m_proposalHandler;
QString m_snippetsGroup; QString m_snippetsGroup;
int m_activationCharSequenceLength = 0; int m_activationCharSequenceLength = 0;
Client *m_client = nullptr; // not owned Client *m_client = nullptr; // not owned
@@ -98,7 +94,6 @@ public:
LanguageClientCompletionAssistProcessor(Client *client, LanguageClientCompletionAssistProcessor(Client *client,
const CompletionItemsTransformer &itemsTransformer, const CompletionItemsTransformer &itemsTransformer,
const CompletionApplyHelper &applyHelper, const CompletionApplyHelper &applyHelper,
const ProposalHandler &proposalHandler,
const QString &snippetsGroup); const QString &snippetsGroup);
~LanguageClientCompletionAssistProcessor() override; ~LanguageClientCompletionAssistProcessor() override;
TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *interface) override; TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *interface) override;
@@ -116,7 +111,6 @@ private:
QMetaObject::Connection m_postponedUpdateConnection; QMetaObject::Connection m_postponedUpdateConnection;
const CompletionItemsTransformer m_itemsTransformer; const CompletionItemsTransformer m_itemsTransformer;
const CompletionApplyHelper m_applyHelper; const CompletionApplyHelper m_applyHelper;
const ProposalHandler m_proposalHandler;
const QString m_snippetsGroup; const QString m_snippetsGroup;
int m_pos = -1; int m_pos = -1;
int m_basePos = -1; int m_basePos = -1;

View File

@@ -81,9 +81,8 @@ QString FunctionHintProposalModel::text(int index) const
+ label.mid(end).toHtmlEscaped(); + label.mid(end).toHtmlEscaped();
} }
FunctionHintProcessor::FunctionHintProcessor(Client *client, const ProposalHandler &proposalHandler) FunctionHintProcessor::FunctionHintProcessor(Client *client)
: m_client(client) : m_client(client)
, m_proposalHandler(proposalHandler)
{} {}
IAssistProposal *FunctionHintProcessor::perform(const AssistInterface *interface) IAssistProposal *FunctionHintProcessor::perform(const AssistInterface *interface)
@@ -117,26 +116,18 @@ void FunctionHintProcessor::handleSignatureResponse(const SignatureHelpRequest::
m_client->removeAssistProcessor(this); m_client->removeAssistProcessor(this);
auto result = response.result().value_or(LanguageClientValue<SignatureHelp>()); auto result = response.result().value_or(LanguageClientValue<SignatureHelp>());
if (result.isNull()) { if (result.isNull()) {
processProposal(nullptr); setAsyncProposalAvailable(nullptr);
return; return;
} }
const SignatureHelp &signatureHelp = result.value(); const SignatureHelp &signatureHelp = result.value();
if (signatureHelp.signatures().isEmpty()) { if (signatureHelp.signatures().isEmpty()) {
processProposal(nullptr); setAsyncProposalAvailable(nullptr);
} else { } else {
FunctionHintProposalModelPtr model(new FunctionHintProposalModel(signatureHelp)); FunctionHintProposalModelPtr model(new FunctionHintProposalModel(signatureHelp));
processProposal(new FunctionHintProposal(m_pos, model)); setAsyncProposalAvailable(new FunctionHintProposal(m_pos, model));
} }
} }
void FunctionHintProcessor::processProposal(IAssistProposal *proposal)
{
if (m_proposalHandler)
m_proposalHandler(proposal);
else
setAsyncProposalAvailable(proposal);
}
FunctionHintAssistProvider::FunctionHintAssistProvider(Client *client) FunctionHintAssistProvider::FunctionHintAssistProvider(Client *client)
: CompletionAssistProvider(client) : CompletionAssistProvider(client)
, m_client(client) , m_client(client)
@@ -145,7 +136,7 @@ FunctionHintAssistProvider::FunctionHintAssistProvider(Client *client)
TextEditor::IAssistProcessor *FunctionHintAssistProvider::createProcessor( TextEditor::IAssistProcessor *FunctionHintAssistProvider::createProcessor(
const AssistInterface *) const const AssistInterface *) const
{ {
return new FunctionHintProcessor(m_client, m_proposalHandler); return new FunctionHintProcessor(m_client);
} }
IAssistProvider::RunType FunctionHintAssistProvider::runType() const IAssistProvider::RunType FunctionHintAssistProvider::runType() const

View File

@@ -40,8 +40,6 @@ namespace LanguageClient {
class Client; class Client;
using ProposalHandler = std::function<void(TextEditor::IAssistProposal *)>;
class LANGUAGECLIENT_EXPORT FunctionHintAssistProvider : public TextEditor::CompletionAssistProvider class LANGUAGECLIENT_EXPORT FunctionHintAssistProvider : public TextEditor::CompletionAssistProvider
{ {
Q_OBJECT Q_OBJECT
@@ -58,11 +56,8 @@ public:
void setTriggerCharacters(const Utils::optional<QList<QString>> &triggerChars); void setTriggerCharacters(const Utils::optional<QList<QString>> &triggerChars);
void setProposalHandler(const ProposalHandler &handler) { m_proposalHandler = handler; }
private: private:
QList<QString> m_triggerChars; QList<QString> m_triggerChars;
ProposalHandler m_proposalHandler;
int m_activationCharSequenceLength = 0; int m_activationCharSequenceLength = 0;
Client *m_client = nullptr; // not owned Client *m_client = nullptr; // not owned
}; };
@@ -70,7 +65,7 @@ private:
class LANGUAGECLIENT_EXPORT FunctionHintProcessor : public TextEditor::IAssistProcessor class LANGUAGECLIENT_EXPORT FunctionHintProcessor : public TextEditor::IAssistProcessor
{ {
public: public:
explicit FunctionHintProcessor(Client *client, const ProposalHandler &proposalHandler); explicit FunctionHintProcessor(Client *client);
TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *interface) override; TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *interface) override;
bool running() override { return m_currentRequest.has_value(); } bool running() override { return m_currentRequest.has_value(); }
bool needsRestart() const override { return true; } bool needsRestart() const override { return true; }
@@ -79,10 +74,8 @@ public:
private: private:
void handleSignatureResponse( void handleSignatureResponse(
const LanguageServerProtocol::SignatureHelpRequest::Response &response); const LanguageServerProtocol::SignatureHelpRequest::Response &response);
void processProposal(TextEditor::IAssistProposal *proposal);
QPointer<Client> m_client; QPointer<Client> m_client;
const ProposalHandler m_proposalHandler;
Utils::optional<LanguageServerProtocol::MessageId> m_currentRequest; Utils::optional<LanguageServerProtocol::MessageId> m_currentRequest;
int m_pos = -1; int m_pos = -1;
}; };