From 7fcc52bf47e11f34b18ef4aaea0b70e5a545f96e Mon Sep 17 00:00:00 2001
From: Przemyslaw Gorszkowski <pgorszkowski@gmail.com>
Date: Tue, 29 Jan 2013 13:18:08 +0100
Subject: [PATCH] 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>
---
src/libs/cplusplus/LookupContext.cpp | 4 ++
src/plugins/cpptools/cppchecksymbols.cpp | 4 ++
.../checksymbols/tst_checksymbols.cpp | 46 ++++++++++++++++++
.../cplusplus/findusages/tst_findusages.cpp | 47 +++++++++++++++++++
4 files changed, 101 insertions(+)
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index 95399bc0674..b73c22b6571 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -335,6 +335,10 @@ QList<LookupItem> LookupContext::lookup(const Name *name, Scope *scope) const
if (ClassOrNamespace *binding = bindings()->lookupType(fun)) {
candidates = binding->find(name);
+ // try find this name in parent class
+ while (candidates.isEmpty() && (binding = binding->parent()))
+ candidates = binding->find(name);
+
if (! candidates.isEmpty())
return candidates;
}
diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp
index 8d930457896..5f7b6f04d78 100644
--- a/src/plugins/cpptools/cppchecksymbols.cpp
+++ b/src/plugins/cpptools/cppchecksymbols.cpp
@@ -1164,6 +1164,7 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList<LookupItem> &candidates, Nam
else if (c->isUsingNamespaceDirective()) // ... and using namespace directives.
continue;
else if (c->isTypedef() || c->isNamespace() ||
+ c->isStatic() || //consider also static variable
c->isClass() || c->isEnum() || isTemplateClass(c) ||
c->isForwardClassDeclaration() || c->isTypenameArgument() || c->enclosingEnum() != 0) {
@@ -1174,6 +1175,9 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList<LookupItem> &candidates, Nam
UseKind kind = SemanticInfo::TypeUse;
if (c->enclosingEnum() != 0)
kind = SemanticInfo::EnumerationUse;
+ else if (c->isStatic())
+ // treat static variable as a field(highlighting)
+ kind = SemanticInfo::FieldUse;
const Use use(line, column, length, kind);
addUse(use);
diff --git a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
index 34d4569a315..ac586b75d85 100644
--- a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
+++ b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
@@ -182,6 +182,7 @@ private slots:
void test_checksymbols_MacroUse();
void test_checksymbols_FunctionUse();
void test_checksymbols_PseudoKeywordUse();
+ void test_checksymbols_StaticUse();
};
void tst_CheckSymbols::test_checksymbols_TypeUse()
@@ -331,5 +332,50 @@ void tst_CheckSymbols::test_checksymbols_PseudoKeywordUse()
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)
#include "tst_checksymbols.moc"
diff --git a/tests/auto/cplusplus/findusages/tst_findusages.cpp b/tests/auto/cplusplus/findusages/tst_findusages.cpp
index 0d84cb515bc..ed98cb80301 100644
--- a/tests/auto/cplusplus/findusages/tst_findusages.cpp
+++ b/tests/auto/cplusplus/findusages/tst_findusages.cpp
@@ -81,6 +81,7 @@ private Q_SLOTS:
void lambdaCaptureByReference();
void shadowedNames_1();
void shadowedNames_2();
+ void staticVariables();
// Qt keywords
void qproperty_1();
@@ -257,6 +258,52 @@ void tst_FindUsages::shadowedNames_2()
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
@interface Clazz {} +(void)method:(int)arg; @end
@implementation Clazz +(void)method:(int)arg {
--
GitLab