diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/autotest/autotest.qbs | 5 | ||||
-rw-r--r-- | plugins/autotest/autotest_dependencies.pri | 7 | ||||
-rw-r--r-- | plugins/autotest/testcodeparser.cpp | 108 | ||||
-rw-r--r-- | plugins/autotest/testcodeparser.h | 5 | ||||
-rw-r--r-- | plugins/autotest/testnavigationwidget.cpp | 2 | ||||
-rw-r--r-- | 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 <cpptools/cppmodelmanager.h> #include <cpptools/cppworkingcopy.h> +#include <projectexplorer/project.h> #include <projectexplorer/session.h> -#include <qmakeprojectmanager/qmakeproject.h> -#include <qmakeprojectmanager/qmakeprojectmanagerconstants.h> - #include <qmljs/parser/qmljsast_p.h> #include <qmljs/qmljsdialect.h> #include <qmljstools/qmljsmodelmanager.h> @@ -46,8 +44,10 @@ #include <utils/qtcassert.h> #include <utils/textfileformat.h> +#include <QDirIterator> #include <QFuture> #include <QFutureInterface> +#include <QTimer> 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<QmakeProjectManager::QmakeProject *>(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<void> &futureInterface, QStringList list, TestCodeParser *testCodeParser) { @@ -383,6 +384,9 @@ void performParse(QFutureInterface<void> &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<QString> 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<QString> &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<CppTools::ProjectPart::Ptr> 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<QString> 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; |