Output parsers: Make file look-up self-contained

Change-Id: Iffe104b6b52f0902f1977adeaa0fee3dc1e374a4
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2020-04-09 14:30:44 +02:00
parent 1eacbc98a8
commit c564805095
4 changed files with 46 additions and 34 deletions

View File

@@ -108,7 +108,6 @@ public:
std::unique_ptr<Utils::QtcProcess> m_process; std::unique_ptr<Utils::QtcProcess> m_process;
IOutputParser m_outputParser; IOutputParser m_outputParser;
ProcessParameters m_param; ProcessParameters m_param;
Utils::FileInProjectFinder m_fileFinder;
bool m_ignoreReturnValue = false; bool m_ignoreReturnValue = false;
bool m_lowPriority = false; bool m_lowPriority = false;
std::unique_ptr<QTextDecoder> stdoutStream; std::unique_ptr<QTextDecoder> stdoutStream;
@@ -119,8 +118,15 @@ AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl, Core::Id id) :
BuildStep(bsl, id), BuildStep(bsl, id),
d(new Private(this)) d(new Private(this))
{ {
connect(&d->m_outputParser, &IOutputParser::addTask, connect(&d->m_outputParser, &IOutputParser::addTask, this,
this, &AbstractProcessStep::taskAdded); [this](const Task &task, int linkedLines, int skipLines) {
// Do not bother to report issues if we do not care about the results of
// the buildstep anyway:
// TODO: Does that make sense? The user might still want to know that
// something failed, even if it wasn't fatal...
if (!d->m_ignoreReturnValue)
emit addTask(task, linkedLines, skipLines);
});
} }
AbstractProcessStep::~AbstractProcessStep() AbstractProcessStep::~AbstractProcessStep()
@@ -188,9 +194,11 @@ void AbstractProcessStep::setIgnoreReturnValue(bool b)
bool AbstractProcessStep::init() bool AbstractProcessStep::init()
{ {
Utils::FileInProjectFinder fileFinder;
fileFinder.setProjectDirectory(project()->projectDirectory());
fileFinder.setProjectFiles(project()->files(Project::AllFiles));
d->m_outputParser.addFilter(&Internal::filterAnsiEscapeCodes); d->m_outputParser.addFilter(&Internal::filterAnsiEscapeCodes);
d->m_fileFinder.setProjectDirectory(project()->projectDirectory()); d->m_outputParser.setFileFinder(fileFinder);
d->m_fileFinder.setProjectFiles(project()->files(Project::AllFiles));
return !d->m_process; return !d->m_process;
} }
@@ -387,30 +395,6 @@ void AbstractProcessStep::finish(bool success)
emit finished(success); emit finished(success);
} }
void AbstractProcessStep::taskAdded(const Task &task, int linkedOutputLines, int skipLines)
{
// Do not bother to report issues if we do not care about the results of
// the buildstep anyway:
if (d->m_ignoreReturnValue)
return;
Task editable(task);
QString filePath = task.file.toString();
if (!filePath.isEmpty() && !filePath.startsWith('<') && !QDir::isAbsolutePath(filePath)) {
while (filePath.startsWith("../"))
filePath.remove(0, 3);
bool found = false;
const Utils::FilePaths candidates
= d->m_fileFinder.findFile(QUrl::fromLocalFile(filePath), &found);
if (found && candidates.size() == 1)
editable.file = candidates.first();
else
qWarning() << "Could not find absolute location of file " << filePath;
}
emit addTask(editable, linkedOutputLines, skipLines);
}
void AbstractProcessStep::outputAdded(const QString &string, BuildStep::OutputFormat format) void AbstractProcessStep::outputAdded(const QString &string, BuildStep::OutputFormat format)
{ {
emit addOutput(string, format, BuildStep::DontAppendNewline); emit addOutput(string, format, BuildStep::DontAppendNewline);

View File

@@ -79,8 +79,6 @@ private:
void cleanUp(QProcess *process); void cleanUp(QProcess *process);
void taskAdded(const Task &task, int linkedOutputLines = 0, int skipLines = 0);
void outputAdded(const QString &string, BuildStep::OutputFormat format); void outputAdded(const QString &string, BuildStep::OutputFormat format);
class Private; class Private;

View File

@@ -27,6 +27,7 @@
#include "task.h" #include "task.h"
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/fileinprojectfinder.h>
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
#include <QDir> #include <QDir>
@@ -76,6 +77,7 @@ class OutputTaskParser::Private
{ {
public: public:
Utils::FilePaths searchDirs; Utils::FilePaths searchDirs;
Utils::FileInProjectFinder *fileFinder = nullptr;
QPointer<const OutputTaskParser> redirectionDetector; QPointer<const OutputTaskParser> redirectionDetector;
bool skipFileExistsCheck = false; bool skipFileExistsCheck = false;
}; };
@@ -122,6 +124,11 @@ bool OutputTaskParser::needsRedirection() const
|| d->redirectionDetector->needsRedirection()); || d->redirectionDetector->needsRedirection());
} }
void OutputTaskParser::setFileFinder(Utils::FileInProjectFinder *finder)
{
d->fileFinder = finder;
}
Utils::FilePath OutputTaskParser::absoluteFilePath(const Utils::FilePath &filePath) Utils::FilePath OutputTaskParser::absoluteFilePath(const Utils::FilePath &filePath)
{ {
if (filePath.isEmpty() || filePath.toFileInfo().isAbsolute()) if (filePath.isEmpty() || filePath.toFileInfo().isAbsolute())
@@ -134,6 +141,15 @@ Utils::FilePath OutputTaskParser::absoluteFilePath(const Utils::FilePath &filePa
} }
if (candidates.count() == 1) if (candidates.count() == 1)
return Utils::FilePath::fromString(QDir::cleanPath(candidates.first().toString())); return Utils::FilePath::fromString(QDir::cleanPath(candidates.first().toString()));
QString fp = filePath.toString();
while (fp.startsWith("../"))
fp.remove(0, 3);
bool found = false;
candidates = d->fileFinder->findFile(QUrl::fromLocalFile(fp), &found);
if (found && candidates.size() == 1)
return candidates.first();
return filePath; return filePath;
} }
@@ -200,6 +216,7 @@ public:
QList<OutputTaskParser *> lineParsers; QList<OutputTaskParser *> lineParsers;
OutputTaskParser *nextParser = nullptr; OutputTaskParser *nextParser = nullptr;
QList<Filter> filters; QList<Filter> filters;
Utils::FileInProjectFinder fileFinder;
OutputChannelState stdoutState; OutputChannelState stdoutState;
OutputChannelState stderrState; OutputChannelState stderrState;
}; };
@@ -261,8 +278,9 @@ QString IOutputParser::filteredLine(const QString &line) const
return l; return l;
} }
void IOutputParser::connectLineParser(OutputTaskParser *parser) void IOutputParser::setupLineParser(OutputTaskParser *parser)
{ {
parser->setFileFinder(&d->fileFinder);
connect(parser, &OutputTaskParser::addTask, this, &IOutputParser::addTask); connect(parser, &OutputTaskParser::addTask, this, &IOutputParser::addTask);
connect(parser, &OutputTaskParser::newSearchDir, this, &IOutputParser::addSearchDir); connect(parser, &OutputTaskParser::newSearchDir, this, &IOutputParser::addSearchDir);
connect(parser, &OutputTaskParser::searchDirExpired, this, &IOutputParser::dropSearchDir); connect(parser, &OutputTaskParser::searchDirExpired, this, &IOutputParser::dropSearchDir);
@@ -291,11 +309,12 @@ void IOutputParser::clear()
d->lineParsers.clear(); d->lineParsers.clear();
d->stdoutState.pendingData.clear(); d->stdoutState.pendingData.clear();
d->stderrState.pendingData.clear(); d->stderrState.pendingData.clear();
d->fileFinder = Utils::FileInProjectFinder();
} }
void IOutputParser::addLineParser(OutputTaskParser *parser) void IOutputParser::addLineParser(OutputTaskParser *parser)
{ {
connectLineParser(parser); setupLineParser(parser);
d->lineParsers << parser; d->lineParsers << parser;
} }
@@ -312,6 +331,11 @@ void IOutputParser::setLineParsers(const QList<OutputTaskParser *> &parsers)
addLineParsers(parsers); addLineParsers(parsers);
} }
void IOutputParser::setFileFinder(const Utils::FileInProjectFinder &finder)
{
d->fileFinder = finder;
}
#ifdef WITH_TESTS #ifdef WITH_TESTS
QList<OutputTaskParser *> IOutputParser::lineParsers() const QList<OutputTaskParser *> IOutputParser::lineParsers() const
{ {

View File

@@ -33,6 +33,8 @@
#include <functional> #include <functional>
namespace Utils { class FileInProjectFinder; }
namespace ProjectExplorer { namespace ProjectExplorer {
class Task; class Task;
@@ -57,6 +59,8 @@ public:
bool needsRedirection() const; bool needsRedirection() const;
virtual bool hasDetectedRedirection() const { return false; } virtual bool hasDetectedRedirection() const { return false; }
void setFileFinder(Utils::FileInProjectFinder *finder);
#ifdef WITH_TESTS #ifdef WITH_TESTS
void skipFileExistsCheck(); void skipFileExistsCheck();
#endif #endif
@@ -102,6 +106,8 @@ public:
void addLineParsers(const QList<OutputTaskParser *> &parsers); void addLineParsers(const QList<OutputTaskParser *> &parsers);
void setLineParsers(const QList<OutputTaskParser *> &parsers); void setLineParsers(const QList<OutputTaskParser *> &parsers);
void setFileFinder(const Utils::FileInProjectFinder &finder);
#ifdef WITH_TESTS #ifdef WITH_TESTS
QList<OutputTaskParser *> lineParsers() const; QList<OutputTaskParser *> lineParsers() const;
#endif #endif
@@ -112,7 +118,7 @@ signals:
private: private:
void handleLine(const QString &line, Utils::OutputFormat type); void handleLine(const QString &line, Utils::OutputFormat type);
QString filteredLine(const QString &line) const; QString filteredLine(const QString &line) const;
void connectLineParser(OutputTaskParser *parser); void setupLineParser(OutputTaskParser *parser);
Utils::OutputFormat outputTypeForParser(const OutputTaskParser *parser, Utils::OutputFormat outputTypeForParser(const OutputTaskParser *parser,
Utils::OutputFormat type) const; Utils::OutputFormat type) const;