From 3d3802d50f1bbcab599fc1da87979a22cdb8ffe5 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <qtc-committer@nokia.com>
Date: Thu, 4 Dec 2008 12:05:04 +0100
Subject: [PATCH] Added macro expanding events and some initial on the macro
 highlighting support.

---
 src/libs/cplusplus/CppDocument.cpp       |  5 ++++
 src/libs/cplusplus/CppDocument.h         |  6 ++++
 src/plugins/cpptools/cppmodelmanager.cpp | 35 ++++++++++++++++++++++++
 src/plugins/cpptools/rpp/pp-client.h     |  9 ++++++
 src/plugins/cpptools/rpp/pp-engine.cpp   | 34 +++++++++++++++++++++--
 5 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index 782c14ff6d5..3a280416d9b 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -153,6 +153,11 @@ void Document::appendMacro(const QByteArray &macroName, const QByteArray &text)
     _definedMacros += text;
 }
 
+void Document::addMacroUse(unsigned offset, unsigned length)
+{
+    _macroUses.append(Block(offset, offset + length));
+}
+
 TranslationUnit *Document::translationUnit() const
 {
     return _translationUnit;
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index 17762200fa0..e952913a07b 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -68,6 +68,8 @@ public:
 
     void appendMacro(const QByteArray &macroName, const QByteArray &text);
 
+    void addMacroUse(unsigned offset, unsigned length);
+
     Control *control() const;
     TranslationUnit *translationUnit() const;
 
@@ -176,6 +178,9 @@ public:
     QList<Block> skippedBlocks() const
     { return _skippedBlocks; }
 
+    QList<Block> macroUses() const
+    { return _macroUses; }
+
 private:
     Symbol *findSymbolAt(unsigned line, unsigned column, Scope *scope) const;
 
@@ -189,6 +194,7 @@ private:
     QByteArray _definedMacros;
     QSet<QByteArray> _macroNames;
     QList<Block> _skippedBlocks;
+    QList<Block> _macroUses;
 };
 
 } // end of namespace CPlusPlus
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 313ea7f21ff..ccaff0bcfe5 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -253,6 +253,25 @@ protected:
         m_currentDoc->appendMacro(macroName, macroText);
     }
 
+    virtual void startExpandingMacro(unsigned offset,
+                                     const rpp::Macro &macro,
+                                     const QByteArray &originalText)
+    {
+        if (! m_currentDoc)
+            return;
+
+        //qDebug() << "start expanding:" << macro.name << "text:" << originalText;
+        m_currentDoc->addMacroUse(offset, originalText.length());
+    }
+
+    virtual void stopExpandingMacro(unsigned offset, const rpp::Macro &macro)
+    {
+        if (! m_currentDoc)
+            return;
+
+        //qDebug() << "stop expanding:" << macro.name;
+    }
+
     void mergeEnvironment(Document::Ptr doc)
     {
         QSet<QString> processed;
@@ -595,6 +614,22 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
 
             QList<QTextEdit::ExtraSelection> selections;
 
+#ifdef QTCREATOR_WITH_MACRO_HIGHLIGHTING
+            // set up the format for the macros
+            QTextCharFormat macroFormat;
+            macroFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+
+            QTextCursor c = ed->textCursor();
+            foreach (const Document::Block block, doc->macroUses()) {
+                QTextEdit::ExtraSelection sel;
+                sel.cursor = c;
+                sel.cursor.setPosition(block.begin());
+                sel.cursor.setPosition(block.end(), QTextCursor::KeepAnchor);
+                sel.format = macroFormat;
+                selections.append(sel);
+            }
+#endif // QTCREATOR_WITH_MACRO_HIGHLIGHTING
+
             // set up the format for the errors
             QTextCharFormat errorFormat;
             errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
diff --git a/src/plugins/cpptools/rpp/pp-client.h b/src/plugins/cpptools/rpp/pp-client.h
index 073fc44c362..974004a6ce5 100644
--- a/src/plugins/cpptools/rpp/pp-client.h
+++ b/src/plugins/cpptools/rpp/pp-client.h
@@ -40,6 +40,8 @@
 
 namespace rpp {
 
+class Macro;
+
 class Client
 {
   Client(const Client &other);
@@ -61,6 +63,13 @@ public:
   virtual void macroAdded(const QByteArray &macroId, const QByteArray &text) = 0;
   virtual void sourceNeeded(QString &fileName, IncludeType mode) = 0; // ### FIX the signature.
 
+  virtual void startExpandingMacro(unsigned offset,
+                                   const Macro &macro,
+                                   const QByteArray &originalTextt) = 0;
+
+  virtual void stopExpandingMacro(unsigned offset,
+                                  const Macro &macro) = 0;
+
   virtual void startSkippingBlocks(unsigned offset) = 0;
   virtual void stopSkippingBlocks(unsigned offset) = 0;
 };
diff --git a/src/plugins/cpptools/rpp/pp-engine.cpp b/src/plugins/cpptools/rpp/pp-engine.cpp
index 3a3e9245b30..2fa6e4ba67f 100644
--- a/src/plugins/cpptools/rpp/pp-engine.cpp
+++ b/src/plugins/cpptools/rpp/pp-engine.cpp
@@ -575,7 +575,17 @@ void pp::operator()(const QByteArray &source, QByteArray *result)
 
                 const QByteArray spell = tokenSpell(*identifierToken);
                 if (env.isBuiltinMacro(spell)) {
+                    const Macro trivial;
+
+                    if (client)
+                        client->startExpandingMacro(identifierToken->offset,
+                                                    trivial, spell);
+
                     expand(spell.constBegin(), spell.constEnd(), result);
+
+                    if (client)
+                        client->stopExpandingMacro(_dot->offset, trivial);
+
                     continue;
                 }
 
@@ -585,10 +595,19 @@ void pp::operator()(const QByteArray &source, QByteArray *result)
                 } else {
                     if (! m->function_like) {
                         if (_dot->isNot(T_LPAREN)) {
+                            if (client)
+                                client->startExpandingMacro(identifierToken->offset,
+                                                            *m, spell);
+
                             m->hidden = true;
+
                             expand(m->definition.constBegin(),
                                    m->definition.constEnd(),
                                    result);
+
+                            if (client)
+                                client->stopExpandingMacro(_dot->offset, *m);
+
                             m->hidden = false;
                             continue;
                         } else {
@@ -640,9 +659,20 @@ void pp::operator()(const QByteArray &source, QByteArray *result)
                         const char *beginOfText = startOfToken(*identifierToken);
                         const char *endOfText = endOfToken(*_dot);
                         ++_dot; // skip T_RPAREN
-                        //m->hidden = true;
+
+                        if (client) {
+                            const QByteArray text =
+                                    QByteArray::fromRawData(beginOfText,
+                                                            endOfText - beginOfText);
+
+                            client->startExpandingMacro(identifierToken->offset,
+                                                        *m, text);
+                        }
+
                         expand(beginOfText, endOfText, result);
-                        //m->hidden = false;
+
+                        if (client)
+                            client->stopExpandingMacro(_dot->offset, *m);
                     }
                 }
             }
-- 
GitLab