From b3cf5ae50a8d60e9d99416006d961f37b7feb9cf Mon Sep 17 00:00:00 2001 From: Roberto Raggi <roberto.raggi@nokia.com> Date: Fri, 25 Sep 2009 14:19:43 +0200 Subject: [PATCH] Some work on `find references of a symbol'. --- src/libs/cplusplus/LookupContext.cpp | 14 ++- src/libs/cplusplus/LookupContext.h | 1 + src/plugins/cppeditor/cppeditor.cpp | 17 +-- src/plugins/cpptools/cppfindreferences.cpp | 127 ++++++++++++--------- 4 files changed, 88 insertions(+), 71 deletions(-) diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 082304a47d3..f0bbb4ffca8 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -467,7 +467,7 @@ void LookupContext::expandFunction(Function *function, } void LookupContext::expandObjCMethod(ObjCMethod *method, - const QList<Scope *> &visibleScopes, + const QList<Scope *> &, QList<Scope *> *expandedScopes) const { if (! expandedScopes->contains(method->arguments())) @@ -519,7 +519,7 @@ Symbol *LookupContext::canonicalSymbol(const QList<Symbol *> &candidates) Symbol *c = candidates.at(i); if (! c->scope()->isClassScope()) - continue; // ### or break? + continue; else if (Function *f = c->type()->asFunctionType()) { if (f->isVirtual()) @@ -533,3 +533,13 @@ Symbol *LookupContext::canonicalSymbol(const QList<Symbol *> &candidates) 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); +} diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index 54c27cd3ebd..bb5b0539268 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -56,6 +56,7 @@ public: static Symbol *canonicalSymbol(Symbol *symbol); static Symbol *canonicalSymbol(const QList<Symbol *> &candidates); + static Symbol *canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &candidates); // ### FIXME QList<Symbol *> resolve(Name *name) const { return resolve(name, visibleScopes()); } diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 1c3c02e9447..04ceb351a73 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -857,22 +857,9 @@ void CPPEditor::findReferences() lastVisibleSymbol, TypeOfExpression::Preprocess); - if (! results.isEmpty()) { - TypeOfExpression::Result result = results.first(); - Symbol *symbol = result.second; - qDebug() << "result:" << symbol->fileName() << symbol->line() << symbol->column(); - m_modelManager->findReferences(symbol); + if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(results)) { + m_modelManager->findReferences(canonicalSymbol); } - - -#if 0 - LookupContext context( - Overview oo; - qDebug() << "==============> filename:" << symbol->fileName() - << "name:" << oo(symbol->name()); - m_modelManager->findReferences(symbol); - } -#endif } void CPPEditor::renameSymbolUnderCursor() diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index d0a83d768b8..d56b4e64aa1 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -44,10 +44,13 @@ #include <Literals.h> #include <TranslationUnit.h> #include <Symbols.h> +#include <Names.h> +#include <Scope.h> #include <cplusplus/CppDocument.h> #include <cplusplus/ExpressionUnderCursor.h> #include <cplusplus/ResolveExpression.h> +#include <cplusplus/Overview.h> #include <QtCore/QTime> #include <QtCore/QtConcurrentRun> @@ -69,13 +72,16 @@ public: _future(future), _doc(doc), _snapshot(snapshot), - _source(_doc->source()) - { } + _source(_doc->source()), + _sem(doc->control()) + { + _snapshot.insert(_doc); + } - void operator()(Identifier *id, AST *ast) + void operator()(Symbol *symbol, Identifier *id, AST *ast) { + _declSymbol = symbol; _id = id; - _currentSymbol = _doc->globalNamespace(); _exprDoc = Document::create("<references>"); accept(ast); } @@ -122,55 +128,63 @@ protected: line, lineText, col, len)); } - LookupContext currentContext() const - { - return LookupContext(_currentSymbol, _exprDoc, _doc, _snapshot); - } - - virtual bool visit(ClassSpecifierAST *ast) + bool checkCandidates(const QList<Symbol *> &candidates) const { - _currentSymbol = ast->symbol; + // ### FIXME return isDeclSymbol(LookupContext::canonicalSymbol(candidates)); return true; } - virtual bool visit(NamespaceAST *ast) + bool isDeclSymbol(Symbol *symbol) const { - _currentSymbol = ast->symbol; - return true; - } + if (! symbol) + return false; - virtual bool visit(CompoundStatementAST *ast) - { - _currentSymbol = ast->symbol; - return true; + 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(FunctionDefinitionAST *ast) + LookupContext currentContext(AST *ast) const { - _currentSymbol = ast->symbol; - return true; + unsigned line, column; + getTokenStartPosition(ast->firstToken(), &line, &column); + Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); + return LookupContext(lastVisibleSymbol, _exprDoc, _doc, _snapshot); } 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) { Identifier *id = identifier(ast->identifier_token); if (id == _id) { -#if 0 - LookupContext context = currentContext(); - ResolveExpression resolveExpression(context); - QList<ResolveExpression::Result> results = resolveExpression(ast); - if (! results.isEmpty()) { - ResolveExpression::Result result = results.first(); - Symbol *resolvedSymbol = result.second; - qDebug() << "resolves to:" << resolvedSymbol->fileName() << resolvedSymbol->line(); - } -#endif - reportResult(ast->identifier_token); + LookupContext context = currentContext(ast); + const QList<Symbol *> candidates = context.resolve(ast->name); + if (checkCandidates(candidates)) + reportResult(ast->identifier_token); } return false; @@ -179,20 +193,25 @@ protected: virtual bool visit(TemplateIdAST *ast) { Identifier *id = identifier(ast->identifier_token); - if (id == _id) - reportResult(ast->identifier_token); + if (id == _id) { + LookupContext context = currentContext(ast); + const QList<Symbol *> candidates = context.resolve(ast->name); + if (checkCandidates(candidates)) + reportResult(ast->identifier_token); + } - return true; + return false; } private: QFutureInterface<Core::Utils::FileSearchResult> &_future; - Identifier *_id; + Identifier *_id; // ### remove me + Symbol *_declSymbol; Document::Ptr _doc; Snapshot _snapshot; QByteArray _source; - Symbol *_currentSymbol; Document::Ptr _exprDoc; + Semantic _sem; }; } // end of anonymous namespace @@ -217,6 +236,9 @@ static void find_helper(QFutureInterface<Core::Utils::FileSearchResult> &future, QTime tm; tm.start(); + Identifier *symbolId = symbol->identifier(); + Q_ASSERT(symbolId != 0); + const QString fileName = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()); QStringList files(fileName); @@ -229,24 +251,30 @@ static void find_helper(QFutureInterface<Core::Utils::FileSearchResult> &future, for (int i = 0; i < files.size(); ++i) { const QString &fn = files.at(i); 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); if (! f.open(QFile::ReadOnly)) continue; - const QString source = QTextStream(&f).readAll(); + const QString source = QTextStream(&f).readAll(); // ### FIXME const QByteArray preprocessedCode = snapshot.preprocessedCode(source, fn); Document::Ptr doc = snapshot.documentFromSource(preprocessedCode, fn); doc->tokenize(); - Identifier *symbolId = symbol->identifier(); - Q_ASSERT(symbolId != 0); - Control *control = doc->control(); if (Identifier *id = control->findIdentifier(symbolId->chars(), symbolId->size())) { doc->check(); TranslationUnit *unit = doc->translationUnit(); Process process(future, doc, snapshot); - process(id, unit->ast()); + process(symbol, id, unit->ast()); } } future.setProgressValue(files.size()); @@ -259,16 +287,7 @@ void CppFindReferences::findAll(const Snapshot &snapshot, Symbol *symbol) Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager(); - // find the canonical 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); - + QFuture<Core::Utils::FileSearchResult> result = QtConcurrent::run(&find_helper, snapshot, symbol); m_watcher.setFuture(result); Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."), -- GitLab