summaryrefslogtreecommitdiff
path: root/plugins/autotest/testcodeparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/autotest/testcodeparser.cpp')
-rw-r--r--plugins/autotest/testcodeparser.cpp108
1 files changed, 35 insertions, 73 deletions
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
{