C++: improve support for anonymous classes

Fix:
* highlighting
* find usages
* follow symbol
* code completion

Task-number: QTCREATORBUG-6497
Task-number: QTCREATORBUG-8963
Task-number: QTCREATORBUG-3610
Task-number: QTCREATORBUG-7579

Change-Id: I3dcaf1c515d0199c3e6bee72284fbb40064686ee
Reviewed-by: Petar Perisin <petar.perisin@gmail.com>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
Przemyslaw Gorszkowski
2013-04-10 23:30:18 +02:00
committed by Erik Verbruggen
parent a2b2857b44
commit 080bf4ecb8
27 changed files with 341 additions and 7 deletions

View File

@@ -188,6 +188,9 @@ private slots:
void operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG9006();
void test_checksymbols_templated_functions();
void test_checksymbols_QTCREATORBUG9098();
void test_checksymbols_AnonymousClass();
void test_checksymbols_AnonymousClass_insideNamespace();
void test_checksymbols_AnonymousClass_QTCREATORBUG8963();
};
void tst_CheckSymbols::test_checksymbols_TypeUse()
@@ -1421,6 +1424,28 @@ void tst_CheckSymbols::test_checksymbols_templated_functions()
TestData::check(source, expectedUses);
}
void tst_CheckSymbols::test_checksymbols_AnonymousClass()
{
const QByteArray source =
"struct\n"
"{\n"
" int foo;\n"
"} Foo;\n"
"\n"
"void fun()\n"
"{\n"
" foo = 3;\n"
"}\n"
;
const QList<Use> expectedUses = QList<Use>()
<< Use(3, 7, 3, CppHighlightingSupport::FieldUse)
<< Use(6, 6, 3, CppHighlightingSupport::FunctionUse)
;
TestData::check(source, expectedUses);
}
void tst_CheckSymbols::test_checksymbols_QTCREATORBUG9098()
{
const QByteArray source =
@@ -1460,5 +1485,87 @@ void tst_CheckSymbols::test_checksymbols_QTCREATORBUG9098()
TestData::check(source, expectedUses);
}
void tst_CheckSymbols::test_checksymbols_AnonymousClass_insideNamespace()
{
const QByteArray source =
"struct { int foo1; } Foo1;\n"
"void bar1()\n"
"{\n"
" Foo1.foo1 = 42;\n"
"}\n"
"namespace Ns1 {\n"
" struct { int foo2; } Foo2;\n"
" void bar2()\n"
" {\n"
" Foo2.foo2 = 42;\n"
" }\n"
"}\n"
"namespace Ns2 {\n"
" struct {\n"
" struct { struct { int foo3; }; };\n"
" void func() { foo3 = 42; }\n"
" } Foo3;\n"
" void bar3()\n"
" {\n"
" Foo3.foo3 = 42;\n"
" }\n"
"}\n"
;
const QList<Use> expectedUses = QList<Use>()
<< Use(1, 14, 4, CppHighlightingSupport::FieldUse)
<< Use(2, 6, 4, CppHighlightingSupport::FunctionUse)
<< Use(4, 8, 4, CppHighlightingSupport::FieldUse)
<< Use(6, 11, 3, CppHighlightingSupport::TypeUse)
<< Use(7, 16, 4, CppHighlightingSupport::FieldUse)
<< Use(8, 8, 4, CppHighlightingSupport::FunctionUse)
<< Use(10, 10, 4, CppHighlightingSupport::FieldUse)
<< Use(13, 11, 3, CppHighlightingSupport::TypeUse)
<< Use(15, 27, 4, CppHighlightingSupport::FieldUse)
<< Use(16, 10, 4, CppHighlightingSupport::FunctionUse)
<< Use(18, 8, 4, CppHighlightingSupport::FunctionUse)
;
TestData::check(source, expectedUses);
}
void tst_CheckSymbols::test_checksymbols_AnonymousClass_QTCREATORBUG8963()
{
const QByteArray source =
"typedef enum {\n"
" FIRST\n"
"} isNotInt;\n"
"typedef struct {\n"
" int isint;\n"
" int isNotInt;\n"
"} Struct;\n"
"void foo()\n"
"{\n"
" Struct s;\n"
" s.isint;\n"
" s.isNotInt;\n"
" FIRST;\n"
"}\n"
;
const QList<Use> expectedUses = QList<Use>()
<< Use(2, 5, 5, CppHighlightingSupport::EnumerationUse)
<< Use(3, 3, 8, CppHighlightingSupport::TypeUse)
<< Use(5, 9, 5, CppHighlightingSupport::FieldUse)
<< Use(6, 9, 8, CppHighlightingSupport::FieldUse)
<< Use(7, 3, 6, CppHighlightingSupport::TypeUse)
<< Use(8, 6, 3, CppHighlightingSupport::FunctionUse)
<< Use(10, 5, 6, CppHighlightingSupport::TypeUse)
<< Use(10, 12, 1, CppHighlightingSupport::LocalUse)
<< Use(11, 5, 1, CppHighlightingSupport::LocalUse)
<< Use(11, 7, 5, CppHighlightingSupport::FieldUse)
<< Use(12, 5, 1, CppHighlightingSupport::LocalUse)
<< Use(12, 7, 8, CppHighlightingSupport::FieldUse)
<< Use(13, 5, 5, CppHighlightingSupport::EnumerationUse)
;
TestData::check(source, expectedUses);
}
QTEST_APPLESS_MAIN(tst_CheckSymbols)
#include "tst_checksymbols.moc"

View File

@@ -96,6 +96,8 @@ private Q_SLOTS:
void instantiateTemplateWithNestedClass();
void operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG9006();
void operatorArrowOfNestedClassOfTemplateClass_QTCREATORBUG9005();
void anonymousClass_QTCREATORBUG8963();
};
void tst_FindUsages::inlineMethod()
@@ -475,7 +477,6 @@ void tst_FindUsages::operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG90
QVERIFY(doc->diagnosticMessages().isEmpty());
QCOMPARE(doc->globalSymbolCount(), 3U);
Snapshot snapshot;
snapshot.insert(doc);
@@ -488,6 +489,50 @@ void tst_FindUsages::operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG90
FindUsages findUsages(src, doc, snapshot);
findUsages(fooDeclaration);
QCOMPARE(findUsages.usages().size(), 2);
}
void tst_FindUsages::anonymousClass_QTCREATORBUG8963()
{
const QByteArray src =
"typedef enum {\n"
" FIRST\n"
"} isNotInt;\n"
"typedef struct {\n"
" int isint;\n"
" int isNotInt;\n"
"} Struct;\n"
"void foo()\n"
"{\n"
" Struct s;\n"
" s.isint;\n"
" s.isNotInt;\n"
" FIRST;\n"
"}\n"
;
Document::Ptr doc = Document::create("anonymousClass_QTCREATORBUG8963");
doc->setUtf8Source(src);
doc->parse();
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
QCOMPARE(doc->globalSymbolCount(), 5U);
Snapshot snapshot;
snapshot.insert(doc);
Class *structSymbol = doc->globalSymbolAt(2)->asClass();
QVERIFY(structSymbol);
QCOMPARE(structSymbol->memberCount(), 2U);
Declaration *isNotIntDeclaration = structSymbol->memberAt(1)->asDeclaration();
QVERIFY(isNotIntDeclaration);
QCOMPARE(isNotIntDeclaration->name()->identifier()->chars(), "isNotInt");
FindUsages findUsages(src, doc, snapshot);
findUsages(isNotIntDeclaration);
QCOMPARE(findUsages.usages().size(), 2);
}