Commit 5643a45a authored by Nikolai Kosjar's avatar Nikolai Kosjar

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: default avatarMarco Bubke <marco.bubke@theqtcompany.com>
parent 889237f9
......@@ -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)
......
......@@ -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.
}
}
......
......@@ -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;
......
......@@ -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>
......@@ -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");
......
......@@ -57,6 +57,7 @@ private slots:
void testCompleteGlobals();
void testCompleteMembers();
void testCompleteFunctions();
void testCompleteConstructorAndFallbackToGlobalCompletion();
void testProjectDependentCompletion();
void testChangingProjectDependentCompletion();
......
int globalVariable;
struct GlobalClassWithCustomConstructor {
GlobalClassWithCustomConstructor(int) {}
};
void f() {
GlobalClassWithCustomConstructor foo( /* COMPLETE HERE */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment