From db698db17190613d3dc059879530a72e60422372 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 11 Jun 2025 17:33:56 +0200 Subject: [PATCH] ProjectExplorer: Add an "origin" field to the Task class ... and set it in some relevant contexts. Change-Id: Id620ff8688617158d06240c92d52ad119e793c94 Reviewed-by: hjk --- src/plugins/baremetal/iarewparser.cpp | 1 + .../cmakeautogenparser.cpp | 35 +++++------- .../cmakeprojectmanager/cmakeautogenparser.h | 10 +--- .../cmakeprojectmanager/cmakeoutputparser.cpp | 55 +++++++++---------- .../cmakeprojectmanager/cmakeoutputparser.h | 21 +++++-- .../cmakeprojectmanager/cmakeprocess.cpp | 9 +-- src/plugins/projectexplorer/clangparser.cpp | 1 + src/plugins/projectexplorer/gccparser.cpp | 1 + src/plugins/projectexplorer/gnumakeparser.cpp | 40 +++++++++----- src/plugins/projectexplorer/ioutputparser.cpp | 8 +++ src/plugins/projectexplorer/ioutputparser.h | 1 + src/plugins/projectexplorer/ldparser.cpp | 1 + .../projectexplorer/linuxiccparser.cpp | 3 +- src/plugins/projectexplorer/msvcparser.cpp | 2 + src/plugins/projectexplorer/task.h | 1 + src/plugins/qbsprojectmanager/qbsproject.cpp | 4 +- src/plugins/qbsprojectmanager/qbssession.cpp | 7 ++- .../qmakeprojectmanager/qmakeparser.cpp | 19 ++++--- src/plugins/qmakeprojectmanager/qmakeparser.h | 16 +++++- .../qmakeprojectmanager/qmakeproject.cpp | 4 +- 20 files changed, 137 insertions(+), 102 deletions(-) diff --git a/src/plugins/baremetal/iarewparser.cpp b/src/plugins/baremetal/iarewparser.cpp index 6a02da9641c..67caaaceda2 100644 --- a/src/plugins/baremetal/iarewparser.cpp +++ b/src/plugins/baremetal/iarewparser.cpp @@ -40,6 +40,7 @@ void IarParser::newTask(const Task &task) { flush(); m_lastTask = task; + m_lastTask.origin = "IAR compiler"; m_lines = 1; } diff --git a/src/plugins/cmakeprojectmanager/cmakeautogenparser.cpp b/src/plugins/cmakeprojectmanager/cmakeautogenparser.cpp index 7c2f2eab63d..59175bff36c 100644 --- a/src/plugins/cmakeprojectmanager/cmakeautogenparser.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeautogenparser.cpp @@ -2,16 +2,19 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "cmakeautogenparser.h" +#include "cmakeoutputparser.h" -#include #include -#include +#ifdef WITH_TESTS +#include +#include +#endif using namespace ProjectExplorer; using namespace Utils; -namespace CMakeProjectManager { +namespace CMakeProjectManager::Internal { const char COMMON_ERROR_PATTERN[] = "^(AutoMoc|AUTOMOC|AutoUic).*error.*$"; const char COMMON_WARNING_PATTERN[] = "^(AutoMoc|AUTOMOC|AutoUic).*warning.*$"; @@ -37,7 +40,7 @@ OutputLineParser::Result CMakeAutogenParser::handleLine(const QString &line, Out case NONE: { match = m_commonError.match(trimmedLine); if (match.hasMatch()) { - m_lastTask = BuildSystemTask(Task::Error, match.captured()); + m_lastTask = CMakeTask(Task::Error, match.captured()); m_lines = 1; m_expectedState = LINE_SEPARATOR; @@ -45,7 +48,7 @@ OutputLineParser::Result CMakeAutogenParser::handleLine(const QString &line, Out } match = m_commonWarning.match(trimmedLine); if (match.hasMatch()) { - m_lastTask = BuildSystemTask(Task::Warning, match.captured()); + m_lastTask = CMakeTask(Task::Warning, match.captured()); m_lines = 1; m_expectedState = LINE_SEPARATOR; @@ -93,16 +96,8 @@ void CMakeAutogenParser::flush() m_lines = 0; } -} // namespace CMakeProjectManager - #ifdef WITH_TESTS -#include - -#include - -namespace CMakeProjectManager::Internal { - class CMakeAutogenParserTest final : public QObject { Q_OBJECT @@ -137,7 +132,7 @@ Consider to - add #include "main.moc" - enable SKIP_AUTOMOC for this file)" << OutputParserTester::STDERR << QStringList() << QStringList() - << (Tasks() << BuildSystemTask( + << (Tasks() << CMakeTask( Task::Error, R"(AutoMoc error "SRC:/main.cpp" @@ -156,7 +151,7 @@ included by "BIN:/src/quickcontrols/basic/impl/qtquickcontrols2basicstyleimplplugin_QtQuickControls2BasicStyleImplPlugin.cpp" Process failed with return value 1)" << OutputParserTester::STDERR << QStringList() << QStringList() - << (Tasks() << BuildSystemTask( + << (Tasks() << CMakeTask( Task::Error, R"(AutoMoc subprocess error The moc process failed to compile @@ -174,7 +169,7 @@ moc on "/home/alex/src/CMake/tests/solid.orig/solid/solid/device_p.h" ! Include "moc_device_p.cpp" for compatibility with strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).)" << OutputParserTester::STDERR << QStringList() << QStringList() - << (Tasks() << BuildSystemTask( + << (Tasks() << CMakeTask( Task::Warning, R"(AUTOMOC: warning: /home/alex/src/CMake/tests/solid.orig/solid/solid/device.cpp: The file @@ -188,7 +183,7 @@ CMAKE_AUTOMOC_RELAXED_MODE).)")); "SRC:/src/main.cpp" includes the moc file "main.moc", but does not contain a Q_OBJECT, Q_GADGET, Q_NAMESPACE, Q_NAMESPACE_EXPORT, Q_GADGET_EXPORT, Q_ENUM_NS, K_PLUGIN_FACTORY, K_PLUGIN_CLASS, K_PLUGIN_FACTORY_WITH_JSON or K_PLUGIN_CLASS_WITH_JSON macro.)" << OutputParserTester::STDERR << QStringList() << QStringList() - << (Tasks() << BuildSystemTask( + << (Tasks() << CMakeTask( Task::Warning, R"(AutoMoc warning "SRC:/src/main.cpp" @@ -202,7 +197,7 @@ but the user interface file "global.ui" could not be found in the following directories "SRC:/monitor/ui")" << OutputParserTester::STDERR << QStringList() << QStringList() - << (Tasks() << BuildSystemTask( + << (Tasks() << CMakeTask( Task::Error, R"(AutoUic error "SRC:/monitor/ui/LiveBoard.h" @@ -230,8 +225,8 @@ QObject *createCMakeAutogenParserTest() return new CMakeAutogenParserTest; } -} // namespace CMakeProjectManager::Internal - #endif +} // namespace CMakeProjectManager::Internal + #include "cmakeautogenparser.moc" diff --git a/src/plugins/cmakeprojectmanager/cmakeautogenparser.h b/src/plugins/cmakeprojectmanager/cmakeautogenparser.h index f4ba4a468a7..4a6b8dc0fb0 100644 --- a/src/plugins/cmakeprojectmanager/cmakeautogenparser.h +++ b/src/plugins/cmakeprojectmanager/cmakeautogenparser.h @@ -3,16 +3,14 @@ #pragma once -#include "cmake_global.h" - #include #include #include -namespace CMakeProjectManager { +namespace CMakeProjectManager::Internal { -class CMAKE_EXPORT CMakeAutogenParser : public ProjectExplorer::OutputTaskParser +class CMakeAutogenParser : public ProjectExplorer::OutputTaskParser { public: explicit CMakeAutogenParser(); @@ -33,9 +31,7 @@ private: }; #ifdef WITH_TESTS -namespace Internal { QObject *createCMakeAutogenParserTest(); -} #endif -} // namespace CMakeProjectManager +} // namespace CMakeProjectManager::Internal diff --git a/src/plugins/cmakeprojectmanager/cmakeoutputparser.cpp b/src/plugins/cmakeprojectmanager/cmakeoutputparser.cpp index b62cc3ce0d9..b1ac3c2a0f2 100644 --- a/src/plugins/cmakeprojectmanager/cmakeoutputparser.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeoutputparser.cpp @@ -8,12 +8,15 @@ #include #include -#include +#ifdef WITH_TESTS +#include +#include +#endif using namespace ProjectExplorer; using namespace Utils; -namespace CMakeProjectManager { +namespace CMakeProjectManager::Internal { const char COMMON_ERROR_PATTERN[] = "^CMake Error at (.*?):([0-9]*?)( \\((.*?)\\))?:"; const char NEXT_SUBERROR_PATTERN[] = "^CMake Error in (.*?):"; @@ -57,7 +60,7 @@ FilePath CMakeOutputParser::resolvePath(const QString &path) const OutputLineParser::Result CMakeOutputParser::handleLine(const QString &line, OutputFormat type) { if (line.startsWith("ninja: build stopped")) { - m_lastTask = BuildSystemTask(Task::Error, line); + m_lastTask = CMakeTask(Task::Error, line); m_lines = 1; flush(); return Status::Done; @@ -87,7 +90,7 @@ OutputLineParser::Result CMakeOutputParser::handleLine(const QString &line, Outp if (match.hasMatch()) { const FilePath path = resolvePath(match.captured(1)); - m_lastTask = BuildSystemTask(Task::Error, + m_lastTask = CMakeTask(Task::Error, QString(), absoluteFilePath(path), match.captured(2).toInt()); @@ -104,7 +107,7 @@ OutputLineParser::Result CMakeOutputParser::handleLine(const QString &line, Outp } match = m_nextSubError.match(trimmedLine); if (match.hasMatch()) { - m_lastTask = BuildSystemTask(Task::Error, QString(), + m_lastTask = CMakeTask(Task::Error, QString(), absoluteFilePath(FilePath::fromUserInput(match.captured(1)))); LinkSpecs linkSpecs; addLinkSpecForAbsoluteFilePath( @@ -115,7 +118,7 @@ OutputLineParser::Result CMakeOutputParser::handleLine(const QString &line, Outp match = m_commonWarning.match(trimmedLine); if (match.hasMatch()) { const FilePath path = resolvePath(match.captured(2)); - m_lastTask = BuildSystemTask(Task::Warning, + m_lastTask = CMakeTask(Task::Warning, QString(), absoluteFilePath(path), match.captured(3).toInt()); @@ -150,10 +153,10 @@ OutputLineParser::Result CMakeOutputParser::handleLine(const QString &line, Outp flush(); const Task::TaskType type = trimmedLine.contains(QLatin1String("Error")) ? Task::Error : Task::Warning; - m_lastTask = BuildSystemTask(type, QString()); + m_lastTask = CMakeTask(type, QString()); return Status::InProgress; } else if (trimmedLine.startsWith("CMake Error: ")) { - m_lastTask = BuildSystemTask(Task::Error, trimmedLine.mid(13)); + m_lastTask = CMakeTask(Task::Error, trimmedLine.mid(13)); m_lines = 1; return Status::InProgress; } else if (trimmedLine.startsWith("-- ") || trimmedLine.startsWith(" * ")) { @@ -251,16 +254,8 @@ void CMakeOutputParser::flush() m_callStackDetected = false; } -} // CMakeProjectManager - #ifdef WITH_TESTS -#include - -#include - -namespace CMakeProjectManager::Internal { - class CMakeOutputParserTest final : public QObject { Q_OBJECT @@ -303,13 +298,13 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << CMakeTask(Task::Error, "Cannot find source file:\n\n" " unknownFile.qml\n\n" "Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp\n" ".hxx .in .txx", FilePath::fromUserInput("src/1/app/CMakeLists.txt"), 70) - << BuildSystemTask(Task::Error, + << CMakeTask(Task::Error, "Cannot find source file:\n\n" " CMakeLists.txt2\n\n" "Tried extensions " @@ -323,7 +318,7 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << CMakeTask(Task::Error, "add_subdirectory given source \"app1\" which is not an existing directory.", FilePath::fromUserInput("src/1/CMakeLists.txt"), 8)); @@ -333,7 +328,7 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << CMakeTask(Task::Error, "Unknown CMake command \"i_am_wrong_command\".", FilePath::fromUserInput("src/1/CMakeLists.txt"), 8)); @@ -343,7 +338,7 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << CMakeTask(Task::Error, "message called with incorrect number of arguments", FilePath::fromUserInput("src/1/CMakeLists.txt"), 8)); @@ -355,7 +350,7 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << CMakeTask(Task::Error, "Parse error. Expected \"(\", got newline with text \"\n\".", FilePath::fromUserInput("/test/path/CMakeLists.txt"), 9)); @@ -366,7 +361,7 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() << OutputParserTester::STDERR << QStringList() << QStringList{"Missing variable is:", "CMAKE_MAKE_PROGRAM"} << (Tasks() - << BuildSystemTask(Task::Error, + << CMakeTask(Task::Error, "Error required internal CMake variable not set, " "cmake may be not be built correctly.")); @@ -378,7 +373,7 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << CMakeTask(Task::Error, "Parse error. Expected \"(\", got newline with text \"\n" "\n" "\".", @@ -391,7 +386,7 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Warning, + << CMakeTask(Task::Warning, "Argument not separated from preceding token by whitespace.", FilePath::fromUserInput("/test/path/CMakeLists.txt"), 9)); @@ -401,7 +396,7 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Warning, + << CMakeTask(Task::Warning, "this is a warning", FilePath::fromUserInput("CMakeLists.txt"), 13)); @@ -411,7 +406,7 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Warning, + << CMakeTask(Task::Warning, "this is an author warning", FilePath::fromUserInput("CMakeLists.txt"), 15)); @@ -439,7 +434,7 @@ void CMakeOutputParserTest::testCMakeOutputParser_data() "(qt6_add_executable)\n" " /Projects/Test-Project/CMakeLists.txt:13 (qt_add_executable)\n") << OutputParserTester::STDERR << QStringList() << QStringList() - << (Tasks() << BuildSystemTask( + << (Tasks() << CMakeTask( Task::Error, "\n" "Cannot find source file:\n" @@ -480,8 +475,8 @@ QObject *createCMakeOutputParserTest() return new CMakeOutputParserTest; } -} // CMakeProjectManager::Internal - #endif +} // CMakeProjectManager::Internal + #include "cmakeoutputparser.moc" diff --git a/src/plugins/cmakeprojectmanager/cmakeoutputparser.h b/src/plugins/cmakeprojectmanager/cmakeoutputparser.h index 1f8321c0722..33925720e00 100644 --- a/src/plugins/cmakeprojectmanager/cmakeoutputparser.h +++ b/src/plugins/cmakeprojectmanager/cmakeoutputparser.h @@ -3,8 +3,6 @@ #pragma once -#include "cmake_global.h" - #include #include @@ -14,9 +12,9 @@ #include -namespace CMakeProjectManager { +namespace CMakeProjectManager::Internal { -class CMAKE_EXPORT CMakeOutputParser : public ProjectExplorer::OutputTaskParser +class CMakeOutputParser : public ProjectExplorer::OutputTaskParser { public: explicit CMakeOutputParser(); @@ -52,8 +50,19 @@ private: CallStackLine m_errorOrWarningLine; }; +class CMakeTask : public ProjectExplorer::BuildSystemTask +{ +public: + CMakeTask(TaskType type, const QString &description, const Utils::FilePath &file = {}, + int line = -1) + : ProjectExplorer::BuildSystemTask(type, description, file, line) + { + origin = "CMake"; + } +}; + #ifdef WITH_TESTS -namespace Internal { QObject *createCMakeOutputParserTest(); } +QObject *createCMakeOutputParserTest(); #endif -} // CMakeProjectManager +} // namespace CMakeProjectManager::Internal diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp index f67d32ce003..b026fec88cb 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp @@ -17,18 +17,11 @@ #include #include #include -#include - -#include -#include #include #include -#include -#include #include #include -#include #include using namespace Core; @@ -154,7 +147,7 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList & if (m_process->result() != ProcessResult::FinishedWithSuccess) { const QString message = m_process->exitMessage(); BuildSystem::appendBuildSystemOutput(addCMakePrefix({{}, message}).join('\n')); - TaskHub::addTask(BuildSystemTask(Task::Error, message)); + TaskHub::addTask(CMakeTask(Task::Error, message)); } emit finished(m_process->exitCode()); diff --git a/src/plugins/projectexplorer/clangparser.cpp b/src/plugins/projectexplorer/clangparser.cpp index bf38d05ae09..db4d3599d5a 100644 --- a/src/plugins/projectexplorer/clangparser.cpp +++ b/src/plugins/projectexplorer/clangparser.cpp @@ -32,6 +32,7 @@ ClangParser::ClangParser() : m_expectSnippet(false) { setObjectName(QLatin1String("ClangParser")); + setOrigin("Clang compiler"); } QList ClangParser::clangParserSuite() diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp index 11c491edb12..ac27158b66e 100644 --- a/src/plugins/projectexplorer/gccparser.cpp +++ b/src/plugins/projectexplorer/gccparser.cpp @@ -118,6 +118,7 @@ private: GccParser::GccParser() { setObjectName(QLatin1String("GCCParser")); + setOrigin("GCC compiler"); m_regExpIncluded.setPattern(QString::fromLatin1("\\bfrom\\s") + filePattern() + QLatin1String("(\\d+)(:\\d+)?[,:]?$")); diff --git a/src/plugins/projectexplorer/gnumakeparser.cpp b/src/plugins/projectexplorer/gnumakeparser.cpp index 5ef31748a12..4e256d2b6d8 100644 --- a/src/plugins/projectexplorer/gnumakeparser.cpp +++ b/src/plugins/projectexplorer/gnumakeparser.cpp @@ -16,9 +16,19 @@ using namespace Utils; namespace ProjectExplorer { namespace { - // optional full path, make executable name, optional exe extension, optional number in square brackets, colon space - const char * const MAKEEXEC_PATTERN("^(.*?[/\\\\])?(mingw(32|64)-|g)?make(.exe)?(\\[\\d+\\])?:\\s"); - const char * const MAKEFILE_PATTERN("^((.*?[/\\\\])?[Mm]akefile(\\.[a-zA-Z]+)?):(\\d+):\\s"); +class MakeTask : public BuildSystemTask +{ +public: + MakeTask(TaskType type, const QString &description, const Utils::FilePath &file = {}, + int line = -1) : BuildSystemTask(type, description, file, line) + { + origin = "make"; + } +}; + +// optional full path, make executable name, optional exe extension, optional number in square brackets, colon space +const char * const MAKEEXEC_PATTERN("^(.*?[/\\\\])?(mingw(32|64)-|g)?make(.exe)?(\\[\\d+\\])?:\\s"); +const char * const MAKEFILE_PATTERN("^((.*?[/\\\\])?[Mm]akefile(\\.[a-zA-Z]+)?):(\\d+):\\s"); } GnuMakeParser::GnuMakeParser() @@ -104,7 +114,7 @@ OutputLineParser::Result GnuMakeParser::handleLine(const QString &line, OutputFo const FilePath file = absoluteFilePath(FilePath::fromUserInput(match.captured(1))); const int lineNo = match.captured(4).toInt(); addLinkSpecForAbsoluteFilePath(linkSpecs, file, lineNo, -1, match, 1); - emitTask(BuildSystemTask(res.type, res.description, file, lineNo)); + emitTask(MakeTask(res.type, res.description, file, lineNo)); } return {Status::Done, linkSpecs}; } @@ -114,7 +124,7 @@ OutputLineParser::Result GnuMakeParser::handleLine(const QString &line, OutputFo if (res.isFatal) ++m_fatalErrorCount; if (!m_suppressIssues) - emitTask(BuildSystemTask(res.type, res.description)); + emitTask(MakeTask(res.type, res.description)); return Status::Done; } @@ -216,7 +226,7 @@ void ProjectExplorerTest::testGnuMakeParserParsing_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << MakeTask(Task::Error, "No rule to make target `hello.c', needed by `hello.o'. Stop.")) << QStringList(); @@ -228,7 +238,7 @@ void ProjectExplorerTest::testGnuMakeParserParsing_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << MakeTask(Task::Error, "[.obj/debug-shared/gnumakeparser.o] Error 1")) << QStringList(); @@ -238,7 +248,7 @@ void ProjectExplorerTest::testGnuMakeParserParsing_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << MakeTask(Task::Error, "missing separator (did you mean TAB instead of 8 spaces?). Stop.", Utils::FilePath::fromUserInput("Makefile"), 360)) << QStringList(); @@ -250,7 +260,7 @@ void ProjectExplorerTest::testGnuMakeParserParsing_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << MakeTask(Task::Error, "[debug/qplotaxis.o] Error 1")) << QStringList(); @@ -260,7 +270,7 @@ void ProjectExplorerTest::testGnuMakeParserParsing_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << MakeTask(Task::Error, "[dynlib.inst] Error -1073741819")) << QStringList(); @@ -270,7 +280,7 @@ void ProjectExplorerTest::testGnuMakeParserParsing_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Warning, + << MakeTask(Task::Warning, "jobserver unavailable: using -j1. Add `+' to parent make rule.")) << QStringList(); @@ -288,7 +298,7 @@ void ProjectExplorerTest::testGnuMakeParserParsing_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << MakeTask(Task::Error, "[sis] Error 2")) << QStringList(); @@ -298,7 +308,7 @@ void ProjectExplorerTest::testGnuMakeParserParsing_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << MakeTask(Task::Error, "g++: Command not found")) << QStringList(); @@ -308,7 +318,7 @@ void ProjectExplorerTest::testGnuMakeParserParsing_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Warning, + << MakeTask(Task::Warning, "overriding commands for target `xxxx.app/Contents/Info.plist'", "Makefile", 794)) << QStringList(); @@ -371,7 +381,7 @@ void ProjectExplorerTest::testGnuMakeParserTaskMangling() testbench.testParsing( fi.fileName() + ":360: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.", OutputParserTester::STDERR, - {BuildSystemTask(Task::Error, + {MakeTask(Task::Error, "missing separator (did you mean TAB instead of 8 spaces?). Stop.", FilePath::fromString(theMakeFile.fileName()), 360)}, {}, {}); diff --git a/src/plugins/projectexplorer/ioutputparser.cpp b/src/plugins/projectexplorer/ioutputparser.cpp index 254b8a96e92..79ea5db0a31 100644 --- a/src/plugins/projectexplorer/ioutputparser.cpp +++ b/src/plugins/projectexplorer/ioutputparser.cpp @@ -60,6 +60,7 @@ public: QList scheduledTasks; Task currentTask; LinkSpecs linkSpecs; + QString origin; int lineCount = 0; bool targetLinkFixed = false; }; @@ -140,6 +141,7 @@ void OutputTaskParser::createOrAmendTask( flush(); d->currentTask = CompileTask(type, description, file, line, column); d->currentTask.details.append(originalLine); + d->currentTask.origin = d->origin; d->linkSpecs = linkSpecs; d->lineCount = 1; return; @@ -212,4 +214,10 @@ void OutputTaskParser::flush() d->lineCount = 0; d->targetLinkFixed = false; } + +void OutputTaskParser::setOrigin(const QString &source) +{ + d->origin = source; +} + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/ioutputparser.h b/src/plugins/projectexplorer/ioutputparser.h index 414f5854073..97461073b9c 100644 --- a/src/plugins/projectexplorer/ioutputparser.h +++ b/src/plugins/projectexplorer/ioutputparser.h @@ -30,6 +30,7 @@ public: protected: void flush() override; + void setOrigin(const QString &source); void scheduleTask(const Task &task, int outputLines, int skippedLines = 0); void setDetailsFormat(Task &task, const LinkSpecs &linkSpecs = {}); void fixTargetLink(); diff --git a/src/plugins/projectexplorer/ldparser.cpp b/src/plugins/projectexplorer/ldparser.cpp index e58e9b1ddc6..df79fcb01a6 100644 --- a/src/plugins/projectexplorer/ldparser.cpp +++ b/src/plugins/projectexplorer/ldparser.cpp @@ -20,6 +20,7 @@ namespace ProjectExplorer::Internal { LdParser::LdParser() { setObjectName(QLatin1String("LdParser")); + setOrigin("ld linker"); } OutputLineParser::Result LdParser::handleLine(const QString &line, OutputFormat type) diff --git a/src/plugins/projectexplorer/linuxiccparser.cpp b/src/plugins/projectexplorer/linuxiccparser.cpp index 6c79f57a697..f8537595740 100644 --- a/src/plugins/projectexplorer/linuxiccparser.cpp +++ b/src/plugins/projectexplorer/linuxiccparser.cpp @@ -4,7 +4,6 @@ #include "linuxiccparser.h" #include "ldparser.h" #include "lldparser.h" -#include "projectexplorerconstants.h" #include @@ -15,6 +14,8 @@ namespace ProjectExplorer { LinuxIccParser::LinuxIccParser() { setObjectName(QLatin1String("LinuxIccParser")); + setOrigin("ICC compiler"); + // main.cpp(53): error #308: function \"AClass::privatefunc\" (declared at line 4 of \"main.h\") is inaccessible m_firstLine.setPattern(QLatin1String("^([^\\(\\)]+?)" // filename (cap 1) diff --git a/src/plugins/projectexplorer/msvcparser.cpp b/src/plugins/projectexplorer/msvcparser.cpp index e72827cba5e..6eb22445777 100644 --- a/src/plugins/projectexplorer/msvcparser.cpp +++ b/src/plugins/projectexplorer/msvcparser.cpp @@ -77,6 +77,8 @@ static Task::TaskType taskType(const QString &category) MsvcParser::MsvcParser() { setObjectName("MsvcParser"); + setOrigin("MSVC compiler"); + m_compileRegExp.setPattern(QString(FILE_POS_PATTERN) + ".*(?:(warning|error) ([A-Z]+\\d{4} ?: )|note: )(.*)$"); QTC_CHECK(m_compileRegExp.isValid()); diff --git a/src/plugins/projectexplorer/task.h b/src/plugins/projectexplorer/task.h index ef9cb6f31c7..a4799f62b54 100644 --- a/src/plugins/projectexplorer/task.h +++ b/src/plugins/projectexplorer/task.h @@ -71,6 +71,7 @@ public: int movedLine = -1; // contains a line number if the line was moved in the editor int column = 0; Utils::Id category; + QString origin; // Having a container of QTextLayout::FormatRange in Task isn't that great // It would be cleaner to split up the text into diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index ac554b9d2bb..e0da471838b 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -179,7 +179,9 @@ QbsBuildSystem::QbsBuildSystem(BuildConfiguration *bc) }); connect(m_session, &QbsSession::errorOccurred, this, [](QbsSession::Error e) { const QString msg = Tr::tr("Fatal qbs error: %1").arg(QbsSession::errorString(e)); - TaskHub::addTask(BuildSystemTask(Task::Error, msg)); + BuildSystemTask t(Task::Error, msg); + t.origin = "qbs"; + TaskHub::addTask(t); }); connect(m_session, &QbsSession::fileListUpdated, this, &QbsBuildSystem::delayParsing); diff --git a/src/plugins/qbsprojectmanager/qbssession.cpp b/src/plugins/qbsprojectmanager/qbssession.cpp index 11beef03550..3b64bc7f7cc 100644 --- a/src/plugins/qbsprojectmanager/qbssession.cpp +++ b/src/plugins/qbsprojectmanager/qbssession.cpp @@ -723,8 +723,11 @@ QString ErrorInfo::toString() const void ErrorInfo::generateTasks(ProjectExplorer::Task::TaskType type) const { - for (const ErrorInfoItem &item : items) - TaskHub::addTask(BuildSystemTask(type, item.description, item.filePath, item.line)); + for (const ErrorInfoItem &item : items) { + BuildSystemTask t(type, item.description, item.filePath, item.line); + t.origin = "qbs"; + TaskHub::addTask(t); + } } void forAllProducts(const QJsonObject &project, const WorkerFunction &productFunction) diff --git a/src/plugins/qmakeprojectmanager/qmakeparser.cpp b/src/plugins/qmakeprojectmanager/qmakeparser.cpp index 568c54033b4..b4153a4696d 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparser.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparser.cpp @@ -11,6 +11,7 @@ using namespace ProjectExplorer; using namespace Utils; namespace QmakeProjectManager { +using namespace Internal; QMakeParser::QMakeParser() : m_error(QLatin1String("^(.+?):(\\d+?):\\s(.+?)$")) { @@ -43,7 +44,7 @@ OutputLineParser::Result QMakeParser::handleLine(const QString &line, OutputForm else if (description.startsWith(QLatin1String("error:"), Qt::CaseInsensitive)) type = Task::Error; - BuildSystemTask t(type, description, absoluteFilePath(FilePath::fromUserInput(fileName)), + QmakeTask t(type, description, absoluteFilePath(FilePath::fromUserInput(fileName)), match.captured(2).toInt() /* line */); LinkSpecs linkSpecs; addLinkSpecForAbsoluteFilePath(linkSpecs, t.file, t.line, t.column, fileNameOffset, @@ -54,13 +55,13 @@ OutputLineParser::Result QMakeParser::handleLine(const QString &line, OutputForm if (lne.startsWith(QLatin1String("Project ERROR: ")) || lne.startsWith(QLatin1String("ERROR: "))) { const QString description = lne.mid(lne.indexOf(QLatin1Char(':')) + 2); - scheduleTask(BuildSystemTask(Task::Error, description), 1); + scheduleTask(QmakeTask(Task::Error, description), 1); return Status::Done; } if (lne.startsWith(QLatin1String("Project WARNING: ")) || lne.startsWith(QLatin1String("WARNING: "))) { const QString description = lne.mid(lne.indexOf(QLatin1Char(':')) + 2); - scheduleTask(BuildSystemTask(Task::Warning, description), 1); + scheduleTask(QmakeTask(Task::Warning, description), 1); return Status::Done; } return Status::NotHandled; @@ -109,7 +110,7 @@ void QmakeOutputParserTest::testQmakeOutputParsers_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << QmakeTask(Task::Error, "undefined file")); QTest::newRow("qMake Parse Error") @@ -117,7 +118,7 @@ void QmakeOutputParserTest::testQmakeOutputParsers_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Error, + << QmakeTask(Task::Error, "Parse Error ('sth odd')", FilePath::fromUserInput("e:\\project.pro"), 14)); @@ -127,7 +128,7 @@ void QmakeOutputParserTest::testQmakeOutputParsers_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Warning, + << QmakeTask(Task::Warning, "bearer module might require ReadUserData capability")); QTest::newRow("qMake warning 2") @@ -135,7 +136,7 @@ void QmakeOutputParserTest::testQmakeOutputParsers_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Warning, + << QmakeTask(Task::Warning, "Failure to find: blackberrycreatepackagestepconfigwidget.cpp")); QTest::newRow("qMake warning with location") @@ -143,7 +144,7 @@ void QmakeOutputParserTest::testQmakeOutputParsers_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Warning, + << QmakeTask(Task::Warning, "Unescaped backslashes are deprecated.", FilePath::fromUserInput("e:\\QtSDK\\Simulator\\Qt\\msvc2008\\lib\\qtmaind.prl"), 1)); @@ -152,7 +153,7 @@ void QmakeOutputParserTest::testQmakeOutputParsers_data() << OutputParserTester::STDERR << QStringList() << QStringList() << (Tasks() - << BuildSystemTask(Task::Unknown, + << QmakeTask(Task::Unknown, "Note: No relevant classes found. No output generated.", FilePath::fromUserInput("/home/qtwebkithelpviewer.h"), -1)); } diff --git a/src/plugins/qmakeprojectmanager/qmakeparser.h b/src/plugins/qmakeprojectmanager/qmakeparser.h index 4f4225902c2..af6b27e2d89 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparser.h +++ b/src/plugins/qmakeprojectmanager/qmakeparser.h @@ -22,8 +22,22 @@ private: const QRegularExpression m_error; }; +namespace Internal { + +class QmakeTask : public ProjectExplorer::BuildSystemTask +{ +public: + QmakeTask(TaskType type, const QString &description, const Utils::FilePath &file = {}, + int line = -1) + : ProjectExplorer::BuildSystemTask(type, description, file, line) + { + origin = "qmake"; + } +}; + #ifdef WITH_TESTS -namespace Internal { QObject *createQmakeOutputParserTest(); } +QObject *createQmakeOutputParserTest(); #endif +} // namespace Internal } // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 0280ca7da96..6105be515e2 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -6,6 +6,7 @@ #include "qmakebuildconfiguration.h" #include "qmakenodes.h" #include "qmakenodetreebuilder.h" +#include "qmakeparser.h" #include "qmakeprojectimporter.h" #include "qmakeprojectmanagerconstants.h" #include "qmakeprojectmanagertr.h" @@ -18,7 +19,6 @@ #include #include -#include #include #include @@ -831,7 +831,7 @@ FilePath QmakeBuildSystem::buildDir(const FilePath &proFilePath) const void QmakeBuildSystem::proFileParseError(const QString &errorMessage, const FilePath &filePath) { - TaskHub::addTask(BuildSystemTask(Task::Error, errorMessage, filePath)); + TaskHub::addTask(QmakeTask(Task::Error, errorMessage, filePath)); } QtSupport::ProFileReader *QmakeBuildSystem::createProFileReader(const QmakeProFile *qmakeProFile)