Task: Add column information to compiler output tasks

Allows to directly jump to the problematic code
location in the editor.

Done for GCC and Clang which both use the format:
  file:line:column

Not done for MSVC, as this compiler uses the format:
  file(line)
and does not include column information.

It seems like clang-cl does use the format:
  file(line,column)
but the existing parsers were not prepared for
that and were therefore left unchanged for now.

Change-Id: I182634e1c5c941b19801ecafb69fa2b8f91f9d7a
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Andre Hartmann
2021-05-06 16:42:56 +02:00
committed by André Hartmann
parent 7cc2b149b1
commit 6bbe508e38
7 changed files with 79 additions and 58 deletions

View File

@@ -47,7 +47,7 @@ static const char *const FILE_PATTERN = "(<command line>|([A-Za-z]:)?[^:]+\\.[^:
ClangParser::ClangParser() : ClangParser::ClangParser() :
m_commandRegExp(QLatin1String("^clang(\\+\\+)?: +(fatal +)?(warning|error|note): (.*)$")), m_commandRegExp(QLatin1String("^clang(\\+\\+)?: +(fatal +)?(warning|error|note): (.*)$")),
m_inLineRegExp(QLatin1String("^In (.*?) included from (.*?):(\\d+):$")), m_inLineRegExp(QLatin1String("^In (.*?) included from (.*?):(\\d+):$")),
m_messageRegExp(QLatin1Char('^') + QLatin1String(FILE_PATTERN) + QLatin1String("(:(\\d+):\\d+|\\((\\d+)\\) *): +(fatal +)?(error|warning|note): (.*)$")), m_messageRegExp(QLatin1Char('^') + QLatin1String(FILE_PATTERN) + QLatin1String("(:(\\d+):(\\d+)|\\((\\d+)\\) *): +(fatal +)?(error|warning|note): (.*)$")),
m_summaryRegExp(QLatin1String("^\\d+ (warnings?|errors?)( and \\d (warnings?|errors?))? generated.$")), m_summaryRegExp(QLatin1String("^\\d+ (warnings?|errors?)( and \\d (warnings?|errors?))? generated.$")),
m_codesignRegExp(QLatin1String("^Code ?Sign error: (.*)$")), m_codesignRegExp(QLatin1String("^Code ?Sign error: (.*)$")),
m_expectSnippet(false) m_expectSnippet(false)
@@ -84,9 +84,11 @@ OutputLineParser::Result ClangParser::handleLine(const QString &line, OutputForm
m_expectSnippet = true; m_expectSnippet = true;
const FilePath filePath = absoluteFilePath(FilePath::fromUserInput(match.captured(2))); const FilePath filePath = absoluteFilePath(FilePath::fromUserInput(match.captured(2)));
const int lineNo = match.captured(3).toInt(); const int lineNo = match.captured(3).toInt();
const int column = 0;
LinkSpecs linkSpecs; LinkSpecs linkSpecs;
addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineNo, match, 2); addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineNo, match, 2);
createOrAmendTask(Task::Unknown, lne.trimmed(), lne, false, filePath, lineNo, linkSpecs); createOrAmendTask(Task::Unknown, lne.trimmed(), lne, false,
filePath, lineNo, column, linkSpecs);
return {Status::InProgress, linkSpecs}; return {Status::InProgress, linkSpecs};
} }
@@ -95,13 +97,17 @@ OutputLineParser::Result ClangParser::handleLine(const QString &line, OutputForm
m_expectSnippet = true; m_expectSnippet = true;
bool ok = false; bool ok = false;
int lineNo = match.captured(4).toInt(&ok); int lineNo = match.captured(4).toInt(&ok);
if (!ok) int column = match.captured(5).toInt();
lineNo = match.captured(5).toInt(&ok); if (!ok) {
lineNo = match.captured(6).toInt(&ok);
column = 0;
}
const FilePath filePath = absoluteFilePath(FilePath::fromUserInput(match.captured(1))); const FilePath filePath = absoluteFilePath(FilePath::fromUserInput(match.captured(1)));
LinkSpecs linkSpecs; LinkSpecs linkSpecs;
addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineNo, match, 1); addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineNo, match, 1);
createOrAmendTask(taskType(match.captured(7)), match.captured(8), lne, false, createOrAmendTask(taskType(match.captured(8)), match.captured(9), lne, false,
filePath, lineNo, linkSpecs); filePath, lineNo, column, linkSpecs);
return {Status::InProgress, linkSpecs}; return {Status::InProgress, linkSpecs};
} }
@@ -146,9 +152,10 @@ void ProjectExplorerPlugin::testClangOutputParser_data()
const QString &description, const QString &description,
const Utils::FilePath &file, const Utils::FilePath &file,
int line, int line,
int column,
const QVector<QTextLayout::FormatRange> formats) const QVector<QTextLayout::FormatRange> formats)
{ {
CompileTask task(type, description, file, line); CompileTask task(type, description, file, line, column);
task.formats = formats; task.formats = formats;
return task; return task;
}; };
@@ -206,7 +213,7 @@ void ProjectExplorerPlugin::testClangOutputParser_data()
"class Q_CORE_EXPORT QSysInfo {\n" "class Q_CORE_EXPORT QSysInfo {\n"
" ^", " ^",
FilePath::fromUserInput("..\\..\\..\\QtSDK1.1\\Desktop\\Qt\\4.7.3\\mingw\\include/QtCore/qglobal.h"), FilePath::fromUserInput("..\\..\\..\\QtSDK1.1\\Desktop\\Qt\\4.7.3\\mingw\\include/QtCore/qglobal.h"),
1425, 1425, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(61, 278))} << formatRange(61, 278))}
<< QString(); << QString();
@@ -224,7 +231,7 @@ void ProjectExplorerPlugin::testClangOutputParser_data()
"# define Q_CORE_EXPORT Q_DECL_IMPORT\n" "# define Q_CORE_EXPORT Q_DECL_IMPORT\n"
" ^", " ^",
FilePath::fromUserInput("..\\..\\..\\QtSDK1.1\\Desktop\\Qt\\4.7.3\\mingw\\include/QtCore/qglobal.h"), FilePath::fromUserInput("..\\..\\..\\QtSDK1.1\\Desktop\\Qt\\4.7.3\\mingw\\include/QtCore/qglobal.h"),
1289, 1289, 27,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(19, 167))) << formatRange(19, 167)))
<< QString(); << QString();
@@ -242,7 +249,7 @@ void ProjectExplorerPlugin::testClangOutputParser_data()
"#include <bits/c++config.h>\n" "#include <bits/c++config.h>\n"
" ^", " ^",
FilePath::fromUserInput("/usr/include/c++/4.6/utility"), FilePath::fromUserInput("/usr/include/c++/4.6/utility"),
68, 68, 10,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(34, 0) << formatRange(34, 0)
<< formatRange(34, 28, "olpfile:///usr/include/c++/4.6/utility::68::-1") << formatRange(34, 28, "olpfile:///usr/include/c++/4.6/utility::68::-1")
@@ -262,7 +269,7 @@ void ProjectExplorerPlugin::testClangOutputParser_data()
" int x = option->rect.x() + horizontal ? 2 : 6;\n" " int x = option->rect.x() + horizontal ? 2 : 6;\n"
" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^", " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^",
FilePath::fromUserInput("/home/code/src/creator/src/plugins/coreplugin/manhattanstyle.cpp"), FilePath::fromUserInput("/home/code/src/creator/src/plugins/coreplugin/manhattanstyle.cpp"),
567, 567, 51,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(74, 0) << formatRange(74, 0)
<< formatRange(74, 64, "olpfile:///home/code/src/creator/src/plugins/coreplugin/manhattanstyle.cpp::567::-1") << formatRange(74, 64, "olpfile:///home/code/src/creator/src/plugins/coreplugin/manhattanstyle.cpp::567::-1")

View File

@@ -45,7 +45,7 @@ GccParser::GccParser()
{ {
setObjectName(QLatin1String("GCCParser")); setObjectName(QLatin1String("GCCParser"));
m_regExp.setPattern(QLatin1Char('^') + QLatin1String(FILE_PATTERN) m_regExp.setPattern(QLatin1Char('^') + QLatin1String(FILE_PATTERN)
+ QLatin1String("(?:(?:(\\d+):(\\d+:)?)|\\(.*\\):)\\s+((fatal |#)?(warning|error|note):?\\s)?([^\\s].+)$")); + QLatin1String("(?:(?:(\\d+):(?:(\\d+):)?)|\\(.*\\):)\\s+((fatal |#)?(warning|error|note):?\\s)?([^\\s].+)$"));
QTC_CHECK(m_regExp.isValid()); QTC_CHECK(m_regExp.isValid());
m_regExpScope.setPattern(QLatin1Char('^') + FILE_PATTERN m_regExpScope.setPattern(QLatin1Char('^') + FILE_PATTERN
@@ -90,13 +90,14 @@ void GccParser::createOrAmendTask(
bool forceAmend, bool forceAmend,
const FilePath &file, const FilePath &file,
int line, int line,
int column,
const LinkSpecs &linkSpecs const LinkSpecs &linkSpecs
) )
{ {
const bool amend = !m_currentTask.isNull() && (forceAmend || isContinuation(originalLine)); const bool amend = !m_currentTask.isNull() && (forceAmend || isContinuation(originalLine));
if (!amend) { if (!amend) {
flush(); flush();
m_currentTask = CompileTask(type, description, file, line); m_currentTask = CompileTask(type, description, file, line, column);
m_currentTask.details.append(originalLine); m_currentTask.details.append(originalLine);
m_linkSpecs = linkSpecs; m_linkSpecs = linkSpecs;
m_lines = 1; m_lines = 1;
@@ -119,6 +120,7 @@ void GccParser::createOrAmendTask(
if (!file.isEmpty()) { if (!file.isEmpty()) {
m_currentTask.setFile(file); m_currentTask.setFile(file);
m_currentTask.line = line; m_currentTask.line = line;
m_currentTask.column = column;
} }
} }
++m_lines; ++m_lines;
@@ -183,9 +185,10 @@ OutputLineParser::Result GccParser::handleLine(const QString &line, OutputFormat
if (match.hasMatch()) { if (match.hasMatch()) {
const FilePath filePath = absoluteFilePath(FilePath::fromUserInput(match.captured(1))); const FilePath filePath = absoluteFilePath(FilePath::fromUserInput(match.captured(1)));
const int lineNo = match.captured(3).toInt(); const int lineNo = match.captured(3).toInt();
const int column = match.captured(4).toInt();
LinkSpecs linkSpecs; LinkSpecs linkSpecs;
addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineNo, match, 1); addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineNo, match, 1);
createOrAmendTask(Task::Unknown, lne.trimmed(), lne, false, filePath, lineNo, linkSpecs); createOrAmendTask(Task::Unknown, lne.trimmed(), lne, false, filePath, lineNo, column, linkSpecs);
return {Status::InProgress, linkSpecs}; return {Status::InProgress, linkSpecs};
} }
@@ -196,7 +199,7 @@ OutputLineParser::Result GccParser::handleLine(const QString &line, OutputFormat
LinkSpecs linkSpecs; LinkSpecs linkSpecs;
if (!filePath.isEmpty()) if (!filePath.isEmpty())
addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, -1, match, 3); addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, -1, match, 3);
createOrAmendTask(type, match.captured(2), lne, false, filePath, -1, linkSpecs); createOrAmendTask(type, match.captured(2), lne, false, filePath, -1, 0, linkSpecs);
flush(); flush();
return {Status::Done, linkSpecs}; return {Status::Done, linkSpecs};
} }
@@ -204,6 +207,7 @@ OutputLineParser::Result GccParser::handleLine(const QString &line, OutputFormat
match = m_regExp.match(lne); match = m_regExp.match(lne);
if (match.hasMatch()) { if (match.hasMatch()) {
int lineno = match.captured(3).toInt(); int lineno = match.captured(3).toInt();
int column = match.captured(4).toInt();
Task::TaskType type = Task::Unknown; Task::TaskType type = Task::Unknown;
QString description = match.captured(8); QString description = match.captured(8);
if (match.captured(7) == QLatin1String("warning")) if (match.captured(7) == QLatin1String("warning"))
@@ -220,18 +224,19 @@ OutputLineParser::Result GccParser::handleLine(const QString &line, OutputFormat
const FilePath filePath = absoluteFilePath(FilePath::fromUserInput(match.captured(1))); const FilePath filePath = absoluteFilePath(FilePath::fromUserInput(match.captured(1)));
LinkSpecs linkSpecs; LinkSpecs linkSpecs;
addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineno, match, 1); addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineno, match, 1);
createOrAmendTask(type, description, lne, false, filePath, lineno, linkSpecs); createOrAmendTask(type, description, lne, false, filePath, lineno, column, linkSpecs);
return {Status::InProgress, linkSpecs}; return {Status::InProgress, linkSpecs};
} }
match = m_regExpScope.match(lne); match = m_regExpScope.match(lne);
if (match.hasMatch()) { if (match.hasMatch()) {
const int lineno = match.captured(3).toInt(); const int lineno = match.captured(3).toInt();
const int column = match.captured(4).toInt();
const QString description = match.captured(5); const QString description = match.captured(5);
const FilePath filePath = absoluteFilePath(FilePath::fromUserInput(match.captured(1))); const FilePath filePath = absoluteFilePath(FilePath::fromUserInput(match.captured(1)));
LinkSpecs linkSpecs; LinkSpecs linkSpecs;
addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineno, match, 1); addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineno, match, 1);
createOrAmendTask(Task::Unknown, description, lne, false, filePath, lineno, linkSpecs); createOrAmendTask(Task::Unknown, description, lne, false, filePath, lineno, column, linkSpecs);
return {Status::InProgress, linkSpecs}; return {Status::InProgress, linkSpecs};
} }
@@ -275,9 +280,10 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
const QString &description, const QString &description,
const Utils::FilePath &file, const Utils::FilePath &file,
int line, int line,
int column,
const QVector<QTextLayout::FormatRange> formats) const QVector<QTextLayout::FormatRange> formats)
{ {
CompileTask task(type, description, file, line); CompileTask task(type, description, file, line, column);
task.formats = formats; task.formats = formats;
return task; return task;
}; };
@@ -320,7 +326,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"/temp/test/untitled8/main.cpp: In function `int main(int, char**)':\n" "/temp/test/untitled8/main.cpp: In function `int main(int, char**)':\n"
"/temp/test/untitled8/main.cpp:9: error: `sfasdf' undeclared (first use this function)", "/temp/test/untitled8/main.cpp:9: error: `sfasdf' undeclared (first use this function)",
FilePath::fromUserInput("/temp/test/untitled8/main.cpp"), FilePath::fromUserInput("/temp/test/untitled8/main.cpp"),
9, 9, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(46, 0) << formatRange(46, 0)
<< formatRange(46, 29, "olpfile:///temp/test/untitled8/main.cpp::0::-1") << formatRange(46, 29, "olpfile:///temp/test/untitled8/main.cpp::0::-1")
@@ -330,7 +336,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
<< CompileTask(Task::Error, << CompileTask(Task::Error,
"(Each undeclared identifier is reported only once for each function it appears in.)", "(Each undeclared identifier is reported only once for each function it appears in.)",
FilePath::fromUserInput("/temp/test/untitled8/main.cpp"), FilePath::fromUserInput("/temp/test/untitled8/main.cpp"),
9)) 9, 0))
<< QString(); << QString();
QTest::newRow("GCCE warning") QTest::newRow("GCCE warning")
@@ -341,7 +347,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
<< CompileTask(Task::Warning, << CompileTask(Task::Warning,
"inline function `QDebug qDebug()' used but never defined", "inline function `QDebug qDebug()' used but never defined",
FilePath::fromUserInput("/src/corelib/global/qglobal.h"), FilePath::fromUserInput("/src/corelib/global/qglobal.h"),
1635)) 1635, 0))
<< QString(); << QString();
QTest::newRow("warning") QTest::newRow("warning")
@@ -352,7 +358,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
<< CompileTask(Task::Warning, << CompileTask(Task::Warning,
"Some warning", "Some warning",
FilePath::fromUserInput("main.cpp"), FilePath::fromUserInput("main.cpp"),
7)) 7, 2))
<< QString(); << QString();
QTest::newRow("GCCE #error") QTest::newRow("GCCE #error")
@@ -363,7 +369,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
<< CompileTask(Task::Error, << CompileTask(Task::Error,
"#error Symbian error", "#error Symbian error",
FilePath::fromUserInput("C:\\temp\\test\\untitled8\\main.cpp"), FilePath::fromUserInput("C:\\temp\\test\\untitled8\\main.cpp"),
7)) 7, 0))
<< QString(); << QString();
// Symbian reports #warning(s) twice (using different syntax). // Symbian reports #warning(s) twice (using different syntax).
@@ -375,7 +381,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
<< CompileTask(Task::Warning, << CompileTask(Task::Warning,
"#warning Symbian warning", "#warning Symbian warning",
FilePath::fromUserInput("C:\\temp\\test\\untitled8\\main.cpp"), FilePath::fromUserInput("C:\\temp\\test\\untitled8\\main.cpp"),
8)) 8, 0))
<< QString(); << QString();
QTest::newRow("GCCE #warning2") QTest::newRow("GCCE #warning2")
@@ -386,7 +392,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
<< CompileTask(Task::Warning, << CompileTask(Task::Warning,
"#warning Symbian warning", "#warning Symbian warning",
FilePath::fromUserInput("/temp/test/untitled8/main.cpp"), FilePath::fromUserInput("/temp/test/untitled8/main.cpp"),
8)) 8, 2))
<< QString(); << QString();
QVector<QTextLayout::FormatRange> formatRanges; QVector<QTextLayout::FormatRange> formatRanges;
@@ -409,7 +415,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"main.o: In function `main':\n" "main.o: In function `main':\n"
"C:\\temp\\test\\untitled8/main.cpp:8: undefined reference to `MainWindow::doSomething()'", "C:\\temp\\test\\untitled8/main.cpp:8: undefined reference to `MainWindow::doSomething()'",
FilePath::fromUserInput("C:\\temp\\test\\untitled8/main.cpp"), FilePath::fromUserInput("C:\\temp\\test\\untitled8/main.cpp"),
8, 8, 0,
formatRanges) formatRanges)
<< CompileTask(Task::Error, << CompileTask(Task::Error,
"collect2: ld returned 1 exit status")) "collect2: ld returned 1 exit status"))
@@ -435,7 +441,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"main.o: In function `main':\n" "main.o: In function `main':\n"
"C:\\temp\\test\\untitled8/main.cpp:(.text+0x40): undefined reference to `MainWindow::doSomething()'", "C:\\temp\\test\\untitled8/main.cpp:(.text+0x40): undefined reference to `MainWindow::doSomething()'",
FilePath::fromUserInput("C:\\temp\\test\\untitled8/main.cpp"), FilePath::fromUserInput("C:\\temp\\test\\untitled8/main.cpp"),
-1, -1, 0,
formatRanges) formatRanges)
<< CompileTask(Task::Error, << CompileTask(Task::Error,
"collect2: ld returned 1 exit status")) "collect2: ld returned 1 exit status"))
@@ -472,13 +478,13 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"../../../../master/src/plugins/debugger/gdb/gdbengine.cpp: In member function 'void Debugger::Internal::GdbEngine::handleBreakInsert2(const Debugger::Internal::GdbResponse&)':\n" "../../../../master/src/plugins/debugger/gdb/gdbengine.cpp: In member function 'void Debugger::Internal::GdbEngine::handleBreakInsert2(const Debugger::Internal::GdbResponse&)':\n"
"../../../../master/src/plugins/debugger/gdb/gdbengine.cpp:2114: warning: unused variable 'index'", "../../../../master/src/plugins/debugger/gdb/gdbengine.cpp:2114: warning: unused variable 'index'",
FilePath::fromUserInput("../../../../master/src/plugins/debugger/gdb/gdbengine.cpp"), FilePath::fromUserInput("../../../../master/src/plugins/debugger/gdb/gdbengine.cpp"),
2114, 2114, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(24, 272)) << formatRange(24, 272))
<< CompileTask(Task::Warning, << CompileTask(Task::Warning,
"unused variable 'handler'", "unused variable 'handler'",
FilePath::fromUserInput("../../../../master/src/plugins/debugger/gdb/gdbengine.cpp"), FilePath::fromUserInput("../../../../master/src/plugins/debugger/gdb/gdbengine.cpp"),
2115)) 2115, 0))
<< QString(); << QString();
QTest::newRow("gnumakeparser.cpp errors") QTest::newRow("gnumakeparser.cpp errors")
@@ -493,7 +499,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"/home/code/src/creator/src/plugins/projectexplorer/gnumakeparser.cpp: In member function 'void ProjectExplorer::ProjectExplorerPlugin::testGnuMakeParserTaskMangling_data()':\n" "/home/code/src/creator/src/plugins/projectexplorer/gnumakeparser.cpp: In member function 'void ProjectExplorer::ProjectExplorerPlugin::testGnuMakeParserTaskMangling_data()':\n"
"/home/code/src/creator/src/plugins/projectexplorer/gnumakeparser.cpp:264: error: expected primary-expression before ':' token", "/home/code/src/creator/src/plugins/projectexplorer/gnumakeparser.cpp:264: error: expected primary-expression before ':' token",
FilePath::fromUserInput("/home/code/src/creator/src/plugins/projectexplorer/gnumakeparser.cpp"), FilePath::fromUserInput("/home/code/src/creator/src/plugins/projectexplorer/gnumakeparser.cpp"),
264, 264, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(45, 0) << formatRange(45, 0)
<< formatRange(45, 68, "olpfile:///home/code/src/creator/src/plugins/projectexplorer/gnumakeparser.cpp::0::-1") << formatRange(45, 68, "olpfile:///home/code/src/creator/src/plugins/projectexplorer/gnumakeparser.cpp::0::-1")
@@ -503,7 +509,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
<< CompileTask(Task::Error, << CompileTask(Task::Error,
"expected ';' before ':' token", "expected ';' before ':' token",
FilePath::fromUserInput("/home/code/src/creator/src/plugins/projectexplorer/gnumakeparser.cpp"), FilePath::fromUserInput("/home/code/src/creator/src/plugins/projectexplorer/gnumakeparser.cpp"),
264)) 264, 0))
<< QString(); << QString();
QTest::newRow("distcc error(QTCREATORBUG-904)") QTest::newRow("distcc error(QTCREATORBUG-904)")
@@ -562,7 +568,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"/Qt/4.6.2-Symbian/s60sdk/epoc32/include/stdapis/stlport/stl/_tree.c: In static member function 'static std::_Rb_tree_node_base* std::_Rb_global<_Dummy>::_Rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*&, std::_Rb_tree_node_base*&, std::_Rb_tree_node_base*&)':\n" "/Qt/4.6.2-Symbian/s60sdk/epoc32/include/stdapis/stlport/stl/_tree.c: In static member function 'static std::_Rb_tree_node_base* std::_Rb_global<_Dummy>::_Rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*&, std::_Rb_tree_node_base*&, std::_Rb_tree_node_base*&)':\n"
"/Qt/4.6.2-Symbian/s60sdk/epoc32/include/stdapis/stlport/stl/_tree.c:194: warning: suggest explicit braces to avoid ambiguous 'else'", "/Qt/4.6.2-Symbian/s60sdk/epoc32/include/stdapis/stlport/stl/_tree.c:194: warning: suggest explicit braces to avoid ambiguous 'else'",
FilePath::fromUserInput("/Qt/4.6.2-Symbian/s60sdk/epoc32/include/stdapis/stlport/stl/_tree.c"), FilePath::fromUserInput("/Qt/4.6.2-Symbian/s60sdk/epoc32/include/stdapis/stlport/stl/_tree.c"),
194, 194, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(50, 0) << formatRange(50, 0)
<< formatRange(50, 67, "olpfile:///Qt/4.6.2-Symbian/s60sdk/epoc32/include/stdapis/stlport/stl/_tree.c::0::-1") << formatRange(50, 67, "olpfile:///Qt/4.6.2-Symbian/s60sdk/epoc32/include/stdapis/stlport/stl/_tree.c::0::-1")
@@ -599,7 +605,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"../../scriptbug/main.cpp: In function void foo(i) [with i = double]:\n" "../../scriptbug/main.cpp: In function void foo(i) [with i = double]:\n"
"../../scriptbug/main.cpp:22: instantiated from here", "../../scriptbug/main.cpp:22: instantiated from here",
FilePath::fromUserInput("../../scriptbug/main.cpp"), FilePath::fromUserInput("../../scriptbug/main.cpp"),
-1, -1, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(43, 120)) << formatRange(43, 120))
<< CompileTask(Task::Warning, << CompileTask(Task::Warning,
@@ -644,7 +650,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"../../scriptbug/main.cpp: In instantiation of void bar(i) [with i = double]:\n" "../../scriptbug/main.cpp: In instantiation of void bar(i) [with i = double]:\n"
"../../scriptbug/main.cpp:8: instantiated from void foo(i) [with i = double]", "../../scriptbug/main.cpp:8: instantiated from void foo(i) [with i = double]",
FilePath::fromUserInput("../../scriptbug/main.cpp"), FilePath::fromUserInput("../../scriptbug/main.cpp"),
-1, -1, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(17, 195)) << formatRange(17, 195))
<< CompileTask(Task::Unknown, << CompileTask(Task::Unknown,
@@ -665,7 +671,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
<< CompileTask(Task::Error, << CompileTask(Task::Error,
"test.moc: No such file or directory", "test.moc: No such file or directory",
FilePath::fromUserInput("/home/code/test.cpp"), FilePath::fromUserInput("/home/code/test.cpp"),
54)) 54, 38))
<< QString(); << QString();
formatRanges.clear(); formatRanges.clear();
@@ -689,7 +695,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"debug/qplotaxis.o: In function `QPlotAxis':\n" "debug/qplotaxis.o: In function `QPlotAxis':\n"
"M:\\Development\\x64\\QtPlot/qplotaxis.cpp:26: undefined reference to `vtable for QPlotAxis'", "M:\\Development\\x64\\QtPlot/qplotaxis.cpp:26: undefined reference to `vtable for QPlotAxis'",
FilePath::fromUserInput("M:\\Development\\x64\\QtPlot/qplotaxis.cpp"), FilePath::fromUserInput("M:\\Development\\x64\\QtPlot/qplotaxis.cpp"),
26, 26, 0,
formatRanges) formatRanges)
<< CompileTask(Task::Error, << CompileTask(Task::Error,
"undefined reference to `vtable for QPlotAxis'", "undefined reference to `vtable for QPlotAxis'",
@@ -713,7 +719,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"../stl/main.cpp: In member function typename _Vector_base<_Tp, _Alloc>::_Tp_alloc_type::const_reference Vector<_Tp, _Alloc>::at(int) [with _Tp = Point, _Alloc = Allocator<Point>]:\n" "../stl/main.cpp: In member function typename _Vector_base<_Tp, _Alloc>::_Tp_alloc_type::const_reference Vector<_Tp, _Alloc>::at(int) [with _Tp = Point, _Alloc = Allocator<Point>]:\n"
"../stl/main.cpp:38: instantiated from here", "../stl/main.cpp:38: instantiated from here",
FilePath::fromUserInput("../stl/main.cpp"), FilePath::fromUserInput("../stl/main.cpp"),
-1, -1, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(163, 224)) << formatRange(163, 224))
<< CompileTask(Task::Warning, << CompileTask(Task::Warning,
@@ -724,7 +730,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"../stl/main.cpp: At global scope:\n" "../stl/main.cpp: At global scope:\n"
"../stl/main.cpp:31: warning: unused parameter index", "../stl/main.cpp:31: warning: unused parameter index",
FilePath::fromUserInput("../stl/main.cpp"), FilePath::fromUserInput("../stl/main.cpp"),
31, 31, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(23, 85))) << formatRange(23, 85)))
<< QString(); << QString();
@@ -757,7 +763,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"C:/Symbian_SDK/epoc32/include/e32cmn.inl: In member function 'SSecureId::operator const TSecureId&() const':\n" "C:/Symbian_SDK/epoc32/include/e32cmn.inl: In member function 'SSecureId::operator const TSecureId&() const':\n"
"C:/Symbian_SDK/epoc32/include/e32cmn.inl:7094: warning: returning reference to temporary", "C:/Symbian_SDK/epoc32/include/e32cmn.inl:7094: warning: returning reference to temporary",
FilePath::fromUserInput("C:/Symbian_SDK/epoc32/include/e32cmn.inl"), FilePath::fromUserInput("C:/Symbian_SDK/epoc32/include/e32cmn.inl"),
7094, 7094, 0,
formatRanges)} formatRanges)}
<< QString(); << QString();
QTest::newRow("In constructor 2") QTest::newRow("In constructor 2")
@@ -774,7 +780,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
" 28 | memset(this, 0, sizeof(PerfEventAttributes));\n" " 28 | memset(this, 0, sizeof(PerfEventAttributes));\n"
" | ^", " | ^",
FilePath::fromUserInput("perfattributes.cpp"), FilePath::fromUserInput("perfattributes.cpp"),
28, 28, 48,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(170, 400))} << formatRange(170, 400))}
<< QString(); << QString();
@@ -801,7 +807,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
" from <command line>:26:\n" " from <command line>:26:\n"
"/Symbian/SDK/epoc32/include/variant/Symbian_OS.hrh:1134:26: warning: no newline at end of file", "/Symbian/SDK/epoc32/include/variant/Symbian_OS.hrh:1134:26: warning: no newline at end of file",
FilePath::fromUserInput("/Symbian/SDK/epoc32/include/variant/Symbian_OS.hrh"), FilePath::fromUserInput("/Symbian/SDK/epoc32/include/variant/Symbian_OS.hrh"),
1134, 1134, 26,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(26, 22) << formatRange(26, 22)
<< formatRange(48, 39, "olpfile:///Symbian/SDK/EPOC32/INCLUDE/GCCE/GCCE.h::15::-1") << formatRange(48, 39, "olpfile:///Symbian/SDK/EPOC32/INCLUDE/GCCE/GCCE.h::15::-1")
@@ -831,7 +837,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"../../../src/shared/proparser/profileevaluator.cpp: In member function 'ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateConditionalFunction(const ProString&, const ProStringList&)':\n" "../../../src/shared/proparser/profileevaluator.cpp: In member function 'ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateConditionalFunction(const ProString&, const ProStringList&)':\n"
"../../../src/shared/proparser/profileevaluator.cpp:2817:9: warning: case value '0' not in enumerated type 'ProFileEvaluator::Private::TestFunc'", "../../../src/shared/proparser/profileevaluator.cpp:2817:9: warning: case value '0' not in enumerated type 'ProFileEvaluator::Private::TestFunc'",
FilePath::fromUserInput("../../../src/shared/proparser/profileevaluator.cpp"), FilePath::fromUserInput("../../../src/shared/proparser/profileevaluator.cpp"),
2817, 2817, 9,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(76, 351))) << formatRange(76, 351)))
<< QString(); << QString();
@@ -847,7 +853,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"In file included from <command-line>:0:0:\n" "In file included from <command-line>:0:0:\n"
"./mw.h:4:0: warning: \"STUPID_DEFINE\" redefined", "./mw.h:4:0: warning: \"STUPID_DEFINE\" redefined",
FilePath::fromUserInput("./mw.h"), FilePath::fromUserInput("./mw.h"),
4, 4, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(26, 88))} << formatRange(26, 88))}
<< QString(); << QString();
@@ -864,13 +870,13 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"file.h: In function 'void UnitTest::CheckEqual(UnitTest::TestResults&, const Expected&, const Actual&, const UnitTest::TestDetails&) [with Expected = unsigned int, Actual = int]':\n" "file.h: In function 'void UnitTest::CheckEqual(UnitTest::TestResults&, const Expected&, const Actual&, const UnitTest::TestDetails&) [with Expected = unsigned int, Actual = int]':\n"
"file.cpp:87:10: instantiated from here", "file.cpp:87:10: instantiated from here",
FilePath::fromUserInput("file.h"), FilePath::fromUserInput("file.h"),
-1, -1, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(172, 218)) << formatRange(172, 218))
<< CompileTask(Task::Warning, << CompileTask(Task::Warning,
"comparison between signed and unsigned integer expressions [-Wsign-compare]", "comparison between signed and unsigned integer expressions [-Wsign-compare]",
FilePath::fromUserInput("file.h"), FilePath::fromUserInput("file.h"),
21)) 21, 5))
<< QString(); << QString();
QTest::newRow("linker error") // QTCREATORBUG-3107 QTest::newRow("linker error") // QTCREATORBUG-3107
@@ -908,7 +914,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
" #include <QtGui/QAction>\n" " #include <QtGui/QAction>\n"
" ^", " ^",
FilePath::fromUserInput(".uic/ui_pluginerrorview.h"), FilePath::fromUserInput(".uic/ui_pluginerrorview.h"),
14, 14, 25,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(41, 22) << formatRange(41, 22)
<< formatRange(63, 67, "olpfile:///home/code/src/creator/src/libs/extensionsystem/pluginerrorview.cpp::31::-1") << formatRange(63, 67, "olpfile:///home/code/src/creator/src/libs/extensionsystem/pluginerrorview.cpp::31::-1")
@@ -932,7 +938,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"/usr/include/qt4/QtCore/qstring.h:597:5: error: 'QString::QString(const char*)' is private\n" "/usr/include/qt4/QtCore/qstring.h:597:5: error: 'QString::QString(const char*)' is private\n"
"main.cpp:7:22: error: within this context", "main.cpp:7:22: error: within this context",
FilePath::fromUserInput("/usr/include/qt4/QtCore/qstring.h"), FilePath::fromUserInput("/usr/include/qt4/QtCore/qstring.h"),
597, 597, 5,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(43, 22) << formatRange(43, 22)
<< formatRange(65, 31, "olpfile:///usr/include/qt4/QtCore/QString::1::-1") << formatRange(65, 31, "olpfile:///usr/include/qt4/QtCore/QString::1::-1")
@@ -956,7 +962,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
"foo.o: In function `foo()':\n" "foo.o: In function `foo()':\n"
"/home/user/test/foo.cpp:2: multiple definition of `foo()'", "/home/user/test/foo.cpp:2: multiple definition of `foo()'",
FilePath::fromUserInput("/home/user/test/foo.cpp"), FilePath::fromUserInput("/home/user/test/foo.cpp"),
2, 2, 0,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(31, 28) << formatRange(31, 28)
<< formatRange(59, 23, "olpfile:///home/user/test/foo.cpp::2::-1") << formatRange(59, 23, "olpfile:///home/user/test/foo.cpp::2::-1")
@@ -1211,7 +1217,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
" 399 | inline Private(const Private &other) Q_DECL_NOTHROW\n" " 399 | inline Private(const Private &other) Q_DECL_NOTHROW\n"
" | ^~~~~~~)", " | ^~~~~~~)",
FilePath::fromUserInput("/usr/include/qt/QtCore/qvariant.h"), FilePath::fromUserInput("/usr/include/qt/QtCore/qvariant.h"),
273, 273, 25,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(140, 22) << formatRange(140, 22)
<< formatRange(162, 32, "olpfile:///usr/include/qt/QtCore/qlocale.h::43::-1") << formatRange(162, 32, "olpfile:///usr/include/qt/QtCore/qlocale.h::43::-1")
@@ -1239,7 +1245,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
" | |\n" " | |\n"
" | boxed_value<[...]>", " | boxed_value<[...]>",
FilePath::fromUserInput("t.cc"), FilePath::fromUserInput("t.cc"),
15, 15, 4,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(93, 460)), << formatRange(93, 460)),
compileTask(Task::Error, compileTask(Task::Error,
@@ -1251,7 +1257,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
" +++ |+#include <string>\n" " +++ |+#include <string>\n"
" 1 | std::string test(void)", " 1 | std::string test(void)",
FilePath::fromUserInput("incomplete.c"), FilePath::fromUserInput("incomplete.c"),
1, 1, 6,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(49, 284)), << formatRange(49, 284)),
compileTask(Task::Warning, compileTask(Task::Warning,
@@ -1266,7 +1272,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
" 1 | extern int callee(int one, const char *two, float three);\n" " 1 | extern int callee(int one, const char *two, float three);\n"
" | ~~~~~~~~~~~~^~~", " | ~~~~~~~~~~~~^~~",
FilePath::fromUserInput("param-type-mismatch.c"), FilePath::fromUserInput("param-type-mismatch.c"),
5, 5, 24,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(92, 519))} << formatRange(92, 519))}
<< QString(); << QString();
@@ -1299,7 +1305,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
" 465 | at(newSize) = 0;\n" " 465 | at(newSize) = 0;\n"
" | ~~~~~~~~~~~~^~~", " | ~~~~~~~~~~~~^~~",
FilePath::fromUserInput("smallstring.h"), FilePath::fromUserInput("smallstring.h"),
465, 465, 21,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(62, 805))} << formatRange(62, 805))}
<< QString(); << QString();
@@ -1341,7 +1347,7 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
" 110 | T value;\n" " 110 | T value;\n"
" | ^~~~~", " | ^~~~~",
FilePath::fromUserInput("qmap.h"), FilePath::fromUserInput("qmap.h"),
110, 110, 7,
QVector<QTextLayout::FormatRange>() QVector<QTextLayout::FormatRange>()
<< formatRange(46, 1458))} << formatRange(46, 1458))}
<< QString(); << QString();

View File

@@ -52,6 +52,7 @@ protected:
bool forceAmend = false, bool forceAmend = false,
const Utils::FilePath &file = {}, const Utils::FilePath &file = {},
int line = -1, int line = -1,
int column = 0,
const LinkSpecs &linkSpecs = {} const LinkSpecs &linkSpecs = {}
); );
void flush() override; void flush() override;

View File

@@ -91,6 +91,7 @@ void OutputParserTester::testParsing(const QString &lines,
QVERIFY2(m_receivedTasks.at(i).file == tasks.at(i).file, QVERIFY2(m_receivedTasks.at(i).file == tasks.at(i).file,
msgFileComparisonFail(m_receivedTasks.at(i).file, tasks.at(i).file)); msgFileComparisonFail(m_receivedTasks.at(i).file, tasks.at(i).file));
QCOMPARE(m_receivedTasks.at(i).line, tasks.at(i).line); QCOMPARE(m_receivedTasks.at(i).line, tasks.at(i).line);
QCOMPARE(m_receivedTasks.at(i).column, tasks.at(i).column);
QCOMPARE(static_cast<int>(m_receivedTasks.at(i).type), static_cast<int>(tasks.at(i).type)); QCOMPARE(static_cast<int>(m_receivedTasks.at(i).type), static_cast<int>(tasks.at(i).type));
// Skip formats check if we haven't specified expected // Skip formats check if we haven't specified expected
if (tasks.at(i).formats.size() == 0) if (tasks.at(i).formats.size() == 0)

View File

@@ -46,7 +46,8 @@ bool ShowInEditorTaskHandler::canHandle(const Task &task) const
void ShowInEditorTaskHandler::handle(const Task &task) void ShowInEditorTaskHandler::handle(const Task &task)
{ {
QFileInfo fi(task.file.toFileInfo()); QFileInfo fi(task.file.toFileInfo());
Core::EditorManager::openEditorAt(fi.filePath(), task.movedLine, {}, {}, const int column = task.column ? task.column - 1 : 0;
Core::EditorManager::openEditorAt(fi.filePath(), task.movedLine, column, {},
Core::EditorManager::SwitchSplitIfAlreadyVisible); Core::EditorManager::SwitchSplitIfAlreadyVisible);
} }

View File

@@ -206,9 +206,12 @@ bool containsType(const Tasks &issues, Task::TaskType type)
// CompilerTask // CompilerTask
CompileTask::CompileTask(TaskType type, const QString &desc, const FilePath &file, int line) CompileTask::CompileTask(TaskType type, const QString &desc,
const FilePath &file, int line, int column_)
: Task(type, desc, file, line, ProjectExplorer::Constants::TASK_CATEGORY_COMPILE) : Task(type, desc, file, line, ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)
{} {
column = column_;
}
// BuildSystemTask // BuildSystemTask

View File

@@ -85,6 +85,7 @@ public:
Utils::FilePaths fileCandidates; Utils::FilePaths fileCandidates;
int line = -1; int line = -1;
int movedLine = -1; // contains a line number if the line was moved in the editor int movedLine = -1; // contains a line number if the line was moved in the editor
int column = 0;
Utils::Id category; Utils::Id category;
// Having a container of QTextLayout::FormatRange in Task isn't that great // Having a container of QTextLayout::FormatRange in Task isn't that great
@@ -113,7 +114,8 @@ public:
CompileTask(TaskType type, CompileTask(TaskType type,
const QString &description, const QString &description,
const Utils::FilePath &file = {}, const Utils::FilePath &file = {},
int line = -1); int line = -1,
int column = 0);
}; };
class PROJECTEXPLORER_EXPORT BuildSystemTask : public Task class PROJECTEXPLORER_EXPORT BuildSystemTask : public Task