From 64d80150faaffa34f0a05c9692d7286c473c0b01 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gorszkowski Date: Fri, 26 Apr 2013 14:54:49 +0200 Subject: [PATCH] C++: fix code completion when 'using' declaration inside function Looking for using declaration when lookup a type Task-number: QTCREATORBUG-2668 Change-Id: I11600c5be262840472dd4c9e72334760a35aa4a0 Reviewed-by: Nikolai Kosjar --- src/libs/cplusplus/LookupContext.cpp | 9 ++ src/plugins/cpptools/cppcompletion_test.cpp | 133 ++++++++++++++++++++ src/plugins/cpptools/cpptoolsplugin.h | 2 + 3 files changed, 144 insertions(+) diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index dde50df687..9c583185e6 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -309,6 +309,15 @@ ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope, return lookupType(namedTy->name(), scope); } } + } else if (UsingDeclaration *ud = m->asUsingDeclaration()) { + if (name->isNameId()) { + if (const QualifiedNameId *q = ud->name()->asQualifiedNameId()) { + if (q->name()->isEqualTo(name)) { + return bindings()->globalNamespace()->lookupType(q); + } + } + + } } } return lookupType(name, scope->enclosingScope()); diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index b8ee95f7c0..d231f6f317 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -1882,3 +1882,136 @@ void CppToolsPlugin::test_completion_QTCREATORBUG9098() QVERIFY(completions.contains(QLatin1String("c"))); QVERIFY(completions.contains(QLatin1String("B"))); } + +void CppToolsPlugin::test_completion_type_and_using_declaration() +{ + test_completion(); +} + +void CppToolsPlugin::test_completion_type_and_using_declaration_data() +{ + QTest::addColumn("code"); + QTest::addColumn("expectedCompletions"); + + QByteArray code; + QStringList completions; + + code = "\n" + "namespace NS\n" + "{\n" + "struct C { int m; };\n" + "}\n" + "void foo()\n" + "{\n" + " using NS::C;\n" + " C c;\n" + " @\n" + " // padding so we get the scope right\n" + "}\n"; + completions.append(QLatin1String("C")); + completions.append(QLatin1String("m")); + QTest::newRow("case: type and using declaration inside function") + << code << completions; + + completions.clear(); + + code = "\n" + "namespace NS\n" + "{\n" + "struct C { int m; };\n" + "}\n" + "using NS::C;\n" + "void foo()\n" + "{\n" + " C c;\n" + " @\n" + " // padding so we get the scope right\n" + "}\n"; + completions.append(QLatin1String("C")); + completions.append(QLatin1String("m")); + QTest::newRow("case: type and using declaration in global namespace") + << code << completions; + + completions.clear(); + + code = "\n" + "struct C { int m; };\n" + "namespace NS\n" + "{\n" + " using ::C;\n" + " void foo()\n" + " {\n" + " C c;\n" + " @\n" + " // padding so we get the scope right\n" + " }\n" + "}\n"; + completions.append(QLatin1String("C")); + completions.append(QLatin1String("m")); + QTest::newRow("case: type in global namespace and using declaration in NS namespace") + << code << completions; + + completions.clear(); + + code = "\n" + "struct C { int m; };\n" + "namespace NS\n" + "{\n" + " void foo()\n" + " {\n" + " using ::C;\n" + " C c;\n" + " @\n" + " // padding so we get the scope right\n" + " }\n" + "}\n"; + completions.append(QLatin1String("C")); + completions.append(QLatin1String("m")); + QTest::newRow("case: type in global namespace and using declaration inside function in NS namespace") + << code << completions; + + completions.clear(); + + code = "\n" + "namespace NS1\n" + "{\n" + "struct C { int m; };\n" + "}\n" + "namespace NS2\n" + "{\n" + " void foo()\n" + " {\n" + " using NS1::C;\n" + " C c;\n" + " @\n" + " // padding so we get the scope right\n" + " }\n" + "}\n"; + completions.append(QLatin1String("C")); + completions.append(QLatin1String("m")); + QTest::newRow("case: type inside namespace NS1 and using declaration in function inside NS2 namespace") + << code << completions; + + completions.clear(); + + code = "\n" + "namespace NS1\n" + "{\n" + "struct C { int m; };\n" + "}\n" + "namespace NS2\n" + "{\n" + " using NS1::C;\n" + " void foo()\n" + " {\n" + " C c;\n" + " @\n" + " // padding so we get the scope right\n" + " }\n" + "}\n"; + completions.append(QLatin1String("C")); + completions.append(QLatin1String("m")); + QTest::newRow("case: type inside namespace NS1 and using declaration inside NS2 namespace") + << code << completions; + +} diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index 10975a5301..37e06524fd 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -124,6 +124,8 @@ private slots: void test_completion_typedef_using_templates2(); void test_completion_namespace_alias_with_many_namespace_declarations(); void test_completion_QTCREATORBUG9098(); + void test_completion_type_and_using_declaration(); + void test_completion_type_and_using_declaration_data(); void test_format_pointerdeclaration_in_simpledeclarations(); void test_format_pointerdeclaration_in_simpledeclarations_data(); -- GitLab