ClangCodeModel: Show only valid applicable overloads when completing

libclang is smart enough to filter the overloads according to which
arguments have already been entered, so let's make use of that.

Fixes: QTCREATORBUG-650
Change-Id: Ic2711f460c908c6fd9c8efe28c3c63a0ce2d9205
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2021-02-12 11:36:17 +01:00
committed by Christian Stenger
parent 9c9ca280ea
commit dfa24f09ad
7 changed files with 38 additions and 8 deletions

View File

@@ -183,11 +183,8 @@ void ClangCompletionContextAnalyzer::handleFunctionCall(int afterOperatorPositio
const int functionNameStart = startOfFunctionCall(afterOperatorPosition);
if (functionNameStart >= 0) {
m_addSnippets = functionNameStart == afterOperatorPosition;
// Always pass the position right after '(' to libclang because
// positions after the comma might be problematic if a preceding
// argument is invalid code.
setActionAndClangPosition(PassThroughToLibClangAfterLeftParen,
m_positionForProposal,
afterOperatorPosition,
functionNameStart);
} else { // e.g. "(" without any function name in front
m_addSnippets = true;

View File

@@ -608,6 +608,18 @@ void ClangCodeCompletionTest::testCompleteFunctions()
QVERIFY(hasItem(t.proposal, "TType&lt;QString&gt; f(bool)"));
}
void ClangCodeCompletionTest::testCompleteOverloads()
{
ProjectLessCompletionTest t("functionCompletionFiltered.cpp");
QCOMPARE(t.proposal->size(), 1);
QVERIFY(hasItem(t.proposal, "void func(int i, int j)"));
ProjectLessCompletionTest t2("functionCompletionFiltered2.cpp");
QCOMPARE(t2.proposal->size(), 2);
QVERIFY(hasItem(t2.proposal, "void func(const S &amp;s, int j)"));
QVERIFY(hasItem(t2.proposal, "void func(const S &amp;s, int j, int k)"));
}
void ClangCodeCompletionTest::testCompleteConstructor()
{
ProjectLessCompletionTest t("constructorCompletion.cpp");

View File

@@ -48,6 +48,7 @@ private slots:
void testCompleteMembersFromOutside();
void testCompleteMembersFromFriend();
void testCompleteFunctions();
void testCompleteOverloads();
void testCompleteConstructor();
void testCompleteClassAndConstructor();

View File

@@ -27,5 +27,7 @@
<file>membercompletion-outside.cpp</file>
<file>membercompletion-inside.cpp</file>
<file>membercompletion-friend.cpp</file>
<file>functionCompletionFiltered.cpp</file>
<file>functionCompletionFiltered2.cpp</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,9 @@
struct S;
void func(int i, int j);
void func(const S &s, int j);
void func(const S &s, int j, int k);
void g()
{
func(1, /* COMPLETE HERE */
}

View File

@@ -0,0 +1,9 @@
struct S {};
void func(int i, int j);
void func(const S &s, int j);
void func(const S &s, int j, int k);
void g()
{
func(S(), /* COMPLETE HERE */
}

View File

@@ -261,14 +261,14 @@ TEST_F(ClangCompletionContextAnalyzer, ArgumentTwoAtCall)
{
auto analyzer = runAnalyzer("f(1,@");
ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClangAfterLeftParen, -2, -2, positionInText, false));
ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClangAfterLeftParen, 0, -2, positionInText, false));
}
TEST_F(ClangCompletionContextAnalyzer, ArgumentTwoWithSpaceAtCall)
{
auto analyzer = runAnalyzer("f(1, @");
ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClangAfterLeftParen, -3, -3, positionInText, false));
ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClangAfterLeftParen, 0, -3, positionInText, false));
}
TEST_F(ClangCompletionContextAnalyzer, WhitespaceAfterFunctionName)
@@ -289,7 +289,7 @@ TEST_F(ClangCompletionContextAnalyzer, ArgumentTwoWithSpaceAtConstructorCallWith
{
auto analyzer = runAnalyzer("f{1, @");
ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClangAfterLeftParen, -3, -3, positionInText, false));
ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClangAfterLeftParen, 0, -3, positionInText, false));
}
TEST_F(ClangCompletionContextAnalyzer, WhitespaceBeforeConstructorCallWithBraceInitializer)
@@ -546,7 +546,7 @@ TEST_F(ClangCompletionContextAnalyzer, TemplatedFunctionSecondArgument)
{
auto analyzer = runAnalyzer("f < decltype(bar -> member) > (1, @");
ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClangAfterLeftParen, -3, -3, positionInText, false));
ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClangAfterLeftParen, 0, -3, positionInText, false));
}
TEST_F(ClangCompletionContextAnalyzer, FunctionNameStartPosition)