Some work on `find references of a symbol'.

This commit is contained in:
Roberto Raggi
2009-09-25 14:19:43 +02:00
parent 20ff553b59
commit b3cf5ae50a
4 changed files with 90 additions and 73 deletions

View File

@@ -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);
}

View File

@@ -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()); }

View File

@@ -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()

View File

@@ -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..."),