summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/cpptools')
-rw-r--r--src/plugins/cpptools/cppcompletion_test.cpp227
-rw-r--r--src/plugins/cpptools/cppcompletionassist.cpp20
-rw-r--r--src/plugins/cpptools/cpptoolsplugin.h8
3 files changed, 255 insertions, 0 deletions
diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp
index 369f520cd2..6213df0c47 100644
--- a/src/plugins/cpptools/cppcompletion_test.cpp
+++ b/src/plugins/cpptools/cppcompletion_test.cpp
@@ -2463,3 +2463,230 @@ void CppToolsPlugin::test_completion_recursive_using_typedef_declarations()
QCOMPARE(completions.size(), 0);
}
+
+void CppToolsPlugin::test_completion_class_declaration_inside_function_or_block_QTCREATORBUG3620()
+{
+ test_completion();
+}
+
+void CppToolsPlugin::test_completion_class_declaration_inside_function_or_block_QTCREATORBUG3620_data()
+{
+ QTest::addColumn<QByteArray>("code");
+ QTest::addColumn<QStringList>("expectedCompletions");
+
+ QByteArray code;
+ QStringList completions;
+
+ code = "\n"
+ "void foo()\n"
+ "{\n"
+ " struct C { int m; };\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: class definition inside function")
+ << code << completions;
+
+ completions.clear();
+
+ code = "\n"
+ "void foo()\n"
+ "{\n"
+ " {\n"
+ " struct C { int m; };\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: class definition inside block inside function")
+ << code << completions;
+
+ completions.clear();
+
+ code = "\n"
+ "void foo()\n"
+ "{\n"
+ " {\n"
+ " struct C { int m1; };\n"
+ " }\n"
+ " {\n"
+ " struct C { int m2; };\n"
+ " C c;\n"
+ " @\n"
+ " // padding so we get the scope right\n"
+ " }\n"
+ "}\n"
+ ;
+ completions.append(QLatin1String("C"));
+ completions.append(QLatin1String("m2"));
+ QTest::newRow("case: class definition with the same name inside different block inside function")
+ << code << completions;
+
+ completions.clear();
+}
+
+void CppToolsPlugin::test_completion_namespace_alias_inside_function_or_block_QTCREATORBUG166()
+{
+ test_completion();
+}
+
+void CppToolsPlugin::test_completion_namespace_alias_inside_function_or_block_QTCREATORBUG166_data()
+{
+ QTest::addColumn<QByteArray>("code");
+ QTest::addColumn<QStringList>("expectedCompletions");
+
+ QByteArray code;
+ QStringList completions;
+
+ code = "\n"
+ "namespace NS1\n"
+ "{\n"
+ "namespace NS2\n"
+ "{\n"
+ " struct C\n"
+ " {\n"
+ " int m;\n"
+ " };\n"
+ "}\n"
+ "void foo()\n"
+ "{\n"
+ " namespace NS = NS1::NS2;\n"
+ " NS::C c;\n"
+ " @\n"
+ " // padding so we get the scope right\n"
+ "}\n"
+ ;
+ completions.append(QLatin1String("C"));
+ completions.append(QLatin1String("m"));
+ QTest::newRow("case: namespace alias inside function")
+ << code << completions;
+
+ completions.clear();
+
+ code = "\n"
+ "namespace NS1\n"
+ "{\n"
+ "namespace NS2\n"
+ "{\n"
+ " struct C\n"
+ " {\n"
+ " int m;\n"
+ " };\n"
+ "}\n"
+ "void foo()\n"
+ "{\n"
+ " {\n"
+ " namespace NS = NS1::NS2;\n"
+ " NS::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: namespace alias inside block inside function")
+ << code << completions;
+
+ completions.clear();
+}
+
+void CppToolsPlugin::test_completion_class_declaration_inside_function_or_block_QTCREATORBUG3620_static_member()
+{
+ TestData data;
+ data.srcText =
+ "void foo()\n"
+ "{\n"
+ " {\n"
+ " struct C { static void staticFun1(); int m1; };\n"
+ " }\n"
+ " {\n"
+ " struct C { static void staticFun2(); int m2; };\n"
+ " @\n"
+ " // padding so we get the scope right\n"
+ " }\n"
+ "}\n"
+ ;
+ setup(&data);
+
+ Utils::ChangeSet change;
+ QString txt = QLatin1String("C::");
+ change.insert(data.pos, txt);
+ QTextCursor cursor(data.doc);
+ change.apply(&cursor);
+ data.pos += txt.length();
+
+ QStringList completions = getCompletions(data);
+
+ QCOMPARE(completions.size(), 3);
+ QVERIFY(completions.contains(QLatin1String("C")));
+ QVERIFY(completions.contains(QLatin1String("staticFun2")));
+ QVERIFY(completions.contains(QLatin1String("m2")));
+}
+
+void CppToolsPlugin::test_completion_enum_inside_block_inside_function_QTCREATORBUG5456()
+{
+ TestData data;
+ data.srcText =
+ "void foo()\n"
+ "{\n"
+ " {\n"
+ " enum E { e1, e2, e3 };\n"
+ " @\n"
+ " // padding so we get the scope right\n"
+ " }\n"
+ "}\n"
+ ;
+ setup(&data);
+
+ Utils::ChangeSet change;
+ QString txt = QLatin1String("E::");
+ change.insert(data.pos, txt);
+ QTextCursor cursor(data.doc);
+ change.apply(&cursor);
+ data.pos += txt.length();
+
+ QStringList completions = getCompletions(data);
+
+ QCOMPARE(completions.size(), 4);
+ QVERIFY(completions.contains(QLatin1String("E")));
+ QVERIFY(completions.contains(QLatin1String("e1")));
+ QVERIFY(completions.contains(QLatin1String("e2")));
+ QVERIFY(completions.contains(QLatin1String("e3")));
+}
+
+void CppToolsPlugin::test_completion_enum_inside_function_QTCREATORBUG5456()
+{
+ TestData data;
+ data.srcText =
+ "void foo()\n"
+ "{\n"
+ " enum E { e1, e2, e3 };\n"
+ " @\n"
+ " // padding so we get the scope right\n"
+ "}\n"
+ ;
+ setup(&data);
+
+ Utils::ChangeSet change;
+ QString txt = QLatin1String("E::");
+ change.insert(data.pos, txt);
+ QTextCursor cursor(data.doc);
+ change.apply(&cursor);
+ data.pos += txt.length();
+
+ QStringList completions = getCompletions(data);
+
+ QCOMPARE(completions.size(), 4);
+ QVERIFY(completions.contains(QLatin1String("E")));
+ QVERIFY(completions.contains(QLatin1String("e1")));
+ QVERIFY(completions.contains(QLatin1String("e2")));
+ QVERIFY(completions.contains(QLatin1String("e3")));
+}
diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp
index f132e35a4b..f68079176f 100644
--- a/src/plugins/cpptools/cppcompletionassist.cpp
+++ b/src/plugins/cpptools/cppcompletionassist.cpp
@@ -1430,6 +1430,14 @@ bool CppCompletionAssistProcessor::completeScope(const QList<CPlusPlus::LookupIt
break;
}
+ // it can be class defined inside a block
+ if (classTy->enclosingScope()->isBlock()) {
+ if (ClassOrNamespace *b = context.lookupType(classTy->name(), classTy->enclosingScope())) {
+ completeClass(b);
+ break;
+ }
+ }
+
} else if (Namespace *nsTy = ty->asNamespaceType()) {
if (ClassOrNamespace *b = context.lookupType(nsTy)) {
completeNamespace(b);
@@ -1445,10 +1453,22 @@ bool CppCompletionAssistProcessor::completeScope(const QList<CPlusPlus::LookupIt
}
} else if (Enum *e = ty->asEnumType()) {
+ // it can be class defined inside a block
+ if (e->enclosingScope()->isBlock()) {
+ if (ClassOrNamespace *b = context.lookupType(e)) {
+ Block *block = e->enclosingScope()->asBlock();
+ if (ClassOrNamespace *bb = b->findBlock(block)) {
+ completeNamespace(bb);
+ break;
+ }
+ }
+ }
+
if (ClassOrNamespace *b = context.lookupType(e)) {
completeNamespace(b);
break;
}
+
}
}
diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h
index 4c983bab6c..63fa279550 100644
--- a/src/plugins/cpptools/cpptoolsplugin.h
+++ b/src/plugins/cpptools/cpptoolsplugin.h
@@ -148,6 +148,14 @@ private slots:
void test_completion_recursive_using_declarations2();
void test_completion_recursive_using_typedef_declarations();
+ void test_completion_class_declaration_inside_function_or_block_QTCREATORBUG3620();
+ void test_completion_class_declaration_inside_function_or_block_QTCREATORBUG3620_data();
+ void test_completion_namespace_alias_inside_function_or_block_QTCREATORBUG166();
+ void test_completion_namespace_alias_inside_function_or_block_QTCREATORBUG166_data();
+ void test_completion_class_declaration_inside_function_or_block_QTCREATORBUG3620_static_member();
+ void test_completion_enum_inside_block_inside_function_QTCREATORBUG5456();
+ void test_completion_enum_inside_function_QTCREATORBUG5456();
+
void test_format_pointerdeclaration_in_simpledeclarations();
void test_format_pointerdeclaration_in_simpledeclarations_data();
void test_format_pointerdeclaration_in_controlflowstatements();