forked from qt-creator/qt-creator
ClangCodeModel: remove duplicates from clangd quickfix assist
Do not report quickfixes with a diagnostic since those are already collected by the ClangdQuickFixFactory as builtin quickfixes. Change-Id: I8d29a08b823291f8beaa762c09b7d29a4b9d0384 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -1429,12 +1429,31 @@ private:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleProposalReady(const QuickFixOperations &ops) override
|
TextEditor::GenericProposal *handleCodeActionResult(const CodeActionResult &result) override
|
||||||
{
|
{
|
||||||
// Step 3: Merge the results upon callback from clangd.
|
auto toOperation =
|
||||||
for (const auto &op : ops)
|
[=](const Utils::variant<Command, CodeAction> &item) -> QuickFixOperation * {
|
||||||
|
if (auto action = Utils::get_if<CodeAction>(&item)) {
|
||||||
|
const Utils::optional<QList<Diagnostic>> diagnostics = action->diagnostics();
|
||||||
|
if (!diagnostics.has_value() || diagnostics->isEmpty())
|
||||||
|
return new CodeActionQuickFixOperation(*action, client());
|
||||||
|
}
|
||||||
|
if (auto command = Utils::get_if<Command>(&item))
|
||||||
|
return new CommandQuickFixOperation(*command, client());
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto list = Utils::get_if<QList<Utils::variant<Command, CodeAction>>>(&result)) {
|
||||||
|
QuickFixOperations ops;
|
||||||
|
for (const Utils::variant<Command, CodeAction> &item : *list) {
|
||||||
|
if (QuickFixOperation *op = toOperation(item)) {
|
||||||
op->setDescription("clangd: " + op->description());
|
op->setDescription("clangd: " + op->description());
|
||||||
setAsyncProposalAvailable(GenericProposal::createProposal(m_interface, ops + m_builtinOps));
|
ops << op;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GenericProposal::createProposal(m_interface, ops + m_builtinOps);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QuickFixOperations m_builtinOps;
|
QuickFixOperations m_builtinOps;
|
||||||
|
|||||||
@@ -55,23 +55,17 @@ void CodeActionQuickFixOperation::perform()
|
|||||||
m_client->executeCommand(*command);
|
m_client->executeCommand(*command);
|
||||||
}
|
}
|
||||||
|
|
||||||
class CommandQuickFixOperation : public QuickFixOperation
|
CommandQuickFixOperation::CommandQuickFixOperation(const Command &command, Client *client)
|
||||||
{
|
|
||||||
public:
|
|
||||||
CommandQuickFixOperation(const Command &command, Client *client)
|
|
||||||
: m_command(command)
|
: m_command(command)
|
||||||
, m_client(client)
|
, m_client(client)
|
||||||
{ setDescription(command.title()); }
|
{ setDescription(command.title()); }
|
||||||
void perform() override
|
|
||||||
{
|
|
||||||
|
void CommandQuickFixOperation::perform()
|
||||||
|
{
|
||||||
if (m_client)
|
if (m_client)
|
||||||
m_client->executeCommand(m_command);
|
m_client->executeCommand(m_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
Command m_command;
|
|
||||||
QPointer<Client> m_client;
|
|
||||||
};
|
|
||||||
|
|
||||||
IAssistProposal *LanguageClientQuickFixAssistProcessor::perform(const AssistInterface *interface)
|
IAssistProposal *LanguageClientQuickFixAssistProcessor::perform(const AssistInterface *interface)
|
||||||
{
|
{
|
||||||
@@ -119,24 +113,26 @@ void LanguageClientQuickFixAssistProcessor::handleCodeActionResponse(const CodeA
|
|||||||
m_currentRequest.reset();
|
m_currentRequest.reset();
|
||||||
if (const Utils::optional<CodeActionRequest::Response::Error> &error = response.error())
|
if (const Utils::optional<CodeActionRequest::Response::Error> &error = response.error())
|
||||||
m_client->log(*error);
|
m_client->log(*error);
|
||||||
|
m_client->removeAssistProcessor(this);
|
||||||
|
GenericProposal *proposal = nullptr;
|
||||||
|
if (const Utils::optional<CodeActionResult> &result = response.result())
|
||||||
|
proposal = handleCodeActionResult(*result);
|
||||||
|
setAsyncProposalAvailable(proposal);
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericProposal *LanguageClientQuickFixAssistProcessor::handleCodeActionResult(const CodeActionResult &result)
|
||||||
|
{
|
||||||
|
if (auto list = Utils::get_if<QList<Utils::variant<Command, CodeAction>>>(&result)) {
|
||||||
QuickFixOperations ops;
|
QuickFixOperations ops;
|
||||||
if (const Utils::optional<CodeActionResult> &result = response.result()) {
|
|
||||||
if (auto list = Utils::get_if<QList<Utils::variant<Command, CodeAction>>>(&*result)) {
|
|
||||||
for (const Utils::variant<Command, CodeAction> &item : *list) {
|
for (const Utils::variant<Command, CodeAction> &item : *list) {
|
||||||
if (auto action = Utils::get_if<CodeAction>(&item))
|
if (auto action = Utils::get_if<CodeAction>(&item))
|
||||||
ops << new CodeActionQuickFixOperation(*action, m_client);
|
ops << new CodeActionQuickFixOperation(*action, m_client);
|
||||||
else if (auto command = Utils::get_if<Command>(&item))
|
else if (auto command = Utils::get_if<Command>(&item))
|
||||||
ops << new CommandQuickFixOperation(*command, m_client);
|
ops << new CommandQuickFixOperation(*command, m_client);
|
||||||
}
|
}
|
||||||
|
return GenericProposal::createProposal(m_assistInterface.data(), ops);
|
||||||
}
|
}
|
||||||
}
|
return nullptr;
|
||||||
m_client->removeAssistProcessor(this);
|
|
||||||
handleProposalReady(ops);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LanguageClientQuickFixAssistProcessor::handleProposalReady(const QuickFixOperations &ops)
|
|
||||||
{
|
|
||||||
setAsyncProposalAvailable(GenericProposal::createProposal(m_assistInterface.data(), ops));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client)
|
LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client)
|
||||||
|
|||||||
@@ -35,7 +35,10 @@
|
|||||||
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
namespace TextEditor { class IAssistProposal; }
|
namespace TextEditor {
|
||||||
|
class IAssistProposal;
|
||||||
|
class GenericProposal;
|
||||||
|
} // namespace TextEditor
|
||||||
|
|
||||||
namespace LanguageClient {
|
namespace LanguageClient {
|
||||||
|
|
||||||
@@ -52,6 +55,17 @@ private:
|
|||||||
QPointer<Client> m_client;
|
QPointer<Client> m_client;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LANGUAGECLIENT_EXPORT CommandQuickFixOperation : public TextEditor::QuickFixOperation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommandQuickFixOperation(const LanguageServerProtocol::Command &command, Client *client);
|
||||||
|
void perform() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
LanguageServerProtocol::Command m_command;
|
||||||
|
QPointer<Client> m_client;
|
||||||
|
};
|
||||||
|
|
||||||
class LANGUAGECLIENT_EXPORT LanguageClientQuickFixProvider : public TextEditor::IAssistProvider
|
class LANGUAGECLIENT_EXPORT LanguageClientQuickFixProvider : public TextEditor::IAssistProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -77,10 +91,13 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setOnlyKinds(const QList<LanguageServerProtocol::CodeActionKind> &only);
|
void setOnlyKinds(const QList<LanguageServerProtocol::CodeActionKind> &only);
|
||||||
|
Client *client() { return m_client; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleCodeActionResponse(const LanguageServerProtocol::CodeActionRequest::Response &response);
|
void handleCodeActionResponse(
|
||||||
virtual void handleProposalReady(const TextEditor::QuickFixOperations &ops);
|
const LanguageServerProtocol::CodeActionRequest::Response &response);
|
||||||
|
virtual TextEditor::GenericProposal *handleCodeActionResult(
|
||||||
|
const LanguageServerProtocol::CodeActionResult &result);
|
||||||
|
|
||||||
QSharedPointer<const TextEditor::AssistInterface> m_assistInterface;
|
QSharedPointer<const TextEditor::AssistInterface> m_assistInterface;
|
||||||
Client *m_client = nullptr; // not owned
|
Client *m_client = nullptr; // not owned
|
||||||
|
|||||||
Reference in New Issue
Block a user