diff --git a/src/plugins/cppeditor/cppchecksymbols.cpp b/src/plugins/cppeditor/cppchecksymbols.cpp index d4b3ad882d09fbfb31b49b87419b117fde40674a..47f092e9b6dfa59f8e3388c258a0d23e96a94586 100644 --- a/src/plugins/cppeditor/cppchecksymbols.cpp +++ b/src/plugins/cppeditor/cppchecksymbols.cpp @@ -64,7 +64,7 @@ class CollectTypes: protected SymbolVisitor QSet<QByteArray> _types; QSet<QByteArray> _members; QSet<QByteArray> _virtualMethods; - QList<NameAST *> _names; + QSet<QByteArray> _statics; bool _mainDocument; public: @@ -90,6 +90,11 @@ public: return _virtualMethods; } + const QSet<QByteArray> &statics() const + { + return _statics; + } + protected: void process(Document::Ptr doc, QSet<Namespace *> *processed) { @@ -151,6 +156,18 @@ protected: } } + void addStatic(const Name *name) + { + if (! name) { + return; + + } else if (name->isNameId() || name->isTemplateNameId()) { + const Identifier *id = name->identifier(); + _statics.insert(QByteArray::fromRawData(id->chars(), id->size())); + + } + } + // nothing to do virtual bool visit(UsingNamespaceDirective *) { return true; } virtual bool visit(UsingDeclaration *) { return true; } @@ -184,6 +201,9 @@ protected: virtual bool visit(Declaration *symbol) { + if (symbol->enclosingEnumScope() != 0) + addStatic(symbol->name()); + if (Function *funTy = symbol->type()->asFunctionType()) { if (funTy->isVirtual()) addVirtualMethod(symbol->name()); @@ -288,6 +308,7 @@ CheckSymbols::CheckSymbols(Document::Ptr doc, const LookupContext &context) _potentialTypes = collectTypes.types(); _potentialMembers = collectTypes.members(); _potentialVirtualMethods = collectTypes.virtualMethods(); + _potentialStatics = collectTypes.statics(); _flushRequested = false; _flushLine = 0; @@ -441,6 +462,12 @@ bool CheckSymbols::visit(UsingDirectiveAST *) return true; } +bool CheckSymbols::visit(EnumeratorAST *ast) +{ + addUse(ast->identifier_token, Use::Static); + return true; +} + bool CheckSymbols::visit(SimpleDeclarationAST *ast) { if (ast->declarator_list && !ast->declarator_list->next) { @@ -616,9 +643,9 @@ void CheckSymbols::checkName(NameAST *ast, Scope *scope) Class *klass = scope->owner()->asClass(); if (hasVirtualDestructor(_context.lookupType(klass))) addUse(ast, Use::VirtualMethod); - } else if (maybeType(ast->name)) { + } else if (maybeType(ast->name) || maybeStatic(ast->name)) { const QList<LookupItem> candidates = _context.lookup(ast->name, scope); - addType(candidates, ast); + addTypeOrStatic(candidates, ast); } else if (maybeMember(ast->name)) { const QList<LookupItem> candidates = _context.lookup(ast->name, scope); addClassMember(candidates, ast); @@ -678,7 +705,7 @@ bool CheckSymbols::visit(QualifiedNameAST *ast) if (hasVirtualDestructor(b)) addUse(ast->unqualified_name, Use::VirtualMethod); } else { - addType(b->find(ast->unqualified_name->name), ast->unqualified_name); + addTypeOrStatic(b->find(ast->unqualified_name->name), ast->unqualified_name); } } } @@ -774,12 +801,20 @@ void CheckSymbols::addUse(NameAST *ast, Use::Kind kind) if (DestructorNameAST *dtor = ast->asDestructorName()) startToken = dtor->identifier_token; - const Token &tok = tokenAt(startToken); + addUse(startToken, kind); +} + +void CheckSymbols::addUse(unsigned tokenIndex, Use::Kind kind) +{ + if (! tokenIndex) + return; + + const Token &tok = tokenAt(tokenIndex); if (tok.generated()) return; unsigned line, column; - getTokenStartPosition(startToken, &line, &column); + getTokenStartPosition(tokenIndex, &line, &column); const unsigned length = tok.length(); const Use use(line, column, length, kind); @@ -823,7 +858,7 @@ void CheckSymbols::addType(ClassOrNamespace *b, NameAST *ast) //qDebug() << "added use" << oo(ast->name) << line << column << length; } -void CheckSymbols::addType(const QList<LookupItem> &candidates, NameAST *ast) +void CheckSymbols::addTypeOrStatic(const QList<LookupItem> &candidates, NameAST *ast) { unsigned startToken = ast->firstToken(); if (DestructorNameAST *dtor = ast->asDestructorName()) @@ -841,13 +876,18 @@ void CheckSymbols::addType(const QList<LookupItem> &candidates, NameAST *ast) continue; else if (c->isTypedef() || c->isNamespace() || c->isClass() || c->isEnum() || - c->isForwardClassDeclaration() || c->isTypenameArgument()) { + c->isForwardClassDeclaration() || c->isTypenameArgument() || c->enclosingEnumScope() != 0) { unsigned line, column; getTokenStartPosition(startToken, &line, &column); const unsigned length = tok.length(); - const Use use(line, column, length, Use::Type); + Use::Kind kind = Use::Type; + + if (c->enclosingEnumScope() != 0) + kind = Use::Static; + + const Use use(line, column, length, kind); addUse(use); //qDebug() << "added use" << oo(ast->name) << line << column << length; break; @@ -886,6 +926,33 @@ void CheckSymbols::addClassMember(const QList<LookupItem> &candidates, NameAST * } } +void CheckSymbols::addStatic(const QList<LookupItem> &candidates, NameAST *ast) +{ + if (ast->asDestructorName() != 0) + return; + + unsigned startToken = ast->firstToken(); + const Token &tok = tokenAt(startToken); + if (tok.generated()) + return; + + foreach (const LookupItem &r, candidates) { + Symbol *c = r.declaration(); + if (! c) + return; + if (c->scope()->isEnumScope()) { + unsigned line, column; + getTokenStartPosition(startToken, &line, &column); + const unsigned length = tok.length(); + + const Use use(line, column, length, Use::Static); + addUse(use); + //qDebug() << "added use" << oo(ast->name) << line << column << length; + break; + } + } +} + void CheckSymbols::addVirtualMethod(const QList<LookupItem> &candidates, NameAST *ast, unsigned argumentCount) { unsigned startToken = ast->firstToken(); @@ -962,6 +1029,19 @@ bool CheckSymbols::maybeMember(const Name *name) const return false; } +bool CheckSymbols::maybeStatic(const Name *name) const +{ + if (name) { + if (const Identifier *ident = name->identifier()) { + const QByteArray id = QByteArray::fromRawData(ident->chars(), ident->size()); + if (_potentialStatics.contains(id)) + return true; + } + } + + return false; +} + bool CheckSymbols::maybeVirtualMethod(const Name *name) const { if (name) { diff --git a/src/plugins/cppeditor/cppchecksymbols.h b/src/plugins/cppeditor/cppchecksymbols.h index f0a5543e6162fb36a01da4bc820005f1b3059e33..e07a7e6631f6d5ff63f91d54dda05a05c77cc811 100644 --- a/src/plugins/cppeditor/cppchecksymbols.h +++ b/src/plugins/cppeditor/cppchecksymbols.h @@ -100,17 +100,20 @@ protected: bool maybeType(const Name *name) const; bool maybeMember(const Name *name) const; + bool maybeStatic(const Name *name) const; bool maybeVirtualMethod(const Name *name) const; void checkName(NameAST *ast, Scope *scope = 0); void checkNamespace(NameAST *name); void addUse(const Use &use); + void addUse(unsigned tokenIndex, Use::Kind kind); void addUse(NameAST *name, Use::Kind kind); void addType(ClassOrNamespace *b, NameAST *ast); - void addType(const QList<LookupItem> &candidates, NameAST *ast); + void addTypeOrStatic(const QList<LookupItem> &candidates, NameAST *ast); + void addStatic(const QList<LookupItem> &candidates, NameAST *ast); void addClassMember(const QList<LookupItem> &candidates, NameAST *ast); void addVirtualMethod(const QList<LookupItem> &candidates, NameAST *ast, unsigned argumentCount); @@ -126,6 +129,8 @@ protected: virtual bool visit(SimpleDeclarationAST *); virtual bool visit(NamedTypeSpecifierAST *); + virtual bool visit(EnumeratorAST *); + virtual bool visit(SimpleNameAST *ast); virtual bool visit(DestructorNameAST *ast); virtual bool visit(QualifiedNameAST *ast); @@ -153,6 +158,7 @@ private: QSet<QByteArray> _potentialTypes; QSet<QByteArray> _potentialMembers; QSet<QByteArray> _potentialVirtualMethods; + QSet<QByteArray> _potentialStatics; QList<AST *> _astStack; QVector<Use> _usages; bool _flushRequested; diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 0ee0327d2604cc9637139b459b5cea5d218d8cf9..b7e95c19a2a8062efb0e57af7346860eb6b2f87e 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -1017,6 +1017,10 @@ void CPPEditor::highlightSymbolUsages(int from, int to) formatRange.format = m_localFormat; break; + case SemanticInfo::Use::Static: + formatRange.format = m_staticFormat; + break; + case SemanticInfo::Use::VirtualMethod: formatRange.format = m_virtualMethodFormat; break; @@ -1741,8 +1745,9 @@ void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs) m_typeFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_TYPE)); m_localFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_LOCAL)); m_fieldFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_FIELD)); - m_keywordFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_KEYWORD)); + m_staticFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_STATIC)); m_virtualMethodFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_VIRTUAL_METHOD)); + m_keywordFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_KEYWORD)); // only set the background, we do not want to modify foreground properties set by the syntax highlighter or the link m_occurrencesFormat.clearForeground(); diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 78552b6cda37de9ff675c3a30e8d0bab2ae0c6de..40fe6b1e6cc5df9c3bdf8200bcc3860e0dc7a333 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -290,6 +290,7 @@ private: QTextCharFormat m_typeFormat; QTextCharFormat m_localFormat; QTextCharFormat m_fieldFormat; + QTextCharFormat m_staticFormat; QTextCharFormat m_keywordFormat; QTextCharFormat m_virtualMethodFormat; diff --git a/src/plugins/cppeditor/cppsemanticinfo.h b/src/plugins/cppeditor/cppsemanticinfo.h index 1bafa6703f15d203f04dc309b4f3ba53e84476d0..06ac65b99f2bce29424c885063df84b309be43b7 100644 --- a/src/plugins/cppeditor/cppsemanticinfo.h +++ b/src/plugins/cppeditor/cppsemanticinfo.h @@ -52,6 +52,7 @@ public: Type = 0, Local, Field, + Static, VirtualMethod }; diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index c3d30ddcc5f57ac6c809d0cba254d4c2b08535e0..40a8034dd7adcf75d38a7d1c6fc6231760b020d3 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -110,6 +110,7 @@ const char * const C_STRING = "String"; const char * const C_TYPE = "Type"; const char * const C_LOCAL = "Local"; const char * const C_FIELD = "Field"; +const char * const C_STATIC = "Static"; const char * const C_VIRTUAL_METHOD = "VirtualMethod"; const char * const C_KEYWORD = "Keyword"; const char * const C_OPERATOR = "Operator"; diff --git a/src/plugins/texteditor/texteditorsettings.cpp b/src/plugins/texteditor/texteditorsettings.cpp index 5c72323fee2ce8feb215300eb452879275321326..da0d8965ce7cbe289ce41c5eb823903d621bac63 100644 --- a/src/plugins/texteditor/texteditorsettings.cpp +++ b/src/plugins/texteditor/texteditorsettings.cpp @@ -128,6 +128,7 @@ TextEditorSettings::TextEditorSettings(QObject *parent) formatDescriptions.append(FormatDescription(QLatin1String(C_TYPE), tr("Type"), Qt::darkMagenta)); formatDescriptions.append(FormatDescription(QLatin1String(C_LOCAL), tr("Local"))); formatDescriptions.append(FormatDescription(QLatin1String(C_FIELD), tr("Field"), Qt::darkRed)); + formatDescriptions.append(FormatDescription(QLatin1String(C_STATIC), tr("Static"), Qt::darkMagenta)); FormatDescription virtualMethodFormatDescriptor(QLatin1String(C_VIRTUAL_METHOD), tr("Virtual Method")); virtualMethodFormatDescriptor.format().setItalic(true);