CppTools: Clean up CppModelManager(Interface)

* Const correctness
* Better variable names
* Sort order of includes and forward declarations
* Comment fixes
* Cosmetic/Whitespace changes

Change-Id: Ieb137266ac7eddedb00c37f8b2cc8677d67e4bdd
Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
Nikolai Kosjar
2013-07-11 11:13:07 +02:00
committed by David Schulz
parent f068223133
commit fdaddec7d1
7 changed files with 204 additions and 198 deletions

View File

@@ -128,7 +128,7 @@ CMakeProject::~CMakeProject()
it = m_uiCodeModelSupport.constBegin(); it = m_uiCodeModelSupport.constBegin();
end = m_uiCodeModelSupport.constEnd(); end = m_uiCodeModelSupport.constEnd();
for (; it!=end; ++it) { for (; it!=end; ++it) {
modelManager->removeEditorSupport(it.value()); modelManager->removeExtraEditorSupport(it.value());
delete it.value(); delete it.value();
} }
@@ -794,7 +794,7 @@ void CMakeProject::createUiCodeModelSupport()
// qDebug()<<"adding new codemodelsupport"; // qDebug()<<"adding new codemodelsupport";
QtSupport::UiCodeModelSupport *cms = new QtSupport::UiCodeModelSupport(modelManager, this, uiFile, uiHeaderFilePath); QtSupport::UiCodeModelSupport *cms = new QtSupport::UiCodeModelSupport(modelManager, this, uiFile, uiHeaderFilePath);
m_uiCodeModelSupport.insert(uiFile, cms); m_uiCodeModelSupport.insert(uiFile, cms);
modelManager->addEditorSupport(cms); modelManager->addExtraEditorSupport(cms);
} }
} }
} }
@@ -803,7 +803,7 @@ void CMakeProject::createUiCodeModelSupport()
QMap<QString, QtSupport::UiCodeModelSupport *>::const_iterator it, end; QMap<QString, QtSupport::UiCodeModelSupport *>::const_iterator it, end;
end = oldCodeModelSupport.constEnd(); end = oldCodeModelSupport.constEnd();
for (it = oldCodeModelSupport.constBegin(); it!=end; ++it) { for (it = oldCodeModelSupport.constBegin(); it!=end; ++it) {
modelManager->removeEditorSupport(it.value()); modelManager->removeExtraEditorSupport(it.value());
delete it.value(); delete it.value();
} }
} }

View File

@@ -561,7 +561,7 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent)
CPPEditorWidget::~CPPEditorWidget() CPPEditorWidget::~CPPEditorWidget()
{ {
if (m_modelManager) if (m_modelManager)
m_modelManager->deleteEditorSupport(editor()); m_modelManager->deleteCppEditorSupport(editor());
delete m_completionSupport; delete m_completionSupport;
} }

View File

@@ -28,31 +28,30 @@
****************************************************************************/ ****************************************************************************/
#include "cppmodelmanager.h" #include "cppmodelmanager.h"
#include "cpppreprocessor.h"
#include "cpptoolsconstants.h"
#include "abstracteditorsupport.h"
#include "builtinindexingsupport.h" #include "builtinindexingsupport.h"
#include "cppcompletionassist.h" #include "cppcompletionassist.h"
#include "cppfindreferences.h"
#include "cpphighlightingsupport.h" #include "cpphighlightingsupport.h"
#include "cpphighlightingsupportinternal.h" #include "cpphighlightingsupportinternal.h"
#include "cppindexingsupport.h" #include "cppindexingsupport.h"
#include "abstracteditorsupport.h" #include "cpppreprocessor.h"
#include "cpptoolsconstants.h"
#include "cpptoolseditorsupport.h" #include "cpptoolseditorsupport.h"
#include "cppfindreferences.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
#include <QMutexLocker> #include <QMutexLocker>
#include <QTimer>
#include <QTextBlock> #include <QTextBlock>
#include <QTimer>
#if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU) #if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU)
#define WITH_AST_DUMP #define WITH_AST_DUMP
@@ -99,7 +98,7 @@ using namespace CppTools;
using namespace CppTools::Internal; using namespace CppTools::Internal;
using namespace CPlusPlus; using namespace CPlusPlus;
#ifdef WITH_AST_DUMP #ifdef QTCREATOR_WITH_DUMP_AST
#include <cxxabi.h> #include <cxxabi.h>
@@ -194,41 +193,44 @@ void CppModelManager::updateModifiedSourceFiles()
/*! /*!
\class CppTools::CppModelManager \class CppTools::CppModelManager
\brief The CppModelManager class keeps track of one CppCodeModel instance \brief The CppModelManager keeps tracks of the source files the code model is aware of.
for each project and all the related CppCodeModelPart instances.
It also takes care of updating the code models when C++ files are The CppModelManager manages the source files in a Snapshot object.
modified within Qt Creator.
The snapshot is updated in case e.g.
* New files are opened/edited (Editor integration)
* A project manager pushes updated project information (Project integration)
* Files are garbage collected
*/ */
QMutex CppModelManager::m_modelManagerMutex; QMutex CppModelManager::m_instanceMutex;
CppModelManager *CppModelManager::m_modelManagerInstance = 0; CppModelManager *CppModelManager::m_instance = 0;
CppModelManager *CppModelManager::instance() CppModelManager *CppModelManager::instance()
{ {
if (m_modelManagerInstance) if (m_instance)
return m_modelManagerInstance; return m_instance;
QMutexLocker locker(&m_modelManagerMutex);
if (!m_modelManagerInstance) QMutexLocker locker(&m_instanceMutex);
m_modelManagerInstance = new CppModelManager; if (!m_instance)
return m_modelManagerInstance; m_instance = new CppModelManager;
return m_instance;
} }
CppModelManager::CppModelManager(QObject *parent) CppModelManager::CppModelManager(QObject *parent)
: CppModelManagerInterface(parent) : CppModelManagerInterface(parent)
, m_enableGC(true)
, m_completionAssistProvider(0) , m_completionAssistProvider(0)
, m_highlightingFactory(0) , m_highlightingFactory(0)
, m_indexingSupporter(0) , m_indexingSupporter(0)
, m_enableGC(true)
{ {
m_findReferences = new CppFindReferences(this); m_findReferences = new CppFindReferences(this);
m_indexerEnabled = qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull(); m_indexerEnabled = qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull();
m_dirty = true; m_dirty = true;
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
ProjectExplorer::ProjectExplorerPlugin::instance();
QTC_ASSERT(pe, return); QTC_ASSERT(pe, return);
ProjectExplorer::SessionManager *session = pe->session(); ProjectExplorer::SessionManager *session = pe->session();
@@ -306,10 +308,10 @@ void CppModelManager::ensureUpdated()
QStringList CppModelManager::internalProjectFiles() const QStringList CppModelManager::internalProjectFiles() const
{ {
QStringList files; QStringList files;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projectToProjectsInfo);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
ProjectInfo pinfo = it.value(); const ProjectInfo pinfo = it.value();
foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) { foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) {
foreach (const ProjectFile &file, part->files) foreach (const ProjectFile &file, part->files)
files += file.path; files += file.path;
@@ -322,10 +324,10 @@ QStringList CppModelManager::internalProjectFiles() const
QStringList CppModelManager::internalIncludePaths() const QStringList CppModelManager::internalIncludePaths() const
{ {
QStringList includePaths; QStringList includePaths;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projectToProjectsInfo);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
ProjectInfo pinfo = it.value(); const ProjectInfo pinfo = it.value();
foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) foreach (const ProjectPart::Ptr &part, pinfo.projectParts())
foreach (const QString &path, part->includePaths) foreach (const QString &path, part->includePaths)
includePaths.append(CppPreprocessor::cleanPath(path)); includePaths.append(CppPreprocessor::cleanPath(path));
@@ -337,10 +339,10 @@ QStringList CppModelManager::internalIncludePaths() const
QStringList CppModelManager::internalFrameworkPaths() const QStringList CppModelManager::internalFrameworkPaths() const
{ {
QStringList frameworkPaths; QStringList frameworkPaths;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projectToProjectsInfo);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
ProjectInfo pinfo = it.value(); const ProjectInfo pinfo = it.value();
foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) foreach (const ProjectPart::Ptr &part, pinfo.projectParts())
foreach (const QString &path, part->frameworkPaths) foreach (const QString &path, part->frameworkPaths)
frameworkPaths.append(CppPreprocessor::cleanPath(path)); frameworkPaths.append(CppPreprocessor::cleanPath(path));
@@ -353,10 +355,10 @@ QByteArray CppModelManager::internalDefinedMacros() const
{ {
QByteArray macros; QByteArray macros;
QSet<QByteArray> alreadyIn; QSet<QByteArray> alreadyIn;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projectToProjectsInfo);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
ProjectInfo pinfo = it.value(); const ProjectInfo pinfo = it.value();
foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) { foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) {
const QList<QByteArray> defs = part->defines.split('\n'); const QList<QByteArray> defs = part->defines.split('\n');
foreach (const QByteArray &def, defs) { foreach (const QByteArray &def, defs) {
@@ -375,9 +377,9 @@ QByteArray CppModelManager::internalDefinedMacros() const
void CppModelManager::dumpModelManagerConfiguration() void CppModelManager::dumpModelManagerConfiguration()
{ {
// Tons of debug output... // Tons of debug output...
qDebug()<<"========= CppModelManager::dumpModelManagerConfiguration ======"; qDebug() << "========= CppModelManager::dumpModelManagerConfiguration ======";
foreach (const ProjectInfo &pinfo, m_projects) { foreach (const ProjectInfo &pinfo, m_projectToProjectsInfo) {
qDebug()<<" for project:"<< pinfo.project().data()->document()->filePath(); qDebug() << " for project:"<< pinfo.project().data()->document()->filePath();
foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) { foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) {
qDebug() << "=== part ==="; qDebug() << "=== part ===";
const char* cVersion; const char* cVersion;
@@ -425,35 +427,64 @@ void CppModelManager::dumpModelManagerConfiguration()
qDebug() << inc; qDebug() << inc;
qDebug() << "=== Merged defined macros ==="; qDebug() << "=== Merged defined macros ===";
qDebug() << m_definedMacros; qDebug() << m_definedMacros;
qDebug()<<"========= End of dump ======"; qDebug() << "========= End of dump ======";
} }
void CppModelManager::addEditorSupport(AbstractEditorSupport *editorSupport) void CppModelManager::addExtraEditorSupport(AbstractEditorSupport *editorSupport)
{ {
m_addtionalEditorSupport.insert(editorSupport); m_extraEditorSupports.insert(editorSupport);
} }
void CppModelManager::removeEditorSupport(AbstractEditorSupport *editorSupport) void CppModelManager::removeExtraEditorSupport(AbstractEditorSupport *editorSupport)
{ {
m_addtionalEditorSupport.remove(editorSupport); m_extraEditorSupports.remove(editorSupport);
} }
/// \brief Returns the \c CppEditorSupport for the given text editor. It will /// \brief Returns the \c CppEditorSupport for the given text editor. It will
/// create one when none exists yet. /// create one when none exists yet.
CppEditorSupport *CppModelManager::cppEditorSupport(TextEditor::BaseTextEditor *editor) CppEditorSupport *CppModelManager::cppEditorSupport(TextEditor::BaseTextEditor *textEditor)
{ {
Q_ASSERT(editor); Q_ASSERT(textEditor);
QMutexLocker locker(&m_editorSupportMutex); QMutexLocker locker(&m_cppEditorSupportsMutex);
CppEditorSupport *editorSupport = m_editorSupport.value(editor, 0); CppEditorSupport *editorSupport = m_cppEditorSupports.value(textEditor, 0);
if (!editorSupport) { if (!editorSupport) {
editorSupport = new CppEditorSupport(this, editor); editorSupport = new CppEditorSupport(this, textEditor);
m_editorSupport.insert(editor, editorSupport); m_cppEditorSupports.insert(textEditor, editorSupport);
} }
return editorSupport; return editorSupport;
} }
/// \brief Removes the CppEditorSupport for the closed editor.
void CppModelManager::deleteCppEditorSupport(TextEditor::BaseTextEditor *textEditor)
{
static short numberOfClosedEditors = 0;
QTC_ASSERT(textEditor, return);
if (!isCppEditor(textEditor))
return;
CppEditorSupport *editorSupport;
int numberOfOpenEditors = 0;
{ // Only lock the operations on m_cppEditorSupport
QMutexLocker locker(&m_cppEditorSupportsMutex);
editorSupport = m_cppEditorSupports.value(textEditor, 0);
m_cppEditorSupports.remove(textEditor);
numberOfOpenEditors = m_cppEditorSupports.size();
}
delete editorSupport;
++numberOfClosedEditors;
if (numberOfOpenEditors == 0 || numberOfClosedEditors == 5) {
numberOfClosedEditors = 0;
GC();
}
}
QList<int> CppModelManager::references(CPlusPlus::Symbol *symbol, const LookupContext &context) QList<int> CppModelManager::references(CPlusPlus::Symbol *symbol, const LookupContext &context)
{ {
return m_findReferences->references(symbol, context); return m_findReferences->references(symbol, context);
@@ -465,7 +496,8 @@ void CppModelManager::findUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::Loo
m_findReferences->findUsages(symbol, context); m_findReferences->findUsages(symbol, context);
} }
void CppModelManager::renameUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context, void CppModelManager::renameUsages(CPlusPlus::Symbol *symbol,
const CPlusPlus::LookupContext &context,
const QString &replacement) const QString &replacement)
{ {
if (symbol->identifier()) if (symbol->identifier())
@@ -490,26 +522,26 @@ void CppModelManager::replaceSnapshot(const CPlusPlus::Snapshot &newSnapshot)
CppModelManager::WorkingCopy CppModelManager::buildWorkingCopyList() CppModelManager::WorkingCopy CppModelManager::buildWorkingCopyList()
{ {
QList<CppEditorSupport *> supporters; QList<CppEditorSupport *> cppEditorSupports;
{ {
QMutexLocker locker(&m_editorSupportMutex); QMutexLocker locker(&m_cppEditorSupportsMutex);
supporters = m_editorSupport.values(); cppEditorSupports = m_cppEditorSupports.values();
} }
WorkingCopy workingCopy; WorkingCopy workingCopy;
foreach (const CppEditorSupport *editorSupport, supporters) { foreach (const CppEditorSupport *editorSupport, cppEditorSupports) {
workingCopy.insert(editorSupport->fileName(), editorSupport->contents(), workingCopy.insert(editorSupport->fileName(), editorSupport->contents(),
editorSupport->editorRevision()); editorSupport->editorRevision());
} }
QSetIterator<AbstractEditorSupport *> jt(m_addtionalEditorSupport); QSetIterator<AbstractEditorSupport *> it(m_extraEditorSupports);
while (jt.hasNext()) { while (it.hasNext()) {
AbstractEditorSupport *es = jt.next(); AbstractEditorSupport *es = it.next();
workingCopy.insert(es->fileName(), QString::fromUtf8(es->contents())); workingCopy.insert(es->fileName(), QString::fromUtf8(es->contents()));
} }
// add the project configuration file // Add the project configuration file
QByteArray conf(pp_configuration); QByteArray conf(pp_configuration);
conf += definedMacros(); conf += definedMacros();
workingCopy.insert(configurationFileName(), QString::fromLocal8Bit(conf)); workingCopy.insert(configurationFileName(), QString::fromLocal8Bit(conf));
@@ -536,27 +568,25 @@ QFuture<void> CppModelManager::updateSourceFiles(const QStringList &sourceFiles,
QList<CppModelManager::ProjectInfo> CppModelManager::projectInfos() const QList<CppModelManager::ProjectInfo> CppModelManager::projectInfos() const
{ {
QMutexLocker locker(&m_projectMutex); QMutexLocker locker(&m_projectMutex);
return m_projectToProjectsInfo.values();
return m_projects.values();
} }
CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Project *project) const CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Project *project) const
{ {
QMutexLocker locker(&m_projectMutex); QMutexLocker locker(&m_projectMutex);
return m_projectToProjectsInfo.value(project, ProjectInfo(project));
return m_projects.value(project, ProjectInfo(project));
} }
QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
{ {
{ // only hold the mutex for a limited scope, so the dumping afterwards can aquire it without deadlocking. if (!pinfo.isValid())
return QFuture<void>();
{ // Only hold the mutex for a limited scope, so the dumping afterwards does not deadlock.
QMutexLocker locker(&m_projectMutex); QMutexLocker locker(&m_projectMutex);
if (!pinfo.isValid())
return QFuture<void>();
ProjectExplorer::Project *project = pinfo.project().data(); ProjectExplorer::Project *project = pinfo.project().data();
ProjectInfo oldProjectInfo = m_projects.value(project); ProjectInfo oldProjectInfo = m_projectToProjectsInfo.value(project);
if (oldProjectInfo.isValid()) { if (oldProjectInfo.isValid()) {
if (pinfo.defines() == oldProjectInfo.defines() if (pinfo.defines() == oldProjectInfo.defines()
&& pinfo.includePaths() == oldProjectInfo.includePaths() && pinfo.includePaths() == oldProjectInfo.includePaths()
@@ -577,14 +607,14 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
} }
m_snapshot.remove(configurationFileName()); m_snapshot.remove(configurationFileName());
m_projects.insert(project, pinfo); m_projectToProjectsInfo.insert(project, pinfo);
m_dirty = true; m_dirty = true;
m_srcToProjectPart.clear(); m_fileToProjectParts.clear();
foreach (const ProjectInfo &projectInfo, m_projects) { foreach (const ProjectInfo &projectInfo, m_projectToProjectsInfo) {
foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) { foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) {
foreach (const ProjectFile &cxxFile, projectPart->files) { foreach (const ProjectFile &cxxFile, projectPart->files) {
m_srcToProjectPart[cxxFile.path].append(projectPart); m_fileToProjectParts[cxxFile.path].append(projectPart);
} }
} }
} }
@@ -600,15 +630,15 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
QList<ProjectPart::Ptr> CppModelManager::projectPart(const QString &fileName) const QList<ProjectPart::Ptr> CppModelManager::projectPart(const QString &fileName) const
{ {
QList<ProjectPart::Ptr> parts = m_srcToProjectPart.value(fileName); QList<ProjectPart::Ptr> parts = m_fileToProjectParts.value(fileName);
if (!parts.isEmpty()) if (!parts.isEmpty())
return parts; return parts;
DependencyTable table; DependencyTable table;
table.build(snapshot()); table.build(snapshot());
QStringList deps = table.filesDependingOn(fileName); const QStringList deps = table.filesDependingOn(fileName);
foreach (const QString &dep, deps) { foreach (const QString &dep, deps) {
parts = m_srcToProjectPart.value(dep); parts = m_fileToProjectParts.value(dep);
if (!parts.isEmpty()) if (!parts.isEmpty())
return parts; return parts;
} }
@@ -616,35 +646,6 @@ QList<ProjectPart::Ptr> CppModelManager::projectPart(const QString &fileName) co
return parts; return parts;
} }
/// \brief Removes the CppEditorSupport for the closed editor.
void CppModelManager::deleteEditorSupport(TextEditor::BaseTextEditor *textEditor)
{
static short numberOfClosedEditors = 0;
QTC_ASSERT(textEditor, return);
if (!isCppEditor(textEditor))
return;
CppEditorSupport *editorSupport;
int numberOfOpenEditors = 0;
{ // only lock the operations on m_editorSupport
QMutexLocker locker(&m_editorSupportMutex);
editorSupport = m_editorSupport.value(textEditor, 0);
m_editorSupport.remove(textEditor);
numberOfOpenEditors = m_editorSupport.size();
}
delete editorSupport;
++numberOfClosedEditors;
if (numberOfOpenEditors == 0 || numberOfClosedEditors == 5) {
numberOfClosedEditors = 0;
GC();
}
}
bool CppModelManager::isCppEditor(Core::IEditor *editor) const bool CppModelManager::isCppEditor(Core::IEditor *editor) const
{ {
return editor->context().contains(ProjectExplorer::Constants::LANG_CXX); return editor->context().contains(ProjectExplorer::Constants::LANG_CXX);
@@ -667,7 +668,7 @@ void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
do { do {
QMutexLocker locker(&m_projectMutex); QMutexLocker locker(&m_projectMutex);
m_dirty = true; m_dirty = true;
m_projects.remove(project); m_projectToProjectsInfo.remove(project);
} while (0); } while (0);
GC(); GC();
@@ -679,7 +680,7 @@ void CppModelManager::onAboutToUnloadSession()
pm->cancelTasks(QLatin1String(CppTools::Constants::TASK_INDEX)); pm->cancelTasks(QLatin1String(CppTools::Constants::TASK_INDEX));
do { do {
QMutexLocker locker(&m_projectMutex); QMutexLocker locker(&m_projectMutex);
m_projects.clear(); m_projectToProjectsInfo.clear();
m_dirty = true; m_dirty = true;
} while (0); } while (0);
@@ -696,37 +697,37 @@ void CppModelManager::GC()
if (!m_enableGC) if (!m_enableGC)
return; return;
Snapshot currentSnapshot = snapshot(); const Snapshot currentSnapshot = snapshot();
QSet<QString> processed; QSet<QString> reachableFiles;
QStringList todo = projectFiles(); QStringList todo = projectFiles();
// Collect all files that are reachable from the project files
while (!todo.isEmpty()) { while (!todo.isEmpty()) {
QString fn = todo.last(); const QString file = todo.last();
todo.removeLast(); todo.removeLast();
if (processed.contains(fn)) if (reachableFiles.contains(file))
continue; continue;
reachableFiles.insert(file);
processed.insert(fn); if (Document::Ptr doc = currentSnapshot.document(file))
if (Document::Ptr doc = currentSnapshot.document(fn))
todo += doc->includedFiles(); todo += doc->includedFiles();
} }
QStringList removedFiles; // Find out the files in the current snapshot that are not reachable from the project files
QStringList notReachableFiles;
Snapshot newSnapshot; Snapshot newSnapshot;
for (Snapshot::const_iterator it = currentSnapshot.begin(); it != currentSnapshot.end(); ++it) { for (Snapshot::const_iterator it = currentSnapshot.begin(); it != currentSnapshot.end(); ++it) {
const QString fileName = it.key(); const QString fileName = it.key();
if (processed.contains(fileName)) if (reachableFiles.contains(fileName))
newSnapshot.insert(it.value()); newSnapshot.insert(it.value());
else else
removedFiles.append(fileName); notReachableFiles.append(fileName);
} }
emit aboutToRemoveFiles(removedFiles); // Announce removing files and replace the snapshot
emit aboutToRemoveFiles(notReachableFiles);
replaceSnapshot(newSnapshot); replaceSnapshot(newSnapshot);
} }
@@ -780,19 +781,20 @@ CppIndexingSupport *CppModelManager::indexingSupport()
return m_indexingSupporter ? m_indexingSupporter : m_internalIndexingSupport; return m_indexingSupporter ? m_indexingSupporter : m_internalIndexingSupport;
} }
void CppModelManager::setExtraDiagnostics(const QString &fileName, const QString &kind, void CppModelManager::setExtraDiagnostics(const QString &fileName,
const QString &kind,
const QList<Document::DiagnosticMessage> &diagnostics) const QList<Document::DiagnosticMessage> &diagnostics)
{ {
QList<CppEditorSupport *> supporters; QList<CppEditorSupport *> cppEditorSupports;
{ {
QMutexLocker locker(&m_editorSupportMutex); QMutexLocker locker(&m_cppEditorSupportsMutex);
supporters = m_editorSupport.values(); cppEditorSupports = m_cppEditorSupports.values();
} }
foreach (CppEditorSupport *supporter, supporters) { foreach (CppEditorSupport *editorSupport, cppEditorSupports) {
if (supporter->fileName() == fileName) { if (editorSupport->fileName() == fileName) {
supporter->setExtraDiagnostics(kind, diagnostics); editorSupport->setExtraDiagnostics(kind, diagnostics);
break; break;
} }
} }

View File

@@ -31,6 +31,7 @@
#define CPPMODELMANAGER_H #define CPPMODELMANAGER_H
#include "cpptools_global.h" #include "cpptools_global.h"
#include "cppmodelmanagerinterface.h" #include "cppmodelmanagerinterface.h"
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
@@ -40,10 +41,7 @@
#include <QMutex> #include <QMutex>
namespace Core { class IEditor; } namespace Core { class IEditor; }
namespace TextEditor { class BaseTextEditorWidget; }
namespace TextEditor {
class BaseTextEditorWidget;
} // namespace TextEditor
namespace CppTools { namespace CppTools {
@@ -81,14 +79,14 @@ public:
bool replaceDocument(Document::Ptr newDoc); bool replaceDocument(Document::Ptr newDoc);
virtual void GC(); virtual void GC();
virtual bool isCppEditor(Core::IEditor *editor) const;
void emitDocumentUpdated(CPlusPlus::Document::Ptr doc); void emitDocumentUpdated(CPlusPlus::Document::Ptr doc);
virtual void addEditorSupport(AbstractEditorSupport *editorSupport); virtual bool isCppEditor(Core::IEditor *editor) const;
virtual void removeEditorSupport(AbstractEditorSupport *editorSupport);
virtual CppEditorSupport *cppEditorSupport(TextEditor::BaseTextEditor *editor); virtual void addExtraEditorSupport(AbstractEditorSupport *editorSupport);
virtual void deleteEditorSupport(TextEditor::BaseTextEditor *textEditor); virtual void removeExtraEditorSupport(AbstractEditorSupport *editorSupport);
virtual CppEditorSupport *cppEditorSupport(TextEditor::BaseTextEditor *textEditor);
virtual void deleteCppEditorSupport(TextEditor::BaseTextEditor *textEditor);
virtual QList<int> references(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context); virtual QList<int> references(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context);
@@ -143,14 +141,14 @@ public:
return m_definedMacros; return m_definedMacros;
} }
Q_SIGNALS: signals:
void aboutToRemoveFiles(const QStringList &files); void aboutToRemoveFiles(const QStringList &files);
public Q_SLOTS: public slots:
virtual void updateModifiedSourceFiles(); virtual void updateModifiedSourceFiles();
private Q_SLOTS: private slots:
// this should be executed in the GUI thread. // This should be executed in the GUI thread.
void onAboutToRemoveProject(ProjectExplorer::Project *project); void onAboutToRemoveProject(ProjectExplorer::Project *project);
void onAboutToUnloadSession(); void onAboutToUnloadSession();
void onCoreAboutToClose(); void onCoreAboutToClose();
@@ -169,42 +167,46 @@ private:
void dumpModelManagerConfiguration(); void dumpModelManagerConfiguration();
private: private:
static QMutex m_modelManagerMutex; static QMutex m_instanceMutex;
static CppModelManager *m_modelManagerInstance; static CppModelManager *m_instance;
private: private:
// snapshot // Snapshot
mutable QMutex m_snapshotMutex; mutable QMutex m_snapshotMutex;
CPlusPlus::Snapshot m_snapshot; CPlusPlus::Snapshot m_snapshot;
bool m_enableGC; // Project integration
// project integration
mutable QMutex m_projectMutex; mutable QMutex m_projectMutex;
QMap<ProjectExplorer::Project *, ProjectInfo> m_projects; QMap<ProjectExplorer::Project *, ProjectInfo> m_projectToProjectsInfo;
QMap<QString, QList<CppTools::ProjectPart::Ptr> > m_srcToProjectPart; QMap<QString, QList<CppTools::ProjectPart::Ptr> > m_fileToProjectParts;
// cached/calculated from the projects and/or their project-parts // The members below are cached/(re)calculated from the projects and/or their project parts
bool m_dirty; bool m_dirty;
QStringList m_projectFiles; QStringList m_projectFiles;
QStringList m_includePaths; QStringList m_includePaths;
QStringList m_frameworkPaths; QStringList m_frameworkPaths;
QByteArray m_definedMacros; QByteArray m_definedMacros;
// editor integration // Editor integration
mutable QMutex m_editorSupportMutex; mutable QMutex m_cppEditorSupportsMutex;
QMap<TextEditor::BaseTextEditor *, CppEditorSupport *> m_editorSupport; QMap<TextEditor::BaseTextEditor *, CppEditorSupport *> m_cppEditorSupports;
QSet<AbstractEditorSupport *> m_extraEditorSupports;
QSet<AbstractEditorSupport *> m_addtionalEditorSupport;
CppFindReferences *m_findReferences;
bool m_indexerEnabled;
// Completion
CppCompletionAssistProvider *m_completionAssistProvider; CppCompletionAssistProvider *m_completionAssistProvider;
CppCompletionAssistProvider *m_completionFallback; CppCompletionAssistProvider *m_completionFallback;
// Highlighting
CppHighlightingSupportFactory *m_highlightingFactory; CppHighlightingSupportFactory *m_highlightingFactory;
CppHighlightingSupportFactory *m_highlightingFallback; CppHighlightingSupportFactory *m_highlightingFallback;
// Indexing
CppIndexingSupport *m_indexingSupporter; CppIndexingSupport *m_indexingSupporter;
CppIndexingSupport *m_internalIndexingSupport; CppIndexingSupport *m_internalIndexingSupport;
bool m_indexerEnabled;
CppFindReferences *m_findReferences;
bool m_enableGC;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -29,11 +29,15 @@
#include "cppmodelmanagerinterface.h" #include "cppmodelmanagerinterface.h"
#include <projectexplorer/toolchain.h>
#include <projectexplorer/headerpath.h>
#include <cplusplus/pp-engine.h> #include <cplusplus/pp-engine.h>
#include <QtCore/QSet> #include <projectexplorer/headerpath.h>
#include <projectexplorer/toolchain.h>
#include <QSet>
using namespace CppTools;
using namespace ProjectExplorer;
/*! /*!
\enum CppTools::CppModelManagerInterface::ProgressNotificationMode \enum CppTools::CppModelManagerInterface::ProgressNotificationMode
@@ -44,15 +48,16 @@
\value ForcedProgressNotification \value ForcedProgressNotification
Notify regardless of the number of files requested for update. Notify regardless of the number of files requested for update.
\value ReservedProgressNotification \value ReservedProgressNotification
Notify only if more than one file is requested for update. Notify only if more than one file is requested for update.
*/ */
/*! /*!
\enum CppTools::CppModelManagerInterface::QtVersion \enum CppTools::CppModelManagerInterface::QtVersion
Allows C++ parser engine to inject headers or change inner settings as Allows C++ parser engine to inject headers or change inner settings as
needed to parse Qt language extensions for concrete major Qt version needed to parse Qt language extensions for concrete major Qt version
\value UnknownQt \value UnknownQt
Parser may choose any policy Parser may choose any policy
\value NoQt \value NoQt
@@ -63,9 +68,6 @@
Parser may enable tricks for Qt v5.x Parser may enable tricks for Qt v5.x
*/ */
using namespace CppTools;
using namespace ProjectExplorer;
ProjectPart::ProjectPart() ProjectPart::ProjectPart()
: cVersion(C89) : cVersion(C89)
, cxxVersion(CXX11) , cxxVersion(CXX11)
@@ -76,12 +78,13 @@ ProjectPart::ProjectPart()
{ {
} }
/** /*!
* @brief Retrieves info from concrete compiler using it's flags. \brief Retrieves info from concrete compiler using it's flags.
* @param tc Either nullptr or toolchain for project's active target.
* @param cxxflags C++ or Objective-C++ flags. \param tc Either nullptr or toolchain for project's active target.
* @param cflags C or ObjectiveC flags if possible, \a cxxflags otherwise. \param cxxflags C++ or Objective-C++ flags.
*/ \param cflags C or ObjectiveC flags if possible, \a cxxflags otherwise.
*/
void ProjectPart::evaluateToolchain(const ToolChain *tc, void ProjectPart::evaluateToolchain(const ToolChain *tc,
const QStringList &cxxflags, const QStringList &cxxflags,
const QStringList &cflags, const QStringList &cflags,
@@ -89,6 +92,7 @@ void ProjectPart::evaluateToolchain(const ToolChain *tc,
{ {
if (!tc) if (!tc)
return; return;
ToolChain::CompilerFlags cxx = tc->compilerFlags(cxxflags); ToolChain::CompilerFlags cxx = tc->compilerFlags(cxxflags);
ToolChain::CompilerFlags c = (cxxflags == cflags) ToolChain::CompilerFlags c = (cxxflags == cflags)
? cxx : tc->compilerFlags(cflags); ? cxx : tc->compilerFlags(cflags);
@@ -117,14 +121,14 @@ void ProjectPart::evaluateToolchain(const ToolChain *tc,
cWarningFlags = tc->warningFlags(cflags); cWarningFlags = tc->warningFlags(cflags);
cxxWarningFlags = tc->warningFlags(cxxflags); cxxWarningFlags = tc->warningFlags(cxxflags);
QList<HeaderPath> headers = tc->systemHeaderPaths(cxxflags, sysRoot); const QList<HeaderPath> headers = tc->systemHeaderPaths(cxxflags, sysRoot);
foreach (const HeaderPath &header, headers) foreach (const HeaderPath &header, headers)
if (header.kind() == HeaderPath::FrameworkHeaderPath) if (header.kind() == HeaderPath::FrameworkHeaderPath)
frameworkPaths << header.path(); frameworkPaths << header.path();
else else
includePaths << header.path(); includePaths << header.path();
QByteArray macros = tc->predefinedMacros(cxxflags); const QByteArray macros = tc->predefinedMacros(cxxflags);
if (!macros.isEmpty()) { if (!macros.isEmpty()) {
if (!defines.isEmpty()) if (!defines.isEmpty())
defines += '\n'; defines += '\n';
@@ -156,7 +160,6 @@ CppModelManagerInterface *CppModelManagerInterface::instance()
return g_instance; return g_instance;
} }
void CppModelManagerInterface::ProjectInfo::clearProjectParts() void CppModelManagerInterface::ProjectInfo::clearProjectParts()
{ {
m_projectParts.clear(); m_projectParts.clear();
@@ -166,33 +169,32 @@ void CppModelManagerInterface::ProjectInfo::clearProjectParts()
m_defines.clear(); m_defines.clear();
} }
void CppModelManagerInterface::ProjectInfo::appendProjectPart( void CppModelManagerInterface::ProjectInfo::appendProjectPart(const ProjectPart::Ptr &part)
const ProjectPart::Ptr &part)
{ {
if (!part) if (!part)
return; return;
m_projectParts.append(part); m_projectParts.append(part);
// update include paths // Update include paths
QSet<QString> incs = QSet<QString>::fromList(m_includePaths); QSet<QString> incs = QSet<QString>::fromList(m_includePaths);
foreach (const QString &ins, part->includePaths) foreach (const QString &ins, part->includePaths)
incs.insert(ins); incs.insert(ins);
m_includePaths = incs.toList(); m_includePaths = incs.toList();
// update framework paths // Update framework paths
QSet<QString> frms = QSet<QString>::fromList(m_frameworkPaths); QSet<QString> frms = QSet<QString>::fromList(m_frameworkPaths);
foreach (const QString &frm, part->frameworkPaths) foreach (const QString &frm, part->frameworkPaths)
frms.insert(frm); frms.insert(frm);
m_frameworkPaths = frms.toList(); m_frameworkPaths = frms.toList();
// update source files // Update source files
QSet<QString> srcs = QSet<QString>::fromList(m_sourceFiles); QSet<QString> srcs = QSet<QString>::fromList(m_sourceFiles);
foreach (const ProjectFile &file, part->files) foreach (const ProjectFile &file, part->files)
srcs.insert(file.path); srcs.insert(file.path);
m_sourceFiles = srcs.toList(); m_sourceFiles = srcs.toList();
// update defines // Update defines
if (!m_defines.isEmpty()) if (!m_defines.isEmpty())
m_defines.append('\n'); m_defines.append('\n');
m_defines.append(part->defines); m_defines.append(part->defines);

View File

@@ -31,16 +31,17 @@
#define CPPMODELMANAGERINTERFACE_H #define CPPMODELMANAGERINTERFACE_H
#include "cpptools_global.h" #include "cpptools_global.h"
#include "cppprojectfile.h" #include "cppprojectfile.h"
#include <cplusplus/CppDocument.h> #include <cplusplus/CppDocument.h>
#include <projectexplorer/toolchain.h> #include <projectexplorer/toolchain.h>
#include <QObject> #include <QFuture>
#include <QHash> #include <QHash>
#include <QObject>
#include <QPointer> #include <QPointer>
#include <QStringList> #include <QStringList>
#include <QFuture>
namespace Core { class IEditor; } namespace Core { class IEditor; }
namespace CPlusPlus { class LookupContext; } namespace CPlusPlus { class LookupContext; }
@@ -49,9 +50,10 @@ namespace TextEditor { class BaseTextEditor; }
namespace Utils { class FileName; } namespace Utils { class FileName; }
namespace CppTools { namespace CppTools {
class AbstractEditorSupport; class AbstractEditorSupport;
class CppCompletionSupport;
class CppCompletionAssistProvider; class CppCompletionAssistProvider;
class CppCompletionSupport;
class CppEditorSupport; class CppEditorSupport;
class CppHighlightingSupport; class CppHighlightingSupport;
class CppHighlightingSupportFactory; class CppHighlightingSupportFactory;
@@ -97,7 +99,7 @@ public:
typedef QSharedPointer<ProjectPart> Ptr; typedef QSharedPointer<ProjectPart> Ptr;
public: //attributes public:
QList<ProjectFile> files; QList<ProjectFile> files;
QByteArray defines; QByteArray defines;
QStringList includePaths; QStringList includePaths;
@@ -116,8 +118,7 @@ class CPPTOOLS_EXPORT CppModelManagerInterface : public QObject
Q_OBJECT Q_OBJECT
public: public:
// Documented in source file.
// Documented in source file.
enum ProgressNotificationMode { enum ProgressNotificationMode {
ForcedProgressNotification, ForcedProgressNotification,
ReservedProgressNotification ReservedProgressNotification
@@ -127,11 +128,11 @@ public:
{ {
public: public:
ProjectInfo() ProjectInfo()
{ } {}
ProjectInfo(QPointer<ProjectExplorer::Project> project) ProjectInfo(QPointer<ProjectExplorer::Project> project)
: m_project(project) : m_project(project)
{ } {}
operator bool() const operator bool() const
{ return !m_project.isNull(); } { return !m_project.isNull(); }
@@ -163,10 +164,10 @@ public:
const QByteArray defines() const const QByteArray defines() const
{ return m_defines; } { return m_defines; }
private: // attributes private:
QPointer<ProjectExplorer::Project> m_project; QPointer<ProjectExplorer::Project> m_project;
QList<ProjectPart::Ptr> m_projectParts; QList<ProjectPart::Ptr> m_projectParts;
// the attributes below are calculated from the project parts. // The members below are (re)calculated from the project parts once a part is appended.
QStringList m_includePaths; QStringList m_includePaths;
QStringList m_frameworkPaths; QStringList m_frameworkPaths;
QStringList m_sourceFiles; QStringList m_sourceFiles;
@@ -220,10 +221,10 @@ public:
virtual QStringList includePaths() = 0; virtual QStringList includePaths() = 0;
virtual void addEditorSupport(CppTools::AbstractEditorSupport *editorSupport) = 0; virtual void addExtraEditorSupport(CppTools::AbstractEditorSupport *editorSupport) = 0;
virtual void removeEditorSupport(CppTools::AbstractEditorSupport *editorSupport) = 0; virtual void removeExtraEditorSupport(CppTools::AbstractEditorSupport *editorSupport) = 0;
virtual CppEditorSupport *cppEditorSupport(TextEditor::BaseTextEditor *editor) = 0; virtual CppEditorSupport *cppEditorSupport(TextEditor::BaseTextEditor *textEditor) = 0;
virtual void deleteEditorSupport(TextEditor::BaseTextEditor *textEditor) = 0; virtual void deleteCppEditorSupport(TextEditor::BaseTextEditor *textEditor) = 0;
virtual QList<int> references(CPlusPlus::Symbol *symbol, virtual QList<int> references(CPlusPlus::Symbol *symbol,
const CPlusPlus::LookupContext &context) = 0; const CPlusPlus::LookupContext &context) = 0;
@@ -247,7 +248,7 @@ public:
virtual void setIndexingSupport(CppTools::CppIndexingSupport *indexingSupport) = 0; virtual void setIndexingSupport(CppTools::CppIndexingSupport *indexingSupport) = 0;
virtual CppTools::CppIndexingSupport *indexingSupport() = 0; virtual CppTools::CppIndexingSupport *indexingSupport() = 0;
Q_SIGNALS: signals:
void documentUpdated(CPlusPlus::Document::Ptr doc); void documentUpdated(CPlusPlus::Document::Ptr doc);
void sourceFilesRefreshed(const QStringList &files); void sourceFilesRefreshed(const QStringList &files);
@@ -256,8 +257,7 @@ Q_SIGNALS:
/// Other classes can use this to get notified when the \c ProjectExplorer has updated the parts. /// Other classes can use this to get notified when the \c ProjectExplorer has updated the parts.
void projectPartsUpdated(ProjectExplorer::Project *project); void projectPartsUpdated(ProjectExplorer::Project *project);
public Q_SLOTS: public slots:
virtual void updateModifiedSourceFiles() = 0; virtual void updateModifiedSourceFiles() = 0;
virtual QFuture<void> updateSourceFiles(const QStringList &sourceFiles, virtual QFuture<void> updateSourceFiles(const QStringList &sourceFiles,
ProgressNotificationMode mode = ReservedProgressNotification) = 0; ProgressNotificationMode mode = ReservedProgressNotification) = 0;

View File

@@ -1466,7 +1466,7 @@ Qt4ProFileNode::~Qt4ProFileNode()
QMap<QString, QtSupport::UiCodeModelSupport *>::const_iterator it, end; QMap<QString, QtSupport::UiCodeModelSupport *>::const_iterator it, end;
end = m_uiCodeModelSupport.constEnd(); end = m_uiCodeModelSupport.constEnd();
for (it = m_uiCodeModelSupport.constBegin(); it != end; ++it) { for (it = m_uiCodeModelSupport.constBegin(); it != end; ++it) {
modelManager->removeEditorSupport(it.value()); modelManager->removeExtraEditorSupport(it.value());
delete it.value(); delete it.value();
} }
m_parseFutureWatcher.waitForFinished(); m_parseFutureWatcher.waitForFinished();
@@ -2318,7 +2318,7 @@ void Qt4ProFileNode::createUiCodeModelSupport()
// qDebug()<<"adding new codemodelsupport"; // qDebug()<<"adding new codemodelsupport";
QtSupport::UiCodeModelSupport *cms = new QtSupport::UiCodeModelSupport(modelManager, m_project, uiFile->path(), uiHeaderFilePath); QtSupport::UiCodeModelSupport *cms = new QtSupport::UiCodeModelSupport(modelManager, m_project, uiFile->path(), uiHeaderFilePath);
m_uiCodeModelSupport.insert(uiFile->path(), cms); m_uiCodeModelSupport.insert(uiFile->path(), cms);
modelManager->addEditorSupport(cms); modelManager->addExtraEditorSupport(cms);
} }
} }
} }
@@ -2326,7 +2326,7 @@ void Qt4ProFileNode::createUiCodeModelSupport()
QMap<QString, QtSupport::UiCodeModelSupport *>::const_iterator it, end; QMap<QString, QtSupport::UiCodeModelSupport *>::const_iterator it, end;
end = oldCodeModelSupport.constEnd(); end = oldCodeModelSupport.constEnd();
for (it = oldCodeModelSupport.constBegin(); it!=end; ++it) { for (it = oldCodeModelSupport.constBegin(); it!=end; ++it) {
modelManager->removeEditorSupport(it.value()); modelManager->removeExtraEditorSupport(it.value());
delete it.value(); delete it.value();
} }
} }