Commit d1f58562 authored by Bernd Buschinski's avatar Bernd Buschinski

Fix code completion for nameless structs/unions with the same member

Summary:
The code completion always shows the first declaration it finds for a matching name.
This works fine as long as the parent has a name, for nameless structs/unions it just returns the first declaration it finds.
Fix this by checking that the found declaration has the expected type.

BUG: 409041

Test Plan:
See https://bugs.kde.org/show_bug.cgi?id=409041 for example code
or see the unit test in this patch.

Reviewers: #kdevelop, apol

Reviewed By: #kdevelop, apol

Subscribers: kdevelop-devel

Tags: #kdevelop

Differential Revision: https://phabricator.kde.org/D22455
parent f14891b5
......@@ -1187,6 +1187,19 @@ QList<CompletionTreeItemPointer> ClangCodeCompletionContext::completionItems(boo
auto found = findDeclaration(qid, ctx, m_position, isOverloadCandidate ? overloadsHandled : handled);
if (found && found->type<FunctionType>() == nullptr && parent.isEmpty() && !resultType.isEmpty()) {
// workaround: for multiple nameless structs with the same member.
// Check the type of the member to have at least a higher probability.
auto typeCheckedDeclaration = found;
while (typeCheckedDeclaration != nullptr && typeCheckedDeclaration->abstractType() != nullptr) {
if (typeCheckedDeclaration->abstractType()->toString() == resultType) {
found = typeCheckedDeclaration;
break;
}
typeCheckedDeclaration = findDeclaration(qid, ctx, m_position, isOverloadCandidate ? overloadsHandled : handled);
}
}
CompletionTreeItemPointer item;
if (found) {
// TODO: Bug in Clang: protected members from base classes not accessible in derived classes.
......
......@@ -189,9 +189,10 @@ void executeCompletionTest(const ReferencedTopDUContext& top, const CompletionIt
template<typename CustomTestFunction = NoopTestFunction>
void executeCompletionTest(const QString& code, const CompletionItems& expectedCompletionItems,
const ClangCodeCompletionContext::ContextFilters& filters = NoMacroOrBuiltin,
CustomTestFunction customTestFunction = {})
CustomTestFunction customTestFunction = {},
QString fileExtension = QStringLiteral("cpp"))
{
TestFile file(code, QStringLiteral("cpp"));
TestFile file(code, fileExtension);
QVERIFY(file.parseAndWait(TopDUContext::AllDeclarationsContextsUsesAndAST));
executeCompletionTest(file.topContext(), expectedCompletionItems, filters, customTestFunction);
}
......@@ -505,6 +506,46 @@ struct my_class : Head, my_class<Tail...>
<< CompletionItems{{3, 17}, { "Head", "Tail", "my_class" }};
}
void TestCodeCompletion::testClangCodeCompletionType()
{
QFETCH(QString, fileExtension);
QFETCH(QString, code);
QFETCH(CompletionItems, expectedItems);
QFETCH(QString, expedtedItem);
QFETCH(QString, expectedType);
auto executeItem = [=] (const ClangCodeCompletionItemTester& tester) {
auto item = tester.findItem(expedtedItem);
QVERIFY(item);
auto declaration = item->declaration();
QVERIFY(declaration);
QCOMPARE(declaration->abstractType()->toString(), expectedType);
};
executeCompletionTest(code, expectedItems, NoMacroOrBuiltin, executeItem, fileExtension);
}
void TestCodeCompletion::testClangCodeCompletionType_data()
{
QTest::addColumn<QString>("fileExtension");
QTest::addColumn<QString>("code");
QTest::addColumn<CompletionItems>("expectedItems");
QTest::addColumn<QString>("expedtedItem");
QTest::addColumn<QString>("expectedType");
QTest::newRow("bug409041")
<< "c"
<< "typedef struct { int bitmask[1]; } bitmask_a;\n"
"typedef struct { int bitmask[6]; } bitmask_c;\n"
"typedef union { bitmask_c bitmask; } bitmask_union;\n"
"int main() { bitmask_union u;\n"
"u. \n "
<< CompletionItems{{4, 2}, { "bitmask" }}
<< "bitmask"
<< "bitmask_c";
}
void TestCodeCompletion::testReplaceMemberAccess()
{
QFETCH(QString, code);
......
......@@ -35,6 +35,8 @@ private Q_SLOTS:
void testClangCodeCompletion();
void testClangCodeCompletion_data();
void testClangCodeCompletionType();
void testClangCodeCompletionType_data();
void testVirtualOverride();
void testVirtualOverride_data();
void testOverrideExecute();
......
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