diff options
author | Christian Stenger <christian.stenger@theqtcompany.com> | 2014-11-25 09:32:13 +0100 |
---|---|---|
committer | Christian Stenger <christian.stenger@theqtcompany.com> | 2014-12-04 13:52:16 +0100 |
commit | 0fc6d113d1befa33485adee3de77ad8b2ec0e985 (patch) | |
tree | aeac054b8a82c8544263656a8d50b1b8c8cb2a6c | |
parent | eb073616fbac1d5f1f4c537ecc36047ea43f8b0e (diff) | |
download | qt-creator-0fc6d113d1befa33485adee3de77ad8b2ec0e985.tar.gz |
Update test tree when configuration changes
This takes especially configurations in account when subprojects
are enabled/disabled conditionally.
-rw-r--r-- | plugins/autotest/autotest_dependencies.pri | 1 | ||||
-rw-r--r-- | plugins/autotest/testcodeparser.cpp | 185 | ||||
-rw-r--r-- | plugins/autotest/testcodeparser.h | 5 | ||||
-rw-r--r-- | plugins/autotest/testinfo.h | 5 |
4 files changed, 177 insertions, 19 deletions
diff --git a/plugins/autotest/autotest_dependencies.pri b/plugins/autotest/autotest_dependencies.pri index 6546683f45..a21b5fce96 100644 --- a/plugins/autotest/autotest_dependencies.pri +++ b/plugins/autotest/autotest_dependencies.pri @@ -5,6 +5,7 @@ QTC_PLUGIN_DEPENDS += \ projectexplorer \ cpptools \ qmljstools \ + qmakeprojectmanager \ licensechecker QTC_LIB_DEPENDS += \ diff --git a/plugins/autotest/testcodeparser.cpp b/plugins/autotest/testcodeparser.cpp index 240bb418d5..a0ba1534ce 100644 --- a/plugins/autotest/testcodeparser.cpp +++ b/plugins/autotest/testcodeparser.cpp @@ -31,6 +31,7 @@ #include <projectexplorer/session.h> +#include <qmakeprojectmanager/qmakeproject.h> #include <qmljs/parser/qmljsast_p.h> #include <qmljs/qmljsdialect.h> #include <qmljstools/qmljsmodelmanager.h> @@ -61,6 +62,13 @@ void TestCodeParser::updateTestTree() m_model->removeAllQuickTests(); const ProjectExplorer::SessionManager *session = ProjectExplorer::SessionManager::instance(); if (!session || !session->hasProjects()) { + if (m_currentProject) { + if (QmakeProjectManager::QmakeProject *qmproj + = qobject_cast<QmakeProjectManager::QmakeProject *>(m_currentProject)) { + disconnect(qmproj, &QmakeProjectManager::QmakeProject::proFilesEvaluated, + this, &TestCodeParser::onProFileEvaluated); + } + } m_currentProject = 0; return; } @@ -68,6 +76,13 @@ void TestCodeParser::updateTestTree() m_currentProject = session->startupProject(); if (!m_currentProject) return; + else { + if (QmakeProjectManager::QmakeProject *qmproj + = qobject_cast<QmakeProjectManager::QmakeProject *>(m_currentProject)) { + connect(qmproj, &QmakeProjectManager::QmakeProject::proFilesEvaluated, + this, &TestCodeParser::onProFileEvaluated); + } + } scanForTests(); } @@ -241,6 +256,13 @@ void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr doc) const QString file = doc->fileName(); const CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); + QList<CppTools::ProjectPart::Ptr> projParts = cppMM->projectPart(file); + if (projParts.size()) + if (!projParts.at(0)->selectedForBuilding) { + removeTestsIfNecessary(file); + return; + } + if (includesQtQuickTest(doc, cppMM)) { handleQtQuickTest(doc); return; @@ -299,6 +321,11 @@ void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr doc) // TODO refactoring? // update model and internal map + QString proFile; + QList<CppTools::ProjectPart::Ptr> ppList = cppMM->projectPart(file); + if (ppList.size()) + proFile = ppList.at(0)->projectFile; + TestInfo info; int count; if (m_cppDocMap.contains(file)) { @@ -308,9 +335,9 @@ void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr doc) TestTreeItem *currentItem = autoTestRootItem->child(i); if (currentItem->filePath() == file) { m_model->modifyAutoTestSubtree(i, ttItem); - m_cppDocMap.insert(file, TestInfo(tc, privSlots.keys(), - doc->revision(), - doc->editorRevision())); + TestInfo ti(tc, privSlots.keys(), doc->revision(), doc->editorRevision()); + ti.setProfile(proFile); + m_cppDocMap.insert(file, ti); break; } } @@ -324,6 +351,7 @@ void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr doc) TestInfo ti(tc, privSlots.keys(), doc->revision(), doc->editorRevision()); ti.setReferencingFile(file); + ti.setProfile(proFile); m_cppDocMap.insert(declFileName, ti); break; } @@ -332,11 +360,13 @@ void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr doc) delete ttItem; } else { m_model->addAutoTest(ttItem); - m_cppDocMap.insert(file, TestInfo(tc, privSlots.keys(), doc->revision(), - doc->editorRevision())); + TestInfo ti(tc, privSlots.keys(), doc->revision(), doc->editorRevision()); + ti.setProfile(proFile); + m_cppDocMap.insert(file, ti); if (declFileName != file) { TestInfo ti(tc, privSlots.keys(), doc->revision(), doc->editorRevision()); ti.setReferencingFile(file); + ti.setProfile(proFile); m_cppDocMap.insert(declFileName, ti); } } @@ -466,6 +496,10 @@ void TestCodeParser::handleQtQuickTest(CPlusPlus::Document::Ptr doc) const QString fileName(tcLocationAndType.m_fileName); const QmlJS::Document::Ptr qmlDoc = QmlJSTools::Internal::ModelManager::instance()->snapshot().document(fileName); + QString proFile; + QList<CppTools::ProjectPart::Ptr> ppList = cppMM->projectPart(doc->fileName()); + if (ppList.size()) + proFile = ppList.at(0)->projectFile; if (m_quickDocMap.contains(fileName)) { for (int i = 0; i < quickTestRootItem->childCount(); ++i) { @@ -473,6 +507,7 @@ void TestCodeParser::handleQtQuickTest(CPlusPlus::Document::Ptr doc) m_model->modifyQuickTestSubtree(i, ttItem); TestInfo ti(tcName, testFunctions.keys(), 0, qmlDoc->editorRevision()); ti.setReferencingFile(doc->fileName()); + ti.setProfile(proFile); m_quickDocMap.insert(fileName, ti); break; } @@ -499,6 +534,7 @@ void TestCodeParser::handleQtQuickTest(CPlusPlus::Document::Ptr doc) m_model->addQuickTest(ttItem); TestInfo ti(tcName, testFunctions.keys(), 0, qmlDoc->editorRevision()); ti.setReferencingFile(doc->fileName()); + ti.setProfile(proFile); m_quickDocMap.insert(tcLocationAndType.m_fileName, ti); } } @@ -557,21 +593,19 @@ void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &doc) void TestCodeParser::removeFiles(const QStringList &files) { - foreach (const QString &file, files) { - if (m_cppDocMap.contains(file)) { - m_cppDocMap.remove(file); - m_model->removeAutoTestSubtreeByFilePath(file); - } - if (m_quickDocMap.contains(file)) { - m_quickDocMap.remove(file); - m_model->removeQuickTestSubtreeByFilePath(file); - } - } + foreach (const QString &file, files) + removeTestsIfNecessary(file); } -void TestCodeParser::scanForTests() +void TestCodeParser::scanForTests(const QStringList &fileList) { - const QStringList list = m_currentProject->files(ProjectExplorer::Project::AllFiles); + QStringList list; + if (fileList.isEmpty()) { + list = m_currentProject->files(ProjectExplorer::Project::AllFiles); + } else { + list << fileList; + } + CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); CPlusPlus::Snapshot snapshot = cppMM->snapshot(); @@ -589,5 +623,122 @@ void TestCodeParser::clearMaps() m_quickDocMap.clear(); } +void TestCodeParser::removeTestsIfNecessary(const QString &fileName) +{ + // check if this file was listed before and remove if necessary (switched config,...) + if (m_cppDocMap.contains(fileName)) { + m_cppDocMap.remove(fileName); + m_model->removeAutoTestSubtreeByFilePath(fileName); + } else { // handle Qt Quick Tests + QList<QString> toBeRemoved; + foreach (const QString &file, m_quickDocMap.keys()) { + if (file == fileName) { + toBeRemoved.append(file); + continue; + } + const TestInfo info = m_quickDocMap.value(file); + if (info.referencingFile() == fileName) + toBeRemoved.append(file); + } + foreach (const QString &file, toBeRemoved) { + m_quickDocMap.remove(file); + m_model->removeQuickTestSubtreeByFilePath(file); + } + // unnamed Quick Tests must be handled separately + QSet<QString> filePaths; + QList<QString> functionNames; + if (TestTreeItem *unnamedQT = m_model->unnamedQuickTests()) { + for (int i = 0; i < unnamedQT->childCount(); ++i) { + const TestTreeItem *child = unnamedQT->child(i); + if (child->mainFile() == fileName) { + filePaths.insert(child->filePath()); + functionNames.append(child->name()); + } + } + foreach (const QString &file, filePaths) + m_model->removeUnnamedQuickTests(file); + // update info map + TestInfo unnamedInfo = m_quickDocMap[tr(Constants::UNNAMED_QUICKTESTS)]; + QStringList functions = unnamedInfo.testFunctions(); + foreach (const QString &func, functionNames) + functions.removeOne(func); + unnamedInfo.setTestFunctions(functions); + if (functions.size() == 0) + m_quickDocMap.remove(tr(Constants::UNNAMED_QUICKTESTS)); + else + m_quickDocMap.insert(tr(Constants::UNNAMED_QUICKTESTS), unnamedInfo); + } + } +} + + +void TestCodeParser::removeTestsIfNecessaryByProFile(const QString &proFile) +{ + QList<QString> fl; + foreach (const QString &fn, m_cppDocMap.keys()) { + if (m_cppDocMap[fn].proFile() == proFile) + fl.append(fn); + } + foreach (const QString &fn, fl) { + m_cppDocMap.remove(fn); + m_model->removeAutoTestSubtreeByFilePath(fn); + } + fl.clear(); + foreach (const QString &fn, m_quickDocMap.keys()) { + if (m_quickDocMap[fn].proFile() == proFile) + fl.append(fn); + } + foreach (const QString &fn, fl) { + m_quickDocMap.remove(fn); + m_model->removeQuickTestSubtreeByFilePath(fn); + } + // handle unnamed Quick Tests + fl.clear(); // will now be re-used as function names storage + QSet<QString> filePaths; + CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); + if (TestTreeItem *unnamedQT = m_model->unnamedQuickTests()) { + for (int i = 0; i < unnamedQT->childCount(); ++i) { + const TestTreeItem *child = unnamedQT->child(i); + QList<CppTools::ProjectPart::Ptr> ppList = cppMM->projectPart(child->mainFile()); + if (ppList.size() && ppList.at(0)->projectFile == proFile) { + filePaths.insert(child->filePath()); + fl.append(child->name()); + } + } + } + foreach (const QString &fp, filePaths) { + m_model->removeUnnamedQuickTests(fp); + } + // update info map + TestInfo unnamedInfo = m_quickDocMap[tr(Constants::UNNAMED_QUICKTESTS)]; + QStringList functions = unnamedInfo.testFunctions(); + foreach (const QString &func, fl) + functions.removeOne(func); + unnamedInfo.setTestFunctions(functions); + if (functions.size() == 0) + m_quickDocMap.remove(tr(Constants::UNNAMED_QUICKTESTS)); + else + m_quickDocMap.insert(tr(Constants::UNNAMED_QUICKTESTS), unnamedInfo); +} + +void TestCodeParser::onProFileEvaluated() +{ + if (!m_currentProject) + return; + + CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); + const QList<CppTools::ProjectPart::Ptr> pp = cppMM->projectInfo(m_currentProject).projectParts(); + foreach (const CppTools::ProjectPart::Ptr &p, pp) { + if (!p->selectedForBuilding) + removeTestsIfNecessaryByProFile(p->projectFile); + else { + QStringList files; + foreach (auto projectFile, p->files) + files.append(projectFile.path); + scanForTests(files); + } + } +} + } // namespace Internal } // namespace Autotest diff --git a/plugins/autotest/testcodeparser.h b/plugins/autotest/testcodeparser.h index 5b422ba0e6..da89eb51d7 100644 --- a/plugins/autotest/testcodeparser.h +++ b/plugins/autotest/testcodeparser.h @@ -53,10 +53,13 @@ public slots: void onCppDocumentUpdated(const CPlusPlus::Document::Ptr &doc); void onQmlDocumentUpdated(const QmlJS::Document::Ptr &doc); void removeFiles(const QStringList &files); + void onProFileEvaluated(); private: - void scanForTests(); + void scanForTests(const QStringList &fileList = QStringList()); void clearMaps(); + void removeTestsIfNecessary(const QString &fileName); + void removeTestsIfNecessaryByProFile(const QString &proFile); TestTreeModel *m_model; QMap<QString, TestInfo> m_cppDocMap; diff --git a/plugins/autotest/testinfo.h b/plugins/autotest/testinfo.h index c03236416d..b974824f9e 100644 --- a/plugins/autotest/testinfo.h +++ b/plugins/autotest/testinfo.h @@ -41,7 +41,9 @@ public: unsigned editorRevision() const { return m_editorRevision; } void setEditorRevision(unsigned editorRevision) { m_editorRevision = editorRevision; } const QString referencingFile() const { return m_referencingFile; } - void setReferencingFile(const QString &refFile) {m_referencingFile = refFile; } + void setReferencingFile(const QString &refFile) { m_referencingFile = refFile; } + const QString proFile() const { return m_proFile; } + void setProfile(const QString &proFile) { m_proFile = proFile; } private: QString m_className; @@ -49,6 +51,7 @@ private: unsigned m_revision; unsigned m_editorRevision; QString m_referencingFile; + QString m_proFile; }; } // namespace Internal |