OSDN Git Service

Introduced CPlusPlus::FindUsages.
authorRoberto Raggi <roberto.raggi@nokia.com>
Tue, 27 Oct 2009 11:01:45 +0000 (12:01 +0100)
committerRoberto Raggi <roberto.raggi@nokia.com>
Tue, 27 Oct 2009 11:01:45 +0000 (12:01 +0100)
src/libs/cplusplus/FindUsages.cpp [new file with mode: 0644]
src/libs/cplusplus/FindUsages.h [new file with mode: 0644]
src/libs/cplusplus/cplusplus-lib.pri
src/plugins/cpptools/cppfindreferences.cpp
src/plugins/cpptools/cppfindreferences.h

diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp
new file mode 100644 (file)
index 0000000..714f524
--- /dev/null
@@ -0,0 +1,444 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "FindUsages.h"
+#include "TypeOfExpression.h"
+
+#include <Control.h>
+#include <Literals.h>
+#include <Names.h>
+#include <Symbols.h>
+#include <AST.h>
+
+#include <QtCore/QDir>
+
+using namespace CPlusPlus;
+
+FindUsages::FindUsages(Document::Ptr doc, const Snapshot &snapshot, QFutureInterface<Usage> *future)
+    : ASTVisitor(doc->control()),
+      _future(future),
+      _doc(doc),
+      _snapshot(snapshot),
+      _source(_doc->source()),
+      _sem(doc->control()),
+      _inSimpleDeclaration(0)
+{
+    _snapshot.insert(_doc);
+}
+
+void FindUsages::setGlobalNamespaceBinding(NamespaceBindingPtr globalNamespaceBinding)
+{
+    _globalNamespaceBinding = globalNamespaceBinding;
+}
+
+QList<int> FindUsages::operator()(Symbol *symbol, Identifier *id, AST *ast)
+{
+    _references.clear();
+    _declSymbol = symbol;
+    _id = id;
+    _exprDoc = Document::create("<references>");
+    accept(ast);
+    return _references;
+}
+
+QString FindUsages::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 FindUsages::reportResult(unsigned tokenIndex, const QList<Symbol *> &candidates)
+{
+    const bool isStrongResult = checkCandidates(candidates);
+
+    if (isStrongResult)
+        reportResult(tokenIndex);
+}
+
+void FindUsages::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) {
+        const QString path = QDir::toNativeSeparators(_doc->fileName());
+        _future->reportResult(Usage(path, line, lineText, col, len));
+    }
+
+    _references.append(tokenIndex);
+}
+
+bool FindUsages::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 checkSymbol(canonicalSymbol);
+    }
+
+    return false;
+}
+
+bool FindUsages::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 FindUsages::checkSymbol(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 FindUsages::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 FindUsages::ensureNameIsValid(NameAST *ast)
+{
+    if (ast && ! ast->name)
+        ast->name = _sem.check(ast, /*scope = */ 0);
+}
+
+bool FindUsages::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;
+}
+
+bool FindUsages::visit(PostfixExpressionAST *ast)
+{
+    _postfixExpressionStack.append(ast);
+    return true;
+}
+
+void FindUsages::endVisit(PostfixExpressionAST *)
+{
+    _postfixExpressionStack.removeLast();
+}
+
+bool FindUsages::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 FindUsages::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);
+}
+
+bool FindUsages::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;
+}
+
+bool FindUsages::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;
+}
+
+bool FindUsages::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;
+}
+
+bool FindUsages::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;
+}
+
+bool FindUsages::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;
+}
+
+bool FindUsages::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;
+}
+
+bool FindUsages::visit(ExpressionOrDeclarationStatementAST *ast)
+{
+    accept(ast->declaration);
+    return false;
+}
+
+bool FindUsages::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;
+}
+
+bool FindUsages::visit(SimpleDeclarationAST *)
+{
+    ++_inSimpleDeclaration;
+    return true;
+}
+
+void FindUsages::endVisit(SimpleDeclarationAST *)
+{ --_inSimpleDeclaration; }
diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h
new file mode 100644 (file)
index 0000000..9f82949
--- /dev/null
@@ -0,0 +1,121 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef FINDUSAGES_H
+#define FINDUSAGES_H
+
+#include "LookupContext.h"
+#include "CppDocument.h"
+#include "CppBindings.h"
+#include "Semantic.h"
+
+#include <ASTVisitor.h>
+#include <QtCore/QFutureInterface>
+
+namespace CPlusPlus {
+
+class CPLUSPLUS_EXPORT Usage
+{
+public:
+    Usage()
+        : line(0), col(0), len(0) {}
+
+    Usage(const QString &path, int line, const QString &lineText, int col, int len)
+        : path(path), line(line), lineText(lineText), col(col), len(len) {}
+
+public:
+    QString path;
+    int line;
+    QString lineText;
+    int col;
+    int len;
+};
+
+class CPLUSPLUS_EXPORT FindUsages: protected ASTVisitor
+{
+public:
+    FindUsages(Document::Ptr doc, const Snapshot &snapshot, QFutureInterface<Usage> *future);
+
+    void setGlobalNamespaceBinding(NamespaceBindingPtr globalNamespaceBinding);
+
+    QList<int> operator()(Symbol *symbol, Identifier *id, AST *ast);
+
+protected:
+    using ASTVisitor::visit;
+    using ASTVisitor::endVisit;
+
+    QString matchingLine(const Token &tk) const;
+
+    void reportResult(unsigned tokenIndex, const QList<Symbol *> &candidates);
+    void reportResult(unsigned tokenIndex);
+
+    bool checkSymbol(Symbol *symbol) const;
+    bool checkCandidates(const QList<Symbol *> &candidates) const;
+    bool checkScope(Symbol *symbol, Symbol *otherSymbol) const;
+    void checkExpression(unsigned startToken, unsigned endToken);
+
+    LookupContext currentContext(AST *ast);
+
+    void ensureNameIsValid(NameAST *ast);
+
+    virtual bool visit(MemInitializerAST *ast);
+    virtual bool visit(PostfixExpressionAST *ast);
+    virtual void endVisit(PostfixExpressionAST *);
+    virtual bool visit(MemberAccessAST *ast);
+    virtual bool visit(QualifiedNameAST *ast);
+    virtual bool visit(EnumeratorAST *ast);
+    virtual bool visit(SimpleNameAST *ast);
+    virtual bool visit(DestructorNameAST *ast);
+    virtual bool visit(TemplateIdAST *ast);
+    virtual bool visit(ParameterDeclarationAST *ast);
+    virtual bool visit(ExpressionOrDeclarationStatementAST *ast);
+    virtual bool visit(FunctionDeclaratorAST *ast);
+    virtual bool visit(SimpleDeclarationAST *);
+    virtual void endVisit(SimpleDeclarationAST *);
+
+private:
+    QFutureInterface<Usage> *_future;
+    Identifier *_id;
+    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;
+    LookupContext _previousContext;
+    int _inSimpleDeclaration;
+};
+
+} // end of namespace CPlusPlus
+
+#endif // FINDUSAGES_H
index 2e50a40..611fadf 100644 (file)
@@ -38,6 +38,7 @@ HEADERS += \
     $$PWD/CppBindings.h \
     $$PWD/ASTParent.h \
     $$PWD/GenTemplateInstance.h \
