Commit 03d52a2a authored by Filippo Cucchetto's avatar Filippo Cucchetto

Nim: Added Nim compiler output parser

Change-Id: I45ea20e4767dedfe0f99002f9d8ad2ffb0f268db
Reviewed-by: Tobias Hunger's avatarTobias Hunger <tobias.hunger@qt.io>
parent 2475da1b
......@@ -41,6 +41,12 @@ public:
bool initialize(const QStringList &arguments, QString *errorMessage) final;
void extensionsInitialized() final;
#ifdef WITH_TESTS
private slots:
void testNimParser_data();
void testNimParser();
#endif
};
}
......@@ -30,17 +30,73 @@
#include "nimproject.h"
#include "nimtoolchain.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/ioutputparser.h>
#include <utils/qtcassert.h>
#include <QDir>
#include <QRegularExpression>
using namespace ProjectExplorer;
using namespace Utils;
namespace Nim {
class NimParser : public ProjectExplorer::IOutputParser
{
public:
void stdOutput(const QString &line) final
{
parseLine(line.trimmed());
IOutputParser::stdOutput(line);
}
void stdError(const QString &line) final
{
parseLine(line.trimmed());
IOutputParser::stdError(line);
}
private:
void parseLine(const QString &line)
{
static QRegularExpression regex("(.+.nim)\\((\\d+), (\\d+)\\) (.+)",
QRegularExpression::OptimizeOnFirstUsageOption);
static QRegularExpression warning("(Warning):(.*)",
QRegularExpression::OptimizeOnFirstUsageOption);
static QRegularExpression error("(Error):(.*)",
QRegularExpression::OptimizeOnFirstUsageOption);
QRegularExpressionMatch match = regex.match(line);
if (!match.hasMatch())
return;
const QString filename = match.captured(1);
bool lineOk = false;
const int lineNumber = match.captured(2).toInt(&lineOk);
const QString message = match.captured(4);
if (!lineOk)
return;
Task::TaskType type = Task::Unknown;
if (warning.match(message).hasMatch())
type = Task::Warning;
else if (error.match(message).hasMatch())
type = Task::Error;
else
return;
Task task(type,
message,
Utils::FileName::fromUserInput(filename),
lineNumber,
ProjectExplorer::Constants::TASK_CATEGORY_COMPILE);
emit addTask(task);
}
};
NimCompilerBuildStep::NimCompilerBuildStep(BuildStepList *parentList)
: AbstractProcessStep(parentList, Constants::C_NIMCOMPILERBUILDSTEP_ID)
{
......@@ -57,6 +113,15 @@ NimCompilerBuildStep::NimCompilerBuildStep(BuildStepList *parentList)
updateProcessParameters();
}
bool NimCompilerBuildStep::init(QList<const BuildStep *> &earlierSteps)
{
setOutputParser(new NimParser());
if (IOutputParser *parser = target()->kit()->createOutputParser())
appendOutputParser(parser);
outputParser()->setWorkingDirectory(processParameters()->effectiveWorkingDirectory());
return AbstractProcessStep::init(earlierSteps);
}
BuildStepConfigWidget *NimCompilerBuildStep::createConfigWidget()
{
return new NimCompilerBuildStepConfigWidget(this);
......@@ -221,3 +286,75 @@ void NimCompilerBuildStep::updateTargetNimFile()
}
} // namespace Nim
#ifdef WITH_TESTS
#include "nimplugin.h"
#include <projectexplorer/outputparser_test.h>
#include <QTest>
namespace Nim {
void NimPlugin::testNimParser_data()
{
QTest::addColumn<QString>("input");
QTest::addColumn<OutputParserTester::Channel>("inputChannel");
QTest::addColumn<QString>("childStdOutLines");
QTest::addColumn<QString>("childStdErrLines");
QTest::addColumn<QList<ProjectExplorer::Task> >("tasks");
QTest::addColumn<QString>("outputLines");
// negative tests
QTest::newRow("pass-through stdout")
<< "Sometext" << OutputParserTester::STDOUT
<< "Sometext\n" << QString()
<< QList<Task>()
<< QString();
QTest::newRow("pass-through stderr")
<< "Sometext" << OutputParserTester::STDERR
<< QString() << "Sometext\n"
<< QList<Task>()
<< QString();
// positive tests
QTest::newRow("Parse error string")
<< QString::fromLatin1("main.nim(23, 1) Error: undeclared identifier: 'x'")
<< OutputParserTester::STDERR
<< QString("") << QString("main.nim(23, 1) Error: undeclared identifier: 'x'\n")
<< QList<Task>({ Task(Task::Error,
"Error: undeclared identifier: 'x'",
Utils::FileName::fromUserInput("main.nim"), 23,
ProjectExplorer::Constants::TASK_CATEGORY_COMPILE) })
<< QString();
QTest::newRow("Parse warning string")
<< QString::fromLatin1("lib/pure/parseopt.nim(56, 34) Warning: quoteIfContainsWhite is deprecated [Deprecated]")
<< OutputParserTester::STDERR
<< QString("") << QString("lib/pure/parseopt.nim(56, 34) Warning: quoteIfContainsWhite is deprecated [Deprecated]\n")
<< QList<Task>({ Task(Task::Warning,
"Warning: quoteIfContainsWhite is deprecated [Deprecated]",
Utils::FileName::fromUserInput("lib/pure/parseopt.nim"), 56,
ProjectExplorer::Constants::TASK_CATEGORY_COMPILE) })
<< QString();
}
void NimPlugin::testNimParser()
{
OutputParserTester testbench;
testbench.appendOutputParser(new NimParser);
QFETCH(QString, input);
QFETCH(OutputParserTester::Channel, inputChannel);
QFETCH(QList<Task>, tasks);
QFETCH(QString, childStdOutLines);
QFETCH(QString, childStdErrLines);
QFETCH(QString, outputLines);
testbench.testParsing(input, inputChannel,
tasks, childStdOutLines, childStdErrLines,
outputLines);
}
}
#endif
......@@ -41,6 +41,7 @@ public:
NimCompilerBuildStep(ProjectExplorer::BuildStepList *parentList);
bool init(QList<const ProjectExplorer::BuildStep *> &earlierSteps) override;
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
bool fromMap(const QVariantMap &map) override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment