Clang: Don't send multiple completions for the same position

If we send already a completion we should test if there is already one
sent for the same position.

Change-Id: Ie88f89bff0e1da1c5e747827a45154c7ccaecabc
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com>
This commit is contained in:
Marco Bubke
2015-12-01 13:21:02 +01:00
parent 03056a6d64
commit a08336fcc2
5 changed files with 61 additions and 26 deletions

View File

@@ -137,6 +137,11 @@ void IpcReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *t
}
}
bool IpcReceiver::isExpectingCodeCompletedMessage() const
{
return !m_assistProcessorsTable.isEmpty();
}
void IpcReceiver::alive()
{
qCDebug(log) << "<<< AliveMessage";
@@ -446,6 +451,11 @@ void IpcCommunicator::updateTranslationUnitVisiblity()
updateTranslationUnitVisiblity(currentCppEditorDocumentFilePath(), visibleCppEditorDocumentsFilePaths());
}
bool IpcCommunicator::isNotWaitingForCompletion() const
{
return !m_ipcReceiver.isExpectingCodeCompletedMessage();
}
void IpcCommunicator::updateTranslationUnitVisiblity(const Utf8String &currentEditorFilePath,
const Utf8StringVector &visibleEditorsFilePaths)
{

View File

@@ -76,6 +76,8 @@ public:
void deleteAndClearWaitingAssistProcessors();
void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget);
bool isExpectingCodeCompletedMessage() const;
private:
void alive() override;
void echo(const ClangBackEnd::EchoMessage &message) override;
@@ -152,6 +154,8 @@ public:
void registerFallbackProjectPart();
void updateTranslationUnitVisiblity();
bool isNotWaitingForCompletion() const;
public: // for tests
IpcSenderInterface *setIpcSender(IpcSenderInterface *ipcSender);
void killBackendProcess();

View File

@@ -342,13 +342,16 @@ IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper()
case ClangCompletionContextAnalyzer::PassThroughToLibClang: {
m_addSnippets = m_completionOperator == T_EOF_SYMBOL;
m_sentRequestType = NormalCompletion;
sendCompletionRequest(analyzer.positionForClang(), modifiedFileContent);
const bool requestSent = sendCompletionRequest(analyzer.positionForClang(),
modifiedFileContent);
setPerformWasApplicable(requestSent);
break;
}
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: {
m_sentRequestType = FunctionHintCompletion;
m_functionName = analyzer.functionName();
sendCompletionRequest(analyzer.positionForClang(), QByteArray());
const bool requestSent = sendCompletionRequest(analyzer.positionForClang(), QByteArray());
setPerformWasApplicable(requestSent);
break;
}
default:
@@ -702,15 +705,34 @@ bool shouldSendDocumentForCompletion(const QString &filePath,
return true;
}
void setLastCompletionPositionAndDocumentRevision(const QString &filePath,
int completionPosition)
bool shouldSendCodeCompletion(const QString &filePath,
int completionPosition)
{
auto *document = cppDocument(filePath);
if (document) {
document->sendTracker().setLastCompletionPosition(completionPosition);
document->sendTracker().setLastSentRevision(document->revision());
auto &sendTracker = document->sendTracker();
return sendTracker.shouldSendCompletion(completionPosition);
}
return true;
}
void setLastDocumentRevision(const QString &filePath)
{
auto *document = cppDocument(filePath);
if (document)
document->sendTracker().setLastSentRevision(int(document->revision()));
}
void setLastCompletionPosition(const QString &filePath,
int completionPosition)
{
auto *document = cppDocument(filePath);
if (document)
document->sendTracker().setLastCompletionPosition(completionPosition);
}
QString projectPartIdForEditorDocument(const QString &filePath)
@@ -726,7 +748,7 @@ QString projectPartIdForEditorDocument(const QString &filePath)
}
}
void ClangCompletionAssistProcessor::sendCompletionRequest(int position,
bool ClangCompletionAssistProcessor::sendCompletionRequest(int position,
const QByteArray &customFileContent)
{
int line, column;
@@ -735,17 +757,22 @@ void ClangCompletionAssistProcessor::sendCompletionRequest(int position,
const QString filePath = m_interface->fileName();
if (shouldSendDocumentForCompletion(filePath, position)) {
sendFileContent(customFileContent);
setLastCompletionPositionAndDocumentRevision(filePath, position);
auto &ipcCommunicator = m_interface->ipcCommunicator();
if (shouldSendCodeCompletion(filePath, position)
|| ipcCommunicator.isNotWaitingForCompletion()) {
if (shouldSendDocumentForCompletion(filePath, position)) {
sendFileContent(customFileContent);
setLastDocumentRevision(filePath);
}
const QString projectPartId = projectPartIdForEditorDocument(filePath);
ipcCommunicator.completeCode(this, filePath, uint(line), uint(column), projectPartId);
setLastCompletionPosition(filePath, position);
return true;
}
const QString projectPartId = projectPartIdForEditorDocument(filePath);
m_interface->ipcCommunicator().completeCode(this,
filePath,
uint(line),
uint(column),
projectPartId);
return false;
}
TextEditor::IAssistProposal *ClangCompletionAssistProcessor::createProposal() const

View File

@@ -84,7 +84,7 @@ private:
UnsavedFileContentInfo unsavedFileContent(const QByteArray &customFileContent) const;
void sendFileContent(const QByteArray &customFileContent);
void sendCompletionRequest(int position, const QByteArray &customFileContent);
bool sendCompletionRequest(int position, const QByteArray &customFileContent);
void handleAvailableCompletions(const CodeCompletions &completions);
bool handleAvailableFunctionHintCompletions(const CodeCompletions &completions);

View File

@@ -263,14 +263,8 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason,
case IAssistProvider::Asynchronous: {
processor->setAsyncCompletionAvailableHandler(
[this, processor, reason](IAssistProposal *newProposal){
if (m_asyncProcessor != processor) {
delete newProposal->model();
delete newProposal;
return;
}
invalidateCurrentRequestData();
QTC_CHECK(newProposal);
invalidateCurrentRequestData();
displayProposal(newProposal, reason);
emit q->finished();
@@ -282,10 +276,10 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason,
delete processor;
} else if (!processor->performWasApplicable()) {
delete processor;
} else { // ...async request was triggered
m_asyncProcessor = processor;
}
// ...otherwise the async request was triggered
m_asyncProcessor = processor;
break;
}
} // switch