diff options
-rw-r--r-- | src/plugins/autotoolsprojectmanager/autotoolsproject.cpp | 2 | ||||
-rw-r--r-- | src/plugins/cmakeprojectmanager/cmakeproject.cpp | 4 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager.cpp | 13 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager.h | 2 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager_test.cpp | 71 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanagerinterface.h | 2 | ||||
-rw-r--r-- | src/plugins/cpptools/cpptoolsplugin.h | 1 | ||||
-rw-r--r-- | src/plugins/genericprojectmanager/genericproject.cpp | 4 | ||||
-rw-r--r-- | src/plugins/qbsprojectmanager/qbsproject.cpp | 4 | ||||
-rw-r--r-- | src/plugins/qt4projectmanager/qt4project.cpp | 4 | ||||
-rw-r--r-- | tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.h | 4 |
11 files changed, 83 insertions, 28 deletions
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp index 82f5c6c9fd..4cffc35127 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -433,8 +433,6 @@ void AutotoolsProject::updateCppCodeModel() pinfo.appendProjectPart(part); modelManager->updateProjectInfo(pinfo); - modelManager->updateSourceFiles(m_files, - CppTools::CppModelManagerInterface::ForcedProgressNotification); setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, !part->files.isEmpty()); } diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index fa278b2a1d..bc6d5fc8a2 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -389,10 +389,8 @@ bool CMakeProject::parseCMakeLists() adder.maybeAdd(file); pinfo.appendProjectPart(part); - modelmanager->updateProjectInfo(pinfo); m_codeModelFuture.cancel(); - m_codeModelFuture = modelmanager->updateSourceFiles(m_files, - CppTools::CppModelManagerInterface::ForcedProgressNotification); + m_codeModelFuture = modelmanager->updateProjectInfo(pinfo); setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, !part->files.isEmpty()); } diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 76b8c4e0e5..d6c718af65 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -547,17 +547,24 @@ CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Proje return m_projects.value(project, ProjectInfo(project)); } -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. QMutexLocker locker(&m_projectMutex); if (! pinfo.isValid()) - return; + return QFuture<void>(); ProjectExplorer::Project *project = pinfo.project().data(); ProjectInfo oldProjectInfo = m_projects.value(project); if (oldProjectInfo.isValid()) { + if (pinfo.defines() == oldProjectInfo.defines() + && pinfo.includePaths() == oldProjectInfo.includePaths() + && pinfo.frameworkPaths() == oldProjectInfo.frameworkPaths() + && pinfo.sourceFiles() == oldProjectInfo.sourceFiles()) { + return QFuture<void>(); + } + foreach (const ProjectPart::Ptr &projectPart, oldProjectInfo.projectParts()) { foreach (const ProjectFile &cxxFile, projectPart->files) { foreach (const QString &fileName, @@ -587,6 +594,8 @@ void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) dumpModelManagerConfiguration(); emit projectPartsUpdated(pinfo.project().data()); + + return updateSourceFiles(pinfo.sourceFiles(), 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 8e51b5e373..5758cdb4b3 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -73,7 +73,7 @@ public: virtual QList<ProjectInfo> projectInfos() const; virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const; - virtual void updateProjectInfo(const ProjectInfo &pinfo); + virtual QFuture<void> updateProjectInfo(const ProjectInfo &pinfo); virtual QList<CppTools::ProjectPart::Ptr> projectPart(const QString &fileName) const; virtual CPlusPlus::Snapshot snapshot() const; diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index ce47b5425b..4971974a25 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -281,7 +281,6 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files() pi.appendProjectPart(part); mm->updateProjectInfo(pi); - mm->updateSourceFiles(QStringList() << testCpp); QStringList refreshedFiles = helper.waitForRefreshedSourceFiles(); @@ -291,13 +290,16 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files() QVERIFY(snapshot.contains(testHeader)); QVERIFY(snapshot.contains(testCpp)); - part->defines = QByteArray(); - mm->updateProjectInfo(pi); - snapshot = mm->snapshot(); - QVERIFY(!snapshot.contains(testHeader)); - QVERIFY(!snapshot.contains(testCpp)); + Document::Ptr headerDocumentBefore = snapshot.document(testHeader); + const QList<CPlusPlus::Macro> macrosInHeaderBefore = headerDocumentBefore->definedMacros(); + QCOMPARE(macrosInHeaderBefore.size(), 1); + QVERIFY(macrosInHeaderBefore.first().name() == "test_modelmanager_refresh_h"); - mm->updateSourceFiles(QStringList() << testCpp); + // Introduce a define that will enable another define once the document is reparsed. + part->defines = QByteArray("#define TEST_DEFINE 1\n"); + pi.clearProjectParts(); + pi.appendProjectPart(part); + mm->updateProjectInfo(pi); refreshedFiles = helper.waitForRefreshedSourceFiles(); QCOMPARE(refreshedFiles.size(), 1); @@ -305,6 +307,12 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files() snapshot = mm->snapshot(); QVERIFY(snapshot.contains(testHeader)); QVERIFY(snapshot.contains(testCpp)); + + Document::Ptr headerDocumentAfter = snapshot.document(testHeader); + const QList<CPlusPlus::Macro> macrosInHeaderAfter = headerDocumentAfter->definedMacros(); + QCOMPARE(macrosInHeaderAfter.size(), 2); + QVERIFY(macrosInHeaderAfter.at(0).name() == "test_modelmanager_refresh_h"); + QVERIFY(macrosInHeaderAfter.at(1).name() == "TEST_DEFINE_DEFINED"); } /// QTCREATORBUG-9205 @@ -340,8 +348,21 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times() QStringList refreshedFiles; CPlusPlus::Document::Ptr document; + QByteArray defines = "#define FIRST_DEFINE"; for (int i = 0; i < 2; ++i) { - mm->updateSourceFiles(QStringList() << testHeader1 << testHeader2 << testCpp); + pi.clearProjectParts(); + ProjectPart::Ptr part(new ProjectPart); + // Simulate project configuration change by having different defines each time. + defines += "\n#define ANOTHER_DEFINE"; + part->defines = defines; + part->cxxVersion = ProjectPart::CXX98; + part->qtVersion = ProjectPart::Qt5; + part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader)); + part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader)); + part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); + pi.appendProjectPart(part); + + mm->updateProjectInfo(pi); refreshedFiles = helper.waitForRefreshedSourceFiles(); QCOMPARE(refreshedFiles.size(), 3); @@ -366,6 +387,38 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times() } } +/// QTCREATORBUG-9581 +/// Check: If nothing has changes, nothing should be reindexed. +void CppToolsPlugin::test_modelmanager_refresh_test_for_changes() +{ + ModelManagerTestHelper helper; + CppModelManager *mm = CppModelManager::instance(); + + const TestDataDirectory testDataDir(QLatin1String("testdata_refresh")); + const QString testCpp(testDataDir.file(QLatin1String("source.cpp"))); + + Project *project = helper.createProject(QLatin1String("test_modelmanager_refresh_2")); + 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)); + pi.appendProjectPart(part); + + // Reindexing triggers a reparsing thread + QFuture<void> firstFuture = mm->updateProjectInfo(pi); + QVERIFY(firstFuture.isStarted() || firstFuture.isRunning()); + const QStringList refreshedFiles = helper.waitForRefreshedSourceFiles(); + QCOMPARE(refreshedFiles.size(), 1); + QVERIFY(refreshedFiles.contains(testCpp)); + + // No reindexing since nothing has changed + QFuture<void> subsequentFuture = mm->updateProjectInfo(pi); + QVERIFY(subsequentFuture.isCanceled() && subsequentFuture.isFinished()); +} + /// 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() @@ -384,7 +437,6 @@ void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects() << QLatin1String("main.cpp")); mm->updateProjectInfo(project1.projectInfo); - mm->updateSourceFiles(project1.projectFiles); refreshedFiles = helper.waitForRefreshedSourceFiles(); QCOMPARE(refreshedFiles.toSet(), project1.projectFiles.toSet()); const int snapshotSizeAfterProject1 = mm->snapshot().size(); @@ -400,7 +452,6 @@ void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects() << QLatin1String("main.cpp")); mm->updateProjectInfo(project2.projectInfo); - mm->updateSourceFiles(project2.projectFiles); refreshedFiles = helper.waitForRefreshedSourceFiles(); QCOMPARE(refreshedFiles.toSet(), project2.projectFiles.toSet()); diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h index f9d299b937..ac1bcf9a3d 100644 --- a/src/plugins/cpptools/cppmodelmanagerinterface.h +++ b/src/plugins/cpptools/cppmodelmanagerinterface.h @@ -215,7 +215,7 @@ public: virtual QList<ProjectInfo> projectInfos() const = 0; virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0; - virtual void updateProjectInfo(const ProjectInfo &pinfo) = 0; + virtual QFuture<void> updateProjectInfo(const ProjectInfo &pinfo) = 0; virtual QList<ProjectPart::Ptr> projectPart(const QString &fileName) const = 0; virtual QStringList includePaths() = 0; diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index 902b5908fb..5283c1dd83 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -163,6 +163,7 @@ private slots: void test_modelmanager_framework_headers(); 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_snapshot_after_two_projects(); void test_modelmanager_extraeditorsupport_uiFiles(); diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index afa10b6b59..110339cd85 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -285,9 +285,7 @@ void GenericProject::refresh(RefreshOptions options) pinfo.appendProjectPart(part); setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, !part->files.isEmpty()); - modelManager->updateProjectInfo(pinfo); - m_codeModelFuture = modelManager->updateSourceFiles(filesToUpdate, - CppTools::CppModelManagerInterface::ForcedProgressNotification); + m_codeModelFuture = modelManager->updateProjectInfo(pinfo); } } diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 5a93bf697f..89b51c4619 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -600,9 +600,7 @@ void QbsProject::updateCppCodeModel(const qbs::ProjectData &prj) return; // Register update the code model: - modelmanager->updateProjectInfo(pinfo); - m_codeModelFuture = modelmanager->updateSourceFiles(allFiles, - CppTools::CppModelManagerInterface::ForcedProgressNotification); + m_codeModelFuture = modelmanager->updateProjectInfo(pinfo); } void QbsProject::updateQmlJsCodeModel(const qbs::ProjectData &prj) diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index a5ba933926..a6e04bf8ea 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -615,9 +615,7 @@ void Qt4Project::updateCppCodeModel() setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, !allFiles.isEmpty()); - modelmanager->updateProjectInfo(pinfo); - m_codeModelFuture = modelmanager->updateSourceFiles(allFiles, - CppTools::CppModelManagerInterface::ForcedProgressNotification); + m_codeModelFuture = modelmanager->updateProjectInfo(pinfo); } void Qt4Project::updateQmlJSCodeModel() diff --git a/tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.h b/tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.h index 43bcd86577..617dd0f8ef 100644 --- a/tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.h +++ b/tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.h @@ -1,4 +1,8 @@ #ifndef test_modelmanager_refresh_h #define test_modelmanager_refresh_h +#ifdef TEST_DEFINE +#define TEST_DEFINE_DEFINED 1 +#endif + #endif // test_modelmanager_refresh_h |