diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 70048af73eb..d2ef0243dae 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -360,6 +360,15 @@ ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope, } else if (ClassOrNamespace *b = bindings()->lookupType(scope, enclosingTemplateInstantiation)) { return b->lookupType(name); + } else if (Class *scopeAsClass = scope->asClass()) { + if (scopeAsClass->enclosingScope()->isBlock()) { + if (ClassOrNamespace *b = lookupType(scopeAsClass->name(), + scopeAsClass->enclosingScope(), + enclosingTemplateInstantiation, + typedefsBeingResolved)) { + return b->lookupType(name); + } + } } return 0; diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 01c8072cf32..3486b2466ac 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -2825,3 +2825,205 @@ void CppToolsPlugin::test_completion_lambdaCalls_5() QVERIFY(completions.contains(QLatin1String("S"))); QVERIFY(completions.contains(QLatin1String("bar"))); } + +void CppToolsPlugin::test_completion_local_type_and_member_1() +{ + TestData data; + data.srcText = + "struct OtherType { int otherTypeMember; };\n" + "void foo()\n" + "{\n" + " struct LocalType\n" + " {\n" + " int localTypeMember;\n" + " OtherType ot;\n" + " };\n" + " LocalType lt;\n" + " @\n" + " // padding so we get the scope right\n" + "}\n" + ; + setup(&data); + + Utils::ChangeSet change; + QString txt = QLatin1String("lt.ot."); + change.insert(data.pos, txt); + QTextCursor cursor(data.doc); + change.apply(&cursor); + data.pos += txt.length(); + + QStringList completions = getCompletions(data); + + QCOMPARE(completions.size(), 2); + QVERIFY(completions.contains(QLatin1String("OtherType"))); + QVERIFY(completions.contains(QLatin1String("otherTypeMember"))); +} + +void CppToolsPlugin::test_completion_local_type_and_member_2() +{ + TestData data; + data.srcText = + "void foo()\n" + "{\n" + " struct OtherType { int otherTypeMember; };\n" + " struct LocalType\n" + " {\n" + " int localTypeMember;\n" + " OtherType ot;\n" + " };\n" + " LocalType lt;\n" + " @\n" + " // padding so we get the scope right\n" + "}\n" + ; + setup(&data); + + Utils::ChangeSet change; + QString txt = QLatin1String("lt.ot."); + change.insert(data.pos, txt); + QTextCursor cursor(data.doc); + change.apply(&cursor); + data.pos += txt.length(); + + QStringList completions = getCompletions(data); + + QCOMPARE(completions.size(), 2); + QVERIFY(completions.contains(QLatin1String("OtherType"))); + QVERIFY(completions.contains(QLatin1String("otherTypeMember"))); +} + +void CppToolsPlugin::test_completion_local_type_and_member_3() +{ + TestData data; + data.srcText = + "void foo()\n" + "{\n" + " struct OtherType { int otherTypeMember; };\n" + " {\n" + " struct LocalType\n" + " {\n" + " int localTypeMember;\n" + " OtherType ot;\n" + " };\n" + " LocalType lt;\n" + " @\n" + " // padding so we get the scope right\n" + " }\n" + "}\n" + ; + setup(&data); + + Utils::ChangeSet change; + QString txt = QLatin1String("lt.ot."); + change.insert(data.pos, txt); + QTextCursor cursor(data.doc); + change.apply(&cursor); + data.pos += txt.length(); + + QStringList completions = getCompletions(data); + + QCOMPARE(completions.size(), 2); + QVERIFY(completions.contains(QLatin1String("OtherType"))); + QVERIFY(completions.contains(QLatin1String("otherTypeMember"))); +} + +void CppToolsPlugin::test_completion_local_type_and_member_4() +{ + TestData data; + data.srcText = + "namespace NS {struct OtherType { int otherTypeMember; };}\n" + "void foo()\n" + "{\n" + " struct LocalType\n" + " {\n" + " int localTypeMember;\n" + " NS::OtherType ot;\n" + " };\n" + " LocalType lt;\n" + " @\n" + " // padding so we get the scope right\n" + "}\n" + ; + setup(&data); + + Utils::ChangeSet change; + QString txt = QLatin1String("lt.ot."); + change.insert(data.pos, txt); + QTextCursor cursor(data.doc); + change.apply(&cursor); + data.pos += txt.length(); + + QStringList completions = getCompletions(data); + + QCOMPARE(completions.size(), 2); + QVERIFY(completions.contains(QLatin1String("OtherType"))); + QVERIFY(completions.contains(QLatin1String("otherTypeMember"))); +} + +void CppToolsPlugin::test_completion_local_type_and_member_5() +{ + TestData data; + data.srcText = + "namespace NS {struct OtherType { int otherTypeMember; };}\n" + "void foo()\n" + "{\n" + " using namespace NS;\n" + " struct LocalType\n" + " {\n" + " int localTypeMember;\n" + " OtherType ot;\n" + " };\n" + " LocalType lt;\n" + " @\n" + " // padding so we get the scope right\n" + "}\n" + ; + setup(&data); + + Utils::ChangeSet change; + QString txt = QLatin1String("lt.ot."); + change.insert(data.pos, txt); + QTextCursor cursor(data.doc); + change.apply(&cursor); + data.pos += txt.length(); + + QStringList completions = getCompletions(data); + + QCOMPARE(completions.size(), 2); + QVERIFY(completions.contains(QLatin1String("OtherType"))); + QVERIFY(completions.contains(QLatin1String("otherTypeMember"))); +} + +void CppToolsPlugin::test_completion_local_type_and_member_6() +{ + TestData data; + data.srcText = + "namespace NS {struct OtherType { int otherTypeMember; };}\n" + "void foo()\n" + "{\n" + " using NS::OtherType;\n" + " struct LocalType\n" + " {\n" + " int localTypeMember;\n" + " OtherType ot;\n" + " };\n" + " LocalType lt;\n" + " @\n" + " // padding so we get the scope right\n" + "}\n" + ; + setup(&data); + + Utils::ChangeSet change; + QString txt = QLatin1String("lt.ot."); + change.insert(data.pos, txt); + QTextCursor cursor(data.doc); + change.apply(&cursor); + data.pos += txt.length(); + + QStringList completions = getCompletions(data); + + QCOMPARE(completions.size(), 2); + QVERIFY(completions.contains(QLatin1String("OtherType"))); + QVERIFY(completions.contains(QLatin1String("otherTypeMember"))); +} diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index 118b4e83641..9ebea974611 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -163,6 +163,13 @@ private slots: void test_completion_lambdaCalls_4(); void test_completion_lambdaCalls_5(); + void test_completion_local_type_and_member_1(); + void test_completion_local_type_and_member_2(); + void test_completion_local_type_and_member_3(); + void test_completion_local_type_and_member_4(); + void test_completion_local_type_and_member_5(); + void test_completion_local_type_and_member_6(); + void test_format_pointerdeclaration_in_simpledeclarations(); void test_format_pointerdeclaration_in_simpledeclarations_data(); void test_format_pointerdeclaration_in_controlflowstatements();