diff options
| author | Roberto Raggi <roberto.raggi@nokia.com> | 2009-10-27 12:01:45 +0100 |
|---|---|---|
| committer | Roberto Raggi <roberto.raggi@nokia.com> | 2009-10-27 12:01:45 +0100 |
| commit | fefd72b293d080cfa05eeea27e359e9996dcd6b7 (patch) | |
| tree | d24bc7760b8dccc8ba07a149b9b41ade474d5aa1 /src/plugins/cpptools/cppfindreferences.cpp | |
| parent | 83a7e0f5186acd1d88d33e397dbe26ef203eb9b9 (diff) | |
| download | qt-creator-fefd72b293d080cfa05eeea27e359e9996dcd6b7.tar.gz | |
Introduced CPlusPlus::FindUsages.
Diffstat (limited to 'src/plugins/cpptools/cppfindreferences.cpp')
| -rw-r--r-- | src/plugins/cpptools/cppfindreferences.cpp | 457 |
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() |