+    $$PWD/FindUsages.h \
     $$PWD/CheckUndefinedSymbols.h \
     $$PWD/PreprocessorClient.h \
     $$PWD/PreprocessorEnvironment.h \
@@ -61,6 +62,7 @@ SOURCES += \
     $$PWD/CppBindings.cpp \
     $$PWD/ASTParent.cpp \
     $$PWD/GenTemplateInstance.cpp \
+    $$PWD/FindUsages.cpp \
     $$PWD/CheckUndefinedSymbols.cpp \
     $$PWD/PreprocessorClient.cpp \
     $$PWD/PreprocessorEnvironment.cpp \
index 06ae979..f8eb274 100644 (file)
 
 #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>
 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()
index cbddf8f..5cdfbdc 100644 (file)
@@ -42,6 +42,10 @@ namespace Find {
     struct SearchResultItem;
 } // end of namespace Find
 
+namespace CPlusPlus {
+    class Usage;
+} // end of namespace CPlusPlus
+
 namespace CppTools {
 class CppModelManagerInterface;
 
@@ -78,7 +82,7 @@ private:
 private:
     QPointer<CppModelManagerInterface> _modelManager;
     Find::SearchResultWindow *_resultWindow;
-    QFutureWatcher<Utils::FileSearchResult> m_watcher;
+    QFutureWatcher<CPlusPlus::Usage> m_watcher;
 };
 
 } // end of namespace Internal