--- /dev/null
+/**************************************************************************
+**
+** 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; }
--- /dev/null
+/**************************************************************************
+**
+** 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
$$PWD/CppBindings.h \
$$PWD/ASTParent.h \
$$PWD/GenTemplateInstance.h \
+ $$PWD/FindUsages.h \
$$PWD/CheckUndefinedSymbols.h \
$$PWD/PreprocessorClient.h \
$$PWD/PreprocessorEnvironment.h \
$$PWD/CppBindings.cpp \
$$PWD/ASTParent.cpp \
$$PWD/GenTemplateInstance.cpp \
+ $$PWD/FindUsages.cpp \
$$PWD/CheckUndefinedSymbols.cpp \
$$PWD/PreprocessorClient.cpp \
$$PWD/PreprocessorEnvironment.cpp \
#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>())
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)
tm.start();
- Process process(doc, snapshot, &future);
+ FindUsages process(doc, snapshot, &future);
process.setGlobalNamespaceBinding(bind(doc, snapshot));
TranslationUnit *unit = doc->translationUnit();
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..."),
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()
struct SearchResultItem;
} // end of namespace Find
+namespace CPlusPlus {
+ class Usage;
+} // end of namespace CPlusPlus
+
namespace CppTools {
class CppModelManagerInterface;
private:
QPointer<CppModelManagerInterface> _modelManager;
Find::SearchResultWindow *_resultWindow;
- QFutureWatcher<Utils::FileSearchResult> m_watcher;
+ QFutureWatcher<CPlusPlus::Usage> m_watcher;
};
} // end of namespace Internal