| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | /**************************************************************************
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-03-05 11:25:49 +01:00
										 |  |  | ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-06-17 00:01:27 +10:00
										 |  |  | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Commercial Usage | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** 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. | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** GNU Lesser General Public License Usage | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** 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.
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** If you are unsure which license is appropriate for your use, please | 
					
						
							| 
									
										
										
										
											2009-08-14 09:30:56 +02:00
										 |  |  | ** contact the sales department at http://qt.nokia.com/contact.
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | **************************************************************************/ | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "CppDocument.h"
 | 
					
						
							| 
									
										
										
										
											2009-06-03 16:16:20 +02:00
										 |  |  | #include "FastPreprocessor.h"
 | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  | #include "LookupContext.h"
 | 
					
						
							|  |  |  | #include "Overview.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-13 15:28:22 +02:00
										 |  |  | #include "Bind.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | #include <Control.h>
 | 
					
						
							|  |  |  | #include <TranslationUnit.h>
 | 
					
						
							|  |  |  | #include <DiagnosticClient.h>
 | 
					
						
							|  |  |  | #include <Literals.h>
 | 
					
						
							|  |  |  | #include <Symbols.h>
 | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  | #include <Names.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | #include <AST.h>
 | 
					
						
							|  |  |  | #include <Scope.h>
 | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  | #include <SymbolVisitor.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 10:16:48 +02:00
										 |  |  | #include <QtCore/QByteArray>
 | 
					
						
							|  |  |  | #include <QtCore/QBitArray>
 | 
					
						
							| 
									
										
										
										
											2009-11-09 13:53:28 +01:00
										 |  |  | #include <QtCore/QDir>
 | 
					
						
							| 
									
										
										
										
											2009-07-29 10:16:48 +02:00
										 |  |  | #include <QtCore/QtDebug>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 16:00:14 +02:00
										 |  |  | /*!
 | 
					
						
							|  |  |  |     \namespace CPlusPlus | 
					
						
							|  |  |  |     The namespace for C++ related tools. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | using namespace CPlusPlus; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-17 13:42:04 +02:00
										 |  |  | class LastVisibleSymbolAt: protected SymbolVisitor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Symbol *root; | 
					
						
							|  |  |  |     unsigned line; | 
					
						
							|  |  |  |     unsigned column; | 
					
						
							|  |  |  |     Symbol *symbol; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     LastVisibleSymbolAt(Symbol *root) | 
					
						
							|  |  |  |         : root(root), line(0), column(0), symbol(0) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Symbol *operator()(unsigned line, unsigned column) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         this->line = line; | 
					
						
							|  |  |  |         this->column = column; | 
					
						
							|  |  |  |         this->symbol = 0; | 
					
						
							|  |  |  |         accept(root); | 
					
						
							|  |  |  |         if (! symbol) | 
					
						
							|  |  |  |             symbol = root; | 
					
						
							|  |  |  |         return symbol; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |     bool preVisit(Symbol *s) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (s->asBlock()) { | 
					
						
							|  |  |  |             if (s->line() < line || (s->line() == line && s->column() <= column)) { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // skip blocks
 | 
					
						
							|  |  |  |         } if (s->line() < line || (s->line() == line && s->column() <= column)) { | 
					
						
							|  |  |  |             symbol = s; | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  | class FindScopeAt: protected SymbolVisitor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     TranslationUnit *_unit; | 
					
						
							|  |  |  |     unsigned _line; | 
					
						
							|  |  |  |     unsigned _column; | 
					
						
							|  |  |  |     Scope *_scope; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2010-07-16 15:24:42 +02:00
										 |  |  |     /** line and column should be 1-based */ | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  |     FindScopeAt(TranslationUnit *unit, unsigned line, unsigned column) | 
					
						
							|  |  |  |         : _unit(unit), _line(line), _column(column), _scope(0) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Scope *operator()(Symbol *symbol) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         accept(symbol); | 
					
						
							|  |  |  |         return _scope; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							| 
									
										
										
										
											2010-08-11 12:26:02 +02:00
										 |  |  |     bool process(Scope *symbol) | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         if (! _scope) { | 
					
						
							| 
									
										
										
										
											2010-08-11 12:26:02 +02:00
										 |  |  |             Scope *scope = symbol; | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-11 12:26:02 +02:00
										 |  |  |             for (unsigned i = 0; i < scope->memberCount(); ++i) { | 
					
						
							|  |  |  |                 accept(scope->memberAt(i)); | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 if (_scope) | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             unsigned startLine, startColumn; | 
					
						
							| 
									
										
										
										
											2010-07-19 10:42:07 +02:00
										 |  |  |             _unit->getPosition(scope->startOffset(), &startLine, &startColumn); | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (_line > startLine || (_line == startLine && _column >= startColumn)) { | 
					
						
							|  |  |  |                 unsigned endLine, endColumn; | 
					
						
							| 
									
										
										
										
											2010-07-19 10:42:07 +02:00
										 |  |  |                 _unit->getPosition(scope->endOffset(), &endLine, &endColumn); | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-03 18:41:31 +02:00
										 |  |  |                 if (_line < endLine || (_line == endLine && _column <= endColumn)) | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  |                     _scope = scope; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     using SymbolVisitor::visit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool preVisit(Symbol *) | 
					
						
							|  |  |  |     { return ! _scope; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(UsingNamespaceDirective *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(UsingDeclaration *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(NamespaceAlias *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(Declaration *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(Argument *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(TypenameArgument *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(BaseClass *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(ForwardClassDeclaration *) { return false; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(Enum *symbol) | 
					
						
							|  |  |  |     { return process(symbol); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(Function *symbol) | 
					
						
							|  |  |  |     { return process(symbol); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(Namespace *symbol) | 
					
						
							|  |  |  |     { return process(symbol); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(Class *symbol) | 
					
						
							|  |  |  |     { return process(symbol); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(Block *symbol) | 
					
						
							|  |  |  |     { return process(symbol); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Objective-C
 | 
					
						
							|  |  |  |     virtual bool visit(ObjCBaseClass *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(ObjCBaseProtocol *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(ObjCForwardClassDeclaration *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(ObjCForwardProtocolDeclaration *) { return false; } | 
					
						
							|  |  |  |     virtual bool visit(ObjCPropertyDeclaration *) { return false; } | 
					
						
							| 
									
										
										
										
											2010-05-20 16:07:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(ObjCClass *symbol) | 
					
						
							|  |  |  |     { return process(symbol); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(ObjCProtocol *symbol) | 
					
						
							|  |  |  |     { return process(symbol); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(ObjCMethod *symbol) | 
					
						
							|  |  |  |     { return process(symbol); } | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-03 18:41:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | class DocumentDiagnosticClient : public DiagnosticClient | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enum { MAX_MESSAGE_COUNT = 10 }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     DocumentDiagnosticClient(Document *doc, QList<Document::DiagnosticMessage> *messages) | 
					
						
							|  |  |  |         : doc(doc), | 
					
						
							| 
									
										
										
										
											2009-06-04 11:42:02 +02:00
										 |  |  |           messages(messages), | 
					
						
							|  |  |  |           errorCount(0) | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  |     { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual void report(int level, | 
					
						
							| 
									
										
										
										
											2009-12-01 11:33:13 +01:00
										 |  |  |                         const StringLiteral *fileId, | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  |                         unsigned line, unsigned column, | 
					
						
							|  |  |  |                         const char *format, va_list ap) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-06-04 11:42:02 +02:00
										 |  |  |         if (level == Error) { | 
					
						
							|  |  |  |             ++errorCount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (errorCount >= MAX_MESSAGE_COUNT) | 
					
						
							|  |  |  |                 return; // ignore the error
 | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  |         const QString fileName = QString::fromUtf8(fileId->chars(), fileId->size()); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  |         if (fileName != doc->fileName()) | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  |         QString message; | 
					
						
							|  |  |  |         message.vsprintf(format, ap); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  |         Document::DiagnosticMessage m(convertLevel(level), doc->fileName(), | 
					
						
							|  |  |  |                                       line, column, message); | 
					
						
							|  |  |  |         messages->append(m); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  |     static int convertLevel(int level) { | 
					
						
							|  |  |  |         switch (level) { | 
					
						
							|  |  |  |             case Warning: return Document::DiagnosticMessage::Warning; | 
					
						
							|  |  |  |             case Error:   return Document::DiagnosticMessage::Error; | 
					
						
							|  |  |  |             case Fatal:   return Document::DiagnosticMessage::Fatal; | 
					
						
							|  |  |  |             default:      return Document::DiagnosticMessage::Error; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-04 11:42:02 +02:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  |     Document *doc; | 
					
						
							|  |  |  |     QList<Document::DiagnosticMessage> *messages; | 
					
						
							| 
									
										
										
										
											2009-06-04 11:42:02 +02:00
										 |  |  |     int errorCount; | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | } // anonymous namespace
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 16:00:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | Document::Document(const QString &fileName) | 
					
						
							| 
									
										
										
										
											2009-11-09 13:53:28 +01:00
										 |  |  |     : _fileName(QDir::cleanPath(fileName)), | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  |       _globalNamespace(0), | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |       _revision(0), | 
					
						
							|  |  |  |       _editorRevision(0) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     _control = new Control(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _control->setDiagnosticClient(new DocumentDiagnosticClient(this, &_diagnosticMessages)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QByteArray localFileName = fileName.toUtf8(); | 
					
						
							| 
									
										
										
										
											2010-08-11 14:24:28 +02:00
										 |  |  |     const StringLiteral *fileId = _control->stringLiteral(localFileName.constData(), | 
					
						
							| 
									
										
										
										
											2009-12-01 11:33:13 +01:00
										 |  |  |                                                                       localFileName.size()); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     _translationUnit = new TranslationUnit(_control, fileId); | 
					
						
							|  |  |  |     _translationUnit->setQtMocRunEnabled(true); | 
					
						
							| 
									
										
										
										
											2010-05-21 10:51:48 +02:00
										 |  |  |     _translationUnit->setCxxOxEnabled(true); | 
					
						
							| 
									
										
										
										
											2009-02-04 11:36:17 +01:00
										 |  |  |     _translationUnit->setObjCEnabled(true); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     (void) _control->switchTranslationUnit(_translationUnit); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Document::~Document() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     delete _translationUnit; | 
					
						
							|  |  |  |     delete _control->diagnosticClient(); | 
					
						
							|  |  |  |     delete _control; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Control *Document::control() const | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return _control; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  | unsigned Document::revision() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _revision; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Document::setRevision(unsigned revision) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _revision = revision; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  | unsigned Document::editorRevision() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _editorRevision; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Document::setEditorRevision(unsigned editorRevision) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _editorRevision = editorRevision; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 12:34:02 +01:00
										 |  |  | QDateTime Document::lastModified() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _lastModified; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Document::setLastModified(const QDateTime &lastModified) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _lastModified = lastModified; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | QString Document::fileName() const | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return _fileName; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | QStringList Document::includedFiles() const | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-10 17:21:01 +01:00
										 |  |  |     QStringList files; | 
					
						
							|  |  |  |     foreach (const Include &i, _includes) | 
					
						
							|  |  |  |         files.append(i.fileName()); | 
					
						
							|  |  |  |     files.removeDuplicates(); | 
					
						
							|  |  |  |     return files; | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-10 17:21:01 +01:00
										 |  |  | void Document::addIncludeFile(const QString &fileName, unsigned line) | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-09 13:53:28 +01:00
										 |  |  |     _includes.append(Include(QDir::cleanPath(fileName), line)); | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 12:59:33 +01:00
										 |  |  | void Document::appendMacro(const Macro ¯o) | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-08 12:59:33 +01:00
										 |  |  |     _definedMacros.append(macro); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-04 11:47:30 +01:00
										 |  |  | void Document::addMacroUse(const Macro ¯o, unsigned offset, unsigned length, | 
					
						
							| 
									
										
										
										
											2009-12-21 14:47:22 +01:00
										 |  |  |                            unsigned beginLine, | 
					
						
							| 
									
										
										
										
											2009-09-25 16:00:14 +02:00
										 |  |  |                            const QVector<MacroArgumentReference> &actuals, bool inCondition) | 
					
						
							| 
									
										
										
										
											2008-12-04 12:05:04 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-21 14:47:22 +01:00
										 |  |  |     MacroUse use(macro, offset, offset + length, beginLine); | 
					
						
							| 
									
										
										
										
											2009-09-25 16:00:14 +02:00
										 |  |  |     use.setInCondition(inCondition); | 
					
						
							| 
									
										
										
										
											2009-03-04 11:47:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     foreach (const MacroArgumentReference &actual, actuals) { | 
					
						
							|  |  |  |         const Block arg(actual.position(), actual.position() + actual.length()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         use.addArgument(arg); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _macroUses.append(use); | 
					
						
							| 
									
										
										
										
											2008-12-04 12:05:04 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 16:00:14 +02:00
										 |  |  | void Document::addUndefinedMacroUse(const QByteArray &name, unsigned offset) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QByteArray copy(name.data(), name.size()); | 
					
						
							|  |  |  |     UndefinedMacroUse use(copy, offset); | 
					
						
							|  |  |  |     _undefinedMacroUses.append(use); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \class Document::MacroUse | 
					
						
							|  |  |  |     \brief Represents the usage of a macro in a \l {Document}. | 
					
						
							|  |  |  |     \sa Document::UndefinedMacroUse | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \class Document::UndefinedMacroUse | 
					
						
							|  |  |  |     \brief Represents a macro that was looked up, but not found. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Holds data about the reference to a macro in an \tt{#ifdef} or \tt{#ifndef} | 
					
						
							|  |  |  |     or argument to the \tt{defined} operator inside an \tt{#if} or \tt{#elif} that does | 
					
						
							|  |  |  |     not exist. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     \sa Document::undefinedMacroUses(), Document::MacroUse, Macro | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \fn QByteArray Document::UndefinedMacroUse::name() const | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Returns the name of the macro that was not found. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \fn QList<UndefinedMacroUse> Document::undefinedMacroUses() const | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Returns a list of referenced but undefined macros. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     \sa Document::macroUses(), Document::definedMacros(), Macro | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \fn QList<MacroUse> Document::macroUses() const | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Returns a list of macros used. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     \sa Document::undefinedMacroUses(), Document::definedMacros(), Macro | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \fn QList<Macro> Document::definedMacros() const | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Returns the list of macros defined. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     \sa Document::macroUses(), Document::undefinedMacroUses() | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | TranslationUnit *Document::translationUnit() const | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return _translationUnit; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool Document::skipFunctionBody() const | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return _translationUnit->skipFunctionBody(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void Document::setSkipFunctionBody(bool skipFunctionBody) | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     _translationUnit->setSkipFunctionBody(skipFunctionBody); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | unsigned Document::globalSymbolCount() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! _globalNamespace) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return _globalNamespace->memberCount(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Symbol *Document::globalSymbolAt(unsigned index) const | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return _globalNamespace->memberAt(index); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Namespace *Document::globalNamespace() const | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return _globalNamespace; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-18 15:21:07 +01:00
										 |  |  | void Document::setGlobalNamespace(Namespace *globalNamespace) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _globalNamespace = globalNamespace; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  | Scope *Document::scopeAt(unsigned line, unsigned column) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     FindScopeAt findScopeAt(_translationUnit, line, column); | 
					
						
							| 
									
										
										
										
											2010-05-12 14:41:25 +02:00
										 |  |  |     if (Scope *scope = findScopeAt(_globalNamespace)) | 
					
						
							|  |  |  |         return scope; | 
					
						
							| 
									
										
										
										
											2010-08-11 12:26:02 +02:00
										 |  |  |     return globalNamespace(); | 
					
						
							| 
									
										
										
										
											2010-05-12 12:53:16 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-17 13:01:56 +02:00
										 |  |  | Symbol *Document::lastVisibleSymbolAt(unsigned line, unsigned column) const | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-17 13:42:04 +02:00
										 |  |  |     LastVisibleSymbolAt lastVisibleSymbolAt(globalNamespace()); | 
					
						
							|  |  |  |     return lastVisibleSymbolAt(line, column); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-21 14:47:22 +01:00
										 |  |  | const Macro *Document::findMacroDefinitionAt(unsigned line) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     foreach (const Macro ¯o, _definedMacros) { | 
					
						
							|  |  |  |         if (macro.line() == line) | 
					
						
							|  |  |  |             return ¯o; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const Document::MacroUse *Document::findMacroUseAt(unsigned offset) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     foreach (const Document::MacroUse &use, _macroUses) { | 
					
						
							|  |  |  |         if (use.contains(offset)) | 
					
						
							|  |  |  |             return &use; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(unsigned offset) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     foreach (const Document::UndefinedMacroUse &use, _undefinedMacroUses) { | 
					
						
							|  |  |  |         if (use.contains(offset)) | 
					
						
							|  |  |  |             return &use; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | Document::Ptr Document::create(const QString &fileName) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Document::Ptr doc(new Document(fileName)); | 
					
						
							|  |  |  |     return doc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-05 14:29:57 +02:00
										 |  |  | QByteArray Document::source() const | 
					
						
							|  |  |  | { return _source; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | void Document::setSource(const QByteArray &source) | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  |     _source = source; | 
					
						
							|  |  |  |     _translationUnit->setSource(_source.constBegin(), _source.size()); | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void Document::startSkippingBlocks(unsigned start) | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     _skippedBlocks.append(Block(start, 0)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void Document::stopSkippingBlocks(unsigned stop) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  |     if (_skippedBlocks.isEmpty()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     unsigned start = _skippedBlocks.back().begin(); | 
					
						
							|  |  |  |     if (start > stop) | 
					
						
							|  |  |  |         _skippedBlocks.removeLast(); // Ignore this block, it's invalid.
 | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         _skippedBlocks.back() = Block(start, stop); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  | bool Document::isTokenized() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _translationUnit->isTokenized(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Document::tokenize() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _translationUnit->tokenize(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Document::isParsed() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _translationUnit->isParsed(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-03 14:01:19 +01:00
										 |  |  | bool Document::parse(ParseMode mode) | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-03 14:01:19 +01:00
										 |  |  |     TranslationUnit::ParseMode m = TranslationUnit::ParseTranlationUnit; | 
					
						
							|  |  |  |     switch (mode) { | 
					
						
							|  |  |  |     case ParseTranlationUnit: | 
					
						
							|  |  |  |         m = TranslationUnit::ParseTranlationUnit; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case ParseDeclaration: | 
					
						
							|  |  |  |         m = TranslationUnit::ParseDeclaration; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case ParseExpression: | 
					
						
							|  |  |  |         m = TranslationUnit::ParseExpression; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-30 15:07:30 +02:00
										 |  |  |     case ParseDeclarator: | 
					
						
							|  |  |  |         m = TranslationUnit::ParseDeclarator; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-03 14:01:19 +01:00
										 |  |  |     case ParseStatement: | 
					
						
							|  |  |  |         m = TranslationUnit::ParseStatement; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return _translationUnit->parse(m); | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-26 09:11:14 +02:00
										 |  |  | void Document::check(CheckMode mode) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-10 15:43:17 +01:00
										 |  |  |     Q_ASSERT(!_globalNamespace); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 16:13:43 +02:00
										 |  |  |     if (! isParsed()) | 
					
						
							|  |  |  |         parse(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 15:28:22 +02:00
										 |  |  |     _globalNamespace = _control->newNamespace(0); | 
					
						
							|  |  |  |     Bind semantic(_translationUnit); | 
					
						
							| 
									
										
										
										
											2009-06-26 09:11:14 +02:00
										 |  |  |     if (mode == FastCheck) | 
					
						
							|  |  |  |         semantic.setSkipFunctionBodies(true); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-03 14:01:19 +01:00
										 |  |  |     if (! _translationUnit->ast()) | 
					
						
							|  |  |  |         return; // nothing to do.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (TranslationUnitAST *ast = _translationUnit->ast()->asTranslationUnit()) { | 
					
						
							| 
									
										
										
										
											2010-08-13 15:28:22 +02:00
										 |  |  |         semantic(ast, _globalNamespace); | 
					
						
							| 
									
										
										
										
											2009-06-17 11:11:21 +02:00
										 |  |  |     } else if (ExpressionAST *ast = _translationUnit->ast()->asExpression()) { | 
					
						
							| 
									
										
										
										
											2010-08-13 15:28:22 +02:00
										 |  |  |         semantic(ast, _globalNamespace); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  | void Document::releaseSource() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _source.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | void Document::releaseTranslationUnit() | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     _translationUnit->release(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-04 11:47:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Snapshot::Snapshot() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Snapshot::~Snapshot() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  | int Snapshot::size() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _documents.size(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Snapshot::isEmpty() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _documents.isEmpty(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Document::Ptr Snapshot::operator[](const QString &fileName) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _documents.value(fileName, Document::Ptr()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Snapshot::const_iterator Snapshot::find(const QString &fileName) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _documents.find(fileName); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Snapshot::remove(const QString &fileName) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _documents.remove(fileName); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Snapshot::contains(const QString &fileName) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _documents.contains(fileName); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-04 11:47:30 +01:00
										 |  |  | void Snapshot::insert(Document::Ptr doc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (doc) | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  |         _documents.insert(doc->fileName(), doc); | 
					
						
							| 
									
										
										
										
											2009-03-04 11:47:30 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-15 15:38:20 +02:00
										 |  |  | QByteArray Snapshot::preprocessedCode(const QString &source, const QString &fileName) const | 
					
						
							| 
									
										
										
										
											2009-06-03 16:16:20 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     FastPreprocessor pp(*this); | 
					
						
							|  |  |  |     return pp.run(fileName, source); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Document::Ptr Snapshot::documentFromSource(const QByteArray &preprocessedCode, | 
					
						
							|  |  |  |                                            const QString &fileName) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-24 16:40:30 +02:00
										 |  |  |     Document::Ptr newDoc = Document::create(fileName); | 
					
						
							| 
									
										
										
										
											2009-06-03 16:16:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  |     if (Document::Ptr thisDocument = document(fileName)) { | 
					
						
							| 
									
										
										
										
											2009-11-05 12:34:02 +01:00
										 |  |  |         newDoc->_revision = thisDocument->_revision; | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |         newDoc->_editorRevision = thisDocument->_editorRevision; | 
					
						
							| 
									
										
										
										
											2009-11-05 12:34:02 +01:00
										 |  |  |         newDoc->_lastModified = thisDocument->_lastModified; | 
					
						
							| 
									
										
										
										
											2009-06-03 16:16:20 +02:00
										 |  |  |         newDoc->_includes = thisDocument->_includes; | 
					
						
							|  |  |  |         newDoc->_definedMacros = thisDocument->_definedMacros; | 
					
						
							| 
									
										
										
										
											2009-10-15 16:24:15 +02:00
										 |  |  |         newDoc->_macroUses = thisDocument->_macroUses; | 
					
						
							| 
									
										
										
										
											2009-06-03 16:16:20 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-24 16:40:30 +02:00
										 |  |  |     newDoc->setSource(preprocessedCode); | 
					
						
							|  |  |  |     return newDoc; | 
					
						
							| 
									
										
										
										
											2009-06-03 16:16:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  | Document::Ptr Snapshot::document(const QString &fileName) const | 
					
						
							| 
									
										
										
										
											2009-12-02 17:05:36 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-07 11:20:16 +01:00
										 |  |  |     return _documents.value(fileName); | 
					
						
							| 
									
										
										
										
											2009-12-02 17:05:36 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-10 11:59:01 +02:00
										 |  |  | Snapshot Snapshot::simplified(Document::Ptr doc) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Snapshot snapshot; | 
					
						
							|  |  |  |     simplified_helper(doc, &snapshot); | 
					
						
							|  |  |  |     return snapshot; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! doc) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (! snapshot->contains(doc->fileName())) { | 
					
						
							|  |  |  |         snapshot->insert(doc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach (const Document::Include &incl, doc->includes()) { | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  |             Document::Ptr includedDoc = document(incl.fileName()); | 
					
						
							| 
									
										
										
										
											2009-07-10 11:59:01 +02:00
										 |  |  |             simplified_helper(includedDoc, snapshot); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | class FindMatchingDefinition: public SymbolVisitor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Symbol *_declaration; | 
					
						
							|  |  |  |     QList<Function *> _result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     FindMatchingDefinition(Symbol *declaration) | 
					
						
							|  |  |  |         : _declaration(declaration) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QList<Function *> result() const { return _result; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     using SymbolVisitor::visit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(Function *fun) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (_declaration->identifier()->isEqualTo(fun->identifier())) | 
					
						
							|  |  |  |             _result.append(fun); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(Block *) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | } // end of anonymous namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-05 13:34:27 +02:00
										 |  |  | Symbol *Snapshot::findMatchingDefinition(Symbol *declaration) const | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-05 13:34:27 +02:00
										 |  |  |     if (! (declaration && declaration->identifier())) | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-05 13:34:27 +02:00
										 |  |  |     Document::Ptr thisDocument = document(QString::fromUtf8(declaration->fileName(), declaration->fileNameLength())); | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  |     if (! thisDocument) { | 
					
						
							| 
									
										
										
										
											2010-07-05 13:34:27 +02:00
										 |  |  |         qWarning() << "undefined document:" << declaration->fileName(); | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Function *declarationTy = declaration->type()->asFunctionType(); | 
					
						
							|  |  |  |     if (! declarationTy) { | 
					
						
							|  |  |  |         qWarning() << "not a function:" << declaration->fileName() << declaration->line() << declaration->column(); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (Document::Ptr doc, *this) { | 
					
						
							|  |  |  |         if (! doc->control()->findIdentifier(declaration->identifier()->chars(), | 
					
						
							|  |  |  |                                              declaration->identifier()->size())) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         FindMatchingDefinition candidates(declaration); | 
					
						
							|  |  |  |         candidates.accept(doc->globalNamespace()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const QList<Function *> result = candidates.result(); | 
					
						
							|  |  |  |         if (! result.isEmpty()) { | 
					
						
							|  |  |  |             LookupContext context(doc, *this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QList<Function *> viableFunctions; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-21 11:35:03 +02:00
										 |  |  |             ClassOrNamespace *enclosingType = context.lookupType(declaration); | 
					
						
							|  |  |  |             if (! enclosingType) | 
					
						
							|  |  |  |                 continue; // nothing to do
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  |             foreach (Function *fun, result) { | 
					
						
							| 
									
										
										
										
											2010-08-26 16:16:22 +02:00
										 |  |  |                 const QList<LookupItem> declarations = context.lookup(fun->name(), fun->enclosingScope()); | 
					
						
							| 
									
										
										
										
											2010-05-21 11:35:03 +02:00
										 |  |  |                 if (declarations.isEmpty()) | 
					
						
							|  |  |  |                     continue; | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-16 11:03:39 +02:00
										 |  |  |                 const LookupItem best = declarations.first(); | 
					
						
							|  |  |  |                 if (enclosingType == context.lookupType(best.declaration())) | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  |                     viableFunctions.append(fun); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (viableFunctions.isEmpty()) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             else if (viableFunctions.length() == 1) | 
					
						
							|  |  |  |                 return viableFunctions.first(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             Function *best = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             foreach (Function *fun, viableFunctions) { | 
					
						
							| 
									
										
										
										
											2010-08-26 12:23:09 +02:00
										 |  |  |                 if (fun->unqualifiedName()->isEqualTo(declaration->unqualifiedName())) | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  |                     continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 else if (fun->argumentCount() == declarationTy->argumentCount()) { | 
					
						
							|  |  |  |                     if (! best) | 
					
						
							|  |  |  |                         best = fun; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     unsigned argc = 0; | 
					
						
							|  |  |  |                     for (; argc < declarationTy->argumentCount(); ++argc) { | 
					
						
							|  |  |  |                         Symbol *arg = fun->argumentAt(argc); | 
					
						
							|  |  |  |                         Symbol *otherArg = declarationTy->argumentAt(argc); | 
					
						
							|  |  |  |                         if (! arg->type().isEqualTo(otherArg->type())) | 
					
						
							|  |  |  |                             break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (argc == declarationTy->argumentCount()) | 
					
						
							|  |  |  |                         best = fun; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (! best) | 
					
						
							|  |  |  |                 best = viableFunctions.first(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return best; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-06-16 15:35:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | Class *Snapshot::findMatchingClassDeclaration(Symbol *declaration) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! declaration->identifier()) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (Document::Ptr doc, *this) { | 
					
						
							|  |  |  |         if (! doc->control()->findIdentifier(declaration->identifier()->chars(), | 
					
						
							|  |  |  |                                              declaration->identifier()->size())) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         LookupContext context(doc, *this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ClassOrNamespace *type = context.lookupType(declaration); | 
					
						
							| 
									
										
										
										
											2010-06-18 09:26:38 +02:00
										 |  |  |         if (!type) | 
					
						
							| 
									
										
										
										
											2010-06-16 15:35:34 +02:00
										 |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-18 09:26:38 +02:00
										 |  |  |         foreach (Symbol *s, type->symbols()) { | 
					
						
							|  |  |  |             if (Class *c = s->asClass()) | 
					
						
							|  |  |  |                 return c; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-06-16 15:35:34 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } |