Clang: Fallback to global completion if function call completion fails

We can not offer proper constructor completion with libclang <= 3.6, so
fall back to normal/global completion.

Change-Id: I90bb8d981ae20ed4c228f829ad4267221b92f8a1
Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com>
This commit is contained in:
Nikolai Kosjar
2015-07-22 13:09:44 +02:00
parent 889237f962
commit 5643a45a83
7 changed files with 40 additions and 9 deletions

View File

@@ -145,8 +145,11 @@ void IpcReceiver::codeCompleted(const CodeCompletedCommand &command)
const quint64 ticket = command.ticketNumber();
QScopedPointer<ClangCompletionAssistProcessor> processor(m_assistProcessorsTable.take(ticket));
if (processor)
processor->handleAvailableAsyncCompletions(command.codeCompletions());
if (processor) {
const bool finished = processor->handleAvailableAsyncCompletions(command.codeCompletions());
if (!finished)
processor.take();
}
}
void IpcReceiver::translationUnitDoesNotExist(const TranslationUnitDoesNotExistCommand &command)

View File

@@ -232,20 +232,24 @@ IAssistProposal *ClangCompletionAssistProcessor::perform(const AssistInterface *
return startCompletionHelper(); // == 0 if results are calculated asynchronously
}
void ClangCompletionAssistProcessor::handleAvailableAsyncCompletions(
bool ClangCompletionAssistProcessor::handleAvailableAsyncCompletions(
const CodeCompletions &completions)
{
bool handled = true;
switch (m_sentRequestType) {
case CompletionRequestType::NormalCompletion:
handleAvailableCompletions(completions);
break;
case CompletionRequestType::FunctionHintCompletion:
handleAvailableFunctionHintCompletions(completions);
handled = handleAvailableFunctionHintCompletions(completions);
break;
default:
QTC_CHECK(!"Unhandled ClangCompletionAssistProcessor::CompletionRequestType");
break;
}
return handled;
}
const TextEditorWidget *ClangCompletionAssistProcessor::textEditorWidget() const
@@ -704,7 +708,7 @@ void ClangCompletionAssistProcessor::handleAvailableCompletions(const CodeComple
setAsyncProposalAvailable(createProposal());
}
void ClangCompletionAssistProcessor::handleAvailableFunctionHintCompletions(
bool ClangCompletionAssistProcessor::handleAvailableFunctionHintCompletions(
const CodeCompletions &completions)
{
QTC_CHECK(!m_functionName.isEmpty());
@@ -715,9 +719,13 @@ void ClangCompletionAssistProcessor::handleAvailableFunctionHintCompletions(
auto *proposal = new FunctionHintProposal(m_positionForProposal, model);
setAsyncProposalAvailable(proposal);
return true;
} else {
QTC_CHECK(!"Function completion failed. Would fallback to global completion here...");
// TODO: If we need this, the processor can't be deleted in IpcClient.
m_addSnippets = false;
m_functionName.clear();
m_sentRequestType = NormalCompletion;
sendCompletionRequest(m_interface->position(), QByteArray());
return false; // We are not yet finished.
}
}

View File

@@ -59,7 +59,7 @@ public:
TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *interface) override;
void handleAvailableAsyncCompletions(const CodeCompletions &completions);
bool handleAvailableAsyncCompletions(const CodeCompletions &completions);
const TextEditor::TextEditorWidget *textEditorWidget() const;
@@ -91,7 +91,7 @@ private:
void sendCompletionRequest(int position, const QByteArray &customFileContent);
void handleAvailableCompletions(const CodeCompletions &completions);
void handleAvailableFunctionHintCompletions(const CodeCompletions &completions);
bool handleAvailableFunctionHintCompletions(const CodeCompletions &completions);
private:
QScopedPointer<const ClangCompletionAssistInterface> m_interface;

View File

@@ -20,5 +20,6 @@
<file>exampleIncludeDir/otherFile.h</file>
<file>exampleIncludeDir/mylib/mylib.h</file>
<file>globalCompletion.cpp</file>
<file>constructorCompletion.cpp</file>
</qresource>
</RCC>

View File

@@ -874,6 +874,15 @@ void ClangCodeCompletionTest::testCompleteFunctions()
QVERIFY(hasItem(t.proposal, "TType<QString> f(bool)"));
}
void ClangCodeCompletionTest::testCompleteConstructorAndFallbackToGlobalCompletion()
{
ProjectLessCompletionTest t("constructorCompletion.cpp");
QVERIFY(hasItem(t.proposal, "globalVariable"));
QVERIFY(hasItem(t.proposal, "GlobalClassWithCustomConstructor"));
QVERIFY(!hasSnippet(t.proposal, "class"));
}
void ClangCodeCompletionTest::testProjectDependentCompletion()
{
const TestDocument testDocument("completionWithProject.cpp");

View File

@@ -57,6 +57,7 @@ private slots:
void testCompleteGlobals();
void testCompleteMembers();
void testCompleteFunctions();
void testCompleteConstructorAndFallbackToGlobalCompletion();
void testProjectDependentCompletion();
void testChangingProjectDependentCompletion();

View File

@@ -0,0 +1,9 @@
int globalVariable;
struct GlobalClassWithCustomConstructor {
GlobalClassWithCustomConstructor(int) {}
};
void f() {
GlobalClassWithCustomConstructor foo( /* COMPLETE HERE */
}