diff options
author | Christian Stenger <christian.stenger@qt.io> | 2017-06-01 11:57:57 +0200 |
---|---|---|
committer | Christian Stenger <christian.stenger@qt.io> | 2017-06-13 07:24:35 +0000 |
commit | 3cd688ca4427ac6a7a071a5a20d707e4598689cd (patch) | |
tree | 28ae4016fb81a28b5fa38b29acb3ba35f462ee43 /src/plugins/autotest/quick/quicktestparser.cpp | |
parent | 325eaf4a62e798e8c265c07091b56f54872982d0 (diff) | |
download | qt-creator-3cd688ca4427ac6a7a071a5a20d707e4598689cd.tar.gz |
AutoTest: Avoid full rescans if not necessary
The file system watcher triggers way too often as it
acts not only for removal or addition of files, but
for any change like mtime or similar.
Doing always a full rescan is painful, so limit this
as much as possible to the files that have changed.
Task-number: QTCREATORBUG-18315
Change-Id: Iba4705ff58c34e998d8cf1b40761758c6fd65680
Reviewed-by: David Schulz <david.schulz@qt.io>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Diffstat (limited to 'src/plugins/autotest/quick/quicktestparser.cpp')
-rw-r--r-- | src/plugins/autotest/quick/quicktestparser.cpp | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/src/plugins/autotest/quick/quicktestparser.cpp b/src/plugins/autotest/quick/quicktestparser.cpp index cb7e5a0464..6e249a57b2 100644 --- a/src/plugins/autotest/quick/quicktestparser.cpp +++ b/src/plugins/autotest/quick/quicktestparser.cpp @@ -35,6 +35,7 @@ #include <qmljs/qmljsdialect.h> #include <qmljstools/qmljsmodelmanager.h> #include <utils/hostosinfo.h> +#include <utils/algorithm.h> #include <utils/qtcassert.h> namespace Autotest { @@ -237,6 +238,49 @@ bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> fut return result; } +static QMap<QString, QDateTime> qmlFilesWithMTime(const QString &directory) +{ + const QFileInfoList &qmlFiles = QDir(directory).entryInfoList({ "*.qml" }, + QDir::Files, QDir::Name); + QMap<QString, QDateTime> filesAndDates; + for (const QFileInfo &info : qmlFiles) + filesAndDates.insert(info.fileName(), info.lastModified()); + return filesAndDates; +} + +void QuickTestParser::handleDirectoryChanged(const QString &directory) +{ + const QMap<QString, QDateTime> &filesAndDates = qmlFilesWithMTime(directory); + const QMap<QString, QDateTime> &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<void> 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() |