Commit a0d6df7b authored by Erik Verbruggen's avatar Erik Verbruggen Committed by Nikolai Kosjar

C++: also refresh files not in the project when project changes.

System headers and other file which are not explicitly mentioned in the
project must be reparsed when the project changes.

Task-number: QTCREATORBUG-9056
Change-Id: I32f1206d241a078a4d9b15fac5813f365a1ba303
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent c39b582e
...@@ -705,30 +705,40 @@ Document::Ptr Snapshot::documentFromSource(const QByteArray &preprocessedCode, ...@@ -705,30 +705,40 @@ Document::Ptr Snapshot::documentFromSource(const QByteArray &preprocessedCode,
return newDoc; return newDoc;
} }
Document::Ptr Snapshot::document(const QString &fileName) const QSet<QString> Snapshot::allIncludesForDocument(const QString &fileName) const
{ {
return _documents.value(fileName); QSet<QString> result;
allIncludesForDocument_helper(fileName, result);
return result;
} }
Snapshot Snapshot::simplified(Document::Ptr doc) const void Snapshot::allIncludesForDocument_helper(const QString &fileName, QSet<QString> &result) const
{ {
Snapshot snapshot; if (Document::Ptr doc = document(fileName)) {
simplified_helper(doc, &snapshot); foreach (const QString &inc, doc->includedFiles()) {
return snapshot; if (!result.contains(inc)) {
result.insert(inc);
allIncludesForDocument_helper(inc, result);
}
}
}
} }
void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const Document::Ptr Snapshot::document(const QString &fileName) const
{ {
if (! doc) return _documents.value(fileName);
return; }
if (! snapshot->contains(doc->fileName())) { Snapshot Snapshot::simplified(Document::Ptr doc) const
snapshot->insert(doc); {
Snapshot snapshot;
foreach (const Document::Include &incl, doc->includes()) { if (doc) {
Document::Ptr includedDoc = document(incl.fileName()); snapshot.insert(doc);
simplified_helper(includedDoc, snapshot); foreach (const QString &fileName, allIncludesForDocument(doc->fileName()))
} if (Document::Ptr inc = document(fileName))
snapshot.insert(inc);
} }
}
return snapshot;
}
...@@ -389,8 +389,10 @@ public: ...@@ -389,8 +389,10 @@ public:
Document::Ptr documentFromSource(const QByteArray &preprocessedDocument, Document::Ptr documentFromSource(const QByteArray &preprocessedDocument,
const QString &fileName) const; const QString &fileName) const;
QSet<QString> allIncludesForDocument(const QString &fileName) const;
private: private:
void simplified_helper(Document::Ptr doc, Snapshot *snapshot) const; void allIncludesForDocument_helper(const QString &fileName, QSet<QString> &result) const;
private: private:
_Base _documents; _Base _documents;
......
...@@ -970,10 +970,16 @@ void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) ...@@ -970,10 +970,16 @@ void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
foreach (const ProjectInfo &projectInfo, m_projects) { foreach (const ProjectInfo &projectInfo, m_projects) {
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_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()) if (!qgetenv("QTCREATOR_DUMP_PROJECT_INFO").isEmpty())
......
...@@ -138,3 +138,51 @@ void CppToolsPlugin::test_modelmanager_framework_headers() ...@@ -138,3 +138,51 @@ void CppToolsPlugin::test_modelmanager_framework_headers()
QVERIFY(chars.startsWith("success")); 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));
}
...@@ -137,6 +137,7 @@ private slots: ...@@ -137,6 +137,7 @@ private slots:
void test_modelmanager_paths(); void test_modelmanager_paths();
void test_modelmanager_framework_headers(); void test_modelmanager_framework_headers();
void test_modelmanager_refresh();
private: private:
void test_completion(); void test_completion();
......
...@@ -54,6 +54,7 @@ ModelManagerTestHelper::ModelManagerTestHelper(QObject *parent) : ...@@ -54,6 +54,7 @@ ModelManagerTestHelper::ModelManagerTestHelper(QObject *parent) :
connect(this, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)), mm, SLOT(onAboutToRemoveProject(ProjectExplorer::Project*))); connect(this, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)), mm, SLOT(onAboutToRemoveProject(ProjectExplorer::Project*)));
connect(this, SIGNAL(projectAdded(ProjectExplorer::Project*)), mm, SLOT(onProjectAdded(ProjectExplorer::Project*))); connect(this, SIGNAL(projectAdded(ProjectExplorer::Project*)), mm, SLOT(onProjectAdded(ProjectExplorer::Project*)));
connect(mm, SIGNAL(sourceFilesRefreshed(QStringList)), this, SLOT(sourceFilesRefreshed(QStringList)));
cleanup(); cleanup();
verifyClean(); verifyClean();
...@@ -97,3 +98,19 @@ ModelManagerTestHelper::Project *ModelManagerTestHelper::createProject(const QSt ...@@ -97,3 +98,19 @@ ModelManagerTestHelper::Project *ModelManagerTestHelper::createProject(const QSt
return tp; 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;
}
...@@ -83,9 +83,18 @@ public: ...@@ -83,9 +83,18 @@ public:
Project *createProject(const QString &name); Project *createProject(const QString &name);
QStringList waitForRefreshedSourceFiles();
signals: signals:
void aboutToRemoveProject(ProjectExplorer::Project *project); void aboutToRemoveProject(ProjectExplorer::Project *project);
void projectAdded(ProjectExplorer::Project*); void projectAdded(ProjectExplorer::Project*);
public slots:
void sourceFilesRefreshed(const QStringList &files);
private:
bool m_refreshHappened;
QStringList m_lastRefreshedSourceFiles;
}; };
} // namespace Internal } // namespace Internal
......
#ifndef test_modelmanager_refresh_h
#define test_modelmanager_refresh_h
#endif // test_modelmanager_refresh_h
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment