From 7c06e4b768f34f6e840541c22b96700e5bc93849 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 27 Jul 2015 13:54:27 +0200 Subject: Be more generic regarding supported project types This removes the hard dependency on QmakeProjectManager. Furthermore now unneeded code is removed and some parts of the parsing are slightly modified to support other project types than qmake based projects. Change-Id: I1c23056d5a444ddea857e10fdb71264eb6ecc269 Reviewed-by: Christian Kandeler Reviewed-by: Niels Weber --- plugins/autotest/autotest.qbs | 5 +- plugins/autotest/autotest_dependencies.pri | 7 +- plugins/autotest/testcodeparser.cpp | 108 ++++++++++------------------- plugins/autotest/testcodeparser.h | 5 +- plugins/autotest/testnavigationwidget.cpp | 2 + plugins/autotest/testtreemodel.cpp | 4 ++ 6 files changed, 53 insertions(+), 78 deletions(-) diff --git a/plugins/autotest/autotest.qbs b/plugins/autotest/autotest.qbs index 4a9ec9e4c8..a75f91da6d 100644 --- a/plugins/autotest/autotest.qbs +++ b/plugins/autotest/autotest.qbs @@ -7,11 +7,14 @@ QtcCommercialPlugin { Depends { name: "CppTools" } Depends { name: "CPlusPlus" } Depends { name: "ProjectExplorer" } - Depends { name: "QmakeProjectManager" } Depends { name: "QmlJS" } Depends { name: "QmlJSTools" } Depends { name: "Utils" } + pluginTestDepends: [ + "QmakeProjectManager" + ] + Depends { name: "QtSupport" condition: project.testsEnabled diff --git a/plugins/autotest/autotest_dependencies.pri b/plugins/autotest/autotest_dependencies.pri index 74dc51e15b..fd6653ecf1 100644 --- a/plugins/autotest/autotest_dependencies.pri +++ b/plugins/autotest/autotest_dependencies.pri @@ -4,8 +4,7 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ projectexplorer \ cpptools \ - qmljstools \ - qmakeprojectmanager + qmljstools CONFIG(licensechecker): QTC_PLUGIN_DEPENDS += licensechecker @@ -14,4 +13,8 @@ QTC_LIB_DEPENDS += \ qmljs \ utils +QTC_TEST_DEPENDS += \ + qmakeprojectmanager \ + qtsupport + #QTC_PLUGIN_RECOMMENDS += \ diff --git a/plugins/autotest/testcodeparser.cpp b/plugins/autotest/testcodeparser.cpp index 982bffbffc..337643af6e 100644 --- a/plugins/autotest/testcodeparser.cpp +++ b/plugins/autotest/testcodeparser.cpp @@ -33,11 +33,9 @@ #include #include +#include #include -#include -#include - #include #include #include @@ -46,8 +44,10 @@ #include #include +#include #include #include +#include namespace Autotest { namespace Internal { @@ -58,8 +58,9 @@ TestCodeParser::TestCodeParser(TestTreeModel *parent) m_codeModelParsing(false), m_fullUpdatePostponed(false), m_partialUpdatePostponed(false), - m_dirty(true), + m_dirty(false), m_waitForParseTaskFinish(false), + m_singleShotScheduled(false), m_parserState(Disabled) { // connect to ProgressManager to postpone test parsing when CppModelManager is parsing @@ -105,26 +106,22 @@ void TestCodeParser::setState(State state) void TestCodeParser::emitUpdateTestTree() { + if (m_singleShotScheduled) + return; + + m_singleShotScheduled = true; QTimer::singleShot(1000, this, SLOT(updateTestTree())); } void TestCodeParser::updateTestTree() { + m_singleShotScheduled = false; if (m_codeModelParsing) { m_fullUpdatePostponed = true; return; } - if (ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject()) { - if (auto qmakeProject = qobject_cast(project)) { - if (qmakeProject->asyncUpdateState() != QmakeProjectManager::QmakeProject::Base) { - m_fullUpdatePostponed = true; - return; - } - connect(qmakeProject, &QmakeProjectManager::QmakeProject::proFilesEvaluated, - this, &TestCodeParser::onProFileEvaluated, Qt::UniqueConnection); - } - } else + if (!ProjectExplorer::SessionManager::startupProject()) return; m_fullUpdatePostponed = false; @@ -369,6 +366,10 @@ static TestTreeItem constructTestTreeItem(const QString &fileName, /****** end of helpers ******/ +// used internally to indicate a parse that failed due to having triggered a parse for a file that +// is not (yet) part of the CppModelManager's snapshot +static bool parsingHasFailed; + void performParse(QFutureInterface &futureInterface, QStringList list, TestCodeParser *testCodeParser) { @@ -383,6 +384,9 @@ void performParse(QFutureInterface &futureInterface, QStringList list, CPlusPlus::Document::Ptr doc = snapshot.find(file).value(); futureInterface.setProgressValue(++progressValue); testCodeParser->checkDocumentForTestCode(doc); + } else { + parsingHasFailed |= (CppTools::ProjectFile::classify(file) + != CppTools::ProjectFile::Unclassified); } } futureInterface.setProgressValue(list.size()); @@ -618,6 +622,7 @@ void TestCodeParser::scanForTests(const QStringList &fileList) if (postponed(fileList)) return; + m_postponedFiles.clear(); bool isFullParse = fileList.isEmpty(); bool isSmallChange = !isFullParse && fileList.size() < 6; QStringList list; @@ -631,6 +636,7 @@ void TestCodeParser::scanForTests(const QStringList &fileList) m_parserState = PartialParse; } + parsingHasFailed = false; if (isSmallChange) { // no need to do this async or should we do this always async? CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); CPlusPlus::Snapshot snapshot = cppMM->snapshot(); @@ -638,9 +644,12 @@ void TestCodeParser::scanForTests(const QStringList &fileList) if (snapshot.contains(file)) { CPlusPlus::Document::Ptr doc = snapshot.find(file).value(); checkDocumentForTestCode(doc); + } else { + parsingHasFailed |= (CppTools::ProjectFile::classify(file) + != CppTools::ProjectFile::Unclassified); } } - emit onFinished(); + onFinished(); return; } @@ -699,34 +708,6 @@ void TestCodeParser::removeTestsIfNecessary(const QString &fileName) } } -void TestCodeParser::removeTestsIfNecessaryByProFile(const QString &proFile) -{ - QList fList; - foreach (const QString &fileName, m_cppDocMap.keys()) { - if (m_cppDocMap[fileName].proFile() == proFile) - fList.append(fileName); - } - foreach (const QString &fileName, fList) { - m_cppDocMap.remove(fileName); - emit testItemsRemoved(fileName, TestTreeModel::AutoTest); - } - fList.clear(); - foreach (const QString &fileName, m_quickDocMap.keys()) { - if (m_quickDocMap[fileName].proFile() == proFile) - fList.append(fileName); - } - foreach (const QString &fileName, fList) { - m_quickDocMap.remove(fileName); - emit testItemsRemoved(fileName, TestTreeModel::QuickTest); - } - // handle unnamed Quick Tests - const QSet &filePaths = m_model->qmlFilesForProFile(proFile); - foreach (const QString &fileName, filePaths) { - removeUnnamedQuickTestsByName(fileName); - emit unnamedQuickTestsRemoved(fileName); - } -} - void TestCodeParser::onTaskStarted(Core::Id type) { if (type == CppTools::Constants::TASK_INDEX) @@ -762,7 +743,11 @@ void TestCodeParser::onFinished() break; case FullParse: m_parserState = Idle; - emit parsingFinished(); + m_dirty = parsingHasFailed; + if (m_partialUpdatePostponed || m_fullUpdatePostponed || parsingHasFailed) + emit partialParsingFinished(); + else + emit parsingFinished(); m_dirty = false; break; case Disabled: // can happen if all Test related widgets become hidden while parsing @@ -784,14 +769,13 @@ void TestCodeParser::onPartialParsingFinished() updateTestTree(); } else if (m_partialUpdatePostponed) { m_partialUpdatePostponed = false; - QStringList tmp; - foreach (const QString &file, m_postponedFiles) - tmp << file; - m_postponedFiles.clear(); - scanForTests(tmp); + scanForTests(m_postponedFiles.toList()); } else { - m_dirty = false; - emit parsingFinished(); + m_dirty |= m_codeModelParsing; + if (m_dirty) + emit parsingFailed(); + else if (!m_singleShotScheduled) + emit parsingFinished(); } } @@ -887,28 +871,6 @@ void TestCodeParser::removeUnnamedQuickTestsByName(const QString &fileName) } } -void TestCodeParser::onProFileEvaluated() -{ - ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); - if (!project) - return; - - CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); - const QList pp = modelManager->projectInfo(project).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); - // avoid illegal parser state when respective widgets became hidden while evaluating - setState(Idle); - scanForTests(files); - } - } -} - #ifdef WITH_TESTS int TestCodeParser::autoTestsCount() const { diff --git a/plugins/autotest/testcodeparser.h b/plugins/autotest/testcodeparser.h index ecf1caeb84..a492990f9b 100644 --- a/plugins/autotest/testcodeparser.h +++ b/plugins/autotest/testcodeparser.h @@ -56,6 +56,7 @@ public: virtual ~TestCodeParser(); void setState(State state); State state() const { return m_parserState; } + void setDirty() { m_dirty = true; } #ifdef WITH_TESTS int autoTestsCount() const; @@ -74,6 +75,7 @@ signals: void unnamedQuickTestsRemoved(const QString &filePath); void parsingStarted(); void parsingFinished(); + void parsingFailed(); void partialParsingFinished(); public slots: @@ -87,14 +89,12 @@ public slots: void onStartupProjectChanged(ProjectExplorer::Project *); void onProjectPartsUpdated(ProjectExplorer::Project *project); void removeFiles(const QStringList &files); - void onProFileEvaluated(); private: bool postponed(const QStringList &fileList); void scanForTests(const QStringList &fileList = QStringList()); void clearCache(); void removeTestsIfNecessary(const QString &fileName); - void removeTestsIfNecessaryByProFile(const QString &proFile); void onTaskStarted(Core::Id type); void onAllTasksFinished(Core::Id type); @@ -117,6 +117,7 @@ private: bool m_partialUpdatePostponed; bool m_dirty; bool m_waitForParseTaskFinish; + bool m_singleShotScheduled; QSet m_postponedFiles; State m_parserState; }; diff --git a/plugins/autotest/testnavigationwidget.cpp b/plugins/autotest/testnavigationwidget.cpp index 9745e1a19b..ad1a496b5f 100644 --- a/plugins/autotest/testnavigationwidget.cpp +++ b/plugins/autotest/testnavigationwidget.cpp @@ -75,6 +75,8 @@ TestNavigationWidget::TestNavigationWidget(QWidget *parent) : this, &TestNavigationWidget::onParsingStarted); connect(m_model->parser(), &TestCodeParser::parsingFinished, this, &TestNavigationWidget::onParsingFinished); + connect(m_model->parser(), &TestCodeParser::parsingFailed, + this, &TestNavigationWidget::onParsingFinished); connect(m_progressTimer, &QTimer::timeout, m_progressIndicator, &Utils::ProgressIndicator::show); } diff --git a/plugins/autotest/testtreemodel.cpp b/plugins/autotest/testtreemodel.cpp index 2ef7c76c63..5eea7b7d98 100644 --- a/plugins/autotest/testtreemodel.cpp +++ b/plugins/autotest/testtreemodel.cpp @@ -96,6 +96,10 @@ TestTreeModel::~TestTreeModel() void TestTreeModel::enableParsing() { m_refCounter.ref(); + + if (!m_connectionsInitialized) + m_parser->setDirty(); + m_parser->setState(TestCodeParser::Idle); if (m_connectionsInitialized) return; -- cgit v1.2.1