diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 2385238b9c7..13c0b3f6ad8 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -705,6 +705,25 @@ Document::Ptr Snapshot::documentFromSource(const QByteArray &preprocessedCode, return newDoc; } +QSet Snapshot::allIncludesForDocument(const QString &fileName) const +{ + QSet result; + allIncludesForDocument_helper(fileName, result); + return result; +} + +void Snapshot::allIncludesForDocument_helper(const QString &fileName, QSet &result) const +{ + if (Document::Ptr doc = document(fileName)) { + foreach (const QString &inc, doc->includedFiles()) { + if (!result.contains(inc)) { + result.insert(inc); + allIncludesForDocument_helper(inc, result); + } + } + } +} + Document::Ptr Snapshot::document(const QString &fileName) const { return _documents.value(fileName); @@ -713,22 +732,13 @@ Document::Ptr Snapshot::document(const QString &fileName) const Snapshot Snapshot::simplified(Document::Ptr doc) const { Snapshot snapshot; - simplified_helper(doc, &snapshot); + + if (doc) { + snapshot.insert(doc); + foreach (const QString &fileName, allIncludesForDocument(doc->fileName())) + if (Document::Ptr inc = document(fileName)) + snapshot.insert(inc); + } + return snapshot; } - -void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const -{ - if (! doc) - return; - - if (! snapshot->contains(doc->fileName())) { - snapshot->insert(doc); - - foreach (const Document::Include &incl, doc->includes()) { - Document::Ptr includedDoc = document(incl.fileName()); - simplified_helper(includedDoc, snapshot); - } - } -} - diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index 9d2cd128e21..589e2b9503a 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -389,8 +389,10 @@ public: Document::Ptr documentFromSource(const QByteArray &preprocessedDocument, const QString &fileName) const; + QSet allIncludesForDocument(const QString &fileName) const; + private: - void simplified_helper(Document::Ptr doc, Snapshot *snapshot) const; + void allIncludesForDocument_helper(const QString &fileName, QSet &result) const; private: _Base _documents; diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index e382171c398..cef667fec0e 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -970,10 +970,16 @@ void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) foreach (const ProjectInfo &projectInfo, m_projects) { 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); + foreach (const QString &fileName, m_snapshot.allIncludesForDocument(cxxFile.path)) + m_snapshot.remove(fileName); + m_snapshot.remove(cxxFile.path); + } } } + + m_snapshot.remove(configurationFileName()); } if (!qgetenv("QTCREATOR_DUMP_PROJECT_INFO").isEmpty()) diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index 4525b95a35f..2a9462674f4 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -138,3 +138,51 @@ void CppToolsPlugin::test_modelmanager_framework_headers() QVERIFY(chars.startsWith("success")); } } + +/// QTCREATORBUG-9056 +void CppToolsPlugin::test_modelmanager_refresh() +{ + ModelManagerTestHelper helper; + CppModelManager *mm = CppModelManager::instance(); + + const QString testCpp(testSource(QLatin1String("test_modelmanager_refresh.cpp"))); + const QString testHeader(testSource(QLatin1String("test_modelmanager_refresh.h"))); + + Project *project = helper.createProject(QLatin1String("test_modelmanager_refresh")); + ProjectInfo pi = mm->projectInfo(project); + QCOMPARE(pi.project().data(), project); + + ProjectPart::Ptr part(new ProjectPart); + pi.appendProjectPart(part); + part->cxxVersion = ProjectPart::CXX98; + part->qtVersion = ProjectPart::Qt5; + part->defines = QByteArray("#define OH_BEHAVE -1\n"); + part->includePaths = QStringList() << testIncludeDir(false); + part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); + + mm->updateProjectInfo(pi); + mm->updateSourceFiles(QStringList() << testCpp); + + QStringList refreshedFiles = helper.waitForRefreshedSourceFiles(); + + QCOMPARE(refreshedFiles.size(), 1); + QVERIFY(refreshedFiles.contains(testCpp)); + CPlusPlus::Snapshot snapshot = mm->snapshot(); + 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)); + + mm->updateSourceFiles(QStringList() << testCpp); + refreshedFiles = helper.waitForRefreshedSourceFiles(); + + QCOMPARE(refreshedFiles.size(), 1); + QVERIFY(refreshedFiles.contains(testCpp)); + snapshot = mm->snapshot(); + QVERIFY(snapshot.contains(testHeader)); + QVERIFY(snapshot.contains(testCpp)); +} diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index 4e6ead7b0a9..dfce31798ab 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -137,6 +137,7 @@ private slots: void test_modelmanager_paths(); void test_modelmanager_framework_headers(); + void test_modelmanager_refresh(); private: void test_completion(); diff --git a/src/plugins/cpptools/modelmanagertesthelper.cpp b/src/plugins/cpptools/modelmanagertesthelper.cpp index 54dc946bbad..46f2a917239 100644 --- a/src/plugins/cpptools/modelmanagertesthelper.cpp +++ b/src/plugins/cpptools/modelmanagertesthelper.cpp @@ -54,6 +54,7 @@ ModelManagerTestHelper::ModelManagerTestHelper(QObject *parent) : connect(this, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)), mm, SLOT(onAboutToRemoveProject(ProjectExplorer::Project*))); connect(this, SIGNAL(projectAdded(ProjectExplorer::Project*)), mm, SLOT(onProjectAdded(ProjectExplorer::Project*))); + connect(mm, SIGNAL(sourceFilesRefreshed(QStringList)), this, SLOT(sourceFilesRefreshed(QStringList))); cleanup(); verifyClean(); @@ -97,3 +98,19 @@ ModelManagerTestHelper::Project *ModelManagerTestHelper::createProject(const QSt return tp; } +QStringList ModelManagerTestHelper::waitForRefreshedSourceFiles() +{ + m_refreshHappened = false; + + while (!m_refreshHappened) + QCoreApplication::processEvents(); + + return m_lastRefreshedSourceFiles; +} + + +void ModelManagerTestHelper::sourceFilesRefreshed(const QStringList &files) +{ + m_lastRefreshedSourceFiles = files; + m_refreshHappened = true; +} diff --git a/src/plugins/cpptools/modelmanagertesthelper.h b/src/plugins/cpptools/modelmanagertesthelper.h index ade58b32f64..8a228cac42a 100644 --- a/src/plugins/cpptools/modelmanagertesthelper.h +++ b/src/plugins/cpptools/modelmanagertesthelper.h @@ -83,9 +83,18 @@ public: Project *createProject(const QString &name); + QStringList waitForRefreshedSourceFiles(); + signals: void aboutToRemoveProject(ProjectExplorer::Project *project); void projectAdded(ProjectExplorer::Project*); + +public slots: + void sourceFilesRefreshed(const QStringList &files); + +private: + bool m_refreshHappened; + QStringList m_lastRefreshedSourceFiles; }; } // namespace Internal diff --git a/tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.cpp b/tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.cpp new file mode 100644 index 00000000000..ad92e705f6f --- /dev/null +++ b/tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.cpp @@ -0,0 +1 @@ +#include "test_modelmanager_refresh.h" diff --git a/tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.h b/tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.h new file mode 100644 index 00000000000..43bcd865776 --- /dev/null +++ b/tests/cppmodelmanager/testdata/sources/test_modelmanager_refresh.h @@ -0,0 +1,4 @@ +#ifndef test_modelmanager_refresh_h +#define test_modelmanager_refresh_h + +#endif // test_modelmanager_refresh_h