| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | /**************************************************************************
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2011-01-11 16:28:15 +01:00
										 |  |  | ** Copyright (c) 2011 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
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** No Commercial Usage | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** This file contains pre-release code and may not be distributed. | 
					
						
							|  |  |  | ** You may use this file in accordance with the terms and conditions | 
					
						
							|  |  |  | ** contained in the Technology Preview License Agreement accompanying | 
					
						
							|  |  |  | ** this package. | 
					
						
							| 
									
										
										
										
											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
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** In addition, as a special exception, Nokia gives you certain additional | 
					
						
							|  |  |  | ** rights.  These rights are described in the Nokia Qt LGPL Exception | 
					
						
							|  |  |  | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** If you have questions regarding the use of this file, please contact | 
					
						
							|  |  |  | ** Nokia at qt-info@nokia.com. | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | **************************************************************************/ | 
					
						
							| 
									
										
										
										
											2008-12-02 15:08:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 12:59:33 +01:00
										 |  |  | #include <cplusplus/pp.h>
 | 
					
						
							| 
									
										
										
										
											2009-06-04 11:32:01 +02:00
										 |  |  | #include <cplusplus/Overview.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "cppmodelmanager.h"
 | 
					
						
							| 
									
										
										
										
											2010-12-03 13:49:35 +01:00
										 |  |  | #include "abstracteditorsupport.h"
 | 
					
						
							| 
									
										
										
										
											2010-02-03 13:21:08 +10:00
										 |  |  | #ifndef ICHECK_BUILD
 | 
					
						
							|  |  |  | #  include "cpptoolsconstants.h"
 | 
					
						
							|  |  |  | #  include "cpptoolseditorsupport.h"
 | 
					
						
							|  |  |  | #  include "cppfindreferences.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-06 11:51:45 +01:00
										 |  |  | #include <functional>
 | 
					
						
							|  |  |  | #include <QtConcurrentRun>
 | 
					
						
							| 
									
										
										
										
											2010-02-03 13:21:08 +10:00
										 |  |  | #ifndef ICHECK_BUILD
 | 
					
						
							|  |  |  | #  include <QFutureSynchronizer>
 | 
					
						
							|  |  |  | #  include <qtconcurrent/runextensions.h>
 | 
					
						
							|  |  |  | #  include <texteditor/itexteditor.h>
 | 
					
						
							|  |  |  | #  include <texteditor/basetexteditor.h>
 | 
					
						
							|  |  |  | #  include <projectexplorer/project.h>
 | 
					
						
							|  |  |  | #  include <projectexplorer/projectexplorer.h>
 | 
					
						
							|  |  |  | #  include <projectexplorer/projectexplorerconstants.h>
 | 
					
						
							|  |  |  | #  include <projectexplorer/session.h>
 | 
					
						
							|  |  |  | #  include <coreplugin/icore.h>
 | 
					
						
							|  |  |  | #  include <coreplugin/mimedatabase.h>
 | 
					
						
							|  |  |  | #  include <coreplugin/editormanager/editormanager.h>
 | 
					
						
							|  |  |  | #  include <coreplugin/progressmanager/progressmanager.h>
 | 
					
						
							|  |  |  | #  include <extensionsystem/pluginmanager.h>
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #  include <QDir>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-10-05 13:43:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  | #include <utils/qtcassert.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | #include <TranslationUnit.h>
 | 
					
						
							|  |  |  | #include <AST.h>
 | 
					
						
							|  |  |  | #include <Scope.h>
 | 
					
						
							|  |  |  | #include <Literals.h>
 | 
					
						
							|  |  |  | #include <Symbols.h>
 | 
					
						
							|  |  |  | #include <Names.h>
 | 
					
						
							|  |  |  | #include <NameVisitor.h>
 | 
					
						
							|  |  |  | #include <TypeVisitor.h>
 | 
					
						
							| 
									
										
										
										
											2009-02-18 16:01:28 +01:00
										 |  |  | #include <ASTVisitor.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | #include <Lexer.h>
 | 
					
						
							|  |  |  | #include <Token.h>
 | 
					
						
							| 
									
										
										
										
											2010-03-18 15:21:07 +01:00
										 |  |  | #include <Parser.h>
 | 
					
						
							|  |  |  | #include <Control.h>
 | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  | #include <CoreTypes.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-17 21:11:52 +02:00
										 |  |  | #include <QtCore/QCoreApplication>
 | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  | #include <QtCore/QDebug>
 | 
					
						
							|  |  |  | #include <QtCore/QMutexLocker>
 | 
					
						
							|  |  |  | #include <QtCore/QTime>
 | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  | #include <QtCore/QTimer>
 | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  | #include <QtConcurrentMap>
 | 
					
						
							| 
									
										
										
										
											2010-04-26 14:02:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <QtGui/QTextBlock>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 16:01:28 +01:00
										 |  |  | #include <iostream>
 | 
					
						
							|  |  |  | #include <sstream>
 | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | using namespace CppTools; | 
					
						
							|  |  |  | using namespace CppTools::Internal; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | using namespace CPlusPlus; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-18 16:01:28 +01:00
										 |  |  | #if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <cxxabi.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DumpAST: protected ASTVisitor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     int depth; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DumpAST(Control *control) | 
					
						
							|  |  |  |         : ASTVisitor(control), depth(0) | 
					
						
							|  |  |  |     { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void operator()(AST *ast) | 
					
						
							|  |  |  |     { accept(ast); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |     virtual bool preVisit(AST *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         std::ostringstream s; | 
					
						
							|  |  |  |         PrettyPrinter pp(control(), s); | 
					
						
							|  |  |  |         pp(ast); | 
					
						
							|  |  |  |         QString code = QString::fromStdString(s.str()); | 
					
						
							|  |  |  |         code.replace('\n', ' '); | 
					
						
							|  |  |  |         code.replace(QRegExp("\\s+"), " "); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const char *name = abi::__cxa_demangle(typeid(*ast).name(), 0, 0, 0) + 11; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QByteArray ind(depth, ' '); | 
					
						
							|  |  |  |         ind += name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         printf("%-40s %s\n", ind.constData(), qPrintable(code)); | 
					
						
							|  |  |  |         ++depth; | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual void postVisit(AST *) | 
					
						
							|  |  |  |     { --depth; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-05 09:46:54 +01:00
										 |  |  | #endif // QTCREATOR_WITH_DUMP_AST
 | 
					
						
							| 
									
										
										
										
											2009-02-18 16:01:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | static const char pp_configuration_file[] = "<configuration>"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char pp_configuration[] = | 
					
						
							|  |  |  |     "# 1 \"<configuration>\"\n" | 
					
						
							|  |  |  |     "#define __cplusplus 1\n" | 
					
						
							|  |  |  |     "#define __extension__\n" | 
					
						
							|  |  |  |     "#define __context__\n" | 
					
						
							|  |  |  |     "#define __range__\n" | 
					
						
							|  |  |  |     "#define   restrict\n" | 
					
						
							|  |  |  |     "#define __restrict\n" | 
					
						
							| 
									
										
										
										
											2009-07-17 10:54:08 +02:00
										 |  |  |     "#define __restrict__\n" | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 09:53:26 +01:00
										 |  |  |     "#define __complex__\n" | 
					
						
							|  |  |  |     "#define __imag__\n" | 
					
						
							|  |  |  |     "#define __real__\n" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-18 17:48:55 +02:00
										 |  |  |     "#define __builtin_va_arg(a,b) ((b)0)\n" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     // ### add macros for win32
 | 
					
						
							|  |  |  |     "#define __cdecl\n" | 
					
						
							| 
									
										
										
										
											2009-12-10 16:20:34 +01:00
										 |  |  |     "#define __stdcall\n" | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     "#define QT_WA(x) x\n" | 
					
						
							|  |  |  |     "#define API\n" | 
					
						
							|  |  |  |     "#define WINAPI\n" | 
					
						
							|  |  |  |     "#define CALLBACK\n" | 
					
						
							|  |  |  |     "#define STDMETHODCALLTYPE\n" | 
					
						
							|  |  |  |     "#define __RPC_FAR\n" | 
					
						
							|  |  |  |     "#define APIENTRY\n" | 
					
						
							|  |  |  |     "#define __declspec(a)\n" | 
					
						
							|  |  |  |     "#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  | #ifndef ICHECK_BUILD
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager) | 
					
						
							| 
									
										
										
										
											2009-02-09 12:33:43 +01:00
										 |  |  |     : snapshot(modelManager->snapshot()), | 
					
						
							|  |  |  |       m_modelManager(modelManager), | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  |       preprocess(this, &env), | 
					
						
							|  |  |  |       m_revision(0) | 
					
						
							| 
									
										
										
										
											2009-03-17 14:39:52 +01:00
										 |  |  | { } | 
					
						
							| 
									
										
										
										
											2009-03-11 12:00:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CppPreprocessor::CppPreprocessor(QPointer<CPlusPlus::ParseManager> modelManager) | 
					
						
							|  |  |  |     : preprocess(this, &env), | 
					
						
							|  |  |  |       m_revision(0) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-11 12:00:07 +01:00
										 |  |  | CppPreprocessor::~CppPreprocessor() | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | { } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  | void CppPreprocessor::setRevision(unsigned revision) | 
					
						
							|  |  |  | { m_revision = revision; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 13:49:35 +01:00
										 |  |  | void CppPreprocessor::setWorkingCopy(const CppModelManagerInterface::WorkingCopy &workingCopy) | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | { m_workingCopy = workingCopy; } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | void CppPreprocessor::setIncludePaths(const QStringList &includePaths) | 
					
						
							| 
									
										
										
										
											2010-03-15 18:09:29 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     m_includePaths.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 0; i < includePaths.size(); ++i) { | 
					
						
							| 
									
										
										
										
											2010-03-17 14:49:42 +01:00
										 |  |  |         const QString &path = includePaths.at(i); | 
					
						
							| 
									
										
										
										
											2010-03-15 18:09:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef Q_OS_DARWIN
 | 
					
						
							|  |  |  |         if (i + 1 < includePaths.size() && path.endsWith(QLatin1String(".framework/Headers"))) { | 
					
						
							|  |  |  |             const QFileInfo pathInfo(path); | 
					
						
							|  |  |  |             const QFileInfo frameworkFileInfo(pathInfo.path()); | 
					
						
							|  |  |  |             const QString frameworkName = frameworkFileInfo.baseName(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const QFileInfo nextIncludePath = includePaths.at(i + 1); | 
					
						
							|  |  |  |             if (nextIncludePath.fileName() == frameworkName) { | 
					
						
							|  |  |  |                 // We got a QtXXX.framework/Headers followed by $QTDIR/include/QtXXX.
 | 
					
						
							|  |  |  |                 // In this case we prefer to include files from $QTDIR/include/QtXXX.
 | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         m_includePaths.append(path); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |         m_includePaths.append(path); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths) | 
					
						
							| 
									
										
										
										
											2010-04-13 11:14:34 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     m_frameworkPaths.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const QString &frameworkPath, frameworkPaths) { | 
					
						
							|  |  |  |         addFrameworkPath(frameworkPath); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Add the given framework path, and expand private frameworks.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Example:
 | 
					
						
							|  |  |  | //  <framework-path>/ApplicationServices.framework
 | 
					
						
							|  |  |  | // has private frameworks in:
 | 
					
						
							|  |  |  | //  <framework-path>/ApplicationServices.framework/Frameworks
 | 
					
						
							|  |  |  | // if the "Frameworks" folder exists inside the top level framework.
 | 
					
						
							|  |  |  | void CppPreprocessor::addFrameworkPath(const QString &frameworkPath) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // The algorithm below is a bit too eager, but that's because we're not getting
 | 
					
						
							|  |  |  |     // in the frameworks we're linking against. If we would have that, then we could
 | 
					
						
							|  |  |  |     // add only those private frameworks.
 | 
					
						
							|  |  |  |     if (!m_frameworkPaths.contains(frameworkPath)) { | 
					
						
							|  |  |  |         m_frameworkPaths.append(frameworkPath); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QDir frameworkDir(frameworkPath); | 
					
						
							|  |  |  |     const QStringList filter = QStringList() << QLatin1String("*.framework"); | 
					
						
							|  |  |  |     foreach (const QFileInfo &framework, frameworkDir.entryInfoList(filter)) { | 
					
						
							|  |  |  |         if (!framework.isDir()) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         const QFileInfo privateFrameworks(framework.absoluteFilePath(), QLatin1String("Frameworks")); | 
					
						
							|  |  |  |         if (privateFrameworks.exists() && privateFrameworks.isDir()) { | 
					
						
							|  |  |  |             addFrameworkPath(privateFrameworks.absoluteFilePath()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | void CppPreprocessor::setProjectFiles(const QStringList &files) | 
					
						
							|  |  |  | { m_projectFiles = files; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 15:57:37 +01:00
										 |  |  | void CppPreprocessor::setTodo(const QStringList &files) | 
					
						
							|  |  |  | { m_todo = QSet<QString>::fromList(files); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  | #ifndef ICHECK_BUILD
 | 
					
						
							| 
									
										
										
										
											2010-02-03 13:21:08 +10:00
										 |  |  | namespace { | 
					
						
							| 
									
										
										
										
											2009-03-06 11:51:45 +01:00
										 |  |  | class Process: public std::unary_function<Document::Ptr, void> | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QPointer<CppModelManager> _modelManager; | 
					
						
							| 
									
										
										
										
											2009-06-02 16:50:43 +02:00
										 |  |  |     Snapshot _snapshot; | 
					
						
							|  |  |  |     Document::Ptr _doc; | 
					
						
							| 
									
										
										
										
											2010-05-10 10:19:37 +02:00
										 |  |  |     Document::CheckMode _mode; | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2009-06-02 16:50:43 +02:00
										 |  |  |     Process(QPointer<CppModelManager> modelManager, | 
					
						
							| 
									
										
										
										
											2010-05-10 10:19:37 +02:00
										 |  |  |             Document::Ptr doc, | 
					
						
							|  |  |  |             const Snapshot &snapshot, | 
					
						
							| 
									
										
										
										
											2009-12-15 15:26:40 +01:00
										 |  |  |             const CppModelManager::WorkingCopy &workingCopy) | 
					
						
							| 
									
										
										
										
											2009-06-02 16:50:43 +02:00
										 |  |  |         : _modelManager(modelManager), | 
					
						
							|  |  |  |           _snapshot(snapshot), | 
					
						
							| 
									
										
										
										
											2010-05-10 10:19:37 +02:00
										 |  |  |           _doc(doc), | 
					
						
							|  |  |  |           _mode(Document::FastCheck) | 
					
						
							| 
									
										
										
										
											2009-06-02 16:50:43 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-06-26 09:11:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-10 10:19:37 +02:00
										 |  |  |         if (workingCopy.contains(_doc->fileName())) | 
					
						
							|  |  |  |             _mode = Document::FullCheck; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-06-26 09:11:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-10 10:19:37 +02:00
										 |  |  |     void operator()() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         _doc->check(_mode); | 
					
						
							| 
									
										
										
										
											2011-01-06 10:01:45 +01:00
										 |  |  |         _doc->findExposedQmlTypes(); | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  |         _doc->releaseSource(); | 
					
						
							| 
									
										
										
										
											2010-05-10 10:19:37 +02:00
										 |  |  |         _doc->releaseTranslationUnit(); | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-02 12:50:37 +02:00
										 |  |  |         if (_mode == Document::FastCheck) | 
					
						
							|  |  |  |             _doc->control()->squeeze(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  |         if (_modelManager) | 
					
						
							| 
									
										
										
										
											2010-05-10 10:19:37 +02:00
										 |  |  |             _modelManager->emitDocumentUpdated(_doc); // ### TODO: compress
 | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | } // end of anonymous namespace
 | 
					
						
							| 
									
										
										
										
											2010-02-03 13:21:08 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void CppPreprocessor::run(const QString &fileName) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QString absoluteFilePath = fileName; | 
					
						
							|  |  |  |     sourceNeeded(absoluteFilePath, IncludeGlobal, /*line = */ 0); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  | void CppPreprocessor::resetEnvironment() | 
					
						
							| 
									
										
										
										
											2009-03-09 12:51:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     env.reset(); | 
					
						
							|  |  |  |     m_processed.clear(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  | bool CppPreprocessor::includeFile(const QString &absoluteFilePath, QString *result, unsigned *revision) | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-26 15:31:43 +01:00
										 |  |  |     if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |         return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_workingCopy.contains(absoluteFilePath)) { | 
					
						
							|  |  |  |         m_included.insert(absoluteFilePath); | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |         const QPair<QString, unsigned> r = m_workingCopy.get(absoluteFilePath); | 
					
						
							|  |  |  |         *result = r.first; | 
					
						
							|  |  |  |         *revision = r.second; | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QFileInfo fileInfo(absoluteFilePath); | 
					
						
							|  |  |  |     if (! fileInfo.isFile()) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QFile file(absoluteFilePath); | 
					
						
							|  |  |  |     if (file.open(QFile::ReadOnly)) { | 
					
						
							|  |  |  |         m_included.insert(absoluteFilePath); | 
					
						
							|  |  |  |         QTextStream stream(&file); | 
					
						
							|  |  |  |         const QString contents = stream.readAll(); | 
					
						
							|  |  |  |         *result = contents.toUtf8(); | 
					
						
							|  |  |  |         file.close(); | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  | QString CppPreprocessor::tryIncludeFile(QString &fileName, IncludeType type, unsigned *revision) | 
					
						
							| 
									
										
										
										
											2010-05-10 09:54:30 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (type == IncludeGlobal) { | 
					
						
							|  |  |  |         const QString fn = m_fileNameCache.value(fileName); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (! fn.isEmpty()) { | 
					
						
							|  |  |  |             fileName = fn; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (revision) | 
					
						
							|  |  |  |                 *revision = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return QString(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QString originalFileName = fileName; | 
					
						
							|  |  |  |     const QString contents = tryIncludeFile_helper(fileName, type, revision); | 
					
						
							|  |  |  |     if (type == IncludeGlobal) | 
					
						
							|  |  |  |         m_fileNameCache.insert(originalFileName, fileName); | 
					
						
							|  |  |  |     return contents; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-03 09:23:48 +02:00
										 |  |  | static inline void appendDirSeparatorIfNeeded(QString &path) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!path.endsWith(QLatin1Char('/'), Qt::CaseInsensitive)) | 
					
						
							|  |  |  |         path += QLatin1Char('/'); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-10 09:54:30 +02:00
										 |  |  | QString CppPreprocessor::tryIncludeFile_helper(QString &fileName, IncludeType type, unsigned *revision) | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QFileInfo fileInfo(fileName); | 
					
						
							|  |  |  |     if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) { | 
					
						
							| 
									
										
										
										
											2009-06-15 15:38:20 +02:00
										 |  |  |         QString contents; | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |         includeFile(fileName, &contents, revision); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |         return contents; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (type == IncludeLocal && m_currentDoc) { | 
					
						
							|  |  |  |         QFileInfo currentFileInfo(m_currentDoc->fileName()); | 
					
						
							|  |  |  |         QString path = currentFileInfo.absolutePath(); | 
					
						
							| 
									
										
										
										
											2010-10-03 09:23:48 +02:00
										 |  |  |         appendDirSeparatorIfNeeded(path); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |         path += fileName; | 
					
						
							|  |  |  |         path = QDir::cleanPath(path); | 
					
						
							| 
									
										
										
										
											2009-06-15 15:38:20 +02:00
										 |  |  |         QString contents; | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |         if (includeFile(path, &contents, revision)) { | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |             fileName = path; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             return contents; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 15:19:15 +01:00
										 |  |  |     foreach (const QString &includePath, m_includePaths) { | 
					
						
							|  |  |  |         QString path = includePath; | 
					
						
							| 
									
										
										
										
											2010-10-03 09:23:48 +02:00
										 |  |  |         appendDirSeparatorIfNeeded(path); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |         path += fileName; | 
					
						
							|  |  |  |         path = QDir::cleanPath(path); | 
					
						
							| 
									
										
										
										
											2009-06-15 15:38:20 +02:00
										 |  |  |         QString contents; | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |         if (includeFile(path, &contents, revision)) { | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |             fileName = path; | 
					
						
							|  |  |  |             return contents; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     // look in the system include paths
 | 
					
						
							|  |  |  |     foreach (const QString &includePath, m_systemIncludePaths) { | 
					
						
							|  |  |  |         QString path = includePath; | 
					
						
							| 
									
										
										
										
											2010-10-03 09:23:48 +02:00
										 |  |  |         appendDirSeparatorIfNeeded(path); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |         path += fileName; | 
					
						
							|  |  |  |         path = QDir::cleanPath(path); | 
					
						
							| 
									
										
										
										
											2009-06-15 15:38:20 +02:00
										 |  |  |         QString contents; | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |         if (includeFile(path, &contents, revision)) { | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |             fileName = path; | 
					
						
							|  |  |  |             return contents; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int index = fileName.indexOf(QLatin1Char('/')); | 
					
						
							|  |  |  |     if (index != -1) { | 
					
						
							|  |  |  |         QString frameworkName = fileName.left(index); | 
					
						
							|  |  |  |         QString name = fileName.mid(index + 1); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |         foreach (const QString &frameworkPath, m_frameworkPaths) { | 
					
						
							|  |  |  |             QString path = frameworkPath; | 
					
						
							| 
									
										
										
										
											2010-10-03 09:23:48 +02:00
										 |  |  |             appendDirSeparatorIfNeeded(path); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |             path += frameworkName; | 
					
						
							|  |  |  |             path += QLatin1String(".framework/Headers/"); | 
					
						
							|  |  |  |             path += name; | 
					
						
							| 
									
										
										
										
											2009-06-02 14:56:03 +02:00
										 |  |  |             path = QDir::cleanPath(path); | 
					
						
							| 
									
										
										
										
											2009-06-15 15:38:20 +02:00
										 |  |  |             QString contents; | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |             if (includeFile(path, &contents, revision)) { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                 fileName = path; | 
					
						
							|  |  |  |                 return contents; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     QString path = fileName; | 
					
						
							|  |  |  |     if (path.at(0) != QLatin1Char('/')) | 
					
						
							|  |  |  |         path.prepend(QLatin1Char('/')); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     foreach (const QString &projectFile, m_projectFiles) { | 
					
						
							|  |  |  |         if (projectFile.endsWith(path)) { | 
					
						
							|  |  |  |             fileName = projectFile; | 
					
						
							| 
									
										
										
										
											2009-06-15 15:38:20 +02:00
										 |  |  |             QString contents; | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |             includeFile(fileName, &contents, revision); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |             return contents; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     //qDebug() << "**** file" << fileName << "not found!";
 | 
					
						
							| 
									
										
										
										
											2009-06-15 15:38:20 +02:00
										 |  |  |     return QString(); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 12:59:33 +01:00
										 |  |  | void CppPreprocessor::macroAdded(const Macro ¯o) | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (! m_currentDoc) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 12:59:33 +01:00
										 |  |  |     m_currentDoc->appendMacro(macro); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-04 12:05:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 16:00:14 +02:00
										 |  |  | void CppPreprocessor::passedMacroDefinitionCheck(unsigned offset, const Macro ¯o) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! m_currentDoc) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-21 14:47:22 +01:00
										 |  |  |     m_currentDoc->addMacroUse(macro, offset, macro.name().length(), env.currentLine, | 
					
						
							| 
									
										
										
										
											2009-09-25 16:00:14 +02:00
										 |  |  |                               QVector<MacroArgumentReference>(), true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppPreprocessor::failedMacroDefinitionCheck(unsigned offset, const QByteArray &name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! m_currentDoc) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_currentDoc->addUndefinedMacroUse(name, offset); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | void CppPreprocessor::startExpandingMacro(unsigned offset, | 
					
						
							| 
									
										
										
										
											2008-12-09 15:23:47 +01:00
										 |  |  |                                           const Macro ¯o, | 
					
						
							| 
									
										
										
										
											2009-03-04 11:47:30 +01:00
										 |  |  |                                           const QByteArray &originalText, | 
					
						
							| 
									
										
										
										
											2009-09-25 16:00:14 +02:00
										 |  |  |                                           bool inCondition, | 
					
						
							| 
									
										
										
										
											2009-03-04 11:47:30 +01:00
										 |  |  |                                           const QVector<MacroArgumentReference> &actuals) | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (! m_currentDoc) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2008-12-04 12:05:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 16:00:14 +02:00
										 |  |  |     //qDebug() << "start expanding:" << macro.name() << "text:" << originalText;
 | 
					
						
							| 
									
										
										
										
											2009-12-21 14:47:22 +01:00
										 |  |  |     m_currentDoc->addMacroUse(macro, offset, originalText.length(), env.currentLine, | 
					
						
							|  |  |  |                               actuals, inCondition); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-04 12:05:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 12:17:39 +01:00
										 |  |  | void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &) | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (! m_currentDoc) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     //qDebug() << "stop expanding:" << macro.name;
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | void CppPreprocessor::mergeEnvironment(Document::Ptr doc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! doc) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     const QString fn = doc->fileName(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-09 12:51:13 +01:00
										 |  |  |     if (m_processed.contains(fn)) | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-09 12:51:13 +01:00
										 |  |  |     m_processed.insert(fn); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |     foreach (const Document::Include &incl, doc->includes()) { | 
					
						
							| 
									
										
										
										
											2009-02-09 12:33:43 +01:00
										 |  |  |         QString includedFile = incl.fileName(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  |         if (Document::Ptr includedDoc = snapshot.document(includedFile)) | 
					
						
							| 
									
										
										
										
											2009-03-09 12:51:13 +01:00
										 |  |  |             mergeEnvironment(includedDoc); | 
					
						
							| 
									
										
										
										
											2009-02-09 12:33:43 +01:00
										 |  |  |         else | 
					
						
							|  |  |  |             run(includedFile); | 
					
						
							| 
									
										
										
										
											2008-12-08 12:59:33 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |     env.addMacros(doc->definedMacros()); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | void CppPreprocessor::startSkippingBlocks(unsigned offset) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     //qDebug() << "start skipping blocks:" << offset;
 | 
					
						
							|  |  |  |     if (m_currentDoc) | 
					
						
							|  |  |  |         m_currentDoc->startSkippingBlocks(offset); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppPreprocessor::stopSkippingBlocks(unsigned offset) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     //qDebug() << "stop skipping blocks:" << offset;
 | 
					
						
							|  |  |  |     if (m_currentDoc) | 
					
						
							|  |  |  |         m_currentDoc->stopSkippingBlocks(offset); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  | void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type, unsigned line) | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (fileName.isEmpty()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |     unsigned editorRevision = 0; | 
					
						
							|  |  |  |     QString contents = tryIncludeFile(fileName, type, &editorRevision); | 
					
						
							| 
									
										
										
										
											2009-11-09 13:53:28 +01:00
										 |  |  |     fileName = QDir::cleanPath(fileName); | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     if (m_currentDoc) { | 
					
						
							| 
									
										
										
										
											2008-12-10 17:21:01 +01:00
										 |  |  |         m_currentDoc->addIncludeFile(fileName, line); | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |         if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) { | 
					
						
							| 
									
										
										
										
											2009-04-17 21:11:52 +02:00
										 |  |  |             QString msg = QCoreApplication::translate( | 
					
						
							|  |  |  |                     "CppPreprocessor", "%1: No such file or directory").arg(fileName); | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |             Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning, | 
					
						
							|  |  |  |                                           m_currentDoc->fileName(), | 
					
						
							|  |  |  |                                           env.currentLine, /*column = */ 0, | 
					
						
							|  |  |  |                                           msg); | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |             m_currentDoc->addDiagnosticMessage(d); | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |             //qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |     //qDebug() << "parse file:" << fileName << "contents:" << contents.size();
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  |     Document::Ptr doc = snapshot.document(fileName); | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |     if (doc) { | 
					
						
							|  |  |  |         mergeEnvironment(doc); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |     doc = Document::create(fileName); | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  |     doc->setRevision(m_revision); | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |     doc->setEditorRevision(editorRevision); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 12:34:02 +01:00
										 |  |  |     QFileInfo info(fileName); | 
					
						
							|  |  |  |     if (info.exists()) | 
					
						
							|  |  |  |         doc->setLastModified(info.lastModified()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |     Document::Ptr previousDoc = switchDocument(doc); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-15 15:38:20 +02:00
										 |  |  |     const QByteArray preprocessedCode = preprocess(fileName, contents); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |     doc->setSource(preprocessedCode); | 
					
						
							| 
									
										
										
										
											2009-02-24 11:04:52 +01:00
										 |  |  |     doc->tokenize(); | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  |     snapshot.insert(doc); | 
					
						
							| 
									
										
										
										
											2009-03-06 11:51:45 +01:00
										 |  |  |     m_todo.remove(fileName); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  | #ifndef ICHECK_BUILD
 | 
					
						
							| 
									
										
										
										
											2010-05-10 10:19:37 +02:00
										 |  |  |     Process process(m_modelManager, doc, snapshot, m_workingCopy); | 
					
						
							| 
									
										
										
										
											2009-03-17 14:39:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-10 10:19:37 +02:00
										 |  |  |     process(); | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     (void) switchDocument(previousDoc); | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  |     doc->releaseSource(); | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  |     Document::CheckMode mode = Document::FastCheck; | 
					
						
							|  |  |  |     mode = Document::FullCheck; | 
					
						
							|  |  |  |     doc->parse(); | 
					
						
							|  |  |  |     doc->check(mode); | 
					
						
							| 
									
										
										
										
											2010-04-23 15:25:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     (void) switchDocument(previousDoc); | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 11:08:48 +01:00
										 |  |  | Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Document::Ptr previousDoc = m_currentDoc; | 
					
						
							|  |  |  |     m_currentDoc = doc; | 
					
						
							|  |  |  |     return previousDoc; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  | #ifndef ICHECK_BUILD
 | 
					
						
							| 
									
										
										
										
											2010-12-03 13:49:35 +01:00
										 |  |  | void CppModelManager::updateModifiedSourceFiles() | 
					
						
							| 
									
										
										
										
											2009-11-05 12:34:02 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     const Snapshot snapshot = this->snapshot(); | 
					
						
							|  |  |  |     QStringList sourceFiles; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const Document::Ptr doc, snapshot) { | 
					
						
							|  |  |  |         const QDateTime lastModified = doc->lastModified(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (! lastModified.isNull()) { | 
					
						
							|  |  |  |             QFileInfo fileInfo(doc->fileName()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (fileInfo.exists() && fileInfo.lastModified() != lastModified) | 
					
						
							|  |  |  |                 sourceFiles.append(doc->fileName()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     updateSourceFiles(sourceFiles); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 13:49:35 +01:00
										 |  |  | CppModelManager *CppModelManager::instance() | 
					
						
							| 
									
										
										
										
											2009-10-05 13:43:05 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance(); | 
					
						
							| 
									
										
										
										
											2010-12-03 13:49:35 +01:00
										 |  |  |     return pluginManager->getObject<CppModelManager>(); | 
					
						
							| 
									
										
										
										
											2009-10-05 13:43:05 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \class CppTools::CppModelManager | 
					
						
							|  |  |  |     \brief The CppModelManager keeps track of one CppCodeModel instance | 
					
						
							|  |  |  |            for each project and all related CppCodeModelPart instances. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     It also takes care of updating the code models when C++ files are | 
					
						
							| 
									
										
										
										
											2009-05-08 13:01:32 +02:00
										 |  |  |     modified within Qt Creator. | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-20 11:52:04 +01:00
										 |  |  | CppModelManager::CppModelManager(QObject *parent) | 
					
						
							| 
									
										
										
										
											2009-11-10 18:02:42 +01:00
										 |  |  |     : CppModelManagerInterface(parent) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  |     m_findReferences = new CppFindReferences(this); | 
					
						
							| 
									
										
										
										
											2009-12-07 12:03:31 +01:00
										 |  |  |     m_indexerEnabled = qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull(); | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  |     m_revision = 0; | 
					
						
							| 
									
										
										
										
											2009-03-11 12:00:07 +01:00
										 |  |  |     m_synchronizer.setCancelOnWait(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-20 11:52:04 +01:00
										 |  |  |     m_core = Core::ICore::instance(); // FIXME
 | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |     m_dirty = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-04 11:47:30 +01:00
										 |  |  |     ProjectExplorer::ProjectExplorerPlugin *pe = | 
					
						
							| 
									
										
										
										
											2009-03-04 09:38:01 +01:00
										 |  |  |        ProjectExplorer::ProjectExplorerPlugin::instance(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-04 09:38:01 +01:00
										 |  |  |     QTC_ASSERT(pe, return); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-04 09:38:01 +01:00
										 |  |  |     ProjectExplorer::SessionManager *session = pe->session(); | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  |     QTC_ASSERT(session, return); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  |     m_updateEditorSelectionsTimer = new QTimer(this); | 
					
						
							|  |  |  |     m_updateEditorSelectionsTimer->setInterval(500); | 
					
						
							|  |  |  |     m_updateEditorSelectionsTimer->setSingleShot(true); | 
					
						
							|  |  |  |     connect(m_updateEditorSelectionsTimer, SIGNAL(timeout()), | 
					
						
							|  |  |  |             this, SLOT(updateEditorSelections())); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |     connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)), | 
					
						
							|  |  |  |             this, SLOT(onProjectAdded(ProjectExplorer::Project*))); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)), | 
					
						
							|  |  |  |             this, SLOT(onAboutToRemoveProject(ProjectExplorer::Project *))); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-13 17:10:53 +02:00
										 |  |  |     connect(session, SIGNAL(aboutToUnloadSession()), | 
					
						
							|  |  |  |             this, SLOT(onAboutToUnloadSession())); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     qRegisterMetaType<CPlusPlus::Document::Ptr>("CPlusPlus::Document::Ptr"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // thread connections
 | 
					
						
							|  |  |  |     connect(this, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)), | 
					
						
							|  |  |  |             this, SLOT(onDocumentUpdated(CPlusPlus::Document::Ptr))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Listen for editor closed and opened events so that we can keep track of changing files
 | 
					
						
							|  |  |  |     connect(m_core->editorManager(), SIGNAL(editorOpened(Core::IEditor *)), | 
					
						
							|  |  |  |         this, SLOT(editorOpened(Core::IEditor *))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     connect(m_core->editorManager(), SIGNAL(editorAboutToClose(Core::IEditor *)), | 
					
						
							|  |  |  |         this, SLOT(editorAboutToClose(Core::IEditor *))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CppModelManager::~CppModelManager() | 
					
						
							|  |  |  | { } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-12 10:07:58 +01:00
										 |  |  | Snapshot CppModelManager::snapshot() const | 
					
						
							| 
									
										
										
										
											2009-03-04 09:38:01 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-02 15:27:13 +02:00
										 |  |  |     QMutexLocker locker(&protectSnapshot); | 
					
						
							| 
									
										
										
										
											2009-03-04 09:38:01 +01:00
										 |  |  |     return m_snapshot; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 10:44:56 +01:00
										 |  |  | void CppModelManager::ensureUpdated() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker locker(&mutex); | 
					
						
							|  |  |  |     if (! m_dirty) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 14:48:51 +01:00
										 |  |  |     m_projectFiles = internalProjectFiles(); | 
					
						
							|  |  |  |     m_includePaths = internalIncludePaths(); | 
					
						
							|  |  |  |     m_frameworkPaths = internalFrameworkPaths(); | 
					
						
							|  |  |  |     m_definedMacros = internalDefinedMacros(); | 
					
						
							| 
									
										
										
										
											2008-12-08 10:44:56 +01:00
										 |  |  |     m_dirty = false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 14:48:51 +01:00
										 |  |  | QStringList CppModelManager::internalProjectFiles() const | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QStringList files; | 
					
						
							|  |  |  |     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); | 
					
						
							|  |  |  |     while (it.hasNext()) { | 
					
						
							|  |  |  |         it.next(); | 
					
						
							|  |  |  |         ProjectInfo pinfo = it.value(); | 
					
						
							|  |  |  |         files += pinfo.sourceFiles; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-08 14:48:51 +01:00
										 |  |  |     files.removeDuplicates(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return files; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 14:48:51 +01:00
										 |  |  | QStringList CppModelManager::internalIncludePaths() const | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QStringList includePaths; | 
					
						
							|  |  |  |     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); | 
					
						
							|  |  |  |     while (it.hasNext()) { | 
					
						
							|  |  |  |         it.next(); | 
					
						
							|  |  |  |         ProjectInfo pinfo = it.value(); | 
					
						
							|  |  |  |         includePaths += pinfo.includePaths; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-08 14:48:51 +01:00
										 |  |  |     includePaths.removeDuplicates(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return includePaths; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 14:48:51 +01:00
										 |  |  | QStringList CppModelManager::internalFrameworkPaths() const | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QStringList frameworkPaths; | 
					
						
							|  |  |  |     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); | 
					
						
							|  |  |  |     while (it.hasNext()) { | 
					
						
							|  |  |  |         it.next(); | 
					
						
							|  |  |  |         ProjectInfo pinfo = it.value(); | 
					
						
							|  |  |  |         frameworkPaths += pinfo.frameworkPaths; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-08 14:48:51 +01:00
										 |  |  |     frameworkPaths.removeDuplicates(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return frameworkPaths; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 14:48:51 +01:00
										 |  |  | QByteArray CppModelManager::internalDefinedMacros() const | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QByteArray macros; | 
					
						
							|  |  |  |     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); | 
					
						
							|  |  |  |     while (it.hasNext()) { | 
					
						
							|  |  |  |         it.next(); | 
					
						
							|  |  |  |         ProjectInfo pinfo = it.value(); | 
					
						
							|  |  |  |         macros += pinfo.defines; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return macros; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-13 12:12:51 +02:00
										 |  |  | void CppModelManager::setIncludesInPaths(const QMap<QString, QStringList> &includesInPaths) | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QMutexLocker locker(&mutex); | 
					
						
							|  |  |  |     QMapIterator<QString, QStringList> i(includesInPaths); | 
					
						
							|  |  |  |     while (i.hasNext()) { | 
					
						
							|  |  |  |         i.next(); | 
					
						
							|  |  |  |         m_includesInPaths.insert(i.key(), i.value()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-12 13:45:24 +02:00
										 |  |  | void CppModelManager::addEditorSupport(AbstractEditorSupport *editorSupport) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_addtionalEditorSupport.insert(editorSupport); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppModelManager::removeEditorSupport(AbstractEditorSupport *editorSupport) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_addtionalEditorSupport.remove(editorSupport); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-31 12:09:28 +02:00
										 |  |  | QList<int> CppModelManager::references(CPlusPlus::Symbol *symbol, const LookupContext &context) | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-31 12:09:28 +02:00
										 |  |  |     return m_findReferences->references(symbol, context); | 
					
						
							| 
									
										
										
										
											2009-09-30 13:25:40 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-31 12:09:28 +02:00
										 |  |  | void CppModelManager::findUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context) | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-24 16:51:40 +02:00
										 |  |  |     if (symbol->identifier()) | 
					
						
							| 
									
										
										
										
											2010-05-31 12:09:28 +02:00
										 |  |  |         m_findReferences->findUsages(symbol, context); | 
					
						
							| 
									
										
										
										
											2009-10-05 15:17:25 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-20 11:02:37 +02:00
										 |  |  | void CppModelManager::renameUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context, | 
					
						
							|  |  |  |                                    const QString &replacement) | 
					
						
							| 
									
										
										
										
											2009-10-05 15:17:25 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (symbol->identifier()) | 
					
						
							| 
									
										
										
										
											2010-07-20 11:02:37 +02:00
										 |  |  |         m_findReferences->renameUsages(symbol, context, replacement); | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-21 14:54:10 +01:00
										 |  |  | void CppModelManager::findMacroUsages(const CPlusPlus::Macro ¯o) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_findReferences->findMacroUses(macro); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 15:16:46 +01:00
										 |  |  | CppModelManager::WorkingCopy CppModelManager::buildWorkingCopyList() | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-15 15:16:46 +01:00
										 |  |  |     WorkingCopy workingCopy; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     QMapIterator<TextEditor::ITextEditor *, CppEditorSupport *> it(m_editorSupport); | 
					
						
							|  |  |  |     while (it.hasNext()) { | 
					
						
							|  |  |  |         it.next(); | 
					
						
							|  |  |  |         TextEditor::ITextEditor *textEditor = it.key(); | 
					
						
							|  |  |  |         CppEditorSupport *editorSupport = it.value(); | 
					
						
							|  |  |  |         QString fileName = textEditor->file()->fileName(); | 
					
						
							| 
									
										
										
										
											2009-12-15 15:52:55 +01:00
										 |  |  |         workingCopy.insert(fileName, editorSupport->contents(), editorSupport->editorRevision()); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-12 13:45:24 +02:00
										 |  |  |     QSetIterator<AbstractEditorSupport *> jt(m_addtionalEditorSupport); | 
					
						
							|  |  |  |     while (jt.hasNext()) { | 
					
						
							|  |  |  |         AbstractEditorSupport *es =  jt.next(); | 
					
						
							| 
									
										
										
										
											2009-12-15 15:26:40 +01:00
										 |  |  |         workingCopy.insert(es->fileName(), es->contents()); | 
					
						
							| 
									
										
										
										
											2009-05-12 13:45:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     // add the project configuration file
 | 
					
						
							|  |  |  |     QByteArray conf(pp_configuration); | 
					
						
							|  |  |  |     conf += definedMacros(); | 
					
						
							| 
									
										
										
										
											2009-12-15 15:26:40 +01:00
										 |  |  |     workingCopy.insert(pp_configuration_file, conf); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return workingCopy; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 15:16:46 +01:00
										 |  |  | CppModelManager::WorkingCopy CppModelManager::workingCopy() const | 
					
						
							| 
									
										
										
										
											2009-10-12 10:38:00 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return const_cast<CppModelManager *>(this)->buildWorkingCopyList(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-02 12:51:47 +01:00
										 |  |  | QFuture<void> CppModelManager::updateSourceFiles(const QStringList &sourceFiles) | 
					
						
							|  |  |  | { return refreshSourceFiles(sourceFiles); } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 10:44:56 +01:00
										 |  |  | QList<CppModelManager::ProjectInfo> CppModelManager::projectInfos() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker locker(&mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return m_projects.values(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Project *project) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker locker(&mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return m_projects.value(project, ProjectInfo(project)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker locker(&mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (! pinfo.isValid()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_projects.insert(pinfo.project, pinfo); | 
					
						
							| 
									
										
										
										
											2008-12-08 14:48:51 +01:00
										 |  |  |     m_dirty = true; | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 12:03:31 +01:00
										 |  |  |     if (m_indexerEnabled) { | 
					
						
							| 
									
										
										
										
											2009-08-04 18:16:05 +02:00
										 |  |  |         QFuture<void> result = QtConcurrent::run(&CppModelManager::updateIncludesInPaths, | 
					
						
							|  |  |  |                                                  this, | 
					
						
							|  |  |  |                                                  pinfo.includePaths, | 
					
						
							| 
									
										
										
										
											2009-10-01 17:01:13 +02:00
										 |  |  |                                                  pinfo.frameworkPaths, | 
					
						
							| 
									
										
										
										
											2009-08-04 18:16:05 +02:00
										 |  |  |                                                  m_headerSuffixes); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (pinfo.includePaths.size() > 1) { | 
					
						
							|  |  |  |             m_core->progressManager()->addTask(result, tr("Scanning"), | 
					
						
							| 
									
										
										
										
											2009-11-26 15:51:10 +01:00
										 |  |  |                                                CppTools::Constants::TASK_INDEX); | 
					
						
							| 
									
										
										
										
											2009-08-04 18:16:05 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QStringList CppModelManager::includesInPath(const QString &path) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker locker(&mutex); | 
					
						
							|  |  |  |     return m_includesInPaths.value(path); | 
					
						
							| 
									
										
										
										
											2008-12-08 10:44:56 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-07 12:03:31 +01:00
										 |  |  |     if (! sourceFiles.isEmpty() && m_indexerEnabled) { | 
					
						
							| 
									
										
										
										
											2009-12-15 15:16:46 +01:00
										 |  |  |         const WorkingCopy workingCopy = buildWorkingCopyList(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |         CppPreprocessor *preproc = new CppPreprocessor(this); | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  |         preproc->setRevision(++m_revision); | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |         preproc->setProjectFiles(projectFiles()); | 
					
						
							|  |  |  |         preproc->setIncludePaths(includePaths()); | 
					
						
							|  |  |  |         preproc->setFrameworkPaths(frameworkPaths()); | 
					
						
							|  |  |  |         preproc->setWorkingCopy(workingCopy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QFuture<void> result = QtConcurrent::run(&CppModelManager::parse, | 
					
						
							|  |  |  |                                                  preproc, sourceFiles); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-11 12:21:02 +01:00
										 |  |  |         if (m_synchronizer.futures().size() > 10) { | 
					
						
							|  |  |  |             QList<QFuture<void> > futures = m_synchronizer.futures(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             m_synchronizer.clearFutures(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-01 14:00:07 +01:00
										 |  |  |             foreach (const QFuture<void> &future, futures) { | 
					
						
							| 
									
										
										
										
											2009-03-11 12:21:02 +01:00
										 |  |  |                 if (! (future.isFinished() || future.isCanceled())) | 
					
						
							|  |  |  |                     m_synchronizer.addFuture(future); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-11 12:00:07 +01:00
										 |  |  |         m_synchronizer.addFuture(result); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 18:02:42 +01:00
										 |  |  |         if (sourceFiles.count() > 1) { | 
					
						
							| 
									
										
										
										
											2010-04-13 16:32:01 +02:00
										 |  |  |             m_core->progressManager()->addTask(result, tr("Parsing"), | 
					
						
							| 
									
										
										
										
											2009-11-26 15:51:10 +01:00
										 |  |  |                             CppTools::Constants::TASK_INDEX); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-12-07 12:03:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         return result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return QFuture<void>(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \fn    void CppModelManager::editorOpened(Core::IEditor *editor) | 
					
						
							|  |  |  |     \brief If a C++ editor is opened, the model manager listens to content changes | 
					
						
							|  |  |  |            in order to update the CppCodeModel accordingly. It also updates the | 
					
						
							|  |  |  |            CppCodeModel for the first time with this editor. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     \sa    void CppModelManager::editorContentsChanged() | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void CppModelManager::editorOpened(Core::IEditor *editor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (isCppEditor(editor)) { | 
					
						
							|  |  |  |         TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor *>(editor); | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  |         QTC_ASSERT(textEditor, return); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         CppEditorSupport *editorSupport = new CppEditorSupport(this); | 
					
						
							|  |  |  |         editorSupport->setTextEditor(textEditor); | 
					
						
							|  |  |  |         m_editorSupport[textEditor] = editorSupport; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppModelManager::editorAboutToClose(Core::IEditor *editor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (isCppEditor(editor)) { | 
					
						
							|  |  |  |         TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor *>(editor); | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  |         QTC_ASSERT(textEditor, return); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         CppEditorSupport *editorSupport = m_editorSupport.value(textEditor); | 
					
						
							|  |  |  |         m_editorSupport.remove(textEditor); | 
					
						
							|  |  |  |         delete editorSupport; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CppModelManager::isCppEditor(Core::IEditor *editor) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-25 17:37:59 +02:00
										 |  |  |     return editor->context().contains(ProjectExplorer::Constants::LANG_CXX); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppModelManager::emitDocumentUpdated(Document::Ptr doc) | 
					
						
							| 
									
										
										
										
											2010-06-25 17:37:59 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     emit documentUpdated(doc); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void CppModelManager::onDocumentUpdated(Document::Ptr doc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const QString fileName = doc->fileName(); | 
					
						
							| 
									
										
										
										
											2009-06-02 15:27:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  |     bool outdated = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-02 15:27:13 +02:00
										 |  |  |     protectSnapshot.lock(); | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  |     Document::Ptr previous = m_snapshot.document(fileName); | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (previous && (doc->revision() != 0 && doc->revision() < previous->revision())) | 
					
						
							|  |  |  |         outdated = true; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         m_snapshot.insert(doc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-02 15:27:13 +02:00
										 |  |  |     protectSnapshot.unlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-14 14:23:12 +02:00
										 |  |  |     if (outdated) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     QList<Core::IEditor *> openedEditors = m_core->editorManager()->openedEditors(); | 
					
						
							|  |  |  |     foreach (Core::IEditor *editor, openedEditors) { | 
					
						
							|  |  |  |         if (editor->file()->fileName() == fileName) { | 
					
						
							|  |  |  |             TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor *>(editor); | 
					
						
							|  |  |  |             if (! textEditor) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             TextEditor::BaseTextEditor *ed = qobject_cast<TextEditor::BaseTextEditor *>(textEditor->widget()); | 
					
						
							|  |  |  |             if (! ed) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QList<TextEditor::BaseTextEditor::BlockRange> blockRanges; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |             foreach (const Document::Block &block, doc->skippedBlocks()) { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                 blockRanges.append(TextEditor::BaseTextEditor::BlockRange(block.begin(), block.end())); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QList<QTextEdit::ExtraSelection> selections; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 12:05:04 +01:00
										 |  |  | #ifdef QTCREATOR_WITH_MACRO_HIGHLIGHTING
 | 
					
						
							|  |  |  |             // set up the format for the macros
 | 
					
						
							|  |  |  |             QTextCharFormat macroFormat; | 
					
						
							|  |  |  |             macroFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QTextCursor c = ed->textCursor(); | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |             foreach (const Document::MacroUse &block, doc->macroUses()) { | 
					
						
							| 
									
										
										
										
											2008-12-04 12:05:04 +01:00
										 |  |  |                 QTextEdit::ExtraSelection sel; | 
					
						
							|  |  |  |                 sel.cursor = c; | 
					
						
							|  |  |  |                 sel.cursor.setPosition(block.begin()); | 
					
						
							|  |  |  |                 sel.cursor.setPosition(block.end(), QTextCursor::KeepAnchor); | 
					
						
							|  |  |  |                 sel.format = macroFormat; | 
					
						
							|  |  |  |                 selections.append(sel); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | #endif // QTCREATOR_WITH_MACRO_HIGHLIGHTING
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             // set up the format for the errors
 | 
					
						
							|  |  |  |             QTextCharFormat errorFormat; | 
					
						
							|  |  |  |             errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline); | 
					
						
							|  |  |  |             errorFormat.setUnderlineColor(Qt::red); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // set up the format for the warnings.
 | 
					
						
							|  |  |  |             QTextCharFormat warningFormat; | 
					
						
							|  |  |  |             warningFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline); | 
					
						
							|  |  |  |             warningFormat.setUnderlineColor(Qt::darkYellow); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-03 14:52:09 +01:00
										 |  |  | #ifdef QTCREATOR_WITH_ADVANCED_HIGHLIGHTER
 | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  |             QSet<QPair<unsigned, unsigned> > lines; | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |             foreach (const Document::DiagnosticMessage &m, doc->diagnosticMessages()) { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                 if (m.fileName() != fileName) | 
					
						
							|  |  |  |                     continue; | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 const QPair<unsigned, unsigned> coordinates = qMakePair(m.line(), m.column()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (lines.contains(coordinates)) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                     continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  |                 lines.insert(coordinates); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 QTextEdit::ExtraSelection sel; | 
					
						
							|  |  |  |                 if (m.isWarning()) | 
					
						
							|  |  |  |                     sel.format = warningFormat; | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     sel.format = errorFormat; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 QTextCursor c(ed->document()->findBlockByNumber(m.line() - 1)); | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 // ### check for generated tokens.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 int column = m.column(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (column > c.block().length()) { | 
					
						
							|  |  |  |                     column = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     const QString text = c.block().text(); | 
					
						
							|  |  |  |                     for (int i = 0; i < text.size(); ++i) { | 
					
						
							|  |  |  |                         if (! text.at(i).isSpace()) { | 
					
						
							|  |  |  |                             ++column; | 
					
						
							|  |  |  |                             break; | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 if (column != 0) | 
					
						
							|  |  |  |                     --column; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 c.setPosition(c.position() + column); | 
					
						
							|  |  |  |                 c.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                 sel.cursor = c; | 
					
						
							|  |  |  |                 selections.append(sel); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-03-03 14:52:09 +01:00
										 |  |  | #else
 | 
					
						
							|  |  |  |             QSet<int> lines; | 
					
						
							|  |  |  |             foreach (const Document::DiagnosticMessage &m, doc->diagnosticMessages()) { | 
					
						
							|  |  |  |                 if (m.fileName() != fileName) | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 else if (lines.contains(m.line())) | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 lines.insert(m.line()); | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-03 14:52:09 +01:00
										 |  |  |                 QTextEdit::ExtraSelection sel; | 
					
						
							|  |  |  |                 if (m.isWarning()) | 
					
						
							|  |  |  |                     sel.format = warningFormat; | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     sel.format = errorFormat; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 QTextCursor c(ed->document()->findBlockByNumber(m.line() - 1)); | 
					
						
							|  |  |  |                 const QString text = c.block().text(); | 
					
						
							|  |  |  |                 for (int i = 0; i < text.size(); ++i) { | 
					
						
							|  |  |  |                     if (! text.at(i).isSpace()) { | 
					
						
							|  |  |  |                         c.setPosition(c.position() + i); | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 c.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); | 
					
						
							|  |  |  |                 sel.cursor = c; | 
					
						
							|  |  |  |                 selections.append(sel); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  |             QList<Editor> todo; | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |             foreach (const Editor &e, todo) { | 
					
						
							| 
									
										
										
										
											2009-03-02 16:30:25 +01:00
										 |  |  |                 if (e.textEditor != textEditor) | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  |                     todo.append(e); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             Editor e; | 
					
						
							| 
									
										
										
										
											2009-07-10 13:57:21 +02:00
										 |  |  |             e.revision = ed->document()->revision(); | 
					
						
							| 
									
										
										
										
											2009-03-02 16:30:25 +01:00
										 |  |  |             e.textEditor = textEditor; | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  |             e.selections = selections; | 
					
						
							| 
									
										
										
										
											2009-02-23 17:49:03 +01:00
										 |  |  |             e.ifdefedOutBlocks = blockRanges; | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  |             todo.append(e); | 
					
						
							|  |  |  |             m_todo = todo; | 
					
						
							|  |  |  |             postEditorUpdate(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  | void CppModelManager::postEditorUpdate() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_updateEditorSelectionsTimer->start(500); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppModelManager::updateEditorSelections() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |     foreach (const Editor &ed, m_todo) { | 
					
						
							| 
									
										
										
										
											2009-03-02 16:30:25 +01:00
										 |  |  |         if (! ed.textEditor) | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-02 16:30:25 +01:00
										 |  |  |         TextEditor::ITextEditor *textEditor = ed.textEditor; | 
					
						
							|  |  |  |         TextEditor::BaseTextEditor *editor = qobject_cast<TextEditor::BaseTextEditor *>(textEditor->widget()); | 
					
						
							| 
									
										
										
										
											2009-07-10 13:57:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-02 16:30:25 +01:00
										 |  |  |         if (! editor) | 
					
						
							|  |  |  |             continue; | 
					
						
							| 
									
										
										
										
											2009-07-10 13:57:21 +02:00
										 |  |  |         else if (editor->document()->revision() != ed.revision) | 
					
						
							|  |  |  |             continue; // outdated
 | 
					
						
							| 
									
										
										
										
											2009-03-02 16:30:25 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         editor->setExtraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection, | 
					
						
							|  |  |  |                                    ed.selections); | 
					
						
							| 
									
										
										
										
											2009-02-23 17:49:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-02 16:30:25 +01:00
										 |  |  |         editor->setIfdefedOutBlocks(ed.ifdefedOutBlocks); | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_todo.clear(); | 
					
						
							| 
									
										
										
										
											2009-03-02 16:30:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-10 22:56:04 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  | void CppModelManager::onProjectAdded(ProjectExplorer::Project *) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-08 10:44:56 +01:00
										 |  |  |     QMutexLocker locker(&mutex); | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |     m_dirty = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-08 10:44:56 +01:00
										 |  |  |     do { | 
					
						
							|  |  |  |         QMutexLocker locker(&mutex); | 
					
						
							|  |  |  |         m_dirty = true; | 
					
						
							|  |  |  |         m_projects.remove(project); | 
					
						
							|  |  |  |     } while (0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     GC(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-13 17:10:53 +02:00
										 |  |  | void CppModelManager::onAboutToUnloadSession() | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |     if (m_core->progressManager()) { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX); | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-08 10:44:56 +01:00
										 |  |  |     do { | 
					
						
							|  |  |  |         QMutexLocker locker(&mutex); | 
					
						
							|  |  |  |         m_projects.clear(); | 
					
						
							|  |  |  |         m_dirty = true; | 
					
						
							|  |  |  |     } while (0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GC(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  | void CppModelManager::updateIncludesInPaths(QFutureInterface<void> &future, | 
					
						
							|  |  |  |                                             CppModelManager *manager, | 
					
						
							|  |  |  |                                             QStringList paths, | 
					
						
							| 
									
										
										
										
											2009-10-01 17:01:13 +02:00
										 |  |  |                                             QStringList frameworkPaths, | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  |                                             QStringList suffixes) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMap<QString, QStringList> entriesInPaths; | 
					
						
							| 
									
										
										
										
											2009-08-28 16:54:38 +02:00
										 |  |  |     typedef QPair<QString, QString> SymLink; | 
					
						
							|  |  |  |     typedef QList<SymLink> SymLinks; | 
					
						
							|  |  |  |     SymLinks symlinks; | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  |     int processed = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     future.setProgressRange(0, paths.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-11 17:56:43 +01:00
										 |  |  |     static const int MAX_DEPTH = 3; | 
					
						
							|  |  |  |     QList<int> pathDepths; | 
					
						
							|  |  |  |     pathDepths.reserve(paths.size()); | 
					
						
							|  |  |  |     for (int i = 0; i < paths.size(); ++i) { | 
					
						
							|  |  |  |         pathDepths.append(0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-01 17:01:13 +02:00
										 |  |  |     // Add framework header directories to path list
 | 
					
						
							|  |  |  |     QStringList frameworkFilter; | 
					
						
							|  |  |  |     frameworkFilter << QLatin1String("*.framework"); | 
					
						
							|  |  |  |     QStringListIterator fwPathIt(frameworkPaths); | 
					
						
							|  |  |  |     while (fwPathIt.hasNext()) { | 
					
						
							|  |  |  |         const QString &fwPath = fwPathIt.next(); | 
					
						
							|  |  |  |         QStringList entriesInFrameworkPath; | 
					
						
							|  |  |  |         const QStringList &frameworks = QDir(fwPath).entryList(frameworkFilter, QDir::Dirs | QDir::NoDotAndDotDot); | 
					
						
							|  |  |  |         QStringListIterator fwIt(frameworks); | 
					
						
							|  |  |  |         while (fwIt.hasNext()) { | 
					
						
							|  |  |  |             QString framework = fwIt.next(); | 
					
						
							|  |  |  |             paths.append(fwPath + QLatin1Char('/') + framework + QLatin1String("/Headers")); | 
					
						
							| 
									
										
										
										
											2011-01-11 17:56:43 +01:00
										 |  |  |             pathDepths.append(0); | 
					
						
							| 
									
										
										
										
											2009-10-01 17:01:13 +02:00
										 |  |  |             framework.chop(10); // remove the ".framework"
 | 
					
						
							|  |  |  |             entriesInFrameworkPath.append(framework + QLatin1Char('/')); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         entriesInPaths.insert(fwPath, entriesInFrameworkPath); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  |     while (!paths.isEmpty()) { | 
					
						
							|  |  |  |         if (future.isPaused()) | 
					
						
							|  |  |  |             future.waitForResume(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (future.isCanceled()) | 
					
						
							| 
									
										
										
										
											2009-10-13 12:12:51 +02:00
										 |  |  |             return; | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const QString path = paths.takeFirst(); | 
					
						
							| 
									
										
										
										
											2011-01-11 17:56:43 +01:00
										 |  |  |         const int depth = pathDepths.takeFirst(); | 
					
						
							| 
									
										
										
										
											2010-10-03 09:28:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-14 18:04:27 +02:00
										 |  |  |         // Skip non-existing paths
 | 
					
						
							|  |  |  |         if (!QFile::exists(path)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-28 16:54:38 +02:00
										 |  |  |         // Skip already scanned paths
 | 
					
						
							|  |  |  |         if (entriesInPaths.contains(path)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  |         QStringList entries; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QDirIterator i(path, QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); | 
					
						
							|  |  |  |         while (i.hasNext()) { | 
					
						
							|  |  |  |             const QString fileName = i.next(); | 
					
						
							|  |  |  |             const QFileInfo fileInfo = i.fileInfo(); | 
					
						
							| 
									
										
										
										
											2010-04-14 18:04:27 +02:00
										 |  |  |             QString text = fileInfo.fileName(); | 
					
						
							| 
									
										
										
										
											2011-01-11 17:56:43 +01:00
										 |  |  |             if (depth < MAX_DEPTH && fileInfo.isDir()) { | 
					
						
							| 
									
										
										
										
											2010-04-14 18:04:27 +02:00
										 |  |  |                 text += QLatin1Char('/'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // Also scan subdirectory, but avoid endless recursion with symbolic links
 | 
					
						
							|  |  |  |                 if (fileInfo.isSymLink()) { | 
					
						
							|  |  |  |                     QString target = fileInfo.symLinkTarget(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     // Don't add broken symlinks
 | 
					
						
							|  |  |  |                     if (!QFileInfo(target).exists()) | 
					
						
							|  |  |  |                         continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     QMap<QString, QStringList>::const_iterator result = entriesInPaths.find(target); | 
					
						
							|  |  |  |                     if (result != entriesInPaths.constEnd()) { | 
					
						
							|  |  |  |                         entriesInPaths.insert(fileName, result.value()); | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  |                     } else { | 
					
						
							| 
									
										
										
										
											2010-04-14 18:04:27 +02:00
										 |  |  |                         paths.append(target); | 
					
						
							| 
									
										
										
										
											2011-01-11 17:56:43 +01:00
										 |  |  |                         pathDepths.append(depth + 1); | 
					
						
							| 
									
										
										
										
											2010-04-14 18:04:27 +02:00
										 |  |  |                         symlinks.append(SymLink(fileName, target)); | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2010-04-14 18:04:27 +02:00
										 |  |  |                 } else { | 
					
						
							|  |  |  |                     paths.append(fileName); | 
					
						
							| 
									
										
										
										
											2011-01-11 17:56:43 +01:00
										 |  |  |                     pathDepths.append(depth + 1); | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 entries.append(text); | 
					
						
							| 
									
										
										
										
											2010-04-14 18:04:27 +02:00
										 |  |  |             } else { | 
					
						
							|  |  |  |                 const QString suffix = fileInfo.suffix(); | 
					
						
							|  |  |  |                 if (suffix.isEmpty() || suffixes.contains(suffix)) | 
					
						
							|  |  |  |                     entries.append(text); | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         entriesInPaths.insert(path, entries); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ++processed; | 
					
						
							|  |  |  |         future.setProgressRange(0, processed + paths.size()); | 
					
						
							|  |  |  |         future.setProgressValue(processed); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-08-28 16:54:38 +02:00
										 |  |  |     // link symlinks
 | 
					
						
							|  |  |  |     QListIterator<SymLink> it(symlinks); | 
					
						
							|  |  |  |     it.toBack(); | 
					
						
							|  |  |  |     while (it.hasPrevious()) { | 
					
						
							|  |  |  |         SymLink v = it.previous(); | 
					
						
							|  |  |  |         QMap<QString, QStringList>::const_iterator result = entriesInPaths.find(v.second); | 
					
						
							|  |  |  |         entriesInPaths.insert(v.first, result.value()); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-07-24 12:50:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     manager->setIncludesInPaths(entriesInPaths); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     future.reportFinished(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | void CppModelManager::parse(QFutureInterface<void> &future, | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |                             CppPreprocessor *preproc, | 
					
						
							|  |  |  |                             QStringList files) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-09 12:33:43 +01:00
										 |  |  |     if (files.isEmpty()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-07 10:23:37 +02:00
										 |  |  |     const Core::MimeDatabase *mimeDb = Core::ICore::instance()->mimeDatabase(); | 
					
						
							|  |  |  |     Core::MimeType cSourceTy = mimeDb->findByType(QLatin1String("text/x-csrc")); | 
					
						
							|  |  |  |     Core::MimeType cppSourceTy = mimeDb->findByType(QLatin1String("text/x-c++src")); | 
					
						
							|  |  |  |     Core::MimeType mSourceTy = mimeDb->findByType(QLatin1String("text/x-objcsrc")); | 
					
						
							| 
									
										
										
										
											2010-02-23 15:54:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-22 16:00:47 +01:00
										 |  |  |     QStringList sources; | 
					
						
							|  |  |  |     QStringList headers; | 
					
						
							| 
									
										
										
										
											2010-05-07 10:23:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QStringList suffixes = cSourceTy.suffixes(); | 
					
						
							|  |  |  |     suffixes += cppSourceTy.suffixes(); | 
					
						
							|  |  |  |     suffixes += mSourceTy.suffixes(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const QString &file, files) { | 
					
						
							|  |  |  |         QFileInfo info(file); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         preproc->snapshot.remove(file); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (suffixes.contains(info.suffix())) | 
					
						
							|  |  |  |             sources.append(file); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             headers.append(file); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-03 16:18:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-22 16:00:47 +01:00
										 |  |  |     const int sourceCount = sources.size(); | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |     files = sources; | 
					
						
							|  |  |  |     files += headers; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 15:57:37 +01:00
										 |  |  |     preproc->setTodo(files); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     future.setProgressRange(0, files.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QString conf = QLatin1String(pp_configuration_file); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |     bool processingHeaders = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     for (int i = 0; i < files.size(); ++i) { | 
					
						
							|  |  |  |         if (future.isPaused()) | 
					
						
							|  |  |  |             future.waitForResume(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (future.isCanceled()) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-22 16:00:47 +01:00
										 |  |  |         const QString fileName = files.at(i); | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-22 16:00:47 +01:00
										 |  |  |         const bool isSourceFile = i < sourceCount; | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |         if (isSourceFile) | 
					
						
							|  |  |  |             (void) preproc->run(conf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         else if (! processingHeaders) { | 
					
						
							|  |  |  |             (void) preproc->run(conf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             processingHeaders = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |         preproc->run(fileName); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 15:57:37 +01:00
										 |  |  |         future.setProgressValue(files.size() - preproc->todo().size()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 12:49:56 +01:00
										 |  |  |         if (isSourceFile) | 
					
						
							|  |  |  |             preproc->resetEnvironment(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-03 16:18:33 +01:00
										 |  |  |     future.setProgressValue(files.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |     delete preproc; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CppModelManager::GC() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-02 15:27:13 +02:00
										 |  |  |     protectSnapshot.lock(); | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  |     Snapshot currentSnapshot = m_snapshot; | 
					
						
							| 
									
										
										
										
											2009-06-02 15:27:13 +02:00
										 |  |  |     protectSnapshot.unlock(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QSet<QString> processed; | 
					
						
							| 
									
										
										
										
											2008-12-04 17:07:43 +01:00
										 |  |  |     QStringList todo = projectFiles(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     while (! todo.isEmpty()) { | 
					
						
							|  |  |  |         QString fn = todo.last(); | 
					
						
							|  |  |  |         todo.removeLast(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (processed.contains(fn)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         processed.insert(fn); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  |         if (Document::Ptr doc = currentSnapshot.document(fn)) { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             todo += doc->includedFiles(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QStringList removedFiles; | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Snapshot newSnapshot; | 
					
						
							|  |  |  |     for (Snapshot::const_iterator it = currentSnapshot.begin(); it != currentSnapshot.end(); ++it) { | 
					
						
							|  |  |  |         const QString fileName = it.key(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (processed.contains(fileName)) | 
					
						
							|  |  |  |             newSnapshot.insert(it.value()); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             removedFiles.append(fileName); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     emit aboutToRemoveFiles(removedFiles); | 
					
						
							| 
									
										
										
										
											2009-06-02 15:27:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     protectSnapshot.lock(); | 
					
						
							| 
									
										
										
										
											2009-12-07 10:54:27 +01:00
										 |  |  |     m_snapshot = newSnapshot; | 
					
						
							| 
									
										
										
										
											2009-06-02 15:27:13 +02:00
										 |  |  |     protectSnapshot.unlock(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-12-03 13:49:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  | static FullySpecifiedType stripPointerAndReference(const FullySpecifiedType &type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Type *t = type.type(); | 
					
						
							|  |  |  |     while (t) { | 
					
						
							|  |  |  |         if (PointerType *ptr = t->asPointerType()) | 
					
						
							|  |  |  |             t = ptr->elementType().type(); | 
					
						
							|  |  |  |         else if (ReferenceType *ref = t->asReferenceType()) | 
					
						
							|  |  |  |             t = ref->elementType().type(); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return FullySpecifiedType(t); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static QString toQmlType(const FullySpecifiedType &type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Overview overview; | 
					
						
							|  |  |  |     QString result = overview(stripPointerAndReference(type)); | 
					
						
							|  |  |  |     if (result == QLatin1String("QString")) | 
					
						
							|  |  |  |         result = QLatin1String("string"); | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Class *lookupClass(const QString &expression, Scope *scope, TypeOfExpression &typeOf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<LookupItem> results = typeOf(expression, scope); | 
					
						
							|  |  |  |     Class *klass = 0; | 
					
						
							|  |  |  |     foreach (const LookupItem &item, results) { | 
					
						
							|  |  |  |         if (item.declaration()) { | 
					
						
							|  |  |  |             klass = item.declaration()->asClass(); | 
					
						
							|  |  |  |             if (klass) | 
					
						
							|  |  |  |                 return klass; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-04 17:04:44 +01:00
										 |  |  | static void populate(LanguageUtils::FakeMetaObject::Ptr fmo, Class *klass, | 
					
						
							|  |  |  |                      QHash<Class *, LanguageUtils::FakeMetaObject::Ptr> *classes, | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  |                      TypeOfExpression &typeOf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     using namespace LanguageUtils; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Overview namePrinter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     classes->insert(klass, fmo); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned i = 0; i < klass->memberCount(); ++i) { | 
					
						
							|  |  |  |         Symbol *member = klass->memberAt(i); | 
					
						
							|  |  |  |         if (!member->name()) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (Function *func = member->type()->asFunctionType()) { | 
					
						
							|  |  |  |             if (!func->isSlot() && !func->isInvokable() && !func->isSignal()) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             FakeMetaMethod method(namePrinter(func->name()), toQmlType(func->returnType())); | 
					
						
							|  |  |  |             if (func->isSignal()) | 
					
						
							|  |  |  |                 method.setMethodType(FakeMetaMethod::Signal); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 method.setMethodType(FakeMetaMethod::Slot); | 
					
						
							|  |  |  |             for (unsigned a = 0; a < func->argumentCount(); ++a) { | 
					
						
							|  |  |  |                 Symbol *arg = func->argumentAt(a); | 
					
						
							|  |  |  |                 QString name(CppModelManager::tr("unnamed")); | 
					
						
							|  |  |  |                 if (arg->name()) | 
					
						
							|  |  |  |                     name = namePrinter(arg->name()); | 
					
						
							|  |  |  |                 method.addParameter(name, toQmlType(arg->type())); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             fmo->addMethod(method); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (QtPropertyDeclaration *propDecl = member->asQtPropertyDeclaration()) { | 
					
						
							|  |  |  |             const FullySpecifiedType &type = propDecl->type(); | 
					
						
							|  |  |  |             const bool isList = false; // ### fixme
 | 
					
						
							|  |  |  |             const bool isWritable = propDecl->flags() & QtPropertyDeclaration::WriteFunction; | 
					
						
							|  |  |  |             const bool isPointer = type.type() && type.type()->isPointerType(); | 
					
						
							|  |  |  |             FakeMetaProperty property( | 
					
						
							|  |  |  |                         namePrinter(propDecl->name()), | 
					
						
							|  |  |  |                         toQmlType(type), | 
					
						
							|  |  |  |                         isList, isWritable, isPointer); | 
					
						
							|  |  |  |             fmo->addProperty(property); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (QtEnum *qtEnum = member->asQtEnum()) { | 
					
						
							|  |  |  |             // find the matching enum
 | 
					
						
							|  |  |  |             Enum *e = 0; | 
					
						
							|  |  |  |             QList<LookupItem> result = typeOf(namePrinter(qtEnum->name()), klass); | 
					
						
							|  |  |  |             foreach (const LookupItem &item, result) { | 
					
						
							|  |  |  |                 if (item.declaration()) { | 
					
						
							|  |  |  |                     e = item.declaration()->asEnum(); | 
					
						
							|  |  |  |                     if (e) | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (!e) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             FakeMetaEnum metaEnum(namePrinter(e->name())); | 
					
						
							|  |  |  |             for (unsigned j = 0; j < e->memberCount(); ++j) { | 
					
						
							|  |  |  |                 Symbol *enumMember = e->memberAt(j); | 
					
						
							|  |  |  |                 if (!enumMember->name()) | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 metaEnum.addKey(namePrinter(enumMember->name()), 0); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             fmo->addEnum(metaEnum); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // only single inheritance is supported
 | 
					
						
							|  |  |  |     if (klass->baseClassCount() > 0) { | 
					
						
							|  |  |  |         BaseClass *base = klass->baseClassAt(0); | 
					
						
							|  |  |  |         if (!base->name()) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const QString baseClassName = namePrinter(base->name()); | 
					
						
							|  |  |  |         fmo->setSuperclassName(baseClassName); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Class *baseClass = lookupClass(baseClassName, klass, typeOf); | 
					
						
							|  |  |  |         if (!baseClass) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-04 17:04:44 +01:00
										 |  |  |         FakeMetaObject::Ptr baseFmo = classes->value(baseClass); | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  |         if (!baseFmo) { | 
					
						
							| 
									
										
										
										
											2011-01-04 17:04:44 +01:00
										 |  |  |             baseFmo = FakeMetaObject::Ptr(new FakeMetaObject); | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  |             populate(baseFmo, baseClass, classes, typeOf); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         fmo->setSuperclass(baseFmo); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-06 10:01:45 +01:00
										 |  |  | QList<LanguageUtils::FakeMetaObject::ConstPtr> CppModelManager::exportedQmlObjects(const Document::Ptr &doc) const | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     using namespace LanguageUtils; | 
					
						
							| 
									
										
										
										
											2011-01-04 17:04:44 +01:00
										 |  |  |     QList<FakeMetaObject::ConstPtr> exportedObjects; | 
					
						
							|  |  |  |     QHash<Class *, FakeMetaObject::Ptr> classes; | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-06 10:01:45 +01:00
										 |  |  |     const QList<CPlusPlus::Document::ExportedQmlType> exported = doc->exportedQmlTypes(); | 
					
						
							|  |  |  |     if (exported.isEmpty()) | 
					
						
							|  |  |  |         return exportedObjects; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TypeOfExpression typeOf; | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  |     const Snapshot currentSnapshot = snapshot(); | 
					
						
							| 
									
										
										
										
											2011-01-06 10:01:45 +01:00
										 |  |  |     typeOf.init(doc, currentSnapshot); | 
					
						
							|  |  |  |     foreach (const Document::ExportedQmlType &exportedType, exported) { | 
					
						
							|  |  |  |         FakeMetaObject::Ptr fmo(new FakeMetaObject); | 
					
						
							|  |  |  |         fmo->addExport(exportedType.typeName, exportedType.packageName, | 
					
						
							|  |  |  |                        ComponentVersion(exportedType.majorVersion, exportedType.minorVersion)); | 
					
						
							|  |  |  |         exportedObjects += fmo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Class *klass = lookupClass(exportedType.typeExpression, exportedType.scope, typeOf); | 
					
						
							|  |  |  |         if (!klass) | 
					
						
							|  |  |  |             continue; | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-06 10:01:45 +01:00
										 |  |  |         // add the no-package export, so the cpp name can be used in properties
 | 
					
						
							|  |  |  |         Overview overview; | 
					
						
							|  |  |  |         fmo->addExport(overview(klass->name()), QString(), ComponentVersion()); | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-06 10:01:45 +01:00
										 |  |  |         populate(fmo, klass, &classes, typeOf); | 
					
						
							| 
									
										
										
										
											2010-12-03 10:13:15 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return exportedObjects; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 |