forked from qt-creator/qt-creator
Find macro uses.
Reviewed-by: Erik Verbruggen
This commit is contained in:
@@ -861,11 +861,30 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor,
|
|||||||
return canonicalSymbol;
|
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()
|
void CPPEditor::findUsages()
|
||||||
{
|
{
|
||||||
if (Symbol *canonicalSymbol = markSymbols()) {
|
if (Symbol *canonicalSymbol = markSymbols()) {
|
||||||
m_modelManager->findUsages(canonicalSymbol);
|
m_modelManager->findUsages(canonicalSymbol);
|
||||||
|
} else if (const Macro *macro = findCanonicalMacro(textCursor(), m_lastSemanticInfo.doc)) {
|
||||||
|
m_modelManager->findMacroUsages(*macro);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -227,6 +227,8 @@ protected:
|
|||||||
CPlusPlus::Symbol *findCanonicalSymbol(const QTextCursor &cursor,
|
CPlusPlus::Symbol *findCanonicalSymbol(const QTextCursor &cursor,
|
||||||
CPlusPlus::Document::Ptr doc,
|
CPlusPlus::Document::Ptr doc,
|
||||||
const CPlusPlus::Snapshot &snapshot) const;
|
const CPlusPlus::Snapshot &snapshot) const;
|
||||||
|
const CPlusPlus::Macro *findCanonicalMacro(const QTextCursor &cursor,
|
||||||
|
CPlusPlus::Document::Ptr doc) const;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void updateFileName();
|
void updateFileName();
|
||||||
|
|||||||
@@ -65,6 +65,20 @@
|
|||||||
using namespace CppTools::Internal;
|
using namespace CppTools::Internal;
|
||||||
using namespace CPlusPlus;
|
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 {
|
namespace {
|
||||||
|
|
||||||
class ProcessFile: public std::unary_function<QString, QList<Usage> >
|
class ProcessFile: public std::unary_function<QString, QList<Usage> >
|
||||||
@@ -91,18 +105,8 @@ public:
|
|||||||
return usages; // skip this document, it's not using symbolId.
|
return usages; // skip this document, it's not using symbolId.
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray source;
|
QByteArray source = snapshot.preprocessedCode(
|
||||||
|
getSource(fileName, workingCopy), fileName);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Document::Ptr doc = snapshot.documentFromSource(source, fileName);
|
Document::Ptr doc = snapshot.documentFromSource(source, fileName);
|
||||||
doc->tokenize();
|
doc->tokenize();
|
||||||
@@ -294,3 +298,123 @@ void CppFindReferences::openEditor(const Find::SearchResultItem &item)
|
|||||||
TextEditor::BaseTextEditor::openEditorAt(item.fileName, item.lineNumber, item.searchTermStart);
|
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 ¯o;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FindMacroUsesInFile(const CppTools::CppModelManagerInterface::WorkingCopy &workingCopy,
|
||||||
|
const Snapshot snapshot,
|
||||||
|
const Macro ¯o)
|
||||||
|
: 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 ¯o)
|
||||||
|
{
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ public:
|
|||||||
void findUsages(CPlusPlus::Symbol *symbol);
|
void findUsages(CPlusPlus::Symbol *symbol);
|
||||||
void renameUsages(CPlusPlus::Symbol *symbol);
|
void renameUsages(CPlusPlus::Symbol *symbol);
|
||||||
|
|
||||||
|
void findMacroUses(const CPlusPlus::Macro ¯o);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void displayResults(int first, int last);
|
void displayResults(int first, int last);
|
||||||
void searchFinished();
|
void searchFinished();
|
||||||
|
|||||||
@@ -792,6 +792,11 @@ void CppModelManager::renameUsages(CPlusPlus::Symbol *symbol)
|
|||||||
m_findReferences->renameUsages(symbol);
|
m_findReferences->renameUsages(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CppModelManager::findMacroUsages(const CPlusPlus::Macro ¯o)
|
||||||
|
{
|
||||||
|
m_findReferences->findMacroUses(macro);
|
||||||
|
}
|
||||||
|
|
||||||
CppModelManager::WorkingCopy CppModelManager::buildWorkingCopyList()
|
CppModelManager::WorkingCopy CppModelManager::buildWorkingCopyList()
|
||||||
{
|
{
|
||||||
WorkingCopy workingCopy;
|
WorkingCopy workingCopy;
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ public:
|
|||||||
virtual void findUsages(CPlusPlus::Symbol *symbol);
|
virtual void findUsages(CPlusPlus::Symbol *symbol);
|
||||||
virtual void renameUsages(CPlusPlus::Symbol *symbol);
|
virtual void renameUsages(CPlusPlus::Symbol *symbol);
|
||||||
|
|
||||||
|
virtual void findMacroUsages(const CPlusPlus::Macro ¯o);
|
||||||
|
|
||||||
void setHeaderSuffixes(const QStringList &suffixes)
|
void setHeaderSuffixes(const QStringList &suffixes)
|
||||||
{ m_headerSuffixes = suffixes; }
|
{ m_headerSuffixes = suffixes; }
|
||||||
|
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ public:
|
|||||||
virtual void renameUsages(CPlusPlus::Symbol *symbol) = 0;
|
virtual void renameUsages(CPlusPlus::Symbol *symbol) = 0;
|
||||||
virtual void findUsages(CPlusPlus::Symbol *symbol) = 0;
|
virtual void findUsages(CPlusPlus::Symbol *symbol) = 0;
|
||||||
|
|
||||||
|
virtual void findMacroUsages(const CPlusPlus::Macro ¯o) = 0;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void updateModifiedSourceFiles();
|
void updateModifiedSourceFiles();
|
||||||
virtual void updateSourceFiles(const QStringList &sourceFiles) = 0;
|
virtual void updateSourceFiles(const QStringList &sourceFiles) = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user