summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorChristian Kamm <christian.d.kamm@nokia.com>2009-12-21 14:54:10 +0100
committerChristian Kamm <christian.d.kamm@nokia.com>2009-12-21 14:57:05 +0100
commitf90f9e487961752919e87b4eaea5ef62279ead08 (patch)
tree7ce07c6be6c21af0c52ee556c876c25a478d868a /src/plugins
parentc3cc7cf4d8060af224ebf8ffe0f06a6f5e0d4eeb (diff)
downloadqt-creator-f90f9e487961752919e87b4eaea5ef62279ead08.tar.gz
Find macro uses.
Reviewed-by: Erik Verbruggen
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/cppeditor/cppeditor.cpp19
-rw-r--r--src/plugins/cppeditor/cppeditor.h2
-rw-r--r--src/plugins/cpptools/cppfindreferences.cpp148
-rw-r--r--src/plugins/cpptools/cppfindreferences.h2
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp5
-rw-r--r--src/plugins/cpptools/cppmodelmanager.h2
-rw-r--r--src/plugins/cpptools/cppmodelmanagerinterface.h2
7 files changed, 168 insertions, 12 deletions
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index c45f86834c..8702f9e496 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -861,11 +861,30 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor,
return canonicalSymbol;
}
+const Macro *CPPEditor::findCanonicalMacro(const QTextCursor &cursor,
+ Document::Ptr doc) const
+{
+ if (! doc)
+ return 0;
+
+ int line, col;
+ convertPosition(cursor.position(), &line, &col);
+
+ if (const Macro *macro = doc->findMacroDefinitionAt(line))
+ return macro;
+
+ if (const Document::MacroUse *use = doc->findMacroUseAt(cursor.position()))
+ return &use->macro();
+
+ return 0;
+}
void CPPEditor::findUsages()
{
if (Symbol *canonicalSymbol = markSymbols()) {
m_modelManager->findUsages(canonicalSymbol);
+ } else if (const Macro *macro = findCanonicalMacro(textCursor(), m_lastSemanticInfo.doc)) {
+ m_modelManager->findMacroUsages(*macro);
}
}
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index b7ac5512cf..38f14c141a 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -227,6 +227,8 @@ protected:
CPlusPlus::Symbol *findCanonicalSymbol(const QTextCursor &cursor,
CPlusPlus::Document::Ptr doc,
const CPlusPlus::Snapshot &snapshot) const;
+ const CPlusPlus::Macro *findCanonicalMacro(const QTextCursor &cursor,
+ CPlusPlus::Document::Ptr doc) const;
private Q_SLOTS:
void updateFileName();
diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp
index 60efaf7784..699e7b72c3 100644
--- a/src/plugins/cpptools/cppfindreferences.cpp
+++ b/src/plugins/cpptools/cppfindreferences.cpp
@@ -65,6 +65,20 @@
using namespace CppTools::Internal;
using namespace CPlusPlus;
+static QString getSource(const QString &fileName,
+ const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy)
+{
+ if (workingCopy.contains(fileName)) {
+ return workingCopy.source(fileName);
+ } else {
+ QFile file(fileName);
+ if (! file.open(QFile::ReadOnly))
+ return QString();
+
+ return QTextStream(&file).readAll(); // ### FIXME
+ }
+}
+
namespace {
class ProcessFile: public std::unary_function<QString, QList<Usage> >
@@ -91,18 +105,8 @@ public:
return usages; // skip this document, it's not using symbolId.
}
- QByteArray source;
-
- if (workingCopy.contains(fileName))
- source = snapshot.preprocessedCode(workingCopy.source(fileName), fileName);
- else {
- QFile file(fileName);
- if (! file.open(QFile::ReadOnly))
- return usages;
-
- const QString contents = QTextStream(&file).readAll(); // ### FIXME
- source = snapshot.preprocessedCode(contents, fileName);
- }
+ QByteArray source = snapshot.preprocessedCode(
+ getSource(fileName, workingCopy), fileName);
Document::Ptr doc = snapshot.documentFromSource(source, fileName);
doc->tokenize();
@@ -294,3 +298,123 @@ void CppFindReferences::openEditor(const Find::SearchResultItem &item)
TextEditor::BaseTextEditor::openEditorAt(item.fileName, item.lineNumber, item.searchTermStart);
}
+
+namespace {
+
+class FindMacroUsesInFile: public std::unary_function<QString, QList<Usage> >
+{
+ const CppTools::CppModelManagerInterface::WorkingCopy workingCopy;
+ const Snapshot snapshot;
+ const Macro &macro;
+
+public:
+ FindMacroUsesInFile(const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy,
+ const Snapshot snapshot,
+ const Macro &macro)
+ : workingCopy(workingCopy), snapshot(snapshot), macro(macro)
+ { }
+
+ QList<Usage> operator()(const QString &fileName)
+ {
+ QList<Usage> usages;
+
+ const Document::Ptr &doc = snapshot.document(fileName);
+ QByteArray source;
+
+ foreach (const Document::MacroUse &use, doc->macroUses()) {
+ const Macro &useMacro = use.macro();
+ if (useMacro.line() == macro.line()
+ && useMacro.fileName() == macro.fileName())
+ {
+ if (source.isEmpty())
+ source = getSource(fileName, workingCopy).toLatin1(); // ### FIXME: Encoding?
+
+ unsigned lineStart;
+ const QString &lineSource = matchingLine(use.begin(), source, &lineStart);
+ usages.append(Usage(fileName, lineSource, use.beginLine(),
+ use.begin() - lineStart, use.length()));
+ }
+ }
+
+ return usages;
+ }
+
+ // ### FIXME: Pretty close to FindUsages::matchingLine.
+ static QString matchingLine(unsigned position, const QByteArray &source,
+ unsigned *lineStart = 0)
+ {
+ const char *beg = source.constData();
+ const char *start = beg + position;
+ for (; start != beg - 1; --start) {
+ if (*start == '\n')
+ break;
+ }
+
+ ++start;
+
+ const char *end = start + 1;
+ for (; *end; ++end) {
+ if (*end == '\n')
+ break;
+ }
+
+ if (lineStart)
+ *lineStart = start - beg;
+
+ // ### FIXME: Encoding?
+ const QString matchingLine = QString::fromUtf8(start, end - start);
+ return matchingLine;
+ }
+};
+
+} // end of anonymous namespace
+
+static void findMacroUses_helper(QFutureInterface<Usage> &future,
+ const CppTools::CppModelManagerInterface::WorkingCopy workingCopy,
+ const Snapshot snapshot,
+ const Macro macro)
+{
+ const QString& sourceFile = macro.fileName();
+ QStringList files(sourceFile);
+ files += snapshot.filesDependingOn(sourceFile);
+ files.removeDuplicates();
+
+ future.setProgressRange(0, files.size());
+
+ FindMacroUsesInFile process(workingCopy, snapshot, macro);
+ UpdateUI reduce(&future);
+ QtConcurrent::blockingMappedReduced<QList<Usage> > (files, process, reduce);
+
+ future.setProgressValue(files.size());
+}
+
+void CppFindReferences::findMacroUses(const Macro &macro)
+{
+ Find::SearchResult *search = _resultWindow->startNewSearch(Find::SearchResultWindow::SearchOnly);
+
+ _resultWindow->popup(true);
+
+ connect(search, SIGNAL(activated(Find::SearchResultItem)),
+ this, SLOT(openEditor(Find::SearchResultItem)));
+
+ const Snapshot snapshot = _modelManager->snapshot();
+ const CppTools::CppModelManagerInterface::WorkingCopy workingCopy = _modelManager->workingCopy();
+
+ // add the macro definition itself
+ {
+ // ### FIXME: Encoding?
+ const QByteArray &source = getSource(macro.fileName(), workingCopy).toLatin1();
+ _resultWindow->addResult(macro.fileName(), macro.line(),
+ source.mid(macro.offset(), macro.length()), 0, macro.length());
+ }
+
+ QFuture<Usage> result;
+ result = QtConcurrent::run(&findMacroUses_helper, workingCopy, snapshot, macro);
+ m_watcher.setFuture(result);
+
+ Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
+ Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."),
+ CppTools::Constants::TASK_SEARCH);
+ connect(progress, SIGNAL(clicked()), _resultWindow, SLOT(popup()));
+}
+
diff --git a/src/plugins/cpptools/cppfindreferences.h b/src/plugins/cpptools/cppfindreferences.h
index 5425e4988d..a978103898 100644
--- a/src/plugins/cpptools/cppfindreferences.h
+++ b/src/plugins/cpptools/cppfindreferences.h
@@ -67,6 +67,8 @@ public:
void findUsages(CPlusPlus::Symbol *symbol);
void renameUsages(CPlusPlus::Symbol *symbol);
+ void findMacroUses(const CPlusPlus::Macro &macro);
+
private Q_SLOTS:
void displayResults(int first, int last);
void searchFinished();
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index a31ed64df5..6f7245072f 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -792,6 +792,11 @@ void CppModelManager::renameUsages(CPlusPlus::Symbol *symbol)
m_findReferences->renameUsages(symbol);
}
+void CppModelManager::findMacroUsages(const CPlusPlus::Macro &macro)
+{
+ m_findReferences->findMacroUses(macro);
+}
+
CppModelManager::WorkingCopy CppModelManager::buildWorkingCopyList()
{
WorkingCopy workingCopy;
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index f5f445d605..bd5b7c0768 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -108,6 +108,8 @@ public:
virtual void findUsages(CPlusPlus::Symbol *symbol);
virtual void renameUsages(CPlusPlus::Symbol *symbol);
+ virtual void findMacroUsages(const CPlusPlus::Macro &macro);
+
void setHeaderSuffixes(const QStringList &suffixes)
{ m_headerSuffixes = suffixes; }
diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h
index 8db6b02b71..9b9e3dd3cd 100644
--- a/src/plugins/cpptools/cppmodelmanagerinterface.h
+++ b/src/plugins/cpptools/cppmodelmanagerinterface.h
@@ -123,6 +123,8 @@ public:
virtual void renameUsages(CPlusPlus::Symbol *symbol) = 0;
virtual void findUsages(CPlusPlus::Symbol *symbol) = 0;
+ virtual void findMacroUsages(const CPlusPlus::Macro &macro) = 0;
+
public Q_SLOTS:
void updateModifiedSourceFiles();
virtual void updateSourceFiles(const QStringList &sourceFiles) = 0;