diff --git a/src/plugins/autotest/quick/quicktestparser.cpp b/src/plugins/autotest/quick/quicktestparser.cpp index cb7e5a04646..6e249a57b21 100644 --- a/src/plugins/autotest/quick/quicktestparser.cpp +++ b/src/plugins/autotest/quick/quicktestparser.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include namespace Autotest { @@ -237,6 +238,49 @@ bool QuickTestParser::handleQtQuickTest(QFutureInterface fut return result; } +static QMap qmlFilesWithMTime(const QString &directory) +{ + const QFileInfoList &qmlFiles = QDir(directory).entryInfoList({ "*.qml" }, + QDir::Files, QDir::Name); + QMap filesAndDates; + for (const QFileInfo &info : qmlFiles) + filesAndDates.insert(info.fileName(), info.lastModified()); + return filesAndDates; +} + +void QuickTestParser::handleDirectoryChanged(const QString &directory) +{ + const QMap &filesAndDates = qmlFilesWithMTime(directory); + const QMap &watched = m_watchedFiles.value(directory); + const QStringList &keys = watched.keys(); + if (filesAndDates.keys() != keys) { // removed or added files + m_watchedFiles[directory] = filesAndDates; + TestTreeModel::instance()->parser()->emitUpdateTestTree(this); + } else { // we might still have different timestamps + const bool timestampChanged = Utils::anyOf(keys, [&](const QString &file) { + return filesAndDates.value(file) != watched.value(file); + }); + if (timestampChanged) { + QmlJS::PathsAndLanguages paths; + paths.maybeInsert(Utils::FileName::fromString(directory), QmlJS::Dialect::Qml); + QFutureInterface future; + QmlJS::ModelManagerInterface *qmlJsMM = QmlJS::ModelManagerInterface::instance(); + QmlJS::ModelManagerInterface::importScan(future, qmlJsMM->workingCopy(), paths, qmlJsMM, + true /*emitDocumentChanges*/, + false /*onlyTheLib*/, + true /*forceRescan*/ ); + } + } +} + +void QuickTestParser::doUpdateWatchPaths(const QStringList &directories) +{ + for (const QString &dir : directories) { + m_directoryWatcher.addPath(dir); + m_watchedFiles[dir] = qmlFilesWithMTime(dir); + } +} + QuickTestParser::QuickTestParser() : CppParser() { @@ -245,11 +289,12 @@ QuickTestParser::QuickTestParser() const QStringList &dirs = m_directoryWatcher.directories(); if (!dirs.isEmpty()) m_directoryWatcher.removePaths(dirs); + m_watchedFiles.clear(); }); connect(&m_directoryWatcher, &QFileSystemWatcher::directoryChanged, - [this] { TestTreeModel::instance()->parser()->emitUpdateTestTree(this); }); + this, &QuickTestParser::handleDirectoryChanged); connect(this, &QuickTestParser::updateWatchPaths, - &m_directoryWatcher, &QFileSystemWatcher::addPaths, Qt::QueuedConnection); + this, &QuickTestParser::doUpdateWatchPaths, Qt::QueuedConnection); } QuickTestParser::~QuickTestParser() diff --git a/src/plugins/autotest/quick/quicktestparser.h b/src/plugins/autotest/quick/quicktestparser.h index 26ba514f2fb..2b38efed371 100644 --- a/src/plugins/autotest/quick/quicktestparser.h +++ b/src/plugins/autotest/quick/quicktestparser.h @@ -56,10 +56,13 @@ signals: private: bool handleQtQuickTest(QFutureInterface futureInterface, CPlusPlus::Document::Ptr document, const Core::Id &id) const; + void handleDirectoryChanged(const QString &directory); + void doUpdateWatchPaths(const QStringList &directories); QList scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const; QmlJS::Snapshot m_qmlSnapshot; QHash m_proFilesForQmlFiles; QFileSystemWatcher m_directoryWatcher; + QMap > m_watchedFiles; }; } // namespace Internal