AbstractProcessStep: Re-use FileInProjectFinder

Change-Id: Ifd5d24b6cac707372a95b2b31e270722a6202fc0
Reviewed-by: Antonio Di Monaco <tony@becrux.com>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2019-03-13 16:06:12 +01:00
parent 06e3e23aa5
commit eba3cd6135
2 changed files with 15 additions and 75 deletions

View File

@@ -35,23 +35,19 @@
#include <coreplugin/reaper.h> #include <coreplugin/reaper.h>
#include <utils/fileinprojectfinder.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <QDir> #include <QDir>
#include <QTimer>
#include <QHash> #include <QHash>
#include <QPair> #include <QPair>
#include <QUrl>
#include <algorithm> #include <algorithm>
#include <memory> #include <memory>
namespace {
const int CACHE_SOFT_LIMIT = 500;
const int CACHE_HARD_LIMIT = 1000;
} // namespace
namespace ProjectExplorer { namespace ProjectExplorer {
/*! /*!
@@ -107,10 +103,8 @@ public:
std::unique_ptr<Utils::QtcProcess> m_process; std::unique_ptr<Utils::QtcProcess> m_process;
std::unique_ptr<IOutputParser> m_outputParserChain; std::unique_ptr<IOutputParser> m_outputParserChain;
ProcessParameters m_param; ProcessParameters m_param;
QHash<QString, QPair<Utils::FileName, quint64>> m_filesCache; Utils::FileInProjectFinder m_fileFinder;
QHash<QString, Utils::FileNameList> m_candidates;
QByteArray deferredText; QByteArray deferredText;
quint64 m_cacheCounter = 0;
bool m_ignoreReturnValue = false; bool m_ignoreReturnValue = false;
bool m_skipFlush = false; bool m_skipFlush = false;
@@ -194,11 +188,8 @@ void AbstractProcessStep::setIgnoreReturnValue(bool b)
bool AbstractProcessStep::init() bool AbstractProcessStep::init()
{ {
d->m_candidates.clear(); d->m_fileFinder.setProjectDirectory(project()->projectDirectory());
const Utils::FileNameList fl = project()->files(Project::AllFiles); d->m_fileFinder.setProjectFiles(project()->files(Project::AllFiles));
for (const Utils::FileName &file : fl)
d->m_candidates[file.fileName()].push_back(file);
return !d->m_process; return !d->m_process;
} }
@@ -437,44 +428,16 @@ void AbstractProcessStep::taskAdded(const Task &task, int linkedOutputLines, int
Task editable(task); Task editable(task);
QString filePath = task.file.toString(); QString filePath = task.file.toString();
if (!filePath.isEmpty() && !filePath.startsWith('<') && !QDir::isAbsolutePath(filePath)) {
auto it = d->m_filesCache.find(filePath); while (filePath.startsWith("../"))
if (it != d->m_filesCache.end()) { filePath.remove(0, 3);
editable.file = it.value().first; bool found = false;
it.value().second = ++d->m_cacheCounter; const Utils::FileNameList candidates
} else if (!filePath.isEmpty() && !filePath.startsWith('<') && !QDir::isAbsolutePath(filePath)) { = d->m_fileFinder.findFile(QUrl::fromLocalFile(filePath), &found);
// We have no save way to decide which file in which subfolder if (found && candidates.size() == 1)
// is meant. Therefore we apply following heuristics: editable.file = candidates.first();
// 1. Check if file is unique in whole project else
// 2. Otherwise try again without any ../ qWarning() << "Could not find absolute location of file " << filePath;
// 3. give up.
QString sourceFilePath = filePath;
Utils::FileNameList possibleFiles = d->m_candidates.value(Utils::FileName::fromString(filePath).fileName());
if (possibleFiles.count() == 1) {
editable.file = possibleFiles.first();
} else {
// More then one filename, so do a better compare
// Chop of any "../"
while (filePath.startsWith("../"))
filePath.remove(0, 3);
int count = 0;
Utils::FileName possibleFilePath;
foreach (const Utils::FileName &fn, possibleFiles) {
if (fn.endsWith(filePath)) {
possibleFilePath = fn;
++count;
}
}
if (count == 1)
editable.file = possibleFilePath;
else
qWarning() << "Could not find absolute location of file " << filePath;
}
insertInCache(sourceFilePath, editable.file);
} }
emit addTask(editable, linkedOutputLines, skipLines); emit addTask(editable, linkedOutputLines, skipLines);
@@ -499,27 +462,7 @@ void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus)
for (const QString &l : stdOutLine.split('\n')) for (const QString &l : stdOutLine.split('\n'))
stdError(l); stdError(l);
purgeCache(true);
cleanUp(process); cleanUp(process);
} }
void AbstractProcessStep::purgeCache(bool useSoftLimit)
{
const int limit = useSoftLimit ? CACHE_SOFT_LIMIT : CACHE_HARD_LIMIT;
if (d->m_filesCache.size() <= limit)
return;
const quint64 minCounter = d->m_cacheCounter - static_cast<quint64>(limit);
std::remove_if(d->m_filesCache.begin(), d->m_filesCache.end(),
[minCounter](const QPair<Utils::FileName, quint64> &entry) {
return entry.second <= minCounter;
});
}
void AbstractProcessStep::insertInCache(const QString &relativePath, const Utils::FileName &absPath)
{
purgeCache(false);
d->m_filesCache.insert(relativePath, qMakePair(absPath, ++d->m_cacheCounter));
}
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -80,9 +80,6 @@ private:
void outputAdded(const QString &string, BuildStep::OutputFormat format); void outputAdded(const QString &string, BuildStep::OutputFormat format);
void purgeCache(bool useSoftLimit);
void insertInCache(const QString &relativePath, const Utils::FileName &absPath);
class Private; class Private;
Private *d; Private *d;
}; };