From 11f6ae4a143c2669a443ebcee693b71c310cf564 Mon Sep 17 00:00:00 2001 From: Leandro Melo Date: Wed, 15 Aug 2012 12:50:01 +0200 Subject: C++: Completion for templates as base classes This fixes a variety of issues regarding class completion when templates are used as base classes. The test cases show examples. Task-number: QTCREATORBUG-4357 Change-Id: I764d5ce817a78e1b19336e5beab758ca9e10f34b Reviewed-by: Roberto Raggi --- src/plugins/cpptools/cppcompletion_test.cpp | 169 ++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) (limited to 'src/plugins/cpptools/cppcompletion_test.cpp') diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 6d4a2641f0..7d9d9f3417 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -196,3 +196,172 @@ void CppToolsPlugin::test_completion_template_1() QVERIFY(!completions.contains("f")); QVERIFY(!completions.contains("func")); } + +void CppToolsPlugin::test_completion_template_as_base() +{ + QFETCH(QByteArray, code); + QFETCH(QStringList, expectedCompletions); + + TestData data; + data.srcText = code; + setup(&data); + + Utils::ChangeSet change; + change.insert(data.pos, "c."); + QTextCursor cursor(data.doc); + change.apply(&cursor); + data.pos += 2; + + QStringList actualCompletions = getCompletions(data); + actualCompletions.sort(); + expectedCompletions.sort(); + + QCOMPARE(actualCompletions, expectedCompletions); +} + +void CppToolsPlugin::test_completion_template_as_base_data() +{ + QTest::addColumn("code"); + QTest::addColumn("expectedCompletions"); + + QByteArray code; + QStringList completions; + + code = "\n" + "class Data { int dataMember; };\n" + "template class Other : public T { int otherMember; };\n" + "\n" + "void func() {\n" + " Other c;\n" + " @\n" + " // padding so we get the scope right\n" + "}"; + completions.append("Data"); + completions.append("dataMember"); + completions.append("Other"); + completions.append("otherMember"); + QTest::newRow("case: base as template directly") << code << completions; + + + completions.clear(); + code = "\n" + "class Data { int dataMember; };\n" + "template class Other : public T { int otherMember; };\n" + "template class More : public Other { int moreMember; };\n" + "\n" + "void func() {\n" + " More c;\n" + " @\n" + " // padding so we get the scope right\n" + "}"; + completions.append("Data"); + completions.append("dataMember"); + completions.append("Other"); + completions.append("otherMember"); + completions.append("More"); + completions.append("moreMember"); + QTest::newRow("case: base as class template") << code << completions; + + + completions.clear(); + code = "\n" + "class Data { int dataMember; };\n" + "template class Other : public T { int otherMember; };\n" + "template class More : public ::Other { int moreMember; };\n" + "\n" + "void func() {\n" + " More c;\n" + " @\n" + " // padding so we get the scope right\n" + "}"; + completions.append("Data"); + completions.append("dataMember"); + completions.append("Other"); + completions.append("otherMember"); + completions.append("More"); + completions.append("moreMember"); + QTest::newRow("case: base as globally qualified class template") << code << completions; + + + completions.clear(); + code = "\n" + "class Data { int dataMember; };\n" + "namespace NS {\n" + "template class Other : public T { int otherMember; };\n" + "}\n" + "template class More : public NS::Other { int moreMember; };\n" + "\n" + "void func() {\n" + " More c;\n" + " @\n" + " // padding so we get the scope right\n" + "}"; + completions.append("Data"); + completions.append("dataMember"); + completions.append("Other"); + completions.append("otherMember"); + completions.append("More"); + completions.append("moreMember"); + QTest::newRow("case: base as namespace qualified class template") << code << completions; + + + completions.clear(); + code = "\n" + "class Data { int dataMember; };\n" + "namespace NS {\n" + "template class Delegate { typedef Data Type; };\n" + "}\n" + "template class Final : public NS::Delegate::Type { int finalMember; };\n" + "\n" + "void func() {\n" + " Final c;\n" + " @\n" + " // padding so we get the scope right\n" + "}"; + completions.append("Data"); + completions.append("dataMember"); + completions.append("Final"); + completions.append("finalMember"); + QTest::newRow("case: base as nested template name") << code << completions; + + + completions.clear(); + code = "\n" + "class Data { int dataMember; };\n" + "namespace NS {\n" + "template class Delegate { typedef Data Type; };\n" + "}\n" + "class Final : public NS::Delegate::Type { int finalMember; };\n" + "\n" + "void func() {\n" + " Final c;\n" + " @\n" + " // padding so we get the scope right\n" + "}"; + completions.append("Data"); + completions.append("dataMember"); + completions.append("Final"); + completions.append("finalMember"); + QTest::newRow("case: base as nested template name in non-template") << code << completions; + + completions.clear(); + code = "\n" + "class Data { int dataMember; };\n" + "namespace NS {\n" + "template class Other : public T { int otherMember; };\n" + "}\n" + "class Final : public NS::Other { int finalMember; };\n" + "\n" + "void func() {\n" + " Final c;\n" + " @\n" + " // padding so we get the scope right\n" + "}"; + completions.append("Data"); + completions.append("dataMember"); + completions.append("Final"); + completions.append("finalMember"); + completions.append("Other"); + completions.append("otherMember"); + QTest::newRow("case: base as template name in non-template") << code << completions; +} -- cgit v1.2.1