From b1f5a40ee24e499bc46cdfe33a036ca3974b16d9 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 29 Sep 2009 12:32:35 +0200 Subject: Handle member expressions. --- src/plugins/cpptools/cppfindreferences.cpp | 73 +++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) (limited to 'src/plugins/cpptools/cppfindreferences.cpp') diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index d56b4e64aa..faa7fc944a 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -130,8 +131,17 @@ protected: bool checkCandidates(const QList &candidates) const { - // ### FIXME return isDeclSymbol(LookupContext::canonicalSymbol(candidates)); - return true; + if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates)) { +#if 0 + qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName() + << canonicalSymbol->line() << canonicalSymbol->column() + << "candidates:" << candidates.size(); +#endif + + return isDeclSymbol(canonicalSymbol); + } + + return false; } bool isDeclSymbol(Symbol *symbol) const @@ -158,6 +168,64 @@ protected: return LookupContext(lastVisibleSymbol, _exprDoc, _doc, _snapshot); } + virtual bool visit(PostfixExpressionAST *ast) + { + _postfixExpressionStack.append(ast); + return true; + } + + virtual void endVisit(PostfixExpressionAST *ast) + { + _postfixExpressionStack.removeLast(); + } + + virtual bool visit(MemberAccessAST *ast) + { + if (! ast->member_name) + return false; + + SimpleNameAST *simple = ast->member_name->asSimpleName(); + if (! simple) + return true; // ### TODO handle pseudo-destructors and qualified names. + + Q_ASSERT(! _postfixExpressionStack.isEmpty()); + + if (identifier(simple->identifier_token) == _id) { + unsigned startOfPostfixExpression = _postfixExpressionStack.last()->firstToken(); + + unsigned begin = tokenAt(startOfPostfixExpression).begin(); + unsigned end = tokenAt(ast->member_name->lastToken() - 1).end(); + + const QString expression = _source.mid(begin, end - begin); + // qDebug() << "*** expression:" << expression; + + TypeOfExpression typeofExpression; + typeofExpression.setSnapshot(_snapshot); + + unsigned line, column; + getTokenStartPosition(startOfPostfixExpression, &line, &column); + Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); + + const QList results = + typeofExpression(expression, _doc, lastVisibleSymbol, + TypeOfExpression::NoPreprocess); + + QList candidates; + + foreach (TypeOfExpression::Result r, results) { + FullySpecifiedType ty = r.first; + Symbol *lastVisibleSymbol = r.second; + + candidates.append(lastVisibleSymbol); + } + + if (checkCandidates(candidates)) + reportResult(simple->identifier_token); + } + + return false; + } + virtual bool visit(QualifiedNameAST *ast) { if (! ast->name) { @@ -212,6 +280,7 @@ private: QByteArray _source; Document::Ptr _exprDoc; Semantic _sem; + QList _postfixExpressionStack; }; } // end of anonymous namespace -- cgit v1.2.1 From 9f49cd05b63eec13085b08204847b27b5d33ceab Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 29 Sep 2009 13:02:15 +0200 Subject: Handle mem initializers. --- src/plugins/cpptools/cppfindreferences.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/plugins/cpptools/cppfindreferences.cpp') diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index faa7fc944a..1d2fdba2f6 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -168,13 +168,37 @@ protected: return LookupContext(lastVisibleSymbol, _exprDoc, _doc, _snapshot); } + 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(); + qDebug() << identifier(simple->identifier_token) << _id; + if (identifier(simple->identifier_token) == _id) { + LookupContext context = currentContext(ast); + const QList candidates = context.resolve(simple->name); + if (checkCandidates(candidates)) + reportResult(simple->identifier_token); + } + } + accept(ast->expression); + return false; + } + virtual bool visit(PostfixExpressionAST *ast) { _postfixExpressionStack.append(ast); return true; } - virtual void endVisit(PostfixExpressionAST *ast) + virtual void endVisit(PostfixExpressionAST *) { _postfixExpressionStack.removeLast(); } -- cgit v1.2.1 From 4bc4bd0f5d7cfdfd0fd519d671af02c33fa1c1c4 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 29 Sep 2009 13:34:52 +0200 Subject: Removed useless qDebug. --- src/plugins/cpptools/cppfindreferences.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/plugins/cpptools/cppfindreferences.cpp') diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 1d2fdba2f6..66d9fbcc2f 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -180,7 +180,6 @@ protected: ensureNameIsValid(ast->name); SimpleNameAST *simple = ast->name->asSimpleName(); - qDebug() << identifier(simple->identifier_token) << _id; if (identifier(simple->identifier_token) == _id) { LookupContext context = currentContext(ast); const QList candidates = context.resolve(simple->name); -- cgit v1.2.1 From 86e21bc255fdc883e3094e7abb32764d6ac8678c Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 29 Sep 2009 13:42:47 +0200 Subject: Look at the working copy when searching for references. --- src/plugins/cpptools/cppfindreferences.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'src/plugins/cpptools/cppfindreferences.cpp') diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 66d9fbcc2f..355f2bf61a 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -322,6 +322,7 @@ CppFindReferences::~CppFindReferences() } static void find_helper(QFutureInterface &future, + const QMap wl, Snapshot snapshot, Symbol *symbol) { @@ -339,7 +340,6 @@ static void find_helper(QFutureInterface &future, future.setProgressRange(0, files.size()); - tm.start(); for (int i = 0; i < files.size(); ++i) { const QString &fn = files.at(i); future.setProgressValueAndText(i, QFileInfo(fn).fileName()); @@ -356,9 +356,20 @@ static void find_helper(QFutureInterface &future, if (! f.open(QFile::ReadOnly)) continue; - const QString source = QTextStream(&f).readAll(); // ### FIXME - const QByteArray preprocessedCode = snapshot.preprocessedCode(source, fn); - Document::Ptr doc = snapshot.documentFromSource(preprocessedCode, fn); + QByteArray source; + + if (wl.contains(fileName)) + source = snapshot.preprocessedCode(wl.value(fileName), fileName); + else { + QFile file(fileName); + if (! file.open(QFile::ReadOnly)) + continue; + + const QString contents = QTextStream(&file).readAll(); // ### FIXME + source = snapshot.preprocessedCode(contents, fileName); + } + + Document::Ptr doc = snapshot.documentFromSource(source, fileName); doc->tokenize(); Control *control = doc->control(); @@ -369,17 +380,21 @@ static void find_helper(QFutureInterface &future, process(symbol, id, unit->ast()); } } + future.setProgressValue(files.size()); } -void CppFindReferences::findAll(const Snapshot &snapshot, Symbol *symbol) +void CppFindReferences::findAll(Symbol *symbol) { _resultWindow->clearContents(); _resultWindow->popup(true); + const Snapshot snapshot = _modelManager->snapshot(); + const QMap wl = _modelManager->buildWorkingCopyList(); + Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager(); - QFuture result = QtConcurrent::run(&find_helper, snapshot, symbol); + QFuture result = QtConcurrent::run(&find_helper, wl, snapshot, symbol); m_watcher.setFuture(result); Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."), -- cgit v1.2.1 From 05f7870a6762cc450d304f91c67ecd95fe95f40d Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 29 Sep 2009 13:50:55 +0200 Subject: Cleanup --- src/plugins/cpptools/cppfindreferences.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src/plugins/cpptools/cppfindreferences.cpp') diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 355f2bf61a..46177f1d51 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -332,19 +332,19 @@ static void find_helper(QFutureInterface &future, Identifier *symbolId = symbol->identifier(); Q_ASSERT(symbolId != 0); - const QString fileName = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()); + const QString sourceFile = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()); - QStringList files(fileName); - files += snapshot.dependsOn(fileName); + QStringList files(sourceFile); + files += snapshot.dependsOn(sourceFile); qDebug() << "done in:" << tm.elapsed() << "number of files to parse:" << files.size(); future.setProgressRange(0, files.size()); for (int i = 0; i < files.size(); ++i) { - const QString &fn = files.at(i); - future.setProgressValueAndText(i, QFileInfo(fn).fileName()); + const QString &fileName = files.at(i); + future.setProgressValueAndText(i, QFileInfo(fileName).fileName()); - Document::Ptr previousDoc = snapshot.value(fn); + Document::Ptr previousDoc = snapshot.value(fileName); if (previousDoc) { Control *control = previousDoc->control(); Identifier *id = control->findIdentifier(symbolId->chars(), symbolId->size()); @@ -352,10 +352,6 @@ static void find_helper(QFutureInterface &future, continue; // skip this document, it's not using symbolId. } - QFile f(fn); - if (! f.open(QFile::ReadOnly)) - continue; - QByteArray source; if (wl.contains(fileName)) -- cgit v1.2.1 From 11212eb0d1a1587155b424bb56435bab58545029 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 29 Sep 2009 14:41:15 +0200 Subject: Handle qualified name ids. --- src/plugins/cpptools/cppfindreferences.cpp | 133 ++++++++++++++++++++--------- 1 file changed, 95 insertions(+), 38 deletions(-) (limited to 'src/plugins/cpptools/cppfindreferences.cpp') diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 46177f1d51..9f2f2b3f2c 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -204,71 +204,127 @@ protected: virtual bool visit(MemberAccessAST *ast) { - if (! ast->member_name) - return false; - - SimpleNameAST *simple = ast->member_name->asSimpleName(); - if (! simple) - return true; // ### TODO handle pseudo-destructors and qualified names. + if (ast->member_name) { + if (SimpleNameAST *simple = ast->member_name->asSimpleName()) { + if (identifier(simple->identifier_token) == _id) { + Q_ASSERT(! _postfixExpressionStack.isEmpty()); - Q_ASSERT(! _postfixExpressionStack.isEmpty()); + checkExpression(_postfixExpressionStack.last()->firstToken(), + simple->identifier_token); - if (identifier(simple->identifier_token) == _id) { - unsigned startOfPostfixExpression = _postfixExpressionStack.last()->firstToken(); + return false; + } + } + } - unsigned begin = tokenAt(startOfPostfixExpression).begin(); - unsigned end = tokenAt(ast->member_name->lastToken() - 1).end(); + return true; + } - const QString expression = _source.mid(begin, end - begin); - // qDebug() << "*** expression:" << expression; + void checkExpression(unsigned startToken, unsigned endToken) + { + const unsigned begin = tokenAt(startToken).begin(); + const unsigned end = tokenAt(endToken).end(); - TypeOfExpression typeofExpression; - typeofExpression.setSnapshot(_snapshot); + const QString expression = _source.mid(begin, end - begin); + // qDebug() << "*** expression:" << expression; - unsigned line, column; - getTokenStartPosition(startOfPostfixExpression, &line, &column); - Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); + TypeOfExpression typeofExpression; + typeofExpression.setSnapshot(_snapshot); - const QList results = - typeofExpression(expression, _doc, lastVisibleSymbol, - TypeOfExpression::NoPreprocess); + unsigned line, column; + getTokenStartPosition(startToken, &line, &column); + Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); - QList candidates; + const QList results = + typeofExpression(expression, _doc, lastVisibleSymbol, + TypeOfExpression::NoPreprocess); - foreach (TypeOfExpression::Result r, results) { - FullySpecifiedType ty = r.first; - Symbol *lastVisibleSymbol = r.second; + QList candidates; - candidates.append(lastVisibleSymbol); - } + foreach (TypeOfExpression::Result r, results) { + FullySpecifiedType ty = r.first; + Symbol *lastVisibleSymbol = r.second; - if (checkCandidates(candidates)) - reportResult(simple->identifier_token); + candidates.append(lastVisibleSymbol); } - return false; + if (checkCandidates(candidates)) + reportResult(endToken); } virtual bool visit(QualifiedNameAST *ast) { - if (! ast->name) { - //qWarning() << "invalid AST at" << _doc->fileName() << line << column; - ast->name = _sem.check(ast, /*scope */ static_cast(0)); + 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 (ast->unqualified_name) { + SimpleNameAST *simple_name = ast->unqualified_name->asSimpleName(); + + TemplateIdAST *template_id = 0; + if (! simple_name) { + template_id = ast->unqualified_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); + } } - Q_ASSERT(ast->name != 0); - Identifier *id = ast->name->identifier(); - if (id == _id && ast->unqualified_name) { + return false; + } + + virtual bool visit(SimpleNameAST *ast) + { + Identifier *id = identifier(ast->identifier_token); + if (id == _id) { LookupContext context = currentContext(ast); const QList candidates = context.resolve(ast->name); if (checkCandidates(candidates)) - reportResult(ast->unqualified_name->firstToken()); + reportResult(ast->identifier_token); } return false; } - virtual bool visit(SimpleNameAST *ast) + virtual bool visit(DestructorNameAST *ast) { Identifier *id = identifier(ast->identifier_token); if (id == _id) { @@ -304,6 +360,7 @@ private: Document::Ptr _exprDoc; Semantic _sem; QList _postfixExpressionStack; + QList _qualifiedNameStack; }; } // end of anonymous namespace -- cgit v1.2.1 From f62ecb37f37dbeee74d864ea55f3a4e951441aaa Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 29 Sep 2009 16:20:12 +0200 Subject: Preprocess the given expression when trying to resolve names. --- src/plugins/cpptools/cppfindreferences.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/cpptools/cppfindreferences.cpp') diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 9f2f2b3f2c..2f6964cbe3 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -237,7 +237,7 @@ protected: const QList results = typeofExpression(expression, _doc, lastVisibleSymbol, - TypeOfExpression::NoPreprocess); + TypeOfExpression::Preprocess); QList candidates; -- cgit v1.2.1