diff options
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager.cpp | 185 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager.h | 7 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager_test.cpp | 214 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanagerinterface.cpp | 31 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanagerinterface.h | 7 | ||||
-rw-r--r-- | src/plugins/cpptools/cpptoolsplugin.h | 3 | ||||
-rw-r--r-- | tests/cppmodelmanager/testdata_refresh2/source.cpp | 1 | ||||
-rw-r--r-- | tests/cppmodelmanager/testdata_refresh2/source2.cpp | 1 |
8 files changed, 417 insertions, 32 deletions
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index d9f53f2f5d2..b22c42fdaa8 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -172,12 +172,11 @@ static const char pp_configuration[] = "#define __inline inline\n" "#define __forceinline inline\n"; -void CppModelManager::updateModifiedSourceFiles() +QStringList CppModelManager::timeStampModifiedFiles(const QList<Document::Ptr> documentsToCheck) { - const Snapshot snapshot = this->snapshot(); QStringList sourceFiles; - foreach (const Document::Ptr doc, snapshot) { + foreach (const Document::Ptr doc, documentsToCheck) { const QDateTime lastModified = doc->lastModified(); if (!lastModified.isNull()) { @@ -188,7 +187,18 @@ void CppModelManager::updateModifiedSourceFiles() } } - updateSourceFiles(sourceFiles); + return sourceFiles; +} + +void CppModelManager::updateModifiedSourceFiles() +{ + const Snapshot snapshot = this->snapshot(); + QList<Document::Ptr> documentsToCheck; + foreach (const Document::Ptr document, snapshot) + documentsToCheck << document; + + const QStringList filesToUpdate = timeStampModifiedFiles(documentsToCheck); + updateSourceFiles(filesToUpdate); } /*! @@ -584,39 +594,155 @@ CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Proje return m_projectToProjectsInfo.value(project, ProjectInfo(project)); } -QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) +/// \brief Remove all files and their includes (recursively) of given ProjectInfo from the snapshot. +void CppModelManager::removeProjectInfoFilesAndIncludesFromSnapshot(const ProjectInfo &projectInfo) +{ + if (!projectInfo.isValid()) + return; + + QMutexLocker snapshotLocker(&m_snapshotMutex); + foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) { + foreach (const ProjectFile &cxxFile, projectPart->files) { + foreach (const QString &fileName, m_snapshot.allIncludesForDocument(cxxFile.path)) + m_snapshot.remove(fileName); + m_snapshot.remove(cxxFile.path); + } + } +} + +/// \brief Remove all given files from the snapshot. +void CppModelManager::removeFilesFromSnapshot(const QSet<QString> &filesToRemove) +{ + QMutexLocker snapshotLocker(&m_snapshotMutex); + QSetIterator<QString> i(filesToRemove); + while (i.hasNext()) + m_snapshot.remove(i.next()); +} + +class ProjectInfoComparer +{ +public: + ProjectInfoComparer(const CppModelManager::ProjectInfo &oldProjectInfo, + const CppModelManager::ProjectInfo &newProjectInfo) + : m_old(oldProjectInfo) + , m_oldSourceFiles(oldProjectInfo.sourceFiles().toSet()) + , m_new(newProjectInfo) + , m_newSourceFiles(newProjectInfo.sourceFiles().toSet()) + {} + + bool definesChanged() const + { + return m_new.defines() != m_old.defines(); + } + + bool configurationChanged() const + { + return definesChanged() + || m_new.includePaths() != m_old.includePaths() + || m_new.frameworkPaths() != m_old.frameworkPaths(); + } + + bool nothingChanged() const + { + return !configurationChanged() && m_new.sourceFiles() == m_old.sourceFiles(); + } + + QSet<QString> addedFiles() const + { + QSet<QString> addedFilesSet = m_newSourceFiles; + addedFilesSet.subtract(m_oldSourceFiles); + return addedFilesSet; + } + + QSet<QString> removedFiles() const + { + QSet<QString> removedFilesSet = m_oldSourceFiles; + removedFilesSet.subtract(m_newSourceFiles); + return removedFilesSet; + } + + /// Returns a list of common files that have a changed timestamp. + QSet<QString> timeStampModifiedFiles(const Snapshot &snapshot) const + { + QSet<QString> commonSourceFiles = m_newSourceFiles; + commonSourceFiles.intersect(m_oldSourceFiles); + + QList<Document::Ptr> documentsToCheck; + QSetIterator<QString> i(commonSourceFiles); + while (i.hasNext()) { + const QString file = i.next(); + if (Document::Ptr document = snapshot.document(file)) + documentsToCheck << document; + } + + return CppModelManager::timeStampModifiedFiles(documentsToCheck).toSet(); + } + +private: + const CppModelManager::ProjectInfo &m_old; + const QSet<QString> m_oldSourceFiles; + + const CppModelManager::ProjectInfo &m_new; + const QSet<QString> m_newSourceFiles; +}; + +QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectInfo) { - if (!pinfo.isValid()) + if (!newProjectInfo.isValid()) return QFuture<void>(); + QStringList filesToReindex; + bool filesRemoved = false; + { // Only hold the mutex for a limited scope, so the dumping afterwards does not deadlock. - QMutexLocker locker(&m_projectMutex); + QMutexLocker projectLocker(&m_projectMutex); - ProjectExplorer::Project *project = pinfo.project().data(); + ProjectExplorer::Project *project = newProjectInfo.project().data(); + const QStringList newSourceFiles = newProjectInfo.sourceFiles(); + + // Check if we can avoid a full reindexing ProjectInfo oldProjectInfo = m_projectToProjectsInfo.value(project); if (oldProjectInfo.isValid()) { - if (pinfo.defines() == oldProjectInfo.defines() - && pinfo.includePaths() == oldProjectInfo.includePaths() - && pinfo.frameworkPaths() == oldProjectInfo.frameworkPaths() - && pinfo.sourceFiles() == oldProjectInfo.sourceFiles()) { + ProjectInfoComparer comparer(oldProjectInfo, newProjectInfo); + if (comparer.nothingChanged()) return QFuture<void>(); - } - foreach (const ProjectPart::Ptr &projectPart, oldProjectInfo.projectParts()) { - foreach (const ProjectFile &cxxFile, projectPart->files) { - foreach (const QString &fileName, - m_snapshot.allIncludesForDocument(cxxFile.path)) { - m_snapshot.remove(fileName); - } - m_snapshot.remove(cxxFile.path); + // If the project configuration changed, do a full reindexing + if (comparer.configurationChanged()) { + removeProjectInfoFilesAndIncludesFromSnapshot(oldProjectInfo); + filesToReindex << newSourceFiles; + + // The "configuration file" includes all defines and therefore should be updated + if (comparer.definesChanged()) { + QMutexLocker snapshotLocker(&m_snapshotMutex); + m_snapshot.remove(configurationFileName()); } + + // Otherwise check for added and modified files + } else { + const QSet<QString> addedFiles = comparer.addedFiles(); + filesToReindex << addedFiles.toList(); + + const QSet<QString> modifiedFiles = comparer.timeStampModifiedFiles(snapshot()); + filesToReindex << modifiedFiles.toList(); } + + // Announce and purge the removed files from the snapshot + const QSet<QString> removedFiles = comparer.removedFiles(); + if (!removedFiles.isEmpty()) { + filesRemoved = true; + emit aboutToRemoveFiles(removedFiles.toList()); + removeFilesFromSnapshot(removedFiles); + } + + // A new project was opened/created, do a full indexing + } else { + filesToReindex << newSourceFiles; } - m_snapshot.remove(configurationFileName()); - m_projectToProjectsInfo.insert(project, pinfo); + // Update Project/ProjectInfo and File/ProjectPart table m_dirty = true; - + m_projectToProjectsInfo.insert(project, newProjectInfo); m_fileToProjectParts.clear(); foreach (const ProjectInfo &projectInfo, m_projectToProjectsInfo) { foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) { @@ -625,14 +751,21 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) } } } - } + } // Mutex scope + + // If requested, dump everything we got if (!qgetenv("QTCREATOR_DUMP_PROJECT_INFO").isEmpty()) dumpModelManagerConfiguration(); - emit projectPartsUpdated(pinfo.project().data()); + // Remove files from snapshot that are not reachable any more + if (filesRemoved) + GC(); + + emit projectPartsUpdated(newProjectInfo.project().data()); - return updateSourceFiles(pinfo.sourceFiles(), ForcedProgressNotification); + // Trigger reindexing + return updateSourceFiles(filesToReindex, ForcedProgressNotification); } QList<ProjectPart::Ptr> CppModelManager::projectPart(const QString &fileName) const diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 5c65a9781ad..249cfb65ac0 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -72,7 +72,7 @@ public: virtual QList<ProjectInfo> projectInfos() const; virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const; - virtual QFuture<void> updateProjectInfo(const ProjectInfo &pinfo); + virtual QFuture<void> updateProjectInfo(const ProjectInfo &newProjectInfo); virtual QList<CppTools::ProjectPart::Ptr> projectPart(const QString &fileName) const; virtual CPlusPlus::Snapshot snapshot() const; @@ -141,6 +141,8 @@ public: return m_definedMacros; } + static QStringList timeStampModifiedFiles(const QList<Document::Ptr> documentsToCheck); + signals: void aboutToRemoveFiles(const QStringList &files); void gcFinished(); // Needed for tests. @@ -160,6 +162,9 @@ private slots: private: void delayedGC(); void replaceSnapshot(const CPlusPlus::Snapshot &newSnapshot); + void removeFilesFromSnapshot(const QSet<QString> &removedFiles); + void removeProjectInfoFilesAndIncludesFromSnapshot(const ProjectInfo &projectInfo); + WorkingCopy buildWorkingCopyList(); void ensureUpdated(); diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index 1fb02ba5ed1..34c05f0ac7c 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -48,6 +48,8 @@ typedef CppTools::ProjectPart ProjectPart; typedef CppTools::ProjectFile ProjectFile; typedef ProjectExplorer::Project Project; +Q_DECLARE_METATYPE(ProjectFile) + namespace { class TestDataDirectory @@ -176,6 +178,52 @@ private: QString m_fileToRemove; }; +/// Changes a file on the disk and restores its original contents on destruction +class FileChangerAndRestorer +{ +public: + FileChangerAndRestorer(const QString &filePath) + : m_filePath(filePath) + { + } + + ~FileChangerAndRestorer() + { + restoreContents(); + } + + /// Saves the contents also internally so it can be restored on destruction + bool readContents(QByteArray *contents) + { + Utils::FileReader fileReader; + const bool isFetchOk = fileReader.fetch(m_filePath); + if (isFetchOk) { + m_originalFileContents = fileReader.data(); + if (contents) + *contents = m_originalFileContents; + } + return isFetchOk; + } + + void writeContents(const QByteArray &contents) const + { + Utils::FileSaver fileSaver(m_filePath); + fileSaver.write(contents); + fileSaver.finalize(); + } + +private: + void restoreContents() const + { + Utils::FileSaver fileSaver(m_filePath); + fileSaver.write(m_originalFileContents); + fileSaver.finalize(); + } + + QByteArray m_originalFileContents; + const QString &m_filePath; +}; + } // anonymous namespace /// Check: The preprocessor cleans include and framework paths. @@ -232,8 +280,7 @@ void CppToolsPlugin::test_modelmanager_framework_headers() part->files << ProjectFile(source, ProjectFile::CXXSource); pi.appendProjectPart(part); - mm->updateProjectInfo(pi); - mm->updateSourceFiles(QStringList(source)).waitForFinished(); + mm->updateProjectInfo(pi).waitForFinished(); QCoreApplication::processEvents(); QVERIFY(mm->snapshot().contains(source)); @@ -280,7 +327,6 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files() part->includePaths = QStringList() << testDataDir.includeDir(false); part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); pi.appendProjectPart(part); - mm->updateProjectInfo(pi); QStringList refreshedFiles = helper.waitForRefreshedSourceFiles(); @@ -301,6 +347,7 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files() pi.clearProjectParts(); pi.appendProjectPart(part); mm->updateProjectInfo(pi); + refreshedFiles = helper.waitForRefreshedSourceFiles(); QCOMPARE(refreshedFiles.size(), 1); @@ -342,7 +389,6 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times() part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader)); part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); pi.appendProjectPart(part); - mm->updateProjectInfo(pi); CPlusPlus::Snapshot snapshot; @@ -364,6 +410,7 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times() pi.appendProjectPart(part); mm->updateProjectInfo(pi); + refreshedFiles = helper.waitForRefreshedSourceFiles(); QCOMPARE(refreshedFiles.size(), 3); @@ -420,6 +467,165 @@ void CppToolsPlugin::test_modelmanager_refresh_test_for_changes() QVERIFY(subsequentFuture.isCanceled() && subsequentFuture.isFinished()); } +/// Check: (1) Added project files are recognized and parsed. +/// Check: (2) Removed project files are recognized and purged from the snapshot. +void CppToolsPlugin::test_modelmanager_refresh_added_and_purge_removed() +{ + ModelManagerTestHelper helper; + CppModelManager *mm = CppModelManager::instance(); + + const TestDataDirectory testDataDir(QLatin1String("testdata_refresh")); + + const QString testHeader1(testDataDir.file(QLatin1String("header.h"))); + const QString testHeader2(testDataDir.file(QLatin1String("defines.h"))); + const QString testCpp(testDataDir.file(QLatin1String("source.cpp"))); + + Project *project = helper.createProject(QLatin1String("test_modelmanager_refresh_3")); + ProjectInfo pi = mm->projectInfo(project); + QCOMPARE(pi.project().data(), project); + + ProjectPart::Ptr part(new ProjectPart); + part->cxxVersion = ProjectPart::CXX98; + part->qtVersion = ProjectPart::Qt5; + part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); + part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader)); + pi.appendProjectPart(part); + + CPlusPlus::Snapshot snapshot; + QStringList refreshedFiles; + + mm->updateProjectInfo(pi); + refreshedFiles = helper.waitForRefreshedSourceFiles(); + + QCOMPARE(refreshedFiles.size(), 2); + QVERIFY(refreshedFiles.contains(testHeader1)); + QVERIFY(refreshedFiles.contains(testCpp)); + + snapshot = mm->snapshot(); + QVERIFY(snapshot.contains(testHeader1)); + QVERIFY(snapshot.contains(testCpp)); + + // Now add testHeader2 and remove testHeader1 + pi.clearProjectParts(); + ProjectPart::Ptr newPart(new ProjectPart); + newPart->cxxVersion = ProjectPart::CXX98; + newPart->qtVersion = ProjectPart::Qt5; + newPart->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); + newPart->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader)); + pi.appendProjectPart(newPart); + + mm->updateProjectInfo(pi); + refreshedFiles = helper.waitForRefreshedSourceFiles(); + + // Only the added project file was reparsed + QCOMPARE(refreshedFiles.size(), 1); + QVERIFY(refreshedFiles.contains(testHeader2)); + + snapshot = mm->snapshot(); + QVERIFY(snapshot.contains(testHeader2)); + QVERIFY(snapshot.contains(testCpp)); + // The removed project file is not anymore in the snapshot + QVERIFY(!snapshot.contains(testHeader1)); +} + +/// Check: Timestamp modified files are reparsed if project files are added or removed +/// while the project configuration stays the same +void CppToolsPlugin::test_modelmanager_refresh_timeStampModified_if_sourcefiles_change() +{ + QFETCH(QString, fileToChange); + QFETCH(QList<ProjectFile>, initialProjectFiles); + QFETCH(QList<ProjectFile>, finalProjectFiles); + + ModelManagerTestHelper helper; + CppModelManager *mm = CppModelManager::instance(); + + Project *project = helper.createProject( + QLatin1String("test_modelmanager_refresh_timeStampModified")); + ProjectInfo pi = mm->projectInfo(project); + QCOMPARE(pi.project().data(), project); + + ProjectPart::Ptr part(new ProjectPart); + part->cxxVersion = ProjectPart::CXX98; + part->qtVersion = ProjectPart::Qt5; + foreach (const ProjectFile &file, initialProjectFiles) + part->files.append(file); + pi.appendProjectPart(part); + + Document::Ptr document; + CPlusPlus::Snapshot snapshot; + QStringList refreshedFiles; + + mm->updateProjectInfo(pi); + refreshedFiles = helper.waitForRefreshedSourceFiles(); + + QCOMPARE(refreshedFiles.size(), initialProjectFiles.size()); + snapshot = mm->snapshot(); + foreach (const ProjectFile &file, initialProjectFiles) { + QVERIFY(refreshedFiles.contains(file.path)); + QVERIFY(snapshot.contains(file.path)); + } + + document = snapshot.document(fileToChange); + const QDateTime lastModifiedBefore = document->lastModified(); + QCOMPARE(document->globalSymbolCount(), 1U); + QCOMPARE(document->globalSymbolAt(0)->name()->identifier()->chars(), "someGlobal"); + + // Modify the file + QTest::qSleep(1000); // Make sure the timestamp is different + FileChangerAndRestorer fileChangerAndRestorer(fileToChange); + QByteArray originalContents; + QVERIFY(fileChangerAndRestorer.readContents(&originalContents)); + const QByteArray newFileContentes = originalContents + "\nint addedOtherGlobal;"; + fileChangerAndRestorer.writeContents(newFileContentes); + + // Add or remove source file. The configuration stays the same. + part->files.clear(); + foreach (const ProjectFile &file, finalProjectFiles) + part->files.append(file); + pi.clearProjectParts(); + pi.appendProjectPart(part); + + mm->updateProjectInfo(pi); + refreshedFiles = helper.waitForRefreshedSourceFiles(); + + QCOMPARE(refreshedFiles.size(), finalProjectFiles.size()); + snapshot = mm->snapshot(); + foreach (const ProjectFile &file, finalProjectFiles) { + QVERIFY(refreshedFiles.contains(file.path)); + QVERIFY(snapshot.contains(file.path)); + } + document = snapshot.document(fileToChange); + const QDateTime lastModifiedAfter = document->lastModified(); + QVERIFY(lastModifiedAfter > lastModifiedBefore); + QCOMPARE(document->globalSymbolCount(), 2U); + QCOMPARE(document->globalSymbolAt(0)->name()->identifier()->chars(), "someGlobal"); + QCOMPARE(document->globalSymbolAt(1)->name()->identifier()->chars(), "addedOtherGlobal"); +} + +void CppToolsPlugin::test_modelmanager_refresh_timeStampModified_if_sourcefiles_change_data() +{ + QTest::addColumn<QString>("fileToChange"); + QTest::addColumn<QList<ProjectFile> >("initialProjectFiles"); + QTest::addColumn<QList<ProjectFile> >("finalProjectFiles"); + + const TestDataDirectory testDataDir(QLatin1String("testdata_refresh2")); + const QString testCpp(testDataDir.file(QLatin1String("source.cpp"))); + const QString testCpp2(testDataDir.file(QLatin1String("source2.cpp"))); + + const QString fileToChange = testCpp; + QList<ProjectFile> projectFiles1 = QList<ProjectFile>() + << ProjectFile(testCpp, ProjectFile::CXXSource); + QList<ProjectFile> projectFiles2 = QList<ProjectFile>() + << ProjectFile(testCpp, ProjectFile::CXXSource) + << ProjectFile(testCpp2, ProjectFile::CXXSource); + + // Add a file + QTest::newRow("case: add project file") << fileToChange << projectFiles1 << projectFiles2; + + // Remove a file + QTest::newRow("case: remove project file") << fileToChange << projectFiles2 << projectFiles1; +} + /// Check: If a second project is opened, the code model is still aware of /// files of the first project. void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects() diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.cpp b/src/plugins/cpptools/cppmodelmanagerinterface.cpp index 1338c214a12..cb5ba96e6d1 100644 --- a/src/plugins/cpptools/cppmodelmanagerinterface.cpp +++ b/src/plugins/cpptools/cppmodelmanagerinterface.cpp @@ -68,6 +68,37 @@ using namespace ProjectExplorer; Parser may enable tricks for Qt v5.x */ +/*! + \fn virtual QFuture<void> updateProjectInfo(const ProjectInfo &pinfo) = 0; + \param pinfo Updated ProjectInfo. + \return A future that reports progress and allows to cancel the reparsing operation. + + This function is expected to be called by the project managers to update the + code model with new project information. + + In particular, the function should be called in case: + 1. A new project is opened/created + 2. The project configuration changed. This includes + 2.1 Changes of defines, includes, framework paths + 2.2 Addition/Removal of project files + + \sa CppTools::CppModelManagerInterface::updateSourceFiles() +*/ + +/*! + \fn virtual QFuture<void> updateSourceFiles(const QStringList &sourceFiles, ProgressNotificationMode mode = ReservedProgressNotification) = 0; + \param sourceFiles List of source file to update. The items are absolute paths. + \param mode The progress modification mode. + \return A future that reports progress and allows to cancel the reparsing operation. + + Trigger an asynchronous reparsing of the given source files. + + This function is not meant to be called by the project managers. + + \sa CppTools::CppModelManagerInterface::ProgressNotificationMode + \sa CppTools::CppModelManagerInterface::updateProjectInfo() +*/ + ProjectPart::ProjectPart() : cVersion(C89) , cxxVersion(CXX11) diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h index e4885ea5786..d61020337e8 100644 --- a/src/plugins/cpptools/cppmodelmanagerinterface.h +++ b/src/plugins/cpptools/cppmodelmanagerinterface.h @@ -249,6 +249,9 @@ public: virtual CppTools::CppIndexingSupport *indexingSupport() = 0; signals: + /// Project data might be locked while this is emitted. + void aboutToRemoveFiles(const QStringList &files); + void documentUpdated(CPlusPlus::Document::Ptr doc); void sourceFilesRefreshed(const QStringList &files); @@ -258,9 +261,11 @@ signals: void projectPartsUpdated(ProjectExplorer::Project *project); public slots: - virtual void updateModifiedSourceFiles() = 0; + // Documented in source file. virtual QFuture<void> updateSourceFiles(const QStringList &sourceFiles, ProgressNotificationMode mode = ReservedProgressNotification) = 0; + + virtual void updateModifiedSourceFiles() = 0; virtual void GC() = 0; }; diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index de48a8fe218..70d9dfb6850 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -192,6 +192,9 @@ private slots: void test_modelmanager_refresh_also_includes_of_project_files(); void test_modelmanager_refresh_several_times(); void test_modelmanager_refresh_test_for_changes(); + void test_modelmanager_refresh_added_and_purge_removed(); + void test_modelmanager_refresh_timeStampModified_if_sourcefiles_change(); + void test_modelmanager_refresh_timeStampModified_if_sourcefiles_change_data(); void test_modelmanager_snapshot_after_two_projects(); void test_modelmanager_extraeditorsupport_uiFiles(); void test_modelmanager_gc_if_last_cppeditor_closed(); diff --git a/tests/cppmodelmanager/testdata_refresh2/source.cpp b/tests/cppmodelmanager/testdata_refresh2/source.cpp new file mode 100644 index 00000000000..d459c19d5ef --- /dev/null +++ b/tests/cppmodelmanager/testdata_refresh2/source.cpp @@ -0,0 +1 @@ +int someGlobal; diff --git a/tests/cppmodelmanager/testdata_refresh2/source2.cpp b/tests/cppmodelmanager/testdata_refresh2/source2.cpp new file mode 100644 index 00000000000..45b14673159 --- /dev/null +++ b/tests/cppmodelmanager/testdata_refresh2/source2.cpp @@ -0,0 +1 @@ +int f() {} |