forked from qt-creator/qt-creator
Some work on `find references of a symbol'.
This commit is contained in:
@@ -467,7 +467,7 @@ void LookupContext::expandFunction(Function *function,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LookupContext::expandObjCMethod(ObjCMethod *method,
|
void LookupContext::expandObjCMethod(ObjCMethod *method,
|
||||||
const QList<Scope *> &visibleScopes,
|
const QList<Scope *> &,
|
||||||
QList<Scope *> *expandedScopes) const
|
QList<Scope *> *expandedScopes) const
|
||||||
{
|
{
|
||||||
if (! expandedScopes->contains(method->arguments()))
|
if (! expandedScopes->contains(method->arguments()))
|
||||||
@@ -519,7 +519,7 @@ Symbol *LookupContext::canonicalSymbol(const QList<Symbol *> &candidates)
|
|||||||
Symbol *c = candidates.at(i);
|
Symbol *c = candidates.at(i);
|
||||||
|
|
||||||
if (! c->scope()->isClassScope())
|
if (! c->scope()->isClassScope())
|
||||||
continue; // ### or break?
|
continue;
|
||||||
|
|
||||||
else if (Function *f = c->type()->asFunctionType()) {
|
else if (Function *f = c->type()->asFunctionType()) {
|
||||||
if (f->isVirtual())
|
if (f->isVirtual())
|
||||||
@@ -533,3 +533,13 @@ Symbol *LookupContext::canonicalSymbol(const QList<Symbol *> &candidates)
|
|||||||
|
|
||||||
return canonicalSymbol(candidate);
|
return canonicalSymbol(candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Symbol *LookupContext::canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &results)
|
||||||
|
{
|
||||||
|
QList<Symbol *> candidates;
|
||||||
|
QPair<FullySpecifiedType, Symbol *> result;
|
||||||
|
foreach (result, results) {
|
||||||
|
candidates.append(result.second); // ### not exacly.
|
||||||
|
}
|
||||||
|
return canonicalSymbol(candidates);
|
||||||
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public:
|
|||||||
|
|
||||||
static Symbol *canonicalSymbol(Symbol *symbol);
|
static Symbol *canonicalSymbol(Symbol *symbol);
|
||||||
static Symbol *canonicalSymbol(const QList<Symbol *> &candidates);
|
static Symbol *canonicalSymbol(const QList<Symbol *> &candidates);
|
||||||
|
static Symbol *canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &candidates); // ### FIXME
|
||||||
|
|
||||||
QList<Symbol *> resolve(Name *name) const
|
QList<Symbol *> resolve(Name *name) const
|
||||||
{ return resolve(name, visibleScopes()); }
|
{ return resolve(name, visibleScopes()); }
|
||||||
|
|||||||
@@ -857,22 +857,9 @@ void CPPEditor::findReferences()
|
|||||||
lastVisibleSymbol,
|
lastVisibleSymbol,
|
||||||
TypeOfExpression::Preprocess);
|
TypeOfExpression::Preprocess);
|
||||||
|
|
||||||
if (! results.isEmpty()) {
|
if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(results)) {
|
||||||
TypeOfExpression::Result result = results.first();
|
m_modelManager->findReferences(canonicalSymbol);
|
||||||
Symbol *symbol = result.second;
|
|
||||||
qDebug() << "result:" << symbol->fileName() << symbol->line() << symbol->column();
|
|
||||||
m_modelManager->findReferences(symbol);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
LookupContext context(
|
|
||||||
Overview oo;
|
|
||||||
qDebug() << "==============> filename:" << symbol->fileName()
|
|
||||||
<< "name:" << oo(symbol->name());
|
|
||||||
m_modelManager->findReferences(symbol);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPPEditor::renameSymbolUnderCursor()
|
void CPPEditor::renameSymbolUnderCursor()
|
||||||
|
|||||||
@@ -44,10 +44,13 @@
|
|||||||
#include <Literals.h>
|
#include <Literals.h>
|
||||||
#include <TranslationUnit.h>
|
#include <TranslationUnit.h>
|
||||||
#include <Symbols.h>
|
#include <Symbols.h>
|
||||||
|
#include <Names.h>
|
||||||
|
#include <Scope.h>
|
||||||
|
|
||||||
#include <cplusplus/CppDocument.h>
|
#include <cplusplus/CppDocument.h>
|
||||||
#include <cplusplus/ExpressionUnderCursor.h>
|
#include <cplusplus/ExpressionUnderCursor.h>
|
||||||
#include <cplusplus/ResolveExpression.h>
|
#include <cplusplus/ResolveExpression.h>
|
||||||
|
#include <cplusplus/Overview.h>
|
||||||
|
|
||||||
#include <QtCore/QTime>
|
#include <QtCore/QTime>
|
||||||
#include <QtCore/QtConcurrentRun>
|
#include <QtCore/QtConcurrentRun>
|
||||||
@@ -69,13 +72,16 @@ public:
|
|||||||
_future(future),
|
_future(future),
|
||||||
_doc(doc),
|
_doc(doc),
|
||||||
_snapshot(snapshot),
|
_snapshot(snapshot),
|
||||||
_source(_doc->source())
|
_source(_doc->source()),
|
||||||
{ }
|
_sem(doc->control())
|
||||||
|
|
||||||
void operator()(Identifier *id, AST *ast)
|
|
||||||
{
|
{
|
||||||
|
_snapshot.insert(_doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(Symbol *symbol, Identifier *id, AST *ast)
|
||||||
|
{
|
||||||
|
_declSymbol = symbol;
|
||||||
_id = id;
|
_id = id;
|
||||||
_currentSymbol = _doc->globalNamespace();
|
|
||||||
_exprDoc = Document::create("<references>");
|
_exprDoc = Document::create("<references>");
|
||||||
accept(ast);
|
accept(ast);
|
||||||
}
|
}
|
||||||
@@ -122,55 +128,63 @@ protected:
|
|||||||
line, lineText, col, len));
|
line, lineText, col, len));
|
||||||
}
|
}
|
||||||
|
|
||||||
LookupContext currentContext() const
|
bool checkCandidates(const QList<Symbol *> &candidates) const
|
||||||
{
|
{
|
||||||
return LookupContext(_currentSymbol, _exprDoc, _doc, _snapshot);
|
// ### FIXME return isDeclSymbol(LookupContext::canonicalSymbol(candidates));
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool visit(ClassSpecifierAST *ast)
|
|
||||||
{
|
|
||||||
_currentSymbol = ast->symbol;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool visit(NamespaceAST *ast)
|
bool isDeclSymbol(Symbol *symbol) const
|
||||||
{
|
{
|
||||||
_currentSymbol = ast->symbol;
|
if (! symbol)
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
|
else if (symbol == _declSymbol)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
else if (symbol->line() == _declSymbol->line() && symbol->column() == _declSymbol->column()) {
|
||||||
|
if (! qstrcmp(symbol->fileName(), _declSymbol->fileName()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool visit(CompoundStatementAST *ast)
|
LookupContext currentContext(AST *ast) const
|
||||||
{
|
{
|
||||||
_currentSymbol = ast->symbol;
|
unsigned line, column;
|
||||||
return true;
|
getTokenStartPosition(ast->firstToken(), &line, &column);
|
||||||
}
|
Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column);
|
||||||
|
return LookupContext(lastVisibleSymbol, _exprDoc, _doc, _snapshot);
|
||||||
virtual bool visit(FunctionDefinitionAST *ast)
|
|
||||||
{
|
|
||||||
_currentSymbol = ast->symbol;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool visit(QualifiedNameAST *ast)
|
virtual bool visit(QualifiedNameAST *ast)
|
||||||
{
|
{
|
||||||
return true;
|
if (! ast->name) {
|
||||||
|
//qWarning() << "invalid AST at" << _doc->fileName() << line << column;
|
||||||
|
ast->name = _sem.check(ast, /*scope */ static_cast<Scope *>(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(ast->name != 0);
|
||||||
|
Identifier *id = ast->name->identifier();
|
||||||
|
if (id == _id && ast->unqualified_name) {
|
||||||
|
LookupContext context = currentContext(ast);
|
||||||
|
const QList<Symbol *> candidates = context.resolve(ast->name);
|
||||||
|
if (checkCandidates(candidates))
|
||||||
|
reportResult(ast->unqualified_name->firstToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool visit(SimpleNameAST *ast)
|
virtual bool visit(SimpleNameAST *ast)
|
||||||
{
|
{
|
||||||
Identifier *id = identifier(ast->identifier_token);
|
Identifier *id = identifier(ast->identifier_token);
|
||||||
if (id == _id) {
|
if (id == _id) {
|
||||||
#if 0
|
LookupContext context = currentContext(ast);
|
||||||
LookupContext context = currentContext();
|
const QList<Symbol *> candidates = context.resolve(ast->name);
|
||||||
ResolveExpression resolveExpression(context);
|
if (checkCandidates(candidates))
|
||||||
QList<ResolveExpression::Result> results = resolveExpression(ast);
|
reportResult(ast->identifier_token);
|
||||||
if (! results.isEmpty()) {
|
|
||||||
ResolveExpression::Result result = results.first();
|
|
||||||
Symbol *resolvedSymbol = result.second;
|
|
||||||
qDebug() << "resolves to:" << resolvedSymbol->fileName() << resolvedSymbol->line();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
reportResult(ast->identifier_token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -179,20 +193,25 @@ protected:
|
|||||||
virtual bool visit(TemplateIdAST *ast)
|
virtual bool visit(TemplateIdAST *ast)
|
||||||
{
|
{
|
||||||
Identifier *id = identifier(ast->identifier_token);
|
Identifier *id = identifier(ast->identifier_token);
|
||||||
if (id == _id)
|
if (id == _id) {
|
||||||
reportResult(ast->identifier_token);
|
LookupContext context = currentContext(ast);
|
||||||
|
const QList<Symbol *> candidates = context.resolve(ast->name);
|
||||||
|
if (checkCandidates(candidates))
|
||||||
|
reportResult(ast->identifier_token);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QFutureInterface<Core::Utils::FileSearchResult> &_future;
|
QFutureInterface<Core::Utils::FileSearchResult> &_future;
|
||||||
Identifier *_id;
|
Identifier *_id; // ### remove me
|
||||||
|
Symbol *_declSymbol;
|
||||||
Document::Ptr _doc;
|
Document::Ptr _doc;
|
||||||
Snapshot _snapshot;
|
Snapshot _snapshot;
|
||||||
QByteArray _source;
|
QByteArray _source;
|
||||||
Symbol *_currentSymbol;
|
|
||||||
Document::Ptr _exprDoc;
|
Document::Ptr _exprDoc;
|
||||||
|
Semantic _sem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
@@ -217,6 +236,9 @@ static void find_helper(QFutureInterface<Core::Utils::FileSearchResult> &future,
|
|||||||
QTime tm;
|
QTime tm;
|
||||||
tm.start();
|
tm.start();
|
||||||
|
|
||||||
|
Identifier *symbolId = symbol->identifier();
|
||||||
|
Q_ASSERT(symbolId != 0);
|
||||||
|
|
||||||
const QString fileName = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength());
|
const QString fileName = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength());
|
||||||
|
|
||||||
QStringList files(fileName);
|
QStringList files(fileName);
|
||||||
@@ -229,24 +251,30 @@ static void find_helper(QFutureInterface<Core::Utils::FileSearchResult> &future,
|
|||||||
for (int i = 0; i < files.size(); ++i) {
|
for (int i = 0; i < files.size(); ++i) {
|
||||||
const QString &fn = files.at(i);
|
const QString &fn = files.at(i);
|
||||||
future.setProgressValueAndText(i, QFileInfo(fn).fileName());
|
future.setProgressValueAndText(i, QFileInfo(fn).fileName());
|
||||||
|
|
||||||
|
Document::Ptr previousDoc = snapshot.value(fn);
|
||||||
|
if (previousDoc) {
|
||||||
|
Control *control = previousDoc->control();
|
||||||
|
Identifier *id = control->findIdentifier(symbolId->chars(), symbolId->size());
|
||||||
|
if (! id)
|
||||||
|
continue; // skip this document, it's not using symbolId.
|
||||||
|
}
|
||||||
|
|
||||||
QFile f(fn);
|
QFile f(fn);
|
||||||
if (! f.open(QFile::ReadOnly))
|
if (! f.open(QFile::ReadOnly))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const QString source = QTextStream(&f).readAll();
|
const QString source = QTextStream(&f).readAll(); // ### FIXME
|
||||||
const QByteArray preprocessedCode = snapshot.preprocessedCode(source, fn);
|
const QByteArray preprocessedCode = snapshot.preprocessedCode(source, fn);
|
||||||
Document::Ptr doc = snapshot.documentFromSource(preprocessedCode, fn);
|
Document::Ptr doc = snapshot.documentFromSource(preprocessedCode, fn);
|
||||||
doc->tokenize();
|
doc->tokenize();
|
||||||
|
|
||||||
Identifier *symbolId = symbol->identifier();
|
|
||||||
Q_ASSERT(symbolId != 0);
|
|
||||||
|
|
||||||
Control *control = doc->control();
|
Control *control = doc->control();
|
||||||
if (Identifier *id = control->findIdentifier(symbolId->chars(), symbolId->size())) {
|
if (Identifier *id = control->findIdentifier(symbolId->chars(), symbolId->size())) {
|
||||||
doc->check();
|
doc->check();
|
||||||
TranslationUnit *unit = doc->translationUnit();
|
TranslationUnit *unit = doc->translationUnit();
|
||||||
Process process(future, doc, snapshot);
|
Process process(future, doc, snapshot);
|
||||||
process(id, unit->ast());
|
process(symbol, id, unit->ast());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
future.setProgressValue(files.size());
|
future.setProgressValue(files.size());
|
||||||
@@ -259,16 +287,7 @@ void CppFindReferences::findAll(const Snapshot &snapshot, Symbol *symbol)
|
|||||||
|
|
||||||
Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
|
Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
|
||||||
|
|
||||||
// find the canonical symbol.
|
QFuture<Core::Utils::FileSearchResult> result = QtConcurrent::run(&find_helper, snapshot, symbol);
|
||||||
Symbol *canonicalSymbol = symbol;
|
|
||||||
for (; symbol; symbol = symbol->next()) {
|
|
||||||
if (symbol->name() == canonicalSymbol->name())
|
|
||||||
canonicalSymbol = symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFuture<Core::Utils::FileSearchResult> result =
|
|
||||||
QtConcurrent::run(&find_helper, snapshot, canonicalSymbol);
|
|
||||||
|
|
||||||
m_watcher.setFuture(result);
|
m_watcher.setFuture(result);
|
||||||
|
|
||||||
Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."),
|
Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."),
|
||||||
|
|||||||
Reference in New Issue
Block a user