summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools/cppfindreferences.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2009-10-27 12:01:45 +0100
committerRoberto Raggi <roberto.raggi@nokia.com>2009-10-27 12:01:45 +0100
commitfefd72b293d080cfa05eeea27e359e9996dcd6b7 (patch)
treed24bc7760b8dccc8ba07a149b9b41ade474d5aa1 /src/plugins/cpptools/cppfindreferences.cpp
parent83a7e0f5186acd1d88d33e397dbe26ef203eb9b9 (diff)
downloadqt-creator-fefd72b293d080cfa05eeea27e359e9996dcd6b7.tar.gz
Introduced CPlusPlus::FindUsages.
Diffstat (limited to 'src/plugins/cpptools/cppfindreferences.cpp')
-rw-r--r--src/plugins/cpptools/cppfindreferences.cpp457
1 files changed, 11 insertions, 446 deletions
diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp
index 06ae979060..f8eb27419d 100644
--- a/src/plugins/cpptools/cppfindreferences.cpp
+++ b/src/plugins/cpptools/cppfindreferences.cpp
@@ -50,11 +50,8 @@
#include <cplusplus/CppDocument.h>
#include <cplusplus/CppBindings.h>
-#include <cplusplus/ExpressionUnderCursor.h>
-#include <cplusplus/ResolveExpression.h>
#include <cplusplus/Overview.h>
-#include <cplusplus/TypeOfExpression.h>
-#include <cplusplus/FastPreprocessor.h>
+#include <cplusplus/FindUsages.h>
#include <QtCore/QTime>
#include <QtCore/QtConcurrentRun>
@@ -65,438 +62,6 @@
using namespace CppTools::Internal;
using namespace CPlusPlus;
-namespace {
-
-struct Process: protected ASTVisitor
-{
-public:
- Process(Document::Ptr doc, const Snapshot &snapshot,
- QFutureInterface<Utils::FileSearchResult> *future)
- : ASTVisitor(doc->control()),
- _future(future),
- _doc(doc),
- _snapshot(snapshot),
- _source(_doc->source()),
- _sem(doc->control()),
- _inSimpleDeclaration(0)
- {
- _snapshot.insert(_doc);
- }
-
- void setGlobalNamespaceBinding(NamespaceBindingPtr globalNamespaceBinding)
- {
- _globalNamespaceBinding = globalNamespaceBinding;
- }
-
- QList<int> operator()(Symbol *symbol, Identifier *id, AST *ast)
- {
- _references.clear();
- _declSymbol = symbol;
- _id = id;
- _exprDoc = Document::create("<references>");
- accept(ast);
- return _references;
- }
-
-protected:
- using ASTVisitor::visit;
-
- QString matchingLine(const Token &tk) const
- {
- const char *beg = _source.constData();
- const char *cp = beg + tk.offset;
- for (; cp != beg - 1; --cp) {
- if (*cp == '\n')
- break;
- }
-
- ++cp;
-
- const char *lineEnd = cp + 1;
- for (; *lineEnd; ++lineEnd) {
- if (*lineEnd == '\n')
- break;
- }
-
- const QString matchingLine = QString::fromUtf8(cp, lineEnd - cp);
- return matchingLine;
-
- }
-
- void reportResult(unsigned tokenIndex, const QList<Symbol *> &candidates)
- {
- const bool isStrongResult = checkCandidates(candidates);
-
- if (isStrongResult)
- reportResult(tokenIndex);
- }
-
- void reportResult(unsigned tokenIndex)
- {
- const Token &tk = tokenAt(tokenIndex);
- const QString lineText = matchingLine(tk);
-
- unsigned line, col;
- getTokenStartPosition(tokenIndex, &line, &col);
-
- if (col)
- --col; // adjust the column position.
-
- const int len = tk.f.length;
-
- if (_future)
- _future->reportResult(Utils::FileSearchResult(QDir::toNativeSeparators(_doc->fileName()),
- line, lineText, col, len));
-
- _references.append(tokenIndex);
- }
-
- bool checkCandidates(const QList<Symbol *> &candidates) const
- {
- if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates, _globalNamespaceBinding.data())) {
-
-#if 0
- qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName()
- << canonicalSymbol->line() << canonicalSymbol->column()
- << "candidates:" << candidates.size();
-#endif
-
- return isDeclSymbol(canonicalSymbol);
- }
-
- return false;
- }
-
- bool checkScope(Symbol *symbol, Symbol *otherSymbol) const
- {
- if (! (symbol && otherSymbol))
- return false;
-
- else if (symbol->scope() == otherSymbol->scope())
- return true;
-
- else if (symbol->name() && otherSymbol->name()) {
-
- if (! symbol->name()->isEqualTo(otherSymbol->name()))
- return false;
-
- } else if (symbol->name() != otherSymbol->name()) {
- return false;
- }
-
- return checkScope(symbol->enclosingSymbol(), otherSymbol->enclosingSymbol());
- }
-
- bool isDeclSymbol(Symbol *symbol) const
- {
- if (! symbol) {
- 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;
-
- } else if (symbol->isForwardClassDeclaration() && (_declSymbol->isClass() ||
- _declSymbol->isForwardClassDeclaration())) {
- return checkScope(symbol, _declSymbol);
-
- } else if (_declSymbol->isForwardClassDeclaration() && (symbol->isClass() ||
- symbol->isForwardClassDeclaration())) {
- return checkScope(symbol, _declSymbol);
- }
-
- return false;
- }
-
- LookupContext _previousContext;
-
- LookupContext currentContext(AST *ast)
- {
- unsigned line, column;
- getTokenStartPosition(ast->firstToken(), &line, &column);
- Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column);
-
- if (lastVisibleSymbol && lastVisibleSymbol == _previousContext.symbol())
- return _previousContext;
-
- LookupContext ctx(lastVisibleSymbol, _exprDoc, _doc, _snapshot);
- _previousContext = ctx;
- return ctx;
- }
-
- void ensureNameIsValid(NameAST *ast)
- {
- if (ast && ! ast->name)
- ast->name = _sem.check(ast, /*scope = */ 0);
- }
-
- virtual bool visit(MemInitializerAST *ast)
- {
- if (ast->name && ast->name->asSimpleName() != 0) {
- ensureNameIsValid(ast->name);
-
- SimpleNameAST *simple = ast->name->asSimpleName();
- if (identifier(simple->identifier_token) == _id) {
- LookupContext context = currentContext(ast);
- const QList<Symbol *> candidates = context.resolve(simple->name);
- reportResult(simple->identifier_token, candidates);
- }
- }
- accept(ast->expression);
- return false;
- }
-
- virtual bool visit(PostfixExpressionAST *ast)
- {
- _postfixExpressionStack.append(ast);
- return true;
- }
-
- virtual void endVisit(PostfixExpressionAST *)
- {
- _postfixExpressionStack.removeLast();
- }
-
- virtual bool visit(MemberAccessAST *ast)
- {
- if (ast->member_name) {
- if (SimpleNameAST *simple = ast->member_name->asSimpleName()) {
- if (identifier(simple->identifier_token) == _id) {
- Q_ASSERT(! _postfixExpressionStack.isEmpty());
-
- checkExpression(_postfixExpressionStack.last()->firstToken(),
- simple->identifier_token);
-
- return false;
- }
- }
- }
-
- return true;
- }
-
- void checkExpression(unsigned startToken, unsigned endToken)
- {
- const unsigned begin = tokenAt(startToken).begin();
- const unsigned end = tokenAt(endToken).end();
-
- const QString expression = _source.mid(begin, end - begin);
- // qDebug() << "*** check expression:" << expression;
-
- TypeOfExpression typeofExpression;
- typeofExpression.setSnapshot(_snapshot);
-
- unsigned line, column;
- getTokenStartPosition(startToken, &line, &column);
- Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column);
-
- const QList<TypeOfExpression::Result> results =
- typeofExpression(expression, _doc, lastVisibleSymbol,
- TypeOfExpression::Preprocess);
-
- QList<Symbol *> candidates;
-
- foreach (TypeOfExpression::Result r, results) {
- FullySpecifiedType ty = r.first;
- Symbol *lastVisibleSymbol = r.second;
-
- candidates.append(lastVisibleSymbol);
- }
-
- reportResult(endToken, candidates);
- }
-
- virtual bool visit(QualifiedNameAST *ast)
- {
- for (NestedNameSpecifierAST *nested_name_specifier = ast->nested_name_specifier;
- nested_name_specifier; nested_name_specifier = nested_name_specifier->next) {
-
- if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) {
- SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName();
-
- TemplateIdAST *template_id = 0;
- if (! simple_name) {
- template_id = class_or_namespace_name->asTemplateId();
-
- if (template_id) {
- for (TemplateArgumentListAST *template_arguments = template_id->template_arguments;
- template_arguments; template_arguments = template_arguments->next) {
- accept(template_arguments->template_argument);
- }
- }
- }
-
- if (simple_name || template_id) {
- const unsigned identifier_token = simple_name
- ? simple_name->identifier_token
- : template_id->identifier_token;
-
- if (identifier(identifier_token) == _id)
- checkExpression(ast->firstToken(), identifier_token);
- }
- }
- }
-
- if (NameAST *unqualified_name = ast->unqualified_name) {
- unsigned identifier_token = 0;
-
- if (SimpleNameAST *simple_name = unqualified_name->asSimpleName())
- identifier_token = simple_name->identifier_token;
-
- else if (DestructorNameAST *dtor_name = unqualified_name->asDestructorName())
- identifier_token = dtor_name->identifier_token;
-
- TemplateIdAST *template_id = 0;
- if (! identifier_token) {
- template_id = unqualified_name->asTemplateId();
-
- if (template_id) {
- identifier_token = template_id->identifier_token;
-
- for (TemplateArgumentListAST *template_arguments = template_id->template_arguments;
- template_arguments; template_arguments = template_arguments->next) {
- accept(template_arguments->template_argument);
- }
- }
- }
-
- if (identifier_token && identifier(identifier_token) == _id)
- checkExpression(ast->firstToken(), identifier_token);
- }
-
- return false;
- }
-
- virtual bool visit(EnumeratorAST *ast)
- {
- Identifier *id = identifier(ast->identifier_token);
- if (id == _id) {
- LookupContext context = currentContext(ast);
- const QList<Symbol *> candidates = context.resolve(control()->nameId(id));
- reportResult(ast->identifier_token, candidates);
- }
-
- accept(ast->expression);
-
- return false;
- }
-
- virtual bool visit(SimpleNameAST *ast)
- {
- Identifier *id = identifier(ast->identifier_token);
- if (id == _id) {
- LookupContext context = currentContext(ast);
- const QList<Symbol *> candidates = context.resolve(ast->name);
- reportResult(ast->identifier_token, candidates);
- }
-
- return false;
- }
-
- virtual bool visit(DestructorNameAST *ast)
- {
- Identifier *id = identifier(ast->identifier_token);
- if (id == _id) {
- LookupContext context = currentContext(ast);
- const QList<Symbol *> candidates = context.resolve(ast->name);
- reportResult(ast->identifier_token, candidates);
- }
-
- return false;
- }
-
- virtual bool visit(TemplateIdAST *ast)
- {
- if (_id == identifier(ast->identifier_token)) {
- LookupContext context = currentContext(ast);
- const QList<Symbol *> candidates = context.resolve(ast->name);
- reportResult(ast->identifier_token, candidates);
- }
-
- for (TemplateArgumentListAST *template_arguments = ast->template_arguments;
- template_arguments; template_arguments = template_arguments->next) {
- accept(template_arguments->template_argument);
- }
-
- return false;
- }
-
- virtual bool visit(ParameterDeclarationAST *ast)
- {
- for (SpecifierAST *spec = ast->type_specifier; spec; spec = spec->next)
- accept(spec);
-
- if (DeclaratorAST *declarator = ast->declarator) {
- for (SpecifierAST *attr = declarator->attributes; attr; attr = attr->next)
- accept(attr);
-
- for (PtrOperatorAST *ptr_op = declarator->ptr_operators; ptr_op; ptr_op = ptr_op->next)
- accept(ptr_op);
-
- if (! _inSimpleDeclaration) // visit the core declarator only if we are not in simple-declaration.
- accept(declarator->core_declarator);
-
- for (PostfixDeclaratorAST *fx_op = declarator->postfix_declarators; fx_op; fx_op = fx_op->next)
- accept(fx_op);
-
- for (SpecifierAST *spec = declarator->post_attributes; spec; spec = spec->next)
- accept(spec);
-
- accept(declarator->initializer);
- }
-
- accept(ast->expression);
- return false;
- }
-
- virtual bool visit(ExpressionOrDeclarationStatementAST *ast)
- {
- accept(ast->declaration);
- return false;
- }
-
- virtual bool visit(FunctionDeclaratorAST *ast)
- {
- accept(ast->parameters);
-
- for (SpecifierAST *spec = ast->cv_qualifier_seq; spec; spec = spec->next)
- accept(spec);
-
- accept(ast->exception_specification);
-
- return false;
- }
-
- virtual bool visit(SimpleDeclarationAST *)
- {
- ++_inSimpleDeclaration;
- return true;
- }
-
- virtual void endVisit(SimpleDeclarationAST *)
- { --_inSimpleDeclaration; }
-
-private:
- QFutureInterface<Utils::FileSearchResult> *_future;
- Identifier *_id; // ### remove me
- Symbol *_declSymbol;
- Document::Ptr _doc;
- Snapshot _snapshot;
- QByteArray _source;
- Document::Ptr _exprDoc;
- Semantic _sem;
- NamespaceBindingPtr _globalNamespaceBinding;
- QList<PostfixExpressionAST *> _postfixExpressionStack;
- QList<QualifiedNameAST *> _qualifiedNameStack;
- QList<int> _references;
- int _inSimpleDeclaration;
-};
-
-} // end of anonymous namespace
-
CppFindReferences::CppFindReferences(CppTools::CppModelManagerInterface *modelManager)
: _modelManager(modelManager),
_resultWindow(ExtensionSystem::PluginManager::instance()->getObject<Find::SearchResultWindow>())
@@ -526,14 +91,14 @@ QList<int> CppFindReferences::references(Symbol *symbol,
TranslationUnit *translationUnit = doc->translationUnit();
Q_ASSERT(translationUnit != 0);
- Process process(doc, snapshot, /*future = */ 0);
+ FindUsages process(doc, snapshot, /*future = */ 0);
process.setGlobalNamespaceBinding(bind(doc, snapshot));
references = process(symbol, id, translationUnit->ast());
return references;
}
-static void find_helper(QFutureInterface<Utils::FileSearchResult> &future,
+static void find_helper(QFutureInterface<Usage> &future,
const QMap<QString, QString> wl,
Snapshot snapshot,
Symbol *symbol)
@@ -613,7 +178,7 @@ static void find_helper(QFutureInterface<Utils::FileSearchResult> &future,
tm.start();
- Process process(doc, snapshot, &future);
+ FindUsages process(doc, snapshot, &future);
process.setGlobalNamespaceBinding(bind(doc, snapshot));
TranslationUnit *unit = doc->translationUnit();
@@ -666,7 +231,7 @@ void CppFindReferences::findAll_helper(Symbol *symbol)
Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
- QFuture<Utils::FileSearchResult> result = QtConcurrent::run(&find_helper, wl, snapshot, symbol);
+ QFuture<Usage> result = QtConcurrent::run(&find_helper, wl, snapshot, symbol);
m_watcher.setFuture(result);
Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."),
@@ -759,12 +324,12 @@ void CppFindReferences::onReplaceButtonClicked(const QString &text,
void CppFindReferences::displayResult(int index)
{
- Utils::FileSearchResult result = m_watcher.future().resultAt(index);
- _resultWindow->addResult(result.fileName,
- result.lineNumber,
- result.matchingLine,
- result.matchStart,
- result.matchLength);
+ Usage result = m_watcher.future().resultAt(index);
+ _resultWindow->addResult(result.path,
+ result.line,
+ result.lineText,
+ result.col,
+ result.len);
}
void CppFindReferences::searchFinished()