aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/python/pythonrunconfiguration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/python/pythonrunconfiguration.cpp')
-rw-r--r--src/plugins/python/pythonrunconfiguration.cpp98
1 files changed, 48 insertions, 50 deletions
diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp
index 1783b46930..4d9b12cdc8 100644
--- a/src/plugins/python/pythonrunconfiguration.cpp
+++ b/src/plugins/python/pythonrunconfiguration.cpp
@@ -60,10 +60,10 @@ using namespace Utils;
namespace Python {
namespace Internal {
-class PythonOutputFormatter : public OutputFormatter
+class PythonOutputLineParser : public OutputLineParser
{
public:
- PythonOutputFormatter()
+ PythonOutputLineParser()
// Note that moc dislikes raw string literals.
: filePattern("^(\\s*)(File \"([^\"]+)\", line (\\d+), .*$)")
{
@@ -71,66 +71,64 @@ public:
}
private:
- void appendMessage(const QString &text, OutputFormat format) final
+ Result handleLine(const QString &text, OutputFormat format) final
{
- const bool isTrace = (format == StdErrFormat
- || format == StdErrFormatSameLine)
- && (text.startsWith("Traceback (most recent call last):")
- || text.startsWith("\nTraceback (most recent call last):"));
-
- if (!isTrace) {
- OutputFormatter::appendMessage(text, format);
- return;
+ if (!m_inTraceBack) {
+ m_inTraceBack = format == StdErrFormat
+ && text.startsWith("Traceback (most recent call last):");
+ if (m_inTraceBack)
+ return Status::InProgress;
+ return Status::NotHandled;
}
- const QTextCharFormat frm = charFormat(format);
- const Core::Id id(PythonErrorTaskCategory);
- QVector<Task> tasks;
- const QStringList lines = text.split('\n');
- unsigned taskId = unsigned(lines.size());
-
- for (const QString &line : lines) {
- const QRegularExpressionMatch match = filePattern.match(line);
- if (match.hasMatch()) {
- QTextCursor tc = plainTextEdit()->textCursor();
- tc.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
- tc.insertText('\n' + match.captured(1));
- tc.insertText(match.captured(2), linkFormat(frm, match.captured(2)));
-
- const auto fileName = FilePath::fromString(match.captured(3));
- const int lineNumber = match.capturedRef(4).toInt();
- Task task(Task::Warning,
- QString(), fileName, lineNumber, id);
- task.taskId = --taskId;
- tasks.append(task);
+ const Utils::Id category(PythonErrorTaskCategory);
+ const QRegularExpressionMatch match = filePattern.match(text);
+ if (match.hasMatch()) {
+ const LinkSpec link(match.capturedStart(2), match.capturedLength(2), match.captured(2));
+ const auto fileName = FilePath::fromString(match.captured(3));
+ const int lineNumber = match.captured(4).toInt();
+ m_tasks.append({Task::Warning, QString(), fileName, lineNumber, category});
+ return {Status::InProgress, {link}};
+ }
+
+ Status status = Status::InProgress;
+ if (text.startsWith(' ')) {
+ // Neither traceback start, nor file, nor error message line.
+ // Not sure if that can actually happen.
+ if (m_tasks.isEmpty()) {
+ m_tasks.append({Task::Warning, text.trimmed(), {}, -1, category});
} else {
- if (!tasks.isEmpty()) {
- Task &task = tasks.back();
- if (!task.description.isEmpty())
- task.description += ' ';
- task.description += line.trimmed();
- }
- OutputFormatter::appendMessage('\n' + line, format);
+ Task &task = m_tasks.back();
+ if (!task.summary.isEmpty())
+ task.summary += ' ';
+ task.summary += text.trimmed();
}
- }
- if (!tasks.isEmpty()) {
- tasks.back().type = Task::Error;
- for (auto rit = tasks.crbegin(), rend = tasks.crend(); rit != rend; ++rit)
+ } else {
+ // The actual exception. This ends the traceback.
+ TaskHub::addTask({Task::Error, text, {}, -1, category});
+ for (auto rit = m_tasks.crbegin(), rend = m_tasks.crend(); rit != rend; ++rit)
TaskHub::addTask(*rit);
+ m_tasks.clear();
+ m_inTraceBack = false;
+ status = Status::Done;
}
+ return status;
}
- void handleLink(const QString &href) final
+ bool handleLink(const QString &href) final
{
const QRegularExpressionMatch match = filePattern.match(href);
if (!match.hasMatch())
- return;
+ return false;
const QString fileName = match.captured(3);
- const int lineNumber = match.capturedRef(4).toInt();
+ const int lineNumber = match.captured(4).toInt();
Core::EditorManager::openEditorAt(fileName, lineNumber);
+ return true;
}
const QRegularExpression filePattern;
+ QList<Task> m_tasks;
+ bool m_inTraceBack;
};
////////////////////////////////////////////////////////////////
@@ -235,7 +233,7 @@ public:
MainScriptAspect() = default;
};
-PythonRunConfiguration::PythonRunConfiguration(Target *target, Core::Id id)
+PythonRunConfiguration::PythonRunConfiguration(Target *target, Utils::Id id)
: RunConfiguration(target, id)
{
auto interpreterAspect = addAspect<InterpreterAspect>();
@@ -333,10 +331,10 @@ PythonRunConfigurationFactory::PythonRunConfigurationFactory()
PythonOutputFormatterFactory::PythonOutputFormatterFactory()
{
- setFormatterCreator([](Target *t) -> OutputFormatter * {
- if (t->project()->mimeType() == Constants::C_PY_MIMETYPE)
- return new PythonOutputFormatter;
- return nullptr;
+ setFormatterCreator([](Target *t) -> QList<OutputLineParser *> {
+ if (t && t->project()->mimeType() == Constants::C_PY_MIMETYPE)
+ return {new PythonOutputLineParser};
+ return {};
});
}