| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | /**************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** 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://www.qtsoftware.com/contact.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | **************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "cppfindreferences.h"
 | 
					
						
							|  |  |  | #include "cppmodelmanager.h"
 | 
					
						
							|  |  |  | #include "cpptoolsconstants.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <texteditor/basetexteditor.h>
 | 
					
						
							|  |  |  | #include <find/searchresultwindow.h>
 | 
					
						
							|  |  |  | #include <extensionsystem/pluginmanager.h>
 | 
					
						
							|  |  |  | #include <utils/filesearch.h>
 | 
					
						
							|  |  |  | #include <coreplugin/progressmanager/progressmanager.h>
 | 
					
						
							|  |  |  | #include <coreplugin/icore.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <ASTVisitor.h>
 | 
					
						
							|  |  |  | #include <AST.h>
 | 
					
						
							|  |  |  | #include <Control.h>
 | 
					
						
							|  |  |  | #include <Literals.h>
 | 
					
						
							|  |  |  | #include <TranslationUnit.h>
 | 
					
						
							|  |  |  | #include <Symbols.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  | #include <Names.h>
 | 
					
						
							|  |  |  | #include <Scope.h>
 | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <cplusplus/CppDocument.h>
 | 
					
						
							|  |  |  | #include <cplusplus/ExpressionUnderCursor.h>
 | 
					
						
							|  |  |  | #include <cplusplus/ResolveExpression.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  | #include <cplusplus/Overview.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | #include <cplusplus/TypeOfExpression.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-30 17:15:31 +02:00
										 |  |  | #include <cplusplus/FastPreprocessor.h>
 | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <QtCore/QTime>
 | 
					
						
							|  |  |  | #include <QtCore/QtConcurrentRun>
 | 
					
						
							|  |  |  | #include <QtCore/QDir>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <qtconcurrent/runextensions.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace CppTools::Internal; | 
					
						
							|  |  |  | using namespace CPlusPlus; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct Process: protected ASTVisitor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  |     Process(Document::Ptr doc, const Snapshot &snapshot, | 
					
						
							| 
									
										
										
										
											2009-10-05 11:06:05 +02:00
										 |  |  |             QFutureInterface<Utils::FileSearchResult> *future) | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |             : ASTVisitor(doc->control()), | 
					
						
							|  |  |  |               _future(future), | 
					
						
							|  |  |  |               _doc(doc), | 
					
						
							|  |  |  |               _snapshot(snapshot), | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |               _source(_doc->source()), | 
					
						
							|  |  |  |               _sem(doc->control()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         _snapshot.insert(_doc); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  |     QList<int> operator()(Symbol *symbol, Identifier *id, AST *ast) | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  |         _references.clear(); | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |         _declSymbol = symbol; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |         _id = id; | 
					
						
							|  |  |  |         _exprDoc = Document::create("<references>"); | 
					
						
							|  |  |  |         accept(ast); | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  |         return _references; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 12:53:18 +02:00
										 |  |  |     void reportResult(unsigned tokenIndex, const QList<Symbol *> &candidates) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         const bool isStrongResult = checkCandidates(candidates); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (isStrongResult) | 
					
						
							|  |  |  |             reportResult(tokenIndex); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  |         const int len = tk.f.length; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  |         if (_future) | 
					
						
							| 
									
										
										
										
											2009-10-05 11:06:05 +02:00
										 |  |  |             _future->reportResult(Utils::FileSearchResult(QDir::toNativeSeparators(_doc->fileName()), | 
					
						
							| 
									
										
										
										
											2009-10-05 12:53:18 +02:00
										 |  |  |                                                           line, lineText, col, len)); | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         _references.append(tokenIndex); | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |     bool checkCandidates(const QList<Symbol *> &candidates) const | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  |         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; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |     bool isDeclSymbol(Symbol *symbol) const | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |         if (! symbol) | 
					
						
							|  |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |         else if (symbol == _declSymbol) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         else if (symbol->line() == _declSymbol->line() && symbol->column() == _declSymbol->column()) { | 
					
						
							|  |  |  |             if (! qstrcmp(symbol->fileName(), _declSymbol->fileName())) | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 19:02:33 +02:00
										 |  |  |     LookupContext _previousContext; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     LookupContext currentContext(AST *ast) | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |         unsigned line, column; | 
					
						
							|  |  |  |         getTokenStartPosition(ast->firstToken(), &line, &column); | 
					
						
							|  |  |  |         Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); | 
					
						
							| 
									
										
										
										
											2009-09-30 19:02:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (lastVisibleSymbol && lastVisibleSymbol == _previousContext.symbol()) | 
					
						
							|  |  |  |             return _previousContext; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 18:52:19 +02:00
										 |  |  |         LookupContext ctx(lastVisibleSymbol, _exprDoc, _doc, _snapshot); | 
					
						
							| 
									
										
										
										
											2009-09-30 19:02:33 +02:00
										 |  |  |         _previousContext = ctx; | 
					
						
							| 
									
										
										
										
											2009-09-30 18:52:19 +02:00
										 |  |  |         return ctx; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 13:02:15 +02:00
										 |  |  |     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); | 
					
						
							| 
									
										
										
										
											2009-10-05 12:53:18 +02:00
										 |  |  |                 reportResult(simple->identifier_token, candidates); | 
					
						
							| 
									
										
										
										
											2009-09-29 13:02:15 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         accept(ast->expression); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  |     virtual bool visit(PostfixExpressionAST *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         _postfixExpressionStack.append(ast); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 13:02:15 +02:00
										 |  |  |     virtual void endVisit(PostfixExpressionAST *) | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         _postfixExpressionStack.removeLast(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(MemberAccessAST *ast) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |         if (ast->member_name) { | 
					
						
							|  |  |  |             if (SimpleNameAST *simple = ast->member_name->asSimpleName()) { | 
					
						
							|  |  |  |                 if (identifier(simple->identifier_token) == _id) { | 
					
						
							|  |  |  |                     Q_ASSERT(! _postfixExpressionStack.isEmpty()); | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |                     checkExpression(_postfixExpressionStack.last()->firstToken(), | 
					
						
							|  |  |  |                                     simple->identifier_token); | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |     void checkExpression(unsigned startToken, unsigned endToken) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         const unsigned begin = tokenAt(startToken).begin(); | 
					
						
							|  |  |  |         const unsigned end = tokenAt(endToken).end(); | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |         const QString expression = _source.mid(begin, end - begin); | 
					
						
							| 
									
										
										
										
											2009-09-30 18:52:19 +02:00
										 |  |  |         // qDebug() << "*** check expression:" << expression;
 | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |         TypeOfExpression typeofExpression; | 
					
						
							|  |  |  |         typeofExpression.setSnapshot(_snapshot); | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |         unsigned line, column; | 
					
						
							|  |  |  |         getTokenStartPosition(startToken, &line, &column); | 
					
						
							|  |  |  |         Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |         const QList<TypeOfExpression::Result> results = | 
					
						
							|  |  |  |                 typeofExpression(expression, _doc, lastVisibleSymbol, | 
					
						
							| 
									
										
										
										
											2009-09-29 16:20:12 +02:00
										 |  |  |                                  TypeOfExpression::Preprocess); | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |         QList<Symbol *> candidates; | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |         foreach (TypeOfExpression::Result r, results) { | 
					
						
							|  |  |  |             FullySpecifiedType ty = r.first; | 
					
						
							|  |  |  |             Symbol *lastVisibleSymbol = r.second; | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |             candidates.append(lastVisibleSymbol); | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 12:53:18 +02:00
										 |  |  |         reportResult(endToken, candidates); | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     virtual bool visit(QualifiedNameAST *ast) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |         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); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(SimpleNameAST *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Identifier *id = identifier(ast->identifier_token); | 
					
						
							|  |  |  |         if (id == _id) { | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |             LookupContext context = currentContext(ast); | 
					
						
							|  |  |  |             const QList<Symbol *> candidates = context.resolve(ast->name); | 
					
						
							| 
									
										
										
										
											2009-10-05 12:53:18 +02:00
										 |  |  |             reportResult(ast->identifier_token, candidates); | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |     virtual bool visit(DestructorNameAST *ast) | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         Identifier *id = identifier(ast->identifier_token); | 
					
						
							|  |  |  |         if (id == _id) { | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |             LookupContext context = currentContext(ast); | 
					
						
							|  |  |  |             const QList<Symbol *> candidates = context.resolve(ast->name); | 
					
						
							| 
									
										
										
										
											2009-10-05 12:53:18 +02:00
										 |  |  |             reportResult(ast->identifier_token, candidates); | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(TemplateIdAST *ast) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-10-05 13:46:40 +02:00
										 |  |  |         if (_id == identifier(ast->identifier_token)) { | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |             LookupContext context = currentContext(ast); | 
					
						
							|  |  |  |             const QList<Symbol *> candidates = context.resolve(ast->name); | 
					
						
							| 
									
										
										
										
											2009-10-05 12:53:18 +02:00
										 |  |  |             reportResult(ast->identifier_token, candidates); | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 13:46:40 +02:00
										 |  |  |         for (TemplateArgumentListAST *template_arguments = ast->template_arguments; | 
					
						
							|  |  |  |              template_arguments; template_arguments = template_arguments->next) { | 
					
						
							|  |  |  |             accept(template_arguments->template_argument); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 12:36:46 +02:00
										 |  |  |     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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // ### TODO: well, not exactly. We need to look at qualified-name-ids and nested-declarators.
 | 
					
						
							|  |  |  |             // 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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2009-10-05 11:06:05 +02:00
										 |  |  |     QFutureInterface<Utils::FileSearchResult> *_future; | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |     Identifier *_id; // ### remove me
 | 
					
						
							|  |  |  |     Symbol *_declSymbol; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     Document::Ptr _doc; | 
					
						
							|  |  |  |     Snapshot _snapshot; | 
					
						
							|  |  |  |     QByteArray _source; | 
					
						
							|  |  |  |     Document::Ptr _exprDoc; | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |     Semantic _sem; | 
					
						
							| 
									
										
										
										
											2009-09-29 12:32:35 +02:00
										 |  |  |     QList<PostfixExpressionAST *> _postfixExpressionStack; | 
					
						
							| 
									
										
										
										
											2009-09-29 14:41:15 +02:00
										 |  |  |     QList<QualifiedNameAST *> _qualifiedNameStack; | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  |     QList<int> _references; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // end of anonymous namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CppFindReferences::CppFindReferences(CppModelManager *modelManager) | 
					
						
							|  |  |  |     : _modelManager(modelManager), | 
					
						
							|  |  |  |       _resultWindow(ExtensionSystem::PluginManager::instance()->getObject<Find::SearchResultWindow>()) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_watcher.setPendingResultsLimit(1); | 
					
						
							|  |  |  |     connect(&m_watcher, SIGNAL(resultReadyAt(int)), this, SLOT(displayResult(int))); | 
					
						
							|  |  |  |     connect(&m_watcher, SIGNAL(finished()), this, SLOT(searchFinished())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CppFindReferences::~CppFindReferences() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  | QList<int> CppFindReferences::references(Symbol *symbol, | 
					
						
							|  |  |  |                                          Document::Ptr doc, | 
					
						
							|  |  |  |                                          const Snapshot& snapshot) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Identifier *id = 0; | 
					
						
							|  |  |  |     if (Identifier *symbolId = symbol->identifier()) | 
					
						
							|  |  |  |         id = doc->control()->findIdentifier(symbolId->chars(), symbolId->size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QList<int> references; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (! id) | 
					
						
							|  |  |  |         return references; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TranslationUnit *translationUnit = doc->translationUnit(); | 
					
						
							|  |  |  |     Q_ASSERT(translationUnit != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Process process(doc, snapshot, /*future = */ 0); | 
					
						
							|  |  |  |     references = process(symbol, id, translationUnit->ast()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return references; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:06:05 +02:00
										 |  |  | static void find_helper(QFutureInterface<Utils::FileSearchResult> &future, | 
					
						
							| 
									
										
										
										
											2009-09-29 13:42:47 +02:00
										 |  |  |                         const QMap<QString, QString> wl, | 
					
						
							| 
									
										
										
										
											2009-09-24 16:51:40 +02:00
										 |  |  |                         Snapshot snapshot, | 
					
						
							|  |  |  |                         Symbol *symbol) | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QTime tm; | 
					
						
							|  |  |  |     tm.start(); | 
					
						
							| 
									
										
										
										
											2009-09-24 16:51:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |     Identifier *symbolId = symbol->identifier(); | 
					
						
							|  |  |  |     Q_ASSERT(symbolId != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 13:50:55 +02:00
										 |  |  |     const QString sourceFile = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()); | 
					
						
							| 
									
										
										
										
											2009-09-24 16:51:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 13:50:55 +02:00
										 |  |  |     QStringList files(sourceFile); | 
					
						
							|  |  |  |     files += snapshot.dependsOn(sourceFile); | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     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) { | 
					
						
							| 
									
										
										
										
											2009-10-05 13:43:05 +02:00
										 |  |  |         if (future.isPaused()) | 
					
						
							|  |  |  |             future.waitForResume(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (future.isCanceled()) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 13:50:55 +02:00
										 |  |  |         const QString &fileName = files.at(i); | 
					
						
							|  |  |  |         future.setProgressValueAndText(i, QFileInfo(fileName).fileName()); | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 18:52:19 +02:00
										 |  |  |         if (Document::Ptr previousDoc = snapshot.value(fileName)) { | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |             Control *control = previousDoc->control(); | 
					
						
							|  |  |  |             Identifier *id = control->findIdentifier(symbolId->chars(), symbolId->size()); | 
					
						
							|  |  |  |             if (! id) | 
					
						
							|  |  |  |                 continue; // skip this document, it's not using symbolId.
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 13:42:47 +02:00
										 |  |  |         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); | 
					
						
							| 
									
										
										
										
											2009-09-07 13:40:13 +02:00
										 |  |  |         doc->tokenize(); | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Control *control = doc->control(); | 
					
						
							| 
									
										
										
										
											2009-09-24 16:51:40 +02:00
										 |  |  |         if (Identifier *id = control->findIdentifier(symbolId->chars(), symbolId->size())) { | 
					
						
							| 
									
										
										
										
											2009-09-30 19:02:33 +02:00
										 |  |  |             QTime tm; | 
					
						
							|  |  |  |             tm.start(); | 
					
						
							| 
									
										
										
										
											2009-09-07 13:40:13 +02:00
										 |  |  |             TranslationUnit *unit = doc->translationUnit(); | 
					
						
							| 
									
										
										
										
											2009-09-30 17:15:31 +02:00
										 |  |  |             Control *control = doc->control(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 18:52:19 +02:00
										 |  |  |             FastMacroResolver fastMacroResolver(unit, snapshot); | 
					
						
							| 
									
										
										
										
											2009-09-30 17:15:31 +02:00
										 |  |  |             control->setMacroResolver(&fastMacroResolver); | 
					
						
							|  |  |  |             doc->parse(); | 
					
						
							|  |  |  |             control->setMacroResolver(0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 19:02:33 +02:00
										 |  |  |             //qDebug() << "***" << unit->fileName() << "parsed in:" << tm.elapsed();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             tm.start(); | 
					
						
							| 
									
										
										
										
											2009-09-30 17:15:31 +02:00
										 |  |  |             doc->check(); | 
					
						
							| 
									
										
										
										
											2009-09-30 19:02:33 +02:00
										 |  |  |             //qDebug() << "***" << unit->fileName() << "checked in:" << tm.elapsed();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             tm.start(); | 
					
						
							| 
									
										
										
										
											2009-09-30 17:15:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  |             Process process(doc, snapshot, &future); | 
					
						
							| 
									
										
										
										
											2009-09-25 14:19:43 +02:00
										 |  |  |             process(symbol, id, unit->ast()); | 
					
						
							| 
									
										
										
										
											2009-09-30 19:02:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             //qDebug() << "***" << unit->fileName() << "processed in:" << tm.elapsed();
 | 
					
						
							| 
									
										
										
										
											2009-09-07 13:40:13 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-09-29 13:42:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     future.setProgressValue(files.size()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 13:42:47 +02:00
										 |  |  | void CppFindReferences::findAll(Symbol *symbol) | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     _resultWindow->clearContents(); | 
					
						
							| 
									
										
										
										
											2009-09-29 18:16:13 +02:00
										 |  |  |     _resultWindow->setShowReplaceUI(true); | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     _resultWindow->popup(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 13:42:47 +02:00
										 |  |  |     const Snapshot snapshot = _modelManager->snapshot(); | 
					
						
							|  |  |  |     const QMap<QString, QString> wl = _modelManager->buildWorkingCopyList(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:06:05 +02:00
										 |  |  |     QFuture<Utils::FileSearchResult> result = QtConcurrent::run(&find_helper, wl, snapshot, symbol); | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     m_watcher.setFuture(result); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."), | 
					
						
							| 
									
										
										
										
											2009-09-07 13:55:18 +02:00
										 |  |  |                                                               CppTools::Constants::TASK_SEARCH, | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |                                                               Core::ProgressManager::CloseOnSuccess); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     connect(progress, SIGNAL(clicked()), _resultWindow, SLOT(popup())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppFindReferences::displayResult(int index) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-05 11:06:05 +02:00
										 |  |  |     Utils::FileSearchResult result = m_watcher.future().resultAt(index); | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     Find::ResultWindowItem *item = _resultWindow->addResult(result.fileName, | 
					
						
							|  |  |  |                                                             result.lineNumber, | 
					
						
							|  |  |  |                                                             result.matchingLine, | 
					
						
							|  |  |  |                                                             result.matchStart, | 
					
						
							|  |  |  |                                                             result.matchLength); | 
					
						
							|  |  |  |     if (item) | 
					
						
							|  |  |  |         connect(item, SIGNAL(activated(const QString&,int,int)), | 
					
						
							|  |  |  |                 this, SLOT(openEditor(const QString&,int,int))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppFindReferences::searchFinished() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     emit changed(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppFindReferences::openEditor(const QString &fileName, int line, int column) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     TextEditor::BaseTextEditor::openEditorAt(fileName, line, column); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |