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() void IpcReceiver::alive()
{ {
qCDebug(log) << "<<< AliveMessage"; qCDebug(log) << "<<< AliveMessage";
@@ -446,6 +451,11 @@ void IpcCommunicator::updateTranslationUnitVisiblity()
updateTranslationUnitVisiblity(currentCppEditorDocumentFilePath(), visibleCppEditorDocumentsFilePaths()); updateTranslationUnitVisiblity(currentCppEditorDocumentFilePath(), visibleCppEditorDocumentsFilePaths());
} }
bool IpcCommunicator::isNotWaitingForCompletion() const
{
return !m_ipcReceiver.isExpectingCodeCompletedMessage();
}
void IpcCommunicator::updateTranslationUnitVisiblity(const Utf8String &currentEditorFilePath, void IpcCommunicator::updateTranslationUnitVisiblity(const Utf8String &currentEditorFilePath,
const Utf8StringVector &visibleEditorsFilePaths) const Utf8StringVector &visibleEditorsFilePaths)
{ {

View File

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

View File

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

View File

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

View File

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