summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/autotest/autotest.qbs5
-rw-r--r--plugins/autotest/autotest_dependencies.pri7
-rw-r--r--plugins/autotest/testcodeparser.cpp108
-rw-r--r--plugins/autotest/testcodeparser.h5
-rw-r--r--plugins/autotest/testnavigationwidget.cpp2
-rw-r--r--plugins/autotest/testtreemodel.cpp4
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;