diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index b18cc1dacb9..b8408557db1 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -1743,6 +1743,8 @@ void CPPEditorWidget::setFontSettings(const TextEditor::FontSettings &fs) fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_VIRTUAL_METHOD)); m_semanticHighlightFormatMap[SemanticInfo::LabelUse] = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_LABEL)); + m_semanticHighlightFormatMap[SemanticInfo::MacroUse] = + fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_PREPROCESSOR)); 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 diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp index 406d9b94678..b0bdb679c89 100644 --- a/src/plugins/cppeditor/cpphighlighter.cpp +++ b/src/plugins/cppeditor/cpphighlighter.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -199,7 +200,7 @@ void CppHighlighter::highlightBlock(const QString &text) initialState = 0; } - } else if (tk.isKeyword() || isQtKeyword(text.midRef(tk.begin(), tk.length())) || tk.isObjCAtKeyword()) + } else if (tk.isKeyword() || CppTools::isQtKeyword(text.midRef(tk.begin(), tk.length())) || tk.isObjCAtKeyword()) setFormat(tk.begin(), tk.length(), m_formats[CppKeywordFormat]); else if (tk.isOperator()) @@ -338,51 +339,6 @@ bool CppHighlighter::isPPKeyword(const QStringRef &text) const return false; } -bool CppHighlighter::isQtKeyword(const QStringRef &text) const -{ - switch (text.length()) { - case 4: - switch (text.at(0).toLatin1()) { - case 'e': - if (text == QLatin1String("emit")) - return true; - break; - case 'S': - if (text == QLatin1String("SLOT")) - return true; - break; - } - break; - - case 5: - if (text.at(0) == QLatin1Char('s') && text == QLatin1String("slots")) - return true; - break; - - case 6: - if (text.at(0) == QLatin1Char('S') && text == QLatin1String("SIGNAL")) - return true; - break; - - case 7: - switch (text.at(0).toLatin1()) { - case 's': - if (text == QLatin1String("signals")) - return true; - break; - case 'f': - if (text == QLatin1String("foreach") || text == QLatin1String("forever")) - return true; - break; - } - break; - - default: - break; - } - return false; -} - void CppHighlighter::highlightLine(const QString &text, int position, int length, const QTextCharFormat &format) { diff --git a/src/plugins/cppeditor/cpphighlighter.h b/src/plugins/cppeditor/cpphighlighter.h index ac79df8114f..b1b059cfbec 100644 --- a/src/plugins/cppeditor/cpphighlighter.h +++ b/src/plugins/cppeditor/cpphighlighter.h @@ -68,7 +68,6 @@ private: int length); bool isPPKeyword(const QStringRef &text) const; - bool isQtKeyword(const QStringRef &text) const; QTextCharFormat m_formats[NumCppFormats]; }; diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp index a2d1d6dcf07..f7bbb988855 100644 --- a/src/plugins/cpptools/cppchecksymbols.cpp +++ b/src/plugins/cpptools/cppchecksymbols.cpp @@ -33,7 +33,7 @@ #include "cppchecksymbols.h" #include "cpplocalsymbols.h" -#include +#include #include #include @@ -284,16 +284,21 @@ protected: } // end of anonymous namespace -CheckSymbols::Future CheckSymbols::go(Document::Ptr doc, const LookupContext &context) +static bool sortByLinePredicate(const CheckSymbols::Use &lhs, const CheckSymbols::Use &rhs) +{ + return lhs.line < rhs.line; +} + +CheckSymbols::Future CheckSymbols::go(Document::Ptr doc, const LookupContext &context, const QList ¯oUses) { QTC_ASSERT(doc, return Future()); - return (new CheckSymbols(doc, context))->start(); + return (new CheckSymbols(doc, context, macroUses))->start(); } -CheckSymbols::CheckSymbols(Document::Ptr doc, const LookupContext &context) +CheckSymbols::CheckSymbols(Document::Ptr doc, const LookupContext &context, const QList ¯oUses) : ASTVisitor(doc->translationUnit()), _doc(doc), _context(context) - , _lineOfLastUsage(0) + , _lineOfLastUsage(0), _macroUses(macroUses) { CollectSymbols collectTypes(doc, context.snapshot()); @@ -311,11 +316,13 @@ CheckSymbols::~CheckSymbols() void CheckSymbols::run() { + qSort(_macroUses.begin(), _macroUses.end(), sortByLinePredicate); _diagnosticMessages.clear(); if (! isCanceled()) { if (_doc->translationUnit()) { accept(_doc->translationUnit()->ast()); + _usages << QVector::fromList(_macroUses); flush(); } } @@ -876,6 +883,9 @@ void CheckSymbols::addUse(const Use &use) } } + while (!_macroUses.isEmpty() && _macroUses.first().line <= use.line) + _usages.append(_macroUses.takeFirst()); + _lineOfLastUsage = qMax(_lineOfLastUsage, use.line); _usages.append(use); } @@ -1115,11 +1125,6 @@ bool CheckSymbols::maybeVirtualMethod(const Name *name) const return false; } -static bool sortByLinePredicate(const CheckSymbols::Use &lhs, const CheckSymbols::Use &rhs) -{ - return lhs.line < rhs.line; -} - void CheckSymbols::flush() { _lineOfLastUsage = 0; diff --git a/src/plugins/cpptools/cppchecksymbols.h b/src/plugins/cpptools/cppchecksymbols.h index 56dfc541f5e..5e134e6c73f 100644 --- a/src/plugins/cpptools/cppchecksymbols.h +++ b/src/plugins/cpptools/cppchecksymbols.h @@ -72,7 +72,7 @@ public: return future; } - static Future go(Document::Ptr doc, const LookupContext &context); + static Future go(Document::Ptr doc, const LookupContext &context, const QList ¯oUses); static QMap > chunks(const QFuture &future, int from, int to) { @@ -94,7 +94,7 @@ protected: using ASTVisitor::visit; using ASTVisitor::endVisit; - CheckSymbols(Document::Ptr doc, const LookupContext &context); + CheckSymbols(Document::Ptr doc, const LookupContext &context, const QList ¯oUses); bool hasVirtualDestructor(Class *klass) const; bool hasVirtualDestructor(ClassOrNamespace *binding) const; @@ -174,6 +174,7 @@ private: QList _astStack; QVector _usages; unsigned _lineOfLastUsage; + QList _macroUses; }; } // namespace CPlusPlus diff --git a/src/plugins/cpptools/cpphighlightingsupportinternal.cpp b/src/plugins/cpptools/cpphighlightingsupportinternal.cpp index f9cfcecaa7e..4b62a06999d 100644 --- a/src/plugins/cpptools/cpphighlightingsupportinternal.cpp +++ b/src/plugins/cpptools/cpphighlightingsupportinternal.cpp @@ -34,6 +34,10 @@ #include "cpphighlightingsupportinternal.h" #include +#include +#include +#include +#include using namespace CPlusPlus; using namespace CppTools; @@ -52,8 +56,32 @@ QFuture CppHighlightingSupportInternal::highlightin const Document::Ptr &doc, const Snapshot &snapshot) const { + //Get macro uses + QList macroUses; + foreach (Document::MacroUse macro, doc->macroUses()) { + const QString name = QString::fromUtf8(macro.macro().name()); + + //Filter out QtKeywords + if (isQtKeyword(QStringRef(&name))) + continue; + + //Filter out C++ keywords + SimpleLexer tokenize; + tokenize.setQtMocRunEnabled(false); + tokenize.setObjCEnabled(false); + const QList tokens = tokenize(name); + if (tokens.length() && (tokens.at(0).isKeyword() || tokens.at(0).isObjCAtKeyword())) + continue; + + int line, column; + editor()->convertPosition(macro.begin(), &line, &column); + ++column; //Highlighting starts at (column-1) --> compensate here + CheckSymbols::Use use(line, column, name.size(), SemanticInfo::MacroUse); + macroUses.append(use); + } + LookupContext context(doc, snapshot); - return CheckSymbols::go(doc, context); + return CheckSymbols::go(doc, context, macroUses); } CppHighlightingSupportInternalFactory::~CppHighlightingSupportInternalFactory() diff --git a/src/plugins/cpptools/cppsemanticinfo.h b/src/plugins/cpptools/cppsemanticinfo.h index cf61b745592..f7adb15d18b 100644 --- a/src/plugins/cpptools/cppsemanticinfo.h +++ b/src/plugins/cpptools/cppsemanticinfo.h @@ -52,7 +52,8 @@ public: FieldUse, StaticUse, VirtualMethodUse, - LabelUse + LabelUse, + MacroUse }; typedef TextEditor::SemanticHighlighter::Result Use; diff --git a/src/plugins/cpptools/cpptoolsreuse.cpp b/src/plugins/cpptools/cpptoolsreuse.cpp index 305e84aded9..81eb9986d63 100644 --- a/src/plugins/cpptools/cpptoolsreuse.cpp +++ b/src/plugins/cpptools/cpptoolsreuse.cpp @@ -40,6 +40,7 @@ #include #include #include +#include using namespace CPlusPlus; @@ -131,5 +132,49 @@ bool isValidIdentifier(const QString &s) return true; } +bool isQtKeyword(const QStringRef &text) +{ + switch (text.length()) { + case 4: + switch (text.at(0).toLatin1()) { + case 'e': + if (text == QLatin1String("emit")) + return true; + break; + case 'S': + if (text == QLatin1String("SLOT")) + return true; + break; + } + break; + + case 5: + if (text.at(0) == QLatin1Char('s') && text == QLatin1String("slots")) + return true; + break; + + case 6: + if (text.at(0) == QLatin1Char('S') && text == QLatin1String("SIGNAL")) + return true; + break; + + case 7: + switch (text.at(0).toLatin1()) { + case 's': + if (text == QLatin1String("signals")) + return true; + break; + case 'f': + if (text == QLatin1String("foreach") || text == QLatin1String("forever")) + return true; + break; + } + break; + + default: + break; + } + return false; +} } // CppTools diff --git a/src/plugins/cpptools/cpptoolsreuse.h b/src/plugins/cpptools/cpptoolsreuse.h index 6bdfb1bec64..d914aeb9f14 100644 --- a/src/plugins/cpptools/cpptoolsreuse.h +++ b/src/plugins/cpptools/cpptoolsreuse.h @@ -36,6 +36,7 @@ #include "cpptools_global.h" QT_FORWARD_DECLARE_CLASS(QTextCursor) +QT_FORWARD_DECLARE_CLASS(QStringRef) namespace CPlusPlus { class Symbol; @@ -52,6 +53,8 @@ bool CPPTOOLS_EXPORT isOwnershipRAIIType(CPlusPlus::Symbol *symbol, bool CPPTOOLS_EXPORT isValidIdentifier(const QString &s); +bool CPPTOOLS_EXPORT isQtKeyword(const QStringRef &text); + } // CppTools #endif // CPPTOOLSREUSE_H