ProjectExplorer: Split up the IOutputParser class

For symmetry with Utils::OutputFormatter.

Task-number: QTCREATORBUG-22665
Change-Id: I148fed69dba042ad3ef26e080829c31cd3f357fd
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2020-04-15 14:59:51 +02:00
parent d04597f2aa
commit 6f32538c5d
76 changed files with 345 additions and 311 deletions

View File

@@ -51,7 +51,7 @@ void JavaParser::setSourceDirectory(const Utils::FilePath &sourceDirectory)
m_sourceDirectory = sourceDirectory; m_sourceDirectory = sourceDirectory;
} }
IOutputParser::Status JavaParser::doHandleLine(const QString &line, Utils::OutputFormat type) OutputTaskParser::Status JavaParser::handleLine(const QString &line, Utils::OutputFormat type)
{ {
Q_UNUSED(type); Q_UNUSED(type);
if (m_javaRegExp.indexIn(line) == -1) if (m_javaRegExp.indexIn(line) == -1)

View File

@@ -33,7 +33,7 @@
namespace Android { namespace Android {
namespace Internal { namespace Internal {
class JavaParser : public ProjectExplorer::IOutputParser class JavaParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -45,7 +45,7 @@ public:
void setSourceDirectory(const Utils::FilePath &sourceDirectory); void setSourceDirectory(const Utils::FilePath &sourceDirectory);
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
QRegExp m_javaRegExp; QRegExp m_javaRegExp;
QStringList m_fileList; QStringList m_fileList;

View File

@@ -64,7 +64,7 @@ Core::Id IarParser::id()
void IarParser::newTask(const Task &task) void IarParser::newTask(const Task &task)
{ {
doFlush(); flush();
m_lastTask = task; m_lastTask = task;
m_lines = 1; m_lines = 1;
} }
@@ -190,7 +190,7 @@ bool IarParser::parseErrorMessage1(const QString &lne)
return true; return true;
} }
IOutputParser::Status IarParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status IarParser::handleLine(const QString &line, OutputFormat type)
{ {
const QString lne = rightTrimmed(line); const QString lne = rightTrimmed(line);
if (type == StdOutFormat) { if (type == StdOutFormat) {
@@ -198,7 +198,7 @@ IOutputParser::Status IarParser::doHandleLine(const QString &line, OutputFormat
const bool leastOneParsed = parseErrorInCommandLineMessage(lne) const bool leastOneParsed = parseErrorInCommandLineMessage(lne)
|| parseErrorMessage1(lne); || parseErrorMessage1(lne);
if (!leastOneParsed) { if (!leastOneParsed) {
doFlush(); flush();
return Status::NotHandled; return Status::NotHandled;
} }
return Status::InProgress; return Status::InProgress;
@@ -215,7 +215,7 @@ IOutputParser::Status IarParser::doHandleLine(const QString &line, OutputFormat
if (lne.endsWith(']')) { if (lne.endsWith(']')) {
const QString lastPart = lne.left(lne.size() - 1); const QString lastPart = lne.left(lne.size() - 1);
m_filePathParts.push_back(lastPart); m_filePathParts.push_back(lastPart);
doFlush(); flush();
return Status::Done; return Status::Done;
} else { } else {
m_filePathParts.push_back(lne); m_filePathParts.push_back(lne);
@@ -235,14 +235,14 @@ IOutputParser::Status IarParser::doHandleLine(const QString &line, OutputFormat
} }
if (!m_lastTask.isNull()) { if (!m_lastTask.isNull()) {
doFlush(); flush();
return Status::Done; return Status::Done;
} }
return Status::NotHandled; return Status::NotHandled;
} }
void IarParser::doFlush() void IarParser::flush()
{ {
if (m_lastTask.isNull()) if (m_lastTask.isNull())
return; return;

View File

@@ -33,7 +33,7 @@ namespace Internal {
// IarParser // IarParser
class IarParser final : public ProjectExplorer::IOutputParser class IarParser final : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -52,8 +52,8 @@ private:
bool parseErrorInCommandLineMessage(const QString &lne); bool parseErrorInCommandLineMessage(const QString &lne);
bool parseErrorMessage1(const QString &lne); bool parseErrorMessage1(const QString &lne);
Status doHandleLine(const QString &line, Utils::OutputFormat type) final; Status handleLine(const QString &line, Utils::OutputFormat type) final;
void doFlush() final; void flush() final;
ProjectExplorer::Task m_lastTask; ProjectExplorer::Task m_lastTask;
int m_lines = 0; int m_lines = 0;

View File

@@ -354,7 +354,7 @@ void IarToolChain::addToEnvironment(Environment &env) const
} }
} }
QList<IOutputParser *> IarToolChain::outputParsers() const QList<OutputTaskParser *> IarToolChain::createOutputParsers() const
{ {
return {new IarParser()}; return {new IarParser()};
} }

View File

@@ -68,7 +68,7 @@ public:
const Utils::FilePath &, const Utils::FilePath &,
const Utils::Environment &env) const final; const Utils::Environment &env) const final;
void addToEnvironment(Utils::Environment &env) const final; void addToEnvironment(Utils::Environment &env) const final;
QList<ProjectExplorer::IOutputParser *> outputParsers() const final; QList<ProjectExplorer::OutputTaskParser *> createOutputParsers() const final;
QVariantMap toMap() const final; QVariantMap toMap() const final;
bool fromMap(const QVariantMap &data) final; bool fromMap(const QVariantMap &data) final;

View File

@@ -66,7 +66,7 @@ Core::Id KeilParser::id()
void KeilParser::newTask(const Task &task) void KeilParser::newTask(const Task &task)
{ {
doFlush(); flush();
m_lastTask = task; m_lastTask = task;
m_lines = 1; m_lines = 1;
} }
@@ -206,7 +206,7 @@ static bool hasDetailsPointer(const QString &trimmedLine)
return trimmedLine.contains('_'); return trimmedLine.contains('_');
} }
IOutputParser::Status KeilParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status KeilParser::handleLine(const QString &line, OutputFormat type)
{ {
QString lne = rightTrimmed(line); QString lne = rightTrimmed(line);
if (type == StdOutFormat) { if (type == StdOutFormat) {
@@ -242,7 +242,7 @@ IOutputParser::Status KeilParser::doHandleLine(const QString &line, OutputFormat
return Status::InProgress; return Status::InProgress;
} }
} }
doFlush(); flush();
return Status::NotHandled; return Status::NotHandled;
} }
@@ -257,11 +257,11 @@ IOutputParser::Status KeilParser::doHandleLine(const QString &line, OutputFormat
return Status::InProgress; return Status::InProgress;
} }
doFlush(); flush();
return Status::NotHandled; return Status::NotHandled;
} }
void KeilParser::doFlush() void KeilParser::flush()
{ {
if (m_lastTask.isNull()) if (m_lastTask.isNull())
return; return;

View File

@@ -33,7 +33,7 @@ namespace Internal {
// KeilParser // KeilParser
class KeilParser final : public ProjectExplorer::IOutputParser class KeilParser final : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -55,8 +55,8 @@ private:
bool parseMcs51WarningOrFatalErrorMessage(const QString &lne); bool parseMcs51WarningOrFatalErrorMessage(const QString &lne);
bool parseMcs51FatalErrorMessage2(const QString &lne); bool parseMcs51FatalErrorMessage2(const QString &lne);
Status doHandleLine(const QString &line, Utils::OutputFormat type) final; Status handleLine(const QString &line, Utils::OutputFormat type) final;
void doFlush() final; void flush() final;
ProjectExplorer::Task m_lastTask; ProjectExplorer::Task m_lastTask;
int m_lines = 0; int m_lines = 0;

View File

@@ -506,7 +506,7 @@ void KeilToolChain::addToEnvironment(Environment &env) const
} }
} }
QList<IOutputParser *> KeilToolChain::outputParsers() const QList<OutputTaskParser *> KeilToolChain::createOutputParsers() const
{ {
return {new KeilParser}; return {new KeilParser};
} }

View File

@@ -69,7 +69,7 @@ public:
const Utils::FilePath &, const Utils::FilePath &,
const Utils::Environment &env) const final; const Utils::Environment &env) const final;
void addToEnvironment(Utils::Environment &env) const final; void addToEnvironment(Utils::Environment &env) const final;
QList<ProjectExplorer::IOutputParser *> outputParsers() const final; QList<ProjectExplorer::OutputTaskParser *> createOutputParsers() const final;
QVariantMap toMap() const final; QVariantMap toMap() const final;
bool fromMap(const QVariantMap &data) final; bool fromMap(const QVariantMap &data) final;

View File

@@ -66,7 +66,7 @@ Core::Id SdccParser::id()
void SdccParser::newTask(const Task &task) void SdccParser::newTask(const Task &task)
{ {
doFlush(); flush();
m_lastTask = task; m_lastTask = task;
m_lines = 1; m_lines = 1;
} }
@@ -87,7 +87,7 @@ void SdccParser::amendDescription(const QString &desc)
++m_lines; ++m_lines;
} }
IOutputParser::Status SdccParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status SdccParser::handleLine(const QString &line, OutputFormat type)
{ {
if (type == StdOutFormat) if (type == StdOutFormat)
return Status::NotHandled; return Status::NotHandled;
@@ -150,11 +150,11 @@ IOutputParser::Status SdccParser::doHandleLine(const QString &line, OutputFormat
return Status::InProgress; return Status::InProgress;
} }
doFlush(); flush();
return Status::NotHandled; return Status::NotHandled;
} }
void SdccParser::doFlush() void SdccParser::flush()
{ {
if (m_lastTask.isNull()) if (m_lastTask.isNull())
return; return;

View File

@@ -33,7 +33,7 @@ namespace Internal {
// SdccParser // SdccParser
class SdccParser final : public ProjectExplorer::IOutputParser class SdccParser final : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -45,8 +45,8 @@ private:
void newTask(const ProjectExplorer::Task &task); void newTask(const ProjectExplorer::Task &task);
void amendDescription(const QString &desc); void amendDescription(const QString &desc);
Status doHandleLine(const QString &line, Utils::OutputFormat type) final; Status handleLine(const QString &line, Utils::OutputFormat type) final;
void doFlush() final; void flush() final;
ProjectExplorer::Task m_lastTask; ProjectExplorer::Task m_lastTask;
int m_lines = 0; int m_lines = 0;

View File

@@ -307,7 +307,7 @@ void SdccToolChain::addToEnvironment(Environment &env) const
} }
} }
QList<IOutputParser *> SdccToolChain::outputParsers() const QList<OutputTaskParser *> SdccToolChain::createOutputParsers() const
{ {
return {new SdccParser}; return {new SdccParser};
} }

View File

@@ -69,7 +69,7 @@ public:
const Utils::FilePath &, const Utils::FilePath &,
const Utils::Environment &env) const final; const Utils::Environment &env) const final;
void addToEnvironment(Utils::Environment &env) const final; void addToEnvironment(Utils::Environment &env) const final;
QList<ProjectExplorer::IOutputParser *> outputParsers() const final; QList<ProjectExplorer::OutputTaskParser *> createOutputParsers() const final;
QVariantMap toMap() const final; QVariantMap toMap() const final;
bool fromMap(const QVariantMap &data) final; bool fromMap(const QVariantMap &data) final;

View File

@@ -57,7 +57,7 @@ void CMakeParser::setSourceDirectory(const QString &sourceDir)
m_sourceDirectory = QDir(sourceDir); m_sourceDirectory = QDir(sourceDir);
} }
IOutputParser::Status CMakeParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status CMakeParser::handleLine(const QString &line, OutputFormat type)
{ {
if (type != StdErrFormat) if (type != StdErrFormat)
return Status::NotHandled; return Status::NotHandled;
@@ -67,7 +67,7 @@ IOutputParser::Status CMakeParser::doHandleLine(const QString &line, OutputForma
case NONE: case NONE:
if (trimmedLine.isEmpty() && !m_lastTask.isNull()) { if (trimmedLine.isEmpty() && !m_lastTask.isNull()) {
if (m_skippedFirstEmptyLine) { if (m_skippedFirstEmptyLine) {
doFlush(); flush();
return Status::InProgress; return Status::InProgress;
} }
m_skippedFirstEmptyLine = true; m_skippedFirstEmptyLine = true;
@@ -100,7 +100,7 @@ IOutputParser::Status CMakeParser::doHandleLine(const QString &line, OutputForma
return Status::InProgress; return Status::InProgress;
} else if (trimmedLine.endsWith(QLatin1String("in cmake code at"))) { } else if (trimmedLine.endsWith(QLatin1String("in cmake code at"))) {
m_expectTripleLineErrorData = LINE_LOCATION; m_expectTripleLineErrorData = LINE_LOCATION;
doFlush(); flush();
const Task::TaskType type = const Task::TaskType type =
trimmedLine.contains(QLatin1String("Error")) ? Task::Error : Task::Warning; trimmedLine.contains(QLatin1String("Error")) ? Task::Error : Task::Warning;
m_lastTask = BuildSystemTask(type, QString()); m_lastTask = BuildSystemTask(type, QString());
@@ -129,7 +129,7 @@ IOutputParser::Status CMakeParser::doHandleLine(const QString &line, OutputForma
m_expectTripleLineErrorData = LINE_DESCRIPTION2; m_expectTripleLineErrorData = LINE_DESCRIPTION2;
else { else {
m_expectTripleLineErrorData = NONE; m_expectTripleLineErrorData = NONE;
doFlush(); flush();
return Status::Done; return Status::Done;
} }
return Status::InProgress; return Status::InProgress;
@@ -137,13 +137,13 @@ IOutputParser::Status CMakeParser::doHandleLine(const QString &line, OutputForma
m_lastTask.description.append(QLatin1Char('\n')); m_lastTask.description.append(QLatin1Char('\n'));
m_lastTask.description.append(trimmedLine); m_lastTask.description.append(trimmedLine);
m_expectTripleLineErrorData = NONE; m_expectTripleLineErrorData = NONE;
doFlush(); flush();
return Status::Done; return Status::Done;
} }
return Status::NotHandled; return Status::NotHandled;
} }
void CMakeParser::doFlush() void CMakeParser::flush()
{ {
if (m_lastTask.isNull()) if (m_lastTask.isNull())
return; return;

View File

@@ -36,7 +36,7 @@
namespace CMakeProjectManager { namespace CMakeProjectManager {
class CMAKE_EXPORT CMakeParser : public ProjectExplorer::IOutputParser class CMAKE_EXPORT CMakeParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -45,8 +45,8 @@ public:
void setSourceDirectory(const QString &sourceDir); void setSourceDirectory(const QString &sourceDir);
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
void doFlush() override; void flush() override;
enum TripleLineError { NONE, LINE_LOCATION, LINE_DESCRIPTION, LINE_DESCRIPTION2 }; enum TripleLineError { NONE, LINE_LOCATION, LINE_DESCRIPTION, LINE_DESCRIPTION2 };

View File

@@ -76,9 +76,7 @@ CMakeProcess::~CMakeProcess()
Core::Reaper::reap(m_process.release()); Core::Reaper::reap(m_process.release());
} }
// Delete issue parser: m_parser.flush();
if (m_parser)
m_parser->flush();
if (m_future) { if (m_future) {
reportCanceled(); reportCanceled();
@@ -88,7 +86,7 @@ CMakeProcess::~CMakeProcess()
void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &arguments) void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &arguments)
{ {
QTC_ASSERT(!m_process && !m_parser && !m_future, return); QTC_ASSERT(!m_process && !m_future, return);
CMakeTool *cmake = parameters.cmakeTool(); CMakeTool *cmake = parameters.cmakeTool();
QTC_ASSERT(parameters.isValid() && cmake, return); QTC_ASSERT(parameters.isValid() && cmake, return);
@@ -98,10 +96,11 @@ void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &
const QString srcDir = parameters.sourceDirectory.toString(); const QString srcDir = parameters.sourceDirectory.toString();
auto parser = std::make_unique<CMakeParser>(); const auto parser = new CMakeParser;
parser->setSourceDirectory(srcDir); parser->setSourceDirectory(srcDir);
m_parser.addLineParser(parser);
QDir source = QDir(srcDir); QDir source = QDir(srcDir);
connect(parser.get(), &IOutputParser::addTask, parser.get(), connect(&m_parser, &IOutputParser::addTask, this,
[source](const Task &task) { [source](const Task &task) {
if (task.file.isEmpty() || task.file.toFileInfo().isAbsolute()) { if (task.file.isEmpty() || task.file.toFileInfo().isAbsolute()) {
TaskHub::addTask(task); TaskHub::addTask(task);
@@ -155,7 +154,6 @@ void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &
process->start(); process->start();
m_process = std::move(process); m_process = std::move(process);
m_parser = std::move(parser);
m_future = std::move(future); m_future = std::move(future);
} }
@@ -201,7 +199,7 @@ void CMakeProcess::processStandardError()
static QString rest; static QString rest;
rest = lineSplit(rest, m_process->readAllStandardError(), [this](const QString &s) { rest = lineSplit(rest, m_process->readAllStandardError(), [this](const QString &s) {
m_parser->handleStderr(s); m_parser.handleStderr(s);
Core::MessageManager::write(s); Core::MessageManager::write(s);
}); });
} }

View File

@@ -70,7 +70,7 @@ private:
void checkForCancelled(); void checkForCancelled();
std::unique_ptr<Utils::QtcProcess> m_process; std::unique_ptr<Utils::QtcProcess> m_process;
std::unique_ptr<ProjectExplorer::IOutputParser> m_parser; ProjectExplorer::IOutputParser m_parser;
std::unique_ptr<QFutureInterface<void>> m_future; std::unique_ptr<QFutureInterface<void>> m_future;
bool m_processWasCanceled = false; bool m_processWasCanceled = false;
QTimer m_cancelTimer; QTimer m_cancelTimer;

View File

@@ -73,7 +73,9 @@ const int MAX_PROGRESS = 1400;
ServerModeReader::ServerModeReader() ServerModeReader::ServerModeReader()
{ {
connect(&m_parser, &CMakeParser::addTask, this, [this](const Task &t) { m_cmakeParser = new CMakeParser;
m_parser.addLineParser(m_cmakeParser);
connect(&m_parser, &IOutputParser::addTask, this, [this](const Task &t) {
Task editable(t); Task editable(t);
if (!editable.file.isEmpty()) { if (!editable.file.isEmpty()) {
QDir srcDir(m_parameters.sourceDirectory.toString()); QDir srcDir(m_parameters.sourceDirectory.toString());
@@ -94,8 +96,7 @@ void ServerModeReader::setParameters(const BuildDirParameters &p)
QTC_ASSERT(cmake, return); QTC_ASSERT(cmake, return);
m_parameters = p; m_parameters = p;
m_cmakeParser->setSourceDirectory(m_parameters.sourceDirectory.toString());
m_parser.setSourceDirectory(m_parameters.sourceDirectory.toString());
createNewServer(); createNewServer();
} }

View File

@@ -180,7 +180,8 @@ private:
QList<Target *> m_targets; QList<Target *> m_targets;
QList<FileGroup *> m_fileGroups; QList<FileGroup *> m_fileGroups;
CMakeParser m_parser; CMakeParser *m_cmakeParser = nullptr;
ProjectExplorer::IOutputParser m_parser;
#if defined(WITH_TESTS) #if defined(WITH_TESTS)
friend class CMakeProjectPlugin; friend class CMakeProjectPlugin;

View File

@@ -43,9 +43,9 @@ using namespace Utils;
namespace { namespace {
class NimParser : public IOutputParser class NimParser : public OutputTaskParser
{ {
Status doHandleLine(const QString &lne, Utils::OutputFormat) override Status handleLine(const QString &lne, Utils::OutputFormat) override
{ {
const QString line = lne.trimmed(); const QString line = lne.trimmed();
static QRegularExpression regex("(.+.nim)\\((\\d+), (\\d+)\\) (.+)", static QRegularExpression regex("(.+.nim)\\((\\d+), (\\d+)\\) (.+)",

View File

@@ -45,9 +45,9 @@ using namespace Utils;
namespace Nim { namespace Nim {
class NimParser : public ProjectExplorer::IOutputParser class NimParser : public ProjectExplorer::OutputTaskParser
{ {
Status doHandleLine(const QString &lne, Utils::OutputFormat) override Status handleLine(const QString &lne, Utils::OutputFormat) override
{ {
const QString line = lne.trimmed(); const QString line = lne.trimmed();
static QRegularExpression regex("(.+.nim)\\((\\d+), (\\d+)\\) (.+)", static QRegularExpression regex("(.+.nim)\\((\\d+), (\\d+)\\) (.+)",

View File

@@ -120,7 +120,7 @@ void NimToolChain::setCompilerCommand(const FilePath &compilerCommand)
parseVersion(compilerCommand, m_version); parseVersion(compilerCommand, m_version);
} }
QList<IOutputParser *> NimToolChain::outputParsers() const QList<OutputTaskParser *> NimToolChain::createOutputParsers() const
{ {
return {}; return {};
} }

View File

@@ -56,7 +56,7 @@ public:
Utils::FilePath compilerCommand() const final; Utils::FilePath compilerCommand() const final;
QString compilerVersion() const; QString compilerVersion() const;
void setCompilerCommand(const Utils::FilePath &compilerCommand); void setCompilerCommand(const Utils::FilePath &compilerCommand);
QList<ProjectExplorer::IOutputParser *> outputParsers() const final; QList<ProjectExplorer::OutputTaskParser *> createOutputParsers() const final;
std::unique_ptr<ProjectExplorer::ToolChainConfigWidget> createConfigurationWidget() final; std::unique_ptr<ProjectExplorer::ToolChainConfigWidget> createConfigurationWidget() final;
QVariantMap toMap() const final; QVariantMap toMap() const final;

View File

@@ -132,7 +132,7 @@ AbstractProcessStep::~AbstractProcessStep()
Deletes all existing output parsers and starts a new chain with the Deletes all existing output parsers and starts a new chain with the
given parser. given parser.
*/ */
void AbstractProcessStep::setOutputParser(IOutputParser *parser) void AbstractProcessStep::setOutputParser(OutputTaskParser *parser)
{ {
d->m_outputParser.setLineParsers({parser}); d->m_outputParser.setLineParsers({parser});
} }
@@ -140,16 +140,16 @@ void AbstractProcessStep::setOutputParser(IOutputParser *parser)
/*! /*!
Appends the given output parser to the existing chain of parsers. Appends the given output parser to the existing chain of parsers.
*/ */
void AbstractProcessStep::appendOutputParser(IOutputParser *parser) void AbstractProcessStep::appendOutputParser(OutputTaskParser *parser)
{ {
if (!parser) if (!parser)
return; return;
d->m_outputParser.addLineParser(parser); d->m_outputParser.addLineParser(parser);
} }
void AbstractProcessStep::appendOutputParsers(const QList<IOutputParser *> &parsers) void AbstractProcessStep::appendOutputParsers(const QList<OutputTaskParser *> &parsers)
{ {
for (IOutputParser * const p : parsers) for (OutputTaskParser * const p : parsers)
appendOutputParser(p); appendOutputParser(p);
} }

View File

@@ -33,6 +33,7 @@ namespace Utils { class FilePath; }
namespace ProjectExplorer { namespace ProjectExplorer {
class IOutputParser; class IOutputParser;
class OutputTaskParser;
class ProcessParameters; class ProcessParameters;
// Documentation inside. // Documentation inside.
@@ -46,9 +47,9 @@ public:
bool ignoreReturnValue(); bool ignoreReturnValue();
void setIgnoreReturnValue(bool b); void setIgnoreReturnValue(bool b);
void setOutputParser(IOutputParser *parser); void setOutputParser(OutputTaskParser *parser);
void appendOutputParser(IOutputParser *parser); void appendOutputParser(OutputTaskParser *parser);
void appendOutputParsers(const QList<IOutputParser *> &parsers); void appendOutputParsers(const QList<OutputTaskParser *> &parsers);
IOutputParser *outputParser() const; IOutputParser *outputParser() const;
void emitFaultyConfigurationMessage(); void emitFaultyConfigurationMessage();

View File

@@ -55,19 +55,19 @@ ClangParser::ClangParser() :
setObjectName(QLatin1String("ClangParser")); setObjectName(QLatin1String("ClangParser"));
} }
QList<IOutputParser *> ClangParser::clangParserSuite() QList<OutputTaskParser *> ClangParser::clangParserSuite()
{ {
return {new ClangParser, new Internal::LldParser, new LdParser}; return {new ClangParser, new Internal::LldParser, new LdParser};
} }
IOutputParser::Status ClangParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status ClangParser::handleLine(const QString &line, OutputFormat type)
{ {
if (type != StdErrFormat) if (type != StdErrFormat)
return Status::NotHandled; return Status::NotHandled;
const QString lne = rightTrimmed(line); const QString lne = rightTrimmed(line);
QRegularExpressionMatch match = m_summaryRegExp.match(lne); QRegularExpressionMatch match = m_summaryRegExp.match(lne);
if (match.hasMatch()) { if (match.hasMatch()) {
doFlush(); flush();
m_expectSnippet = false; m_expectSnippet = false;
return Status::Done; return Status::Done;
} }

View File

@@ -39,12 +39,12 @@ class PROJECTEXPLORER_EXPORT ClangParser : public ProjectExplorer::GccParser
public: public:
ClangParser(); ClangParser();
static QList<IOutputParser *> clangParserSuite(); static QList<OutputTaskParser *> clangParserSuite();
static Core::Id id(); static Core::Id id();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
QRegularExpression m_commandRegExp; QRegularExpression m_commandRegExp;
QRegularExpression m_inLineRegExp; QRegularExpression m_inLineRegExp;

View File

@@ -129,7 +129,7 @@ Core::Id CustomParser::id()
return Core::Id("ProjectExplorer.OutputParser.Custom"); return Core::Id("ProjectExplorer.OutputParser.Custom");
} }
IOutputParser::Status CustomParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status CustomParser::handleLine(const QString &line, OutputFormat type)
{ {
const CustomParserExpression::CustomParserChannel channel = type == StdErrFormat const CustomParserExpression::CustomParserChannel channel = type == StdErrFormat
? CustomParserExpression::ParseStdErrChannel ? CustomParserExpression::ParseStdErrChannel

View File

@@ -81,7 +81,7 @@ public:
CustomParserExpression warning; CustomParserExpression warning;
}; };
class CustomParser : public ProjectExplorer::IOutputParser class CustomParser : public ProjectExplorer::OutputTaskParser
{ {
public: public:
CustomParser(const CustomParserSettings &settings = CustomParserSettings()); CustomParser(const CustomParserSettings &settings = CustomParserSettings());
@@ -91,7 +91,7 @@ public:
static Core::Id id(); static Core::Id id();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
bool hasMatch(const QString &line, CustomParserExpression::CustomParserChannel channel, bool hasMatch(const QString &line, CustomParserExpression::CustomParserChannel channel,
const CustomParserExpression &expression, Task::TaskType taskType); const CustomParserExpression &expression, Task::TaskType taskType);

View File

@@ -196,7 +196,7 @@ QStringList CustomToolChain::suggestedMkspecList() const
return m_mkspecs; return m_mkspecs;
} }
QList<IOutputParser *> CustomToolChain::outputParsers() const QList<OutputTaskParser *> CustomToolChain::createOutputParsers() const
{ {
if (m_outputParserId == GccParser::id()) if (m_outputParserId == GccParser::id())
return GccParser::gccParserSuite(); return GccParser::gccParserSuite();

View File

@@ -84,7 +84,7 @@ public:
const Utils::Environment &env) const override; const Utils::Environment &env) const override;
void addToEnvironment(Utils::Environment &env) const override; void addToEnvironment(Utils::Environment &env) const override;
QStringList suggestedMkspecList() const override; QStringList suggestedMkspecList() const override;
QList<IOutputParser *> outputParsers() const override; QList<OutputTaskParser *> createOutputParsers() const override;
QStringList headerPathsList() const; QStringList headerPathsList() const;
void setHeaderPaths(const QStringList &list); void setHeaderPaths(const QStringList &list);

View File

@@ -66,19 +66,19 @@ Core::Id GccParser::id()
return Core::Id("ProjectExplorer.OutputParser.Gcc"); return Core::Id("ProjectExplorer.OutputParser.Gcc");
} }
QList<IOutputParser *> GccParser::gccParserSuite() QList<OutputTaskParser *> GccParser::gccParserSuite()
{ {
return {new GccParser, new Internal::LldParser, new LdParser}; return {new GccParser, new Internal::LldParser, new LdParser};
} }
void GccParser::newTask(const Task &task) void GccParser::newTask(const Task &task)
{ {
doFlush(); flush();
m_currentTask = task; m_currentTask = task;
m_lines = 1; m_lines = 1;
} }
void GccParser::doFlush() void GccParser::flush()
{ {
if (m_currentTask.isNull()) if (m_currentTask.isNull())
return; return;
@@ -107,12 +107,12 @@ void GccParser::amendDescription(const QString &desc, bool monospaced)
return; return;
} }
IOutputParser::Status GccParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status GccParser::handleLine(const QString &line, OutputFormat type)
{ {
if (type == StdOutFormat) { if (type == StdOutFormat) {
// TODO: The "flush on channel switch" logic could possibly also done centrally. // TODO: The "flush on channel switch" logic could possibly also done centrally.
// But see MSVC with the stdout/stderr switches because of jom // But see MSVC with the stdout/stderr switches because of jom
doFlush(); flush();
return Status::NotHandled; return Status::NotHandled;
} }
@@ -177,7 +177,7 @@ IOutputParser::Status GccParser::doHandleLine(const QString &line, OutputFormat
return Status::InProgress; return Status::InProgress;
} }
doFlush(); flush();
return Status::NotHandled; return Status::NotHandled;
} }

View File

@@ -33,7 +33,7 @@
namespace ProjectExplorer { namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT GccParser : public ProjectExplorer::IOutputParser class PROJECTEXPLORER_EXPORT GccParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -42,16 +42,16 @@ public:
static Core::Id id(); static Core::Id id();
static QList<IOutputParser *> gccParserSuite(); static QList<OutputTaskParser *> gccParserSuite();
protected: protected:
void newTask(const Task &task); void newTask(const Task &task);
void doFlush() override; void flush() override;
void amendDescription(const QString &desc, bool monospaced); void amendDescription(const QString &desc, bool monospaced);
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
QRegularExpression m_regExp; QRegularExpression m_regExp;
QRegularExpression m_regExpIncluded; QRegularExpression m_regExpIncluded;

View File

@@ -731,7 +731,7 @@ FilePath GccToolChain::makeCommand(const Environment &environment) const
return tmp.isEmpty() ? FilePath::fromString("make") : tmp; return tmp.isEmpty() ? FilePath::fromString("make") : tmp;
} }
QList<IOutputParser *> GccToolChain::outputParsers() const QList<OutputTaskParser *> GccToolChain::createOutputParsers() const
{ {
return GccParser::gccParserSuite(); return GccParser::gccParserSuite();
} }
@@ -1628,7 +1628,7 @@ LanguageExtensions ClangToolChain::defaultLanguageExtensions() const
return LanguageExtension::Gnu; return LanguageExtension::Gnu;
} }
QList<IOutputParser *> ClangToolChain::outputParsers() const QList<OutputTaskParser *> ClangToolChain::createOutputParsers() const
{ {
return ClangParser::clangParserSuite(); return ClangParser::clangParserSuite();
} }
@@ -1898,7 +1898,7 @@ LanguageExtensions LinuxIccToolChain::languageExtensions(const QStringList &cxxf
return extensions; return extensions;
} }
QList<IOutputParser *> LinuxIccToolChain::outputParsers() const QList<OutputTaskParser *> LinuxIccToolChain::createOutputParsers() const
{ {
return LinuxIccParser::iccParserSuite(); return LinuxIccParser::iccParserSuite();
} }

View File

@@ -94,7 +94,7 @@ public:
void addToEnvironment(Utils::Environment &env) const override; void addToEnvironment(Utils::Environment &env) const override;
Utils::FilePath makeCommand(const Utils::Environment &environment) const override; Utils::FilePath makeCommand(const Utils::Environment &environment) const override;
QStringList suggestedMkspecList() const override; QStringList suggestedMkspecList() const override;
QList<IOutputParser *> outputParsers() const override; QList<OutputTaskParser *> createOutputParsers() const override;
QVariantMap toMap() const override; QVariantMap toMap() const override;
bool fromMap(const QVariantMap &data) override; bool fromMap(const QVariantMap &data) override;
@@ -226,7 +226,7 @@ public:
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override; Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
Utils::WarningFlags warningFlags(const QStringList &cflags) const override; Utils::WarningFlags warningFlags(const QStringList &cflags) const override;
QList<IOutputParser *> outputParsers() const override; QList<OutputTaskParser *> createOutputParsers() const override;
QStringList suggestedMkspecList() const override; QStringList suggestedMkspecList() const override;
void addToEnvironment(Utils::Environment &env) const override; void addToEnvironment(Utils::Environment &env) const override;
@@ -286,7 +286,7 @@ class PROJECTEXPLORER_EXPORT LinuxIccToolChain : public GccToolChain
public: public:
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override; Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
QList<IOutputParser *> outputParsers() const override; QList<OutputTaskParser *> createOutputParsers() const override;
QStringList suggestedMkspecList() const override; QStringList suggestedMkspecList() const override;

View File

@@ -103,16 +103,16 @@ void GnuMakeParser::emitTask(const ProjectExplorer::Task &task)
emit addTask(task, 1, 0); emit addTask(task, 1, 0);
} }
IOutputParser::Status GnuMakeParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status GnuMakeParser::handleLine(const QString &line, OutputFormat type)
{ {
const QString lne = rightTrimmed(line); const QString lne = rightTrimmed(line);
if (type == StdOutFormat) { if (type == StdOutFormat) {
QRegularExpressionMatch match = m_makeDir.match(lne); QRegularExpressionMatch match = m_makeDir.match(lne);
if (match.hasMatch()) { if (match.hasMatch()) {
if (match.captured(6) == QLatin1String("Leaving")) if (match.captured(6) == QLatin1String("Leaving"))
emit searchDirOut(FilePath::fromString(match.captured(7))); emit searchDirExpired(FilePath::fromString(match.captured(7)));
else else
emit searchDirIn(FilePath::fromString(match.captured(7))); emit newSearchDir(FilePath::fromString(match.captured(7)));
return Status::Done; return Status::Done;
} }
return Status::NotHandled; return Status::NotHandled;
@@ -144,7 +144,7 @@ IOutputParser::Status GnuMakeParser::doHandleLine(const QString &line, OutputFor
bool GnuMakeParser::hasFatalErrors() const bool GnuMakeParser::hasFatalErrors() const
{ {
return (m_fatalErrorCount > 0) || IOutputParser::hasFatalErrors(); return m_fatalErrorCount > 0;
} }
} // ProjectExplorer } // ProjectExplorer
@@ -365,7 +365,7 @@ void ProjectExplorerPlugin::testGnuMakeParserParsing()
QFETCH(QString, outputLines); QFETCH(QString, outputLines);
QFETCH(QStringList, additionalSearchDirs); QFETCH(QStringList, additionalSearchDirs);
FilePaths searchDirs = testbench.searchDirectories(); FilePaths searchDirs = childParser->searchDirectories();
// add extra directories: // add extra directories:
foreach (const QString &dir, extraSearchDirs) foreach (const QString &dir, extraSearchDirs)

View File

@@ -32,7 +32,7 @@
namespace ProjectExplorer { namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT GnuMakeParser : public ProjectExplorer::IOutputParser class PROJECTEXPLORER_EXPORT GnuMakeParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -40,7 +40,7 @@ public:
explicit GnuMakeParser(); explicit GnuMakeParser();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
bool hasFatalErrors() const override; bool hasFatalErrors() const override;
void emitTask(const ProjectExplorer::Task &task); void emitTask(const ProjectExplorer::Task &task);

View File

@@ -33,48 +33,127 @@
#include <QFileInfo> #include <QFileInfo>
#include <QPointer> #include <QPointer>
/*!
\class ProjectExplorer::IOutputParser
\brief The IOutputParser class provides an interface for an output parser /*!
\class ProjectExplorer::OutputTaskParser
\brief The OutputTaskParser class provides an interface for an output parser
that emits issues (tasks). that emits issues (tasks).
\sa ProjectExplorer::Task \sa ProjectExplorer::Task
*/ */
/*! /*!
\fn ProjectExplorer::IOutputParser::Status ProjectExplorer::IOutputParser::doHandleLine(const QString &line, Utils::OutputFormat type) \fn ProjectExplorer::OutputTaskParser::Status ProjectExplorer::OutputTaskParser::handleLine(const QString &line, Utils::OutputFormat type)
Called once for each line of standard output or standard error to parse. Called once for each line of standard output or standard error to parse.
*/ */
/*! /*!
\fn bool ProjectExplorer::IOutputParser::hasFatalErrors() const \fn bool ProjectExplorer::OutputTaskParser::hasFatalErrors() const
This is mainly a Symbian specific quirk. This is mainly a Symbian specific quirk.
*/ */
/*! /*!
\fn void ProjectExplorer::IOutputParser::addTask(const ProjectExplorer::Task &task) \fn void ProjectExplorer::OutputTaskParser::addTask(const ProjectExplorer::Task &task)
Should be emitted for each task seen in the output. Should be emitted for each task seen in the output.
*/ */
/*! /*!
\fn void ProjectExplorer::IOutputParser::doFlush() \fn void ProjectExplorer::OutputTaskParser::flush()
Instructs a parser to flush its state. Instructs a parser to flush its state.
Parsers may have state (for example, because they need to aggregate several Parsers may have state (for example, because they need to aggregate several
lines into one task). This lines into one task). This
function is called when this state needs to be flushed out to be visible. function is called when this state needs to be flushed out to be visible.
doFlush() is called by flush(). flush() is called on child parsers
whenever a new task is added.
It is also called once when all input has been parsed.
*/ */
namespace ProjectExplorer { namespace ProjectExplorer {
class OutputTaskParser::Private
{
public:
Utils::FilePaths searchDirs;
QPointer<const OutputTaskParser> redirectionDetector;
bool skipFileExistsCheck = false;
};
OutputTaskParser::OutputTaskParser() : d(new Private)
{
}
OutputTaskParser::~OutputTaskParser() { delete d; }
void OutputTaskParser::addSearchDir(const Utils::FilePath &dir)
{
d->searchDirs << dir;
}
void OutputTaskParser::dropSearchDir(const Utils::FilePath &dir)
{
const int idx = d->searchDirs.lastIndexOf(dir);
// TODO: This apparently triggers. Find out why and either remove the assertion (if it's legit)
// or fix the culprit.
QTC_ASSERT(idx != -1, return);
d->searchDirs.removeAt(idx);
}
const Utils::FilePaths OutputTaskParser::searchDirectories() const
{
return d->searchDirs;
}
// The redirection mechanism is needed for broken build tools (e.g. xcodebuild) that get invoked
// indirectly as part of the build process and redirect their child processes' stderr output
// to stdout. A parser might be able to detect this condition and inform interested
// other parsers that they need to interpret stdout data as stderr.
void OutputTaskParser::setRedirectionDetector(const OutputTaskParser *detector)
{
d->redirectionDetector = detector;
}
bool OutputTaskParser::needsRedirection() const
{
return d->redirectionDetector && (d->redirectionDetector->hasDetectedRedirection()
|| d->redirectionDetector->needsRedirection());
}
Utils::FilePath OutputTaskParser::absoluteFilePath(const Utils::FilePath &filePath)
{
if (filePath.isEmpty() || filePath.toFileInfo().isAbsolute())
return filePath;
Utils::FilePaths candidates;
for (const Utils::FilePath &dir : searchDirectories()) {
const Utils::FilePath candidate = dir.pathAppended(filePath.toString());
if (candidate.exists() || d->skipFileExistsCheck)
candidates << candidate;
}
if (candidates.count() == 1)
return Utils::FilePath::fromString(QDir::cleanPath(candidates.first().toString()));
return filePath;
}
QString OutputTaskParser::rightTrimmed(const QString &in)
{
int pos = in.length();
for (; pos > 0; --pos) {
if (!in.at(pos - 1).isSpace())
break;
}
return in.mid(0, pos);
}
#ifdef WITH_TESTS
void OutputTaskParser::skipFileExistsCheck()
{
d->skipFileExistsCheck = true;
}
#endif
class IOutputParser::OutputChannelState class IOutputParser::OutputChannelState
{ {
public: public:
@@ -118,14 +197,11 @@ public:
stderrState(parser, Utils::StdErrFormat) stderrState(parser, Utils::StdErrFormat)
{} {}
QList<IOutputParser *> lineParsers; QList<OutputTaskParser *> lineParsers;
IOutputParser *nextParser = nullptr; OutputTaskParser *nextParser = nullptr;
QList<Filter> filters; QList<Filter> filters;
Utils::FilePaths searchDirs;
OutputChannelState stdoutState; OutputChannelState stdoutState;
OutputChannelState stderrState; OutputChannelState stderrState;
QPointer<const IOutputParser> redirectionDetector;
bool skipFileExistsCheck = false;
}; };
IOutputParser::IOutputParser() : d(new IOutputParserPrivate(this)) IOutputParser::IOutputParser() : d(new IOutputParserPrivate(this))
@@ -148,39 +224,30 @@ void IOutputParser::handleStderr(const QString &data)
d->stderrState.handleData(data); d->stderrState.handleData(data);
} }
IOutputParser::Status IOutputParser::doHandleLine(const QString &line, Utils::OutputFormat type)
{
Q_UNUSED(line);
Q_UNUSED(type);
return Status::NotHandled;
}
void IOutputParser::doFlush() { }
void IOutputParser::handleLine(const QString &line, Utils::OutputFormat type) void IOutputParser::handleLine(const QString &line, Utils::OutputFormat type)
{ {
const QString cleanLine = filteredLine(line); const QString cleanLine = filteredLine(line);
if (d->nextParser) { if (d->nextParser) {
switch (d->nextParser->doHandleLine(cleanLine, outputTypeForParser(d->nextParser, type))) { switch (d->nextParser->handleLine(cleanLine, outputTypeForParser(d->nextParser, type))) {
case Status::Done: case OutputTaskParser::Status::Done:
d->nextParser = nullptr; d->nextParser = nullptr;
return; return;
case Status::InProgress: case OutputTaskParser::Status::InProgress:
return; return;
case Status::NotHandled: case OutputTaskParser::Status::NotHandled:
d->nextParser = nullptr; d->nextParser = nullptr;
break; break;
} }
} }
QTC_CHECK(!d->nextParser); QTC_CHECK(!d->nextParser);
for (IOutputParser * const lineParser : d->lineParsers) { for (OutputTaskParser * const lineParser : d->lineParsers) {
switch (lineParser->doHandleLine(cleanLine, outputTypeForParser(lineParser, type))) { switch (lineParser->handleLine(cleanLine, outputTypeForParser(lineParser, type))) {
case Status::Done: case OutputTaskParser::Status::Done:
return; return;
case Status::InProgress: case OutputTaskParser::Status::InProgress:
d->nextParser = lineParser; d->nextParser = lineParser;
return; return;
case Status::NotHandled: case OutputTaskParser::Status::NotHandled:
break; break;
} }
} }
@@ -194,52 +261,51 @@ QString IOutputParser::filteredLine(const QString &line) const
return l; return l;
} }
void IOutputParser::connectLineParser(IOutputParser *parser) void IOutputParser::connectLineParser(OutputTaskParser *parser)
{ {
connect(parser, &IOutputParser::addTask, this, &IOutputParser::addTask); connect(parser, &OutputTaskParser::addTask, this, &IOutputParser::addTask);
connect(parser, &IOutputParser::searchDirIn, this, &IOutputParser::addSearchDir); connect(parser, &OutputTaskParser::newSearchDir, this, &IOutputParser::addSearchDir);
connect(parser, &IOutputParser::searchDirOut, this, &IOutputParser::dropSearchDir); connect(parser, &OutputTaskParser::searchDirExpired, this, &IOutputParser::dropSearchDir);
} }
bool IOutputParser::hasFatalErrors() const bool IOutputParser::hasFatalErrors() const
{ {
return Utils::anyOf(d->lineParsers, [](const IOutputParser *p) { return p->hasFatalErrors(); }); return Utils::anyOf(d->lineParsers, [](const OutputTaskParser *p) {
return p->hasFatalErrors();
});
} }
void IOutputParser::flush() void IOutputParser::flush()
{ {
d->stdoutState.flush(); d->stdoutState.flush();
d->stderrState.flush(); d->stderrState.flush();
doFlush(); for (OutputTaskParser * const p : qAsConst(d->lineParsers))
for (IOutputParser * const p : qAsConst(d->lineParsers)) p->flush();
p->doFlush();
} }
void IOutputParser::clear() void IOutputParser::clear()
{ {
d->nextParser = nullptr; d->nextParser = nullptr;
d->redirectionDetector.clear();
d->filters.clear(); d->filters.clear();
d->searchDirs.clear();
qDeleteAll(d->lineParsers); qDeleteAll(d->lineParsers);
d->lineParsers.clear(); d->lineParsers.clear();
d->stdoutState.pendingData.clear(); d->stdoutState.pendingData.clear();
d->stderrState.pendingData.clear(); d->stderrState.pendingData.clear();
} }
void IOutputParser::addLineParser(IOutputParser *parser) void IOutputParser::addLineParser(OutputTaskParser *parser)
{ {
connectLineParser(parser); connectLineParser(parser);
d->lineParsers << parser; d->lineParsers << parser;
} }
void IOutputParser::addLineParsers(const QList<IOutputParser *> &parsers) void IOutputParser::addLineParsers(const QList<OutputTaskParser *> &parsers)
{ {
for (IOutputParser * const p : qAsConst(parsers)) for (OutputTaskParser * const p : qAsConst(parsers))
addLineParser(p); addLineParser(p);
} }
void IOutputParser::setLineParsers(const QList<IOutputParser *> &parsers) void IOutputParser::setLineParsers(const QList<OutputTaskParser *> &parsers)
{ {
qDeleteAll(d->lineParsers); qDeleteAll(d->lineParsers);
d->lineParsers.clear(); d->lineParsers.clear();
@@ -247,27 +313,12 @@ void IOutputParser::setLineParsers(const QList<IOutputParser *> &parsers)
} }
#ifdef WITH_TESTS #ifdef WITH_TESTS
QList<IOutputParser *> IOutputParser::lineParsers() const QList<OutputTaskParser *> IOutputParser::lineParsers() const
{ {
return d->lineParsers; return d->lineParsers;
} }
void IOutputParser::skipFileExistsCheck()
{
d->skipFileExistsCheck = true;
}
#endif // WITH_TESTS #endif // WITH_TESTS
QString IOutputParser::rightTrimmed(const QString &in)
{
int pos = in.length();
for (; pos > 0; --pos) {
if (!in.at(pos - 1).isSpace())
break;
}
return in.mid(0, pos);
}
void IOutputParser::addFilter(const Filter &filter) void IOutputParser::addFilter(const Filter &filter)
{ {
d->filters << filter; d->filters << filter;
@@ -275,56 +326,17 @@ void IOutputParser::addFilter(const Filter &filter)
void IOutputParser::addSearchDir(const Utils::FilePath &dir) void IOutputParser::addSearchDir(const Utils::FilePath &dir)
{ {
d->searchDirs << dir; for (OutputTaskParser * const p : qAsConst(d->lineParsers))
for (IOutputParser * const p : qAsConst(d->lineParsers))
p->addSearchDir(dir); p->addSearchDir(dir);
} }
void IOutputParser::dropSearchDir(const Utils::FilePath &dir) void IOutputParser::dropSearchDir(const Utils::FilePath &dir)
{ {
const int idx = d->searchDirs.lastIndexOf(dir); for (OutputTaskParser * const p : qAsConst(d->lineParsers))
QTC_ASSERT(idx != -1, return);
d->searchDirs.removeAt(idx);
for (IOutputParser * const p : qAsConst(d->lineParsers))
p->dropSearchDir(dir); p->dropSearchDir(dir);
} }
const Utils::FilePaths IOutputParser::searchDirectories() const Utils::OutputFormat IOutputParser::outputTypeForParser(const OutputTaskParser *parser,
{
return d->searchDirs;
}
Utils::FilePath IOutputParser::absoluteFilePath(const Utils::FilePath &filePath)
{
if (filePath.isEmpty() || filePath.toFileInfo().isAbsolute())
return filePath;
Utils::FilePaths candidates;
for (const Utils::FilePath &dir : searchDirectories()) {
const Utils::FilePath candidate = dir.pathAppended(filePath.toString());
if (candidate.exists() || d->skipFileExistsCheck)
candidates << candidate;
}
if (candidates.count() == 1)
return Utils::FilePath::fromString(QDir::cleanPath(candidates.first().toString()));
return filePath;
}
// The redirection mechanism is needed for broken build tools (e.g. xcodebuild) that get invoked
// indirectly as part of the build process and redirect their child processes' stderr output
// to stdout. A parser might be able to detect this condition and inform interested
// other parsers that they need to interpret stdout data as stderr.
void IOutputParser::setRedirectionDetector(const IOutputParser *detector)
{
d->redirectionDetector = detector;
}
bool IOutputParser::needsRedirection() const
{
return d->redirectionDetector && (d->redirectionDetector->hasDetectedRedirection()
|| d->redirectionDetector->needsRedirection());
}
Utils::OutputFormat IOutputParser::outputTypeForParser(const IOutputParser *parser,
Utils::OutputFormat type) const Utils::OutputFormat type) const
{ {
if (type == Utils::StdOutFormat && parser->needsRedirection()) if (type == Utils::StdOutFormat && parser->needsRedirection())

View File

@@ -36,6 +36,45 @@
namespace ProjectExplorer { namespace ProjectExplorer {
class Task; class Task;
class PROJECTEXPLORER_EXPORT OutputTaskParser : public QObject
{
Q_OBJECT
public:
OutputTaskParser();
~OutputTaskParser() override;
void addSearchDir(const Utils::FilePath &dir);
void dropSearchDir(const Utils::FilePath &dir);
const Utils::FilePaths searchDirectories() const;
enum class Status { Done, InProgress, NotHandled };
virtual Status handleLine(const QString &line, Utils::OutputFormat type) = 0;
virtual bool hasFatalErrors() const { return false; }
virtual void flush() {}
void setRedirectionDetector(const OutputTaskParser *detector);
bool needsRedirection() const;
virtual bool hasDetectedRedirection() const { return false; }
#ifdef WITH_TESTS
void skipFileExistsCheck();
#endif
signals:
void newSearchDir(const Utils::FilePath &dir);
void searchDirExpired(const Utils::FilePath &dir);
void addTask(const ProjectExplorer::Task &task, int linkedOutputLines = 0, int skipLines = 0);
protected:
static QString rightTrimmed(const QString &in);
Utils::FilePath absoluteFilePath(const Utils::FilePath &filePath);
private:
class Private;
Private * const d;
};
// Documentation inside. // Documentation inside.
class PROJECTEXPLORER_EXPORT IOutputParser : public QObject class PROJECTEXPLORER_EXPORT IOutputParser : public QObject
{ {
@@ -47,51 +86,34 @@ public:
void handleStdout(const QString &data); void handleStdout(const QString &data);
void handleStderr(const QString &data); void handleStderr(const QString &data);
virtual bool hasFatalErrors() const; bool hasFatalErrors() const;
using Filter = std::function<QString(const QString &)>; using Filter = std::function<QString(const QString &)>;
void addFilter(const Filter &filter); void addFilter(const Filter &filter);
// Forwards to line parsers. Add those before.
void addSearchDir(const Utils::FilePath &dir); void addSearchDir(const Utils::FilePath &dir);
void dropSearchDir(const Utils::FilePath &dir); void dropSearchDir(const Utils::FilePath &dir);
const Utils::FilePaths searchDirectories() const;
void flush(); void flush();
void clear(); void clear();
void addLineParser(IOutputParser *parser); void addLineParser(OutputTaskParser *parser);
void addLineParsers(const QList<IOutputParser *> &parsers); void addLineParsers(const QList<OutputTaskParser *> &parsers);
void setLineParsers(const QList<IOutputParser *> &parsers); void setLineParsers(const QList<OutputTaskParser *> &parsers);
#ifdef WITH_TESTS #ifdef WITH_TESTS
QList<IOutputParser *> lineParsers() const; QList<OutputTaskParser *> lineParsers() const;
void skipFileExistsCheck();
#endif #endif
void setRedirectionDetector(const IOutputParser *detector);
static QString rightTrimmed(const QString &in);
signals: signals:
void searchDirIn(const Utils::FilePath &dir);
void searchDirOut(const Utils::FilePath &dir);
void addTask(const ProjectExplorer::Task &task, int linkedOutputLines = 0, int skipLines = 0); void addTask(const ProjectExplorer::Task &task, int linkedOutputLines = 0, int skipLines = 0);
protected:
enum class Status { Done, InProgress, NotHandled };
Utils::FilePath absoluteFilePath(const Utils::FilePath &filePath);
private: private:
virtual Status doHandleLine(const QString &line, Utils::OutputFormat type);
virtual void doFlush();
virtual bool hasDetectedRedirection() const { return false; }
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(IOutputParser *parser); void connectLineParser(OutputTaskParser *parser);
bool needsRedirection() const; Utils::OutputFormat outputTypeForParser(const OutputTaskParser *parser,
Utils::OutputFormat outputTypeForParser(const IOutputParser *parser,
Utils::OutputFormat type) const; Utils::OutputFormat type) const;
class OutputChannelState; class OutputChannelState;

View File

@@ -559,9 +559,9 @@ void Kit::addToEnvironment(Environment &env) const
aspect->addToEnvironment(this, env); aspect->addToEnvironment(this, env);
} }
QList<IOutputParser *> Kit::createOutputParsers() const QList<OutputTaskParser *> Kit::createOutputParsers() const
{ {
QList<IOutputParser *> parsers{new OsParser}; QList<OutputTaskParser *> parsers{new OsParser};
for (KitAspect *aspect : KitManager::kitAspects()) for (KitAspect *aspect : KitManager::kitAspects())
parsers << aspect->createOutputParsers(this); parsers << aspect->createOutputParsers(this);
return parsers; return parsers;

View File

@@ -41,7 +41,7 @@ class MacroExpander;
} // namespace Utils } // namespace Utils
namespace ProjectExplorer { namespace ProjectExplorer {
class IOutputParser; class OutputTaskParser;
namespace Internal { namespace Internal {
class KitManagerPrivate; class KitManagerPrivate;
@@ -116,7 +116,7 @@ public:
bool isEqual(const Kit *other) const; bool isEqual(const Kit *other) const;
void addToEnvironment(Utils::Environment &env) const; void addToEnvironment(Utils::Environment &env) const;
QList<IOutputParser *> createOutputParsers() const; QList<OutputTaskParser *> createOutputParsers() const;
QString toHtml(const Tasks &additional = Tasks(), const QString &extraText = QString()) const; QString toHtml(const Tasks &additional = Tasks(), const QString &extraText = QString()) const;
Kit *clone(bool keepName = false) const; Kit *clone(bool keepName = false) const;

View File

@@ -557,11 +557,11 @@ void ToolChainKitAspect::addToMacroExpander(Kit *kit, Utils::MacroExpander *expa
}); });
} }
QList<IOutputParser *> ToolChainKitAspect::createOutputParsers(const Kit *k) const QList<OutputTaskParser *> ToolChainKitAspect::createOutputParsers(const Kit *k) const
{ {
for (const Core::Id langId : {Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID}) { for (const Core::Id langId : {Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID}) {
if (const ToolChain * const tc = toolChain(k, langId)) if (const ToolChain * const tc = toolChain(k, langId))
return tc->outputParsers(); return tc->createOutputParsers();
} }
return {}; return {};
} }

View File

@@ -35,6 +35,7 @@
#include <QVariant> #include <QVariant>
namespace ProjectExplorer { namespace ProjectExplorer {
class OutputTaskParser;
class ToolChain; class ToolChain;
class KitAspectWidget; class KitAspectWidget;
@@ -84,7 +85,7 @@ public:
void addToEnvironment(const Kit *k, Utils::Environment &env) const override; void addToEnvironment(const Kit *k, Utils::Environment &env) const override;
void addToMacroExpander(Kit *kit, Utils::MacroExpander *expander) const override; void addToMacroExpander(Kit *kit, Utils::MacroExpander *expander) const override;
QList<IOutputParser *> createOutputParsers(const Kit *k) const override; QList<OutputTaskParser *> createOutputParsers(const Kit *k) const override;
QSet<Core::Id> availableFeatures(const Kit *k) const override; QSet<Core::Id> availableFeatures(const Kit *k) const override;
static Core::Id id(); static Core::Id id();

View File

@@ -677,7 +677,7 @@ void KitAspect::addToEnvironment(const Kit *k, Environment &env) const
Q_UNUSED(env) Q_UNUSED(env)
} }
QList<IOutputParser *> KitAspect::createOutputParsers(const Kit *k) const QList<OutputTaskParser *> KitAspect::createOutputParsers(const Kit *k) const
{ {
Q_UNUSED(k) Q_UNUSED(k)
return {}; return {};

View File

@@ -46,7 +46,7 @@ class MacroExpander;
namespace ProjectExplorer { namespace ProjectExplorer {
class Task; class Task;
class IOutputParser; class OutputTaskParser;
class KitAspectWidget; class KitAspectWidget;
class KitManager; class KitManager;
@@ -91,7 +91,7 @@ public:
virtual KitAspectWidget *createConfigWidget(Kit *) const = 0; virtual KitAspectWidget *createConfigWidget(Kit *) const = 0;
virtual void addToEnvironment(const Kit *k, Utils::Environment &env) const; virtual void addToEnvironment(const Kit *k, Utils::Environment &env) const;
virtual QList<IOutputParser *> createOutputParsers(const Kit *k) const; virtual QList<OutputTaskParser *> createOutputParsers(const Kit *k) const;
virtual QString displayNamePostfix(const Kit *k) const; virtual QString displayNamePostfix(const Kit *k) const;

View File

@@ -54,14 +54,14 @@ LdParser::LdParser()
QTC_CHECK(m_regExpGccNames.isValid()); QTC_CHECK(m_regExpGccNames.isValid());
} }
IOutputParser::Status LdParser::doHandleLine(const QString &line, Utils::OutputFormat type) OutputTaskParser::Status LdParser::handleLine(const QString &line, Utils::OutputFormat type)
{ {
if (type != Utils::StdErrFormat) if (type != Utils::StdErrFormat)
return Status::NotHandled; return Status::NotHandled;
QString lne = rightTrimmed(line); QString lne = rightTrimmed(line);
if (!lne.isEmpty() && !lne.at(0).isSpace() && !m_incompleteTask.isNull()) { if (!lne.isEmpty() && !lne.at(0).isSpace() && !m_incompleteTask.isNull()) {
doFlush(); flush();
return Status::NotHandled; return Status::NotHandled;
} }
@@ -144,7 +144,7 @@ IOutputParser::Status LdParser::doHandleLine(const QString &line, Utils::OutputF
return Status::NotHandled; return Status::NotHandled;
} }
void LdParser::doFlush() void LdParser::flush()
{ {
if (m_incompleteTask.isNull()) if (m_incompleteTask.isNull())
return; return;

View File

@@ -32,15 +32,15 @@
namespace ProjectExplorer { namespace ProjectExplorer {
class LdParser : public ProjectExplorer::IOutputParser class LdParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
public: public:
LdParser(); LdParser();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
void doFlush() override; void flush() override;
QRegularExpression m_ranlib; QRegularExpression m_ranlib;
QRegularExpression m_regExpLinker; QRegularExpression m_regExpLinker;

View File

@@ -65,7 +65,7 @@ LinuxIccParser::LinuxIccParser() :
QTC_CHECK(m_pchInfoLine.isValid()); QTC_CHECK(m_pchInfoLine.isValid());
} }
IOutputParser::Status LinuxIccParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status LinuxIccParser::handleLine(const QString &line, OutputFormat type)
{ {
if (type != Utils::StdErrFormat) if (type != Utils::StdErrFormat)
return Status::NotHandled; return Status::NotHandled;
@@ -129,12 +129,12 @@ Core::Id LinuxIccParser::id()
return Core::Id("ProjectExplorer.OutputParser.Icc"); return Core::Id("ProjectExplorer.OutputParser.Icc");
} }
QList<IOutputParser *> LinuxIccParser::iccParserSuite() QList<OutputTaskParser *> LinuxIccParser::iccParserSuite()
{ {
return {new LinuxIccParser, new Internal::LldParser, new LdParser}; return {new LinuxIccParser, new Internal::LldParser, new LdParser};
} }
void LinuxIccParser::doFlush() void LinuxIccParser::flush()
{ {
if (m_temporary.isNull()) if (m_temporary.isNull())
return; return;

View File

@@ -32,7 +32,7 @@
namespace ProjectExplorer { namespace ProjectExplorer {
class LinuxIccParser : public ProjectExplorer::IOutputParser class LinuxIccParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -41,11 +41,11 @@ public:
static Core::Id id(); static Core::Id id();
static QList<IOutputParser *> iccParserSuite(); static QList<OutputTaskParser *> iccParserSuite();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
void doFlush() override; void flush() override;
QRegExp m_firstLine; QRegExp m_firstLine;
QRegExp m_continuationLines; QRegExp m_continuationLines;

View File

@@ -35,7 +35,7 @@
namespace ProjectExplorer { namespace ProjectExplorer {
namespace Internal { namespace Internal {
IOutputParser::Status LldParser::doHandleLine(const QString &line, Utils::OutputFormat type) OutputTaskParser::Status LldParser::handleLine(const QString &line, Utils::OutputFormat type)
{ {
if (type != Utils::StdErrFormat) if (type != Utils::StdErrFormat)
return Status::NotHandled; return Status::NotHandled;

View File

@@ -30,9 +30,9 @@
namespace ProjectExplorer { namespace ProjectExplorer {
namespace Internal { namespace Internal {
class LldParser : public IOutputParser class LldParser : public OutputTaskParser
{ {
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -105,7 +105,7 @@ Core::Id MsvcParser::id()
return Core::Id("ProjectExplorer.OutputParser.Msvc"); return Core::Id("ProjectExplorer.OutputParser.Msvc");
} }
IOutputParser::Status MsvcParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status MsvcParser::handleLine(const QString &line, OutputFormat type)
{ {
if (type == OutputFormat::StdOutFormat) { if (type == OutputFormat::StdOutFormat) {
QRegularExpressionMatch match = m_additionalInfoRegExp.match(line); QRegularExpressionMatch match = m_additionalInfoRegExp.match(line);
@@ -169,7 +169,7 @@ IOutputParser::Status MsvcParser::doHandleLine(const QString &line, OutputFormat
bool MsvcParser::processCompileLine(const QString &line) bool MsvcParser::processCompileLine(const QString &line)
{ {
doFlush(); flush();
QRegularExpressionMatch match = m_compileRegExp.match(line); QRegularExpressionMatch match = m_compileRegExp.match(line);
if (match.hasMatch()) { if (match.hasMatch()) {
@@ -183,7 +183,7 @@ bool MsvcParser::processCompileLine(const QString &line)
return false; return false;
} }
void MsvcParser::doFlush() void MsvcParser::flush()
{ {
if (m_lastTask.isNull()) if (m_lastTask.isNull())
return; return;
@@ -220,39 +220,39 @@ static inline bool isClangCodeMarker(const QString &trimmedLine)
[] (QChar c) { return c != ' ' && c != '^' && c != '~'; }); [] (QChar c) { return c != ' ' && c != '^' && c != '~'; });
} }
IOutputParser::Status ClangClParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status ClangClParser::handleLine(const QString &line, OutputFormat type)
{ {
if (type == StdOutFormat) { if (type == StdOutFormat) {
if (handleNmakeJomMessage(line, &m_lastTask)) { if (handleNmakeJomMessage(line, &m_lastTask)) {
m_linkedLines = 1; m_linkedLines = 1;
doFlush(); flush();
return Status::Done; return Status::Done;
} }
return Status::NotHandled; return Status::NotHandled;
} }
const QString lne = IOutputParser::rightTrimmed(line); // Strip \n. const QString lne = rightTrimmed(line); // Strip \n.
if (handleNmakeJomMessage(lne, &m_lastTask)) { if (handleNmakeJomMessage(lne, &m_lastTask)) {
m_linkedLines = 1; m_linkedLines = 1;
doFlush(); flush();
return Status::Done; return Status::Done;
} }
// Finish a sequence of warnings/errors: "2 warnings generated." // Finish a sequence of warnings/errors: "2 warnings generated."
if (!lne.isEmpty() && lne.at(0).isDigit() && lne.endsWith("generated.")) { if (!lne.isEmpty() && lne.at(0).isDigit() && lne.endsWith("generated.")) {
doFlush(); flush();
return Status::Done; return Status::Done;
} }
// Start a new error message by a sequence of "In file included from " which is to be skipped. // Start a new error message by a sequence of "In file included from " which is to be skipped.
if (lne.startsWith("In file included from ")) { if (lne.startsWith("In file included from ")) {
doFlush(); flush();
return Status::Done; return Status::Done;
} }
QRegularExpressionMatch match = m_compileRegExp.match(lne); QRegularExpressionMatch match = m_compileRegExp.match(lne);
if (match.hasMatch()) { if (match.hasMatch()) {
doFlush(); flush();
const QPair<FilePath, int> position = parseFileName(match.captured(1)); const QPair<FilePath, int> position = parseFileName(match.captured(1));
m_lastTask = CompileTask(taskType(match.captured(2)), match.captured(3).trimmed(), m_lastTask = CompileTask(taskType(match.captured(2)), match.captured(3).trimmed(),
absoluteFilePath(position.first), position.second); absoluteFilePath(position.first), position.second);
@@ -263,7 +263,7 @@ IOutputParser::Status ClangClParser::doHandleLine(const QString &line, OutputFor
if (!m_lastTask.isNull()) { if (!m_lastTask.isNull()) {
const QString trimmed = lne.trimmed(); const QString trimmed = lne.trimmed();
if (isClangCodeMarker(trimmed)) { if (isClangCodeMarker(trimmed)) {
doFlush(); flush();
return Status::Done; return Status::Done;
} }
m_lastTask.description.append('\n'); m_lastTask.description.append('\n');
@@ -275,7 +275,7 @@ IOutputParser::Status ClangClParser::doHandleLine(const QString &line, OutputFor
return Status::NotHandled; return Status::NotHandled;
} }
void ClangClParser::doFlush() void ClangClParser::flush()
{ {
if (!m_lastTask.isNull()) { if (!m_lastTask.isNull()) {
emit addTask(m_lastTask, m_linkedLines, 1); emit addTask(m_lastTask, m_linkedLines, 1);

View File

@@ -33,7 +33,7 @@
namespace ProjectExplorer { namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT MsvcParser : public ProjectExplorer::IOutputParser class PROJECTEXPLORER_EXPORT MsvcParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -43,8 +43,8 @@ public:
static Core::Id id(); static Core::Id id();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
void doFlush() override; void flush() override;
bool processCompileLine(const QString &line); bool processCompileLine(const QString &line);
@@ -55,7 +55,7 @@ private:
int m_lines = 0; int m_lines = 0;
}; };
class PROJECTEXPLORER_EXPORT ClangClParser : public ProjectExplorer::IOutputParser class PROJECTEXPLORER_EXPORT ClangClParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -63,8 +63,8 @@ public:
ClangClParser(); ClangClParser();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
void doFlush() override; void flush() override;
const QRegularExpression m_compileRegExp; const QRegularExpression m_compileRegExp;
Task m_lastTask; Task m_lastTask;

View File

@@ -1169,7 +1169,7 @@ void MsvcToolChain::rescanForCompiler()
}); });
} }
QList<IOutputParser *> MsvcToolChain::outputParsers() const QList<OutputTaskParser *> MsvcToolChain::createOutputParsers() const
{ {
return {new MsvcParser}; return {new MsvcParser};
} }
@@ -1656,7 +1656,7 @@ QStringList ClangClToolChain::suggestedMkspecList() const
return {mkspec, "win32-clang-msvc"}; return {mkspec, "win32-clang-msvc"};
} }
QList<IOutputParser *> ClangClToolChain::outputParsers() const QList<OutputTaskParser *> ClangClToolChain::createOutputParsers() const
{ {
return {new ClangClParser}; return {new ClangClParser};
} }

View File

@@ -89,7 +89,7 @@ public:
Utils::FilePath makeCommand(const Utils::Environment &environment) const override; Utils::FilePath makeCommand(const Utils::Environment &environment) const override;
Utils::FilePath compilerCommand() const override; Utils::FilePath compilerCommand() const override;
QList<IOutputParser *> outputParsers() const override; QList<OutputTaskParser *> createOutputParsers() const override;
QString varsBatArg() const { return m_varsBatArg; } QString varsBatArg() const { return m_varsBatArg; }
QString varsBat() const { return m_vcvarsBat; } QString varsBat() const { return m_vcvarsBat; }
@@ -174,7 +174,7 @@ public:
QStringList suggestedMkspecList() const override; QStringList suggestedMkspecList() const override;
void addToEnvironment(Utils::Environment &env) const override; void addToEnvironment(Utils::Environment &env) const override;
Utils::FilePath compilerCommand() const override; Utils::FilePath compilerCommand() const override;
QList<IOutputParser *> outputParsers() const override; QList<OutputTaskParser *> createOutputParsers() const override;
QVariantMap toMap() const override; QVariantMap toMap() const override;
bool fromMap(const QVariantMap &data) override; bool fromMap(const QVariantMap &data) override;
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override; std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override;

View File

@@ -36,7 +36,7 @@ OsParser::OsParser()
setObjectName(QLatin1String("OsParser")); setObjectName(QLatin1String("OsParser"));
} }
IOutputParser::Status OsParser::doHandleLine(const QString &line, Utils::OutputFormat type) OutputTaskParser::Status OsParser::handleLine(const QString &line, Utils::OutputFormat type)
{ {
if (type == Utils::StdOutFormat) { if (type == Utils::StdOutFormat) {
if (Utils::HostOsInfo::isWindowsHost()) { if (Utils::HostOsInfo::isWindowsHost()) {

View File

@@ -33,7 +33,7 @@
namespace ProjectExplorer { namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT OsParser : public ProjectExplorer::IOutputParser class PROJECTEXPLORER_EXPORT OsParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -41,7 +41,7 @@ public:
OsParser(); OsParser();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
bool hasFatalErrors() const override { return m_hasFatalError; } bool hasFatalErrors() const override { return m_hasFatalError; }
bool m_hasFatalError = false; bool m_hasFatalError = false;

View File

@@ -102,7 +102,7 @@ TestTerminator::TestTerminator(OutputParserTester *t) :
m_tester(t) m_tester(t)
{ } { }
IOutputParser::Status TestTerminator::doHandleLine(const QString &line, Utils::OutputFormat type) OutputTaskParser::Status TestTerminator::handleLine(const QString &line, Utils::OutputFormat type)
{ {
QTC_CHECK(line.endsWith('\n')); QTC_CHECK(line.endsWith('\n'));
if (type == Utils::StdOutFormat) if (type == Utils::StdOutFormat)

View File

@@ -73,7 +73,7 @@ private:
friend class TestTerminator; friend class TestTerminator;
}; };
class TestTerminator : public IOutputParser class TestTerminator : public OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -81,7 +81,7 @@ public:
TestTerminator(OutputParserTester *t); TestTerminator(OutputParserTester *t);
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
OutputParserTester *m_tester = nullptr; OutputParserTester *m_tester = nullptr;
}; };

View File

@@ -151,7 +151,7 @@ static void parse(QFutureInterface<void> &future, const QString &output,
void ParseIssuesDialog::accept() void ParseIssuesDialog::accept()
{ {
const QList<IOutputParser *> lineParsers = d->kitChooser.currentKit()->createOutputParsers(); const QList<OutputTaskParser *> lineParsers = d->kitChooser.currentKit()->createOutputParsers();
if (lineParsers.isEmpty()) { if (lineParsers.isEmpty()) {
QMessageBox::critical(this, tr("Cannot Parse"), tr("Cannot parse: The chosen kit does " QMessageBox::critical(this, tr("Cannot Parse"), tr("Cannot parse: The chosen kit does "
"not provide an output parser.")); "not provide an output parser."));

View File

@@ -64,7 +64,7 @@ QString languageId(Language l);
} // namespace Deprecated } // namespace Deprecated
class Abi; class Abi;
class IOutputParser; class OutputTaskParser;
class ToolChainConfigWidget; class ToolChainConfigWidget;
class ToolChainFactory; class ToolChainFactory;
class Kit; class Kit;
@@ -150,7 +150,7 @@ public:
Core::Id language() const; Core::Id language() const;
virtual Utils::FilePath compilerCommand() const = 0; virtual Utils::FilePath compilerCommand() const = 0;
virtual QList<IOutputParser *> outputParsers() const = 0; virtual QList<OutputTaskParser *> createOutputParsers() const = 0;
virtual bool operator ==(const ToolChain &) const; virtual bool operator ==(const ToolChain &) const;

View File

@@ -324,7 +324,7 @@ public:
void addToEnvironment(Environment &env) const override { Q_UNUSED(env) } void addToEnvironment(Environment &env) const override { Q_UNUSED(env) }
FilePath makeCommand(const Environment &) const override { return FilePath::fromString("make"); } FilePath makeCommand(const Environment &) const override { return FilePath::fromString("make"); }
FilePath compilerCommand() const override { return Utils::FilePath::fromString("/tmp/test/gcc"); } FilePath compilerCommand() const override { return Utils::FilePath::fromString("/tmp/test/gcc"); }
QList<IOutputParser *> outputParsers() const override { return {}; } QList<OutputTaskParser *> createOutputParsers() const override { return {}; }
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override { return nullptr; } std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override { return nullptr; }
bool operator ==(const ToolChain &other) const override { bool operator ==(const ToolChain &other) const override {
if (!ToolChain::operator==(other)) if (!ToolChain::operator==(other))

View File

@@ -52,7 +52,7 @@ XcodebuildParser::XcodebuildParser()
QTC_CHECK(m_buildRe.isValid()); QTC_CHECK(m_buildRe.isValid());
} }
IOutputParser::Status XcodebuildParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status XcodebuildParser::handleLine(const QString &line, OutputFormat type)
{ {
const QString lne = rightTrimmed(line); const QString lne = rightTrimmed(line);
if (type == StdOutFormat) { if (type == StdOutFormat) {

View File

@@ -34,7 +34,7 @@
namespace ProjectExplorer { namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT XcodebuildParser : public IOutputParser class PROJECTEXPLORER_EXPORT XcodebuildParser : public OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
public: public:
@@ -47,7 +47,7 @@ public:
XcodebuildParser(); XcodebuildParser();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
bool hasDetectedRedirection() const override; bool hasDetectedRedirection() const override;
bool hasFatalErrors() const override { return m_fatalErrorCount > 0; } bool hasFatalErrors() const override { return m_fatalErrorCount > 0; }

View File

@@ -66,7 +66,6 @@ private:
QString m_description; QString m_description;
int m_maxProgress; int m_maxProgress;
bool m_showCompilerOutput = true; bool m_showCompilerOutput = true;
ProjectExplorer::IOutputParser *m_parser = nullptr;
}; };
class QbsCleanStepFactory : public ProjectExplorer::BuildStepFactory class QbsCleanStepFactory : public ProjectExplorer::BuildStepFactory

View File

@@ -80,7 +80,6 @@ private:
QbsSession *m_session = nullptr; QbsSession *m_session = nullptr;
QString m_description; QString m_description;
int m_maxProgress; int m_maxProgress;
ProjectExplorer::IOutputParser *m_parser = nullptr;
friend class QbsInstallStepConfigWidget; friend class QbsInstallStepConfigWidget;
}; };

View File

@@ -166,18 +166,18 @@ bool QmakeMakeStep::init()
setOutputParser(new ProjectExplorer::GnuMakeParser()); setOutputParser(new ProjectExplorer::GnuMakeParser());
ToolChain *tc = ToolChainKitAspect::cxxToolChain(target()->kit()); ToolChain *tc = ToolChainKitAspect::cxxToolChain(target()->kit());
IOutputParser *xcodeBuildParser = nullptr; OutputTaskParser *xcodeBuildParser = nullptr;
if (tc && tc->targetAbi().os() == Abi::DarwinOS) { if (tc && tc->targetAbi().os() == Abi::DarwinOS) {
xcodeBuildParser = new XcodebuildParser; xcodeBuildParser = new XcodebuildParser;
appendOutputParser(xcodeBuildParser); appendOutputParser(xcodeBuildParser);
} }
QList<IOutputParser *> additionalParsers = target()->kit()->createOutputParsers(); QList<OutputTaskParser *> additionalParsers = target()->kit()->createOutputParsers();
// make may cause qmake to be run, add last to make sure // it has a low priority. // make may cause qmake to be run, add last to make sure it has a low priority.
additionalParsers << new QMakeParser; additionalParsers << new QMakeParser;
if (xcodeBuildParser) { if (xcodeBuildParser) {
for (IOutputParser * const p : qAsConst(additionalParsers)) for (OutputTaskParser * const p : qAsConst(additionalParsers))
p->setRedirectionDetector(xcodeBuildParser); p->setRedirectionDetector(xcodeBuildParser);
} }
appendOutputParsers(additionalParsers); appendOutputParsers(additionalParsers);

View File

@@ -40,7 +40,7 @@ QMakeParser::QMakeParser() : m_error(QLatin1String("^(.+):(\\d+):\\s(.+)$"))
m_error.setMinimal(true); m_error.setMinimal(true);
} }
IOutputParser::Status QMakeParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status QMakeParser::handleLine(const QString &line, OutputFormat type)
{ {
if (type != Utils::StdErrFormat) if (type != Utils::StdErrFormat)
return Status::NotHandled; return Status::NotHandled;

View File

@@ -33,7 +33,7 @@
namespace QmakeProjectManager { namespace QmakeProjectManager {
class QMAKEPROJECTMANAGER_EXPORT QMakeParser : public ProjectExplorer::IOutputParser class QMAKEPROJECTMANAGER_EXPORT QMakeParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -41,7 +41,7 @@ public:
QMakeParser(); QMakeParser();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
QRegExp m_error; QRegExp m_error;
}; };

View File

@@ -288,7 +288,7 @@ void QtKitAspect::addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environ
version->addToEnvironment(k, env); version->addToEnvironment(k, env);
} }
QList<IOutputParser *> QtKitAspect::createOutputParsers(const Kit *k) const QList<OutputTaskParser *> QtKitAspect::createOutputParsers(const Kit *k) const
{ {
if (qtVersion(k)) if (qtVersion(k))
return {new Internal::QtTestParser, new QtParser}; return {new Internal::QtTestParser, new QtParser};

View File

@@ -54,7 +54,7 @@ public:
ItemList toUserOutput(const ProjectExplorer::Kit *k) const override; ItemList toUserOutput(const ProjectExplorer::Kit *k) const override;
void addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const override; void addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const override;
QList<ProjectExplorer::IOutputParser *> createOutputParsers(const ProjectExplorer::Kit *k) const override; QList<ProjectExplorer::OutputTaskParser *> createOutputParsers(const ProjectExplorer::Kit *k) const override;
void addToMacroExpander(ProjectExplorer::Kit *kit, Utils::MacroExpander *expander) const override; void addToMacroExpander(ProjectExplorer::Kit *kit, Utils::MacroExpander *expander) const override;
static Core::Id id(); static Core::Id id();

View File

@@ -43,7 +43,7 @@ QtParser::QtParser() :
m_translationRegExp.setMinimal(true); m_translationRegExp.setMinimal(true);
} }
IOutputParser::Status QtParser::doHandleLine(const QString &line, Utils::OutputFormat type) OutputTaskParser::Status QtParser::handleLine(const QString &line, Utils::OutputFormat type)
{ {
if (type != Utils::StdErrFormat) if (type != Utils::StdErrFormat)
return Status::NotHandled; return Status::NotHandled;

View File

@@ -34,7 +34,7 @@ namespace QtSupport {
// Parser for Qt-specific utilities like moc, uic, etc. // Parser for Qt-specific utilities like moc, uic, etc.
class QTSUPPORT_EXPORT QtParser : public ProjectExplorer::IOutputParser class QTSUPPORT_EXPORT QtParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
@@ -42,7 +42,7 @@ public:
QtParser(); QtParser();
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
QRegExp m_mocRegExp; QRegExp m_mocRegExp;
QRegExp m_translationRegExp; QRegExp m_translationRegExp;

View File

@@ -47,7 +47,7 @@ using namespace Utils;
namespace QtSupport { namespace QtSupport {
namespace Internal { namespace Internal {
IOutputParser::Status QtTestParser::doHandleLine(const QString &line, OutputFormat type) OutputTaskParser::Status QtTestParser::handleLine(const QString &line, OutputFormat type)
{ {
if (type != StdOutFormat) if (type != StdOutFormat)
return Status::NotHandled; return Status::NotHandled;

View File

@@ -31,12 +31,12 @@
namespace QtSupport { namespace QtSupport {
namespace Internal { namespace Internal {
class QtTestParser : public ProjectExplorer::IOutputParser class QtTestParser : public ProjectExplorer::OutputTaskParser
{ {
Q_OBJECT Q_OBJECT
private: private:
Status doHandleLine(const QString &line, Utils::OutputFormat type) override; Status handleLine(const QString &line, Utils::OutputFormat type) override;
void doFlush() override { emitCurrentTask(); } void flush() override { emitCurrentTask(); }
void emitCurrentTask(); void emitCurrentTask();