forked from qt-creator/qt-creator
C++ editor: Highlighting static variables
Fix highlighting, find usages, marking for static variables. Task-number: QTCREATORBUG-6822 Change-Id: I0c97c93c6c1024550907eec3820496df22a94e85 Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
committed by
Nikolai Kosjar
parent
8bb0134c50
commit
7fcc52bf47
@@ -335,6 +335,10 @@ QList<LookupItem> LookupContext::lookup(const Name *name, Scope *scope) const
|
|||||||
if (ClassOrNamespace *binding = bindings()->lookupType(fun)) {
|
if (ClassOrNamespace *binding = bindings()->lookupType(fun)) {
|
||||||
candidates = binding->find(name);
|
candidates = binding->find(name);
|
||||||
|
|
||||||
|
// try find this name in parent class
|
||||||
|
while (candidates.isEmpty() && (binding = binding->parent()))
|
||||||
|
candidates = binding->find(name);
|
||||||
|
|
||||||
if (! candidates.isEmpty())
|
if (! candidates.isEmpty())
|
||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1164,6 +1164,7 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList<LookupItem> &candidates, Nam
|
|||||||
else if (c->isUsingNamespaceDirective()) // ... and using namespace directives.
|
else if (c->isUsingNamespaceDirective()) // ... and using namespace directives.
|
||||||
continue;
|
continue;
|
||||||
else if (c->isTypedef() || c->isNamespace() ||
|
else if (c->isTypedef() || c->isNamespace() ||
|
||||||
|
c->isStatic() || //consider also static variable
|
||||||
c->isClass() || c->isEnum() || isTemplateClass(c) ||
|
c->isClass() || c->isEnum() || isTemplateClass(c) ||
|
||||||
c->isForwardClassDeclaration() || c->isTypenameArgument() || c->enclosingEnum() != 0) {
|
c->isForwardClassDeclaration() || c->isTypenameArgument() || c->enclosingEnum() != 0) {
|
||||||
|
|
||||||
@@ -1174,6 +1175,9 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList<LookupItem> &candidates, Nam
|
|||||||
UseKind kind = SemanticInfo::TypeUse;
|
UseKind kind = SemanticInfo::TypeUse;
|
||||||
if (c->enclosingEnum() != 0)
|
if (c->enclosingEnum() != 0)
|
||||||
kind = SemanticInfo::EnumerationUse;
|
kind = SemanticInfo::EnumerationUse;
|
||||||
|
else if (c->isStatic())
|
||||||
|
// treat static variable as a field(highlighting)
|
||||||
|
kind = SemanticInfo::FieldUse;
|
||||||
|
|
||||||
const Use use(line, column, length, kind);
|
const Use use(line, column, length, kind);
|
||||||
addUse(use);
|
addUse(use);
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ private slots:
|
|||||||
void test_checksymbols_MacroUse();
|
void test_checksymbols_MacroUse();
|
||||||
void test_checksymbols_FunctionUse();
|
void test_checksymbols_FunctionUse();
|
||||||
void test_checksymbols_PseudoKeywordUse();
|
void test_checksymbols_PseudoKeywordUse();
|
||||||
|
void test_checksymbols_StaticUse();
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_CheckSymbols::test_checksymbols_TypeUse()
|
void tst_CheckSymbols::test_checksymbols_TypeUse()
|
||||||
@@ -331,5 +332,50 @@ void tst_CheckSymbols::test_checksymbols_PseudoKeywordUse()
|
|||||||
TestData::check(source, expectedUses);
|
TestData::check(source, expectedUses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_CheckSymbols::test_checksymbols_StaticUse()
|
||||||
|
{
|
||||||
|
const QByteArray source =
|
||||||
|
"struct Outer\n"
|
||||||
|
"{\n"
|
||||||
|
" static int Foo;\n"
|
||||||
|
" struct Inner\n"
|
||||||
|
" {\n"
|
||||||
|
" Outer *outer;\n"
|
||||||
|
" void foo();\n"
|
||||||
|
" };\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"int Outer::Foo = 42;\n"
|
||||||
|
"\n"
|
||||||
|
"void Outer::Inner::foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" Foo = 7;\n"
|
||||||
|
" Outer::Foo = 7;\n"
|
||||||
|
" outer->Foo = 7;\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
const QList<Use> expectedUses = QList<Use>()
|
||||||
|
<< Use(1, 8, 5, SemanticInfo::TypeUse)
|
||||||
|
<< Use(3, 16, 3, SemanticInfo::FieldUse)
|
||||||
|
<< Use(4, 12, 5, SemanticInfo::TypeUse)
|
||||||
|
<< Use(6, 16, 5, SemanticInfo::FieldUse)
|
||||||
|
<< Use(6, 9, 5, SemanticInfo::TypeUse)
|
||||||
|
<< Use(7, 14, 3, SemanticInfo::FunctionUse)
|
||||||
|
<< Use(11, 12, 3, SemanticInfo::FieldUse)
|
||||||
|
<< Use(11, 5, 5, SemanticInfo::TypeUse)
|
||||||
|
<< Use(13, 20, 3, SemanticInfo::FunctionUse)
|
||||||
|
<< Use(13, 6, 5, SemanticInfo::TypeUse)
|
||||||
|
<< Use(13, 13, 5, SemanticInfo::TypeUse)
|
||||||
|
<< Use(15, 5, 3, SemanticInfo::FieldUse)
|
||||||
|
<< Use(16, 12, 3, SemanticInfo::FieldUse)
|
||||||
|
<< Use(16, 5, 5, SemanticInfo::TypeUse)
|
||||||
|
<< Use(17, 5, 5, SemanticInfo::FieldUse)
|
||||||
|
<< Use(17, 12, 3, SemanticInfo::FieldUse)
|
||||||
|
;
|
||||||
|
|
||||||
|
TestData::check(source, expectedUses);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(tst_CheckSymbols)
|
QTEST_APPLESS_MAIN(tst_CheckSymbols)
|
||||||
#include "tst_checksymbols.moc"
|
#include "tst_checksymbols.moc"
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ private Q_SLOTS:
|
|||||||
void lambdaCaptureByReference();
|
void lambdaCaptureByReference();
|
||||||
void shadowedNames_1();
|
void shadowedNames_1();
|
||||||
void shadowedNames_2();
|
void shadowedNames_2();
|
||||||
|
void staticVariables();
|
||||||
|
|
||||||
// Qt keywords
|
// Qt keywords
|
||||||
void qproperty_1();
|
void qproperty_1();
|
||||||
@@ -257,6 +258,52 @@ void tst_FindUsages::shadowedNames_2()
|
|||||||
QCOMPARE(findUsages.usages().size(), 3);
|
QCOMPARE(findUsages.usages().size(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_FindUsages::staticVariables()
|
||||||
|
{
|
||||||
|
const QByteArray src = "\n"
|
||||||
|
"struct Outer\n"
|
||||||
|
"{\n"
|
||||||
|
" static int Foo;\n"
|
||||||
|
" struct Inner\n"
|
||||||
|
" {\n"
|
||||||
|
" Outer *outer;\n"
|
||||||
|
" void foo();\n"
|
||||||
|
" };\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"int Outer::Foo = 42;\n"
|
||||||
|
"\n"
|
||||||
|
"void Outer::Inner::foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" Foo = 7;\n"
|
||||||
|
" Outer::Foo = 7;\n"
|
||||||
|
" outer->Foo = 7;\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
Document::Ptr doc = Document::create("staticVariables");
|
||||||
|
doc->setUtf8Source(src);
|
||||||
|
doc->parse();
|
||||||
|
doc->check();
|
||||||
|
|
||||||
|
QVERIFY(doc->diagnosticMessages().isEmpty());
|
||||||
|
QCOMPARE(doc->globalSymbolCount(), 3U);
|
||||||
|
|
||||||
|
Snapshot snapshot;
|
||||||
|
snapshot.insert(doc);
|
||||||
|
|
||||||
|
Class *c = doc->globalSymbolAt(0)->asClass();
|
||||||
|
QVERIFY(c);
|
||||||
|
QCOMPARE(c->name()->identifier()->chars(), "Outer");
|
||||||
|
QCOMPARE(c->memberCount(), 2U);
|
||||||
|
Declaration *d = c->memberAt(0)->asDeclaration();
|
||||||
|
QVERIFY(d);
|
||||||
|
QCOMPARE(d->name()->identifier()->chars(), "Foo");
|
||||||
|
|
||||||
|
FindUsages findUsages(src, doc, snapshot);
|
||||||
|
findUsages(d);
|
||||||
|
QCOMPARE(findUsages.usages().size(), 5);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@interface Clazz {} +(void)method:(int)arg; @end
|
@interface Clazz {} +(void)method:(int)arg; @end
|
||||||
@implementation Clazz +(void)method:(int)arg {
|
@implementation Clazz +(void)method:(int)arg {
|
||||||
|
|||||||
Reference in New Issue
Block a user