aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2020-04-07 13:49:34 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2020-04-07 15:20:22 +0000
commit7745eacc7afae4acf3e07325ab01cf6e6821037c (patch)
tree2a125e0c7530d3ae252a740b42db4cd1d34f805a /src/plugins
parentb22bb5a9a7aa22fe13e1282c5db851688ec4d83f (diff)
Output parsers: Generalize the search directory concept
All parsers can now have search directories, not just the GnuMakeParser. This allows us to get rid of the "task mangling", removing another instance where the order of parsers in the chain mattered. Task-number: QTCREATORBUG-22665 Change-Id: Id0d55522ae6800afd9f50ff36546224b0d8bb382 Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/android/androidpackageinstallationstep.cpp2
-rw-r--r--src/plugins/android/javaparser.cpp2
-rw-r--r--src/plugins/baremetal/iarewparser.cpp2
-rw-r--r--src/plugins/baremetal/keilparser.cpp6
-rw-r--r--src/plugins/baremetal/sdccparser.cpp4
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildstep.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeparser.cpp4
-rw-r--r--src/plugins/ios/iosbuildstep.cpp2
-rw-r--r--src/plugins/ios/iosdsymbuildstep.cpp2
-rw-r--r--src/plugins/nim/project/nimblebuildstep.cpp5
-rw-r--r--src/plugins/nim/project/nimcompilerbuildstep.cpp5
-rw-r--r--src/plugins/projectexplorer/clangparser.cpp4
-rw-r--r--src/plugins/projectexplorer/customparser.cpp13
-rw-r--r--src/plugins/projectexplorer/customparser.h1
-rw-r--r--src/plugins/projectexplorer/gccparser.cpp4
-rw-r--r--src/plugins/projectexplorer/gnumakeparser.cpp169
-rw-r--r--src/plugins/projectexplorer/gnumakeparser.h11
-rw-r--r--src/plugins/projectexplorer/ioutputparser.cpp62
-rw-r--r--src/plugins/projectexplorer/ioutputparser.h9
-rw-r--r--src/plugins/projectexplorer/ldparser.cpp2
-rw-r--r--src/plugins/projectexplorer/linuxiccparser.cpp2
-rw-r--r--src/plugins/projectexplorer/lldparser.cpp3
-rw-r--r--src/plugins/projectexplorer/makestep.cpp2
-rw-r--r--src/plugins/projectexplorer/msvcparser.cpp6
-rw-r--r--src/plugins/projectexplorer/outputparser_test.cpp34
-rw-r--r--src/plugins/projectexplorer/outputparser_test.h6
-rw-r--r--src/plugins/projectexplorer/projectexplorer.h1
-rw-r--r--src/plugins/projectexplorer/xcodebuildparser.cpp4
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildstep.cpp6
-rw-r--r--src/plugins/qmakeprojectmanager/qmakemakestep.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeparser.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakestep.cpp2
-rw-r--r--src/plugins/qtsupport/qtparser.cpp4
-rw-r--r--src/plugins/qtsupport/qttestparser.cpp4
34 files changed, 140 insertions, 249 deletions
diff --git a/src/plugins/android/androidpackageinstallationstep.cpp b/src/plugins/android/androidpackageinstallationstep.cpp
index 4e029fda6b..3c61a32915 100644
--- a/src/plugins/android/androidpackageinstallationstep.cpp
+++ b/src/plugins/android/androidpackageinstallationstep.cpp
@@ -115,7 +115,7 @@ bool AndroidPackageInstallationStep::init()
IOutputParser *parser = target()->kit()->createOutputParser();
if (parser)
appendOutputParser(parser);
- outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
+ outputParser()->addSearchDir(pp->effectiveWorkingDirectory());
m_androidDirsToClean.clear();
// don't remove gradle's cache, it takes ages to rebuild it.
diff --git a/src/plugins/android/javaparser.cpp b/src/plugins/android/javaparser.cpp
index 359d9be819..cc93adc0fb 100644
--- a/src/plugins/android/javaparser.cpp
+++ b/src/plugins/android/javaparser.cpp
@@ -86,7 +86,7 @@ void JavaParser::parse(const QString &line)
CompileTask task(Task::Error,
m_javaRegExp.cap(4).trimmed(),
- file /* filename */,
+ absoluteFilePath(file),
lineno);
emit addTask(task, 1);
return;
diff --git a/src/plugins/baremetal/iarewparser.cpp b/src/plugins/baremetal/iarewparser.cpp
index 2686f58d90..7c4e995561 100644
--- a/src/plugins/baremetal/iarewparser.cpp
+++ b/src/plugins/baremetal/iarewparser.cpp
@@ -158,7 +158,7 @@ bool IarParser::parseWarningOrErrorOrFatalErrorDetailsMessage1(const QString &ln
const int lineno = match.captured(LineNumberIndex).toInt();
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
// A full description will be received later on next lines.
- newTask(CompileTask(type, {}, fileName, lineno));
+ newTask(CompileTask(type, {}, absoluteFilePath(fileName), lineno));
const QString firstPart = QString("[%1]: ").arg(match.captured(MessageCodeIndex));
m_descriptionParts.append(firstPart);
m_expectDescription = true;
diff --git a/src/plugins/baremetal/keilparser.cpp b/src/plugins/baremetal/keilparser.cpp
index 1a09a68b2d..8511727910 100644
--- a/src/plugins/baremetal/keilparser.cpp
+++ b/src/plugins/baremetal/keilparser.cpp
@@ -106,7 +106,7 @@ bool KeilParser::parseArmWarningOrErrorDetailsMessage(const QString &lne)
const int lineno = match.captured(LineNumberIndex).toInt();
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const QString descr = match.captured(DescriptionIndex);
- newTask(CompileTask(type, descr, fileName, lineno));
+ newTask(CompileTask(type, descr, absoluteFilePath(fileName), lineno));
return true;
}
@@ -139,7 +139,7 @@ bool KeilParser::parseMcs51WarningOrErrorDetailsMessage1(const QString &lne)
match.captured(FilePathIndex));
const QString descr = QString("%1: %2").arg(match.captured(MessageCodeIndex),
match.captured(MessageTextIndex));
- newTask(CompileTask(type, descr, fileName, lineno));
+ newTask(CompileTask(type, descr, absoluteFilePath(fileName), lineno));
return true;
}
@@ -157,7 +157,7 @@ bool KeilParser::parseMcs51WarningOrErrorDetailsMessage2(const QString &lne)
match.captured(FilePathIndex));
const QString descr = QString("%1: %2").arg(match.captured(MessageCodeIndex),
match.captured(MessageTextIndex));
- newTask(CompileTask(type, descr, fileName, lineno));
+ newTask(CompileTask(type, descr, absoluteFilePath(fileName), lineno));
return true;
}
diff --git a/src/plugins/baremetal/sdccparser.cpp b/src/plugins/baremetal/sdccparser.cpp
index 5a12b5d66e..e94656c412 100644
--- a/src/plugins/baremetal/sdccparser.cpp
+++ b/src/plugins/baremetal/sdccparser.cpp
@@ -106,7 +106,7 @@ void SdccParser::stdError(const QString &line)
const int lineno = match.captured(LineNumberIndex).toInt();
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const QString descr = match.captured(MessageTextIndex);
- newTask(CompileTask(type, descr, fileName, lineno));
+ newTask(CompileTask(type, descr, absoluteFilePath(fileName), lineno));
return;
}
@@ -120,7 +120,7 @@ void SdccParser::stdError(const QString &line)
const int lineno = match.captured(LineNumberIndex).toInt();
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const QString descr = match.captured(MessageTextIndex);
- newTask(CompileTask(type, descr, fileName, lineno));
+ newTask(CompileTask(type, descr, absoluteFilePath(fileName), lineno));
return;
}
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
index 6a7e5196e1..519433e894 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
@@ -217,7 +217,7 @@ bool CMakeBuildStep::init()
IOutputParser *parser = target()->kit()->createOutputParser();
if (parser)
appendOutputParser(parser);
- outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
+ outputParser()->addSearchDir(pp->effectiveWorkingDirectory());
return AbstractProcessStep::init();
}
diff --git a/src/plugins/cmakeprojectmanager/cmakeparser.cpp b/src/plugins/cmakeprojectmanager/cmakeparser.cpp
index 970dd64eee..01fd9bd3e5 100644
--- a/src/plugins/cmakeprojectmanager/cmakeparser.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeparser.cpp
@@ -80,13 +80,13 @@ void CMakeParser::stdError(const QString &line)
m_lastTask = BuildSystemTask(Task::Error,
QString(),
- FilePath::fromUserInput(path),
+ absoluteFilePath(FilePath::fromUserInput(path)),
m_commonError.cap(2).toInt());
m_lines = 1;
return;
} else if (m_nextSubError.indexIn(trimmedLine) != -1) {
m_lastTask = BuildSystemTask(Task::Error, QString(),
- FilePath::fromUserInput(m_nextSubError.cap(1)));
+ absoluteFilePath(FilePath::fromUserInput(m_nextSubError.cap(1))));
m_lines = 1;
return;
} else if (trimmedLine.startsWith(QLatin1String(" ")) && !m_lastTask.isNull()) {
diff --git a/src/plugins/ios/iosbuildstep.cpp b/src/plugins/ios/iosbuildstep.cpp
index fbf500b099..6566134398 100644
--- a/src/plugins/ios/iosbuildstep.cpp
+++ b/src/plugins/ios/iosbuildstep.cpp
@@ -226,7 +226,7 @@ bool IosBuildStep::init()
IOutputParser *parser = target()->kit()->createOutputParser();
if (parser)
appendOutputParser(parser);
- outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
+ outputParser()->addSearchDir(pp->effectiveWorkingDirectory());
return AbstractProcessStep::init();
}
diff --git a/src/plugins/ios/iosdsymbuildstep.cpp b/src/plugins/ios/iosdsymbuildstep.cpp
index 0221624201..937811bcd3 100644
--- a/src/plugins/ios/iosdsymbuildstep.cpp
+++ b/src/plugins/ios/iosdsymbuildstep.cpp
@@ -82,7 +82,7 @@ bool IosDsymBuildStep::init()
setOutputParser(target()->kit()->createOutputParser());
if (outputParser())
- outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
+ outputParser()->addSearchDir(pp->effectiveWorkingDirectory());
return AbstractProcessStep::init();
}
diff --git a/src/plugins/nim/project/nimblebuildstep.cpp b/src/plugins/nim/project/nimblebuildstep.cpp
index 97014cc17a..6c45f4fb15 100644
--- a/src/plugins/nim/project/nimblebuildstep.cpp
+++ b/src/plugins/nim/project/nimblebuildstep.cpp
@@ -87,7 +87,8 @@ private:
else
return;
- emit addTask(CompileTask(type, message, FilePath::fromUserInput(filename), lineNumber));
+ emit addTask(CompileTask(type, message, absoluteFilePath(FilePath::fromUserInput(filename)),
+ lineNumber));
}
};
@@ -107,7 +108,7 @@ NimbleBuildStep::NimbleBuildStep(BuildStepList *parentList, Core::Id id)
bool NimbleBuildStep::init()
{
auto parser = new NimParser();
- parser->setWorkingDirectory(project()->projectDirectory());
+ parser->addSearchDir(project()->projectDirectory());
setOutputParser(parser);
ProcessParameters* params = processParameters();
diff --git a/src/plugins/nim/project/nimcompilerbuildstep.cpp b/src/plugins/nim/project/nimcompilerbuildstep.cpp
index 521c038afd..83bf618ba8 100644
--- a/src/plugins/nim/project/nimcompilerbuildstep.cpp
+++ b/src/plugins/nim/project/nimcompilerbuildstep.cpp
@@ -89,7 +89,8 @@ private:
else
return;
- emit addTask(CompileTask(type, message, FilePath::fromUserInput(filename), lineNumber));
+ emit addTask(CompileTask(type, message, absoluteFilePath(FilePath::fromUserInput(filename)),
+ lineNumber));
}
};
@@ -116,7 +117,7 @@ bool NimCompilerBuildStep::init()
setOutputParser(new NimParser());
if (IOutputParser *parser = target()->kit()->createOutputParser())
appendOutputParser(parser);
- outputParser()->setWorkingDirectory(processParameters()->effectiveWorkingDirectory());
+ outputParser()->addSearchDir(processParameters()->effectiveWorkingDirectory());
return AbstractProcessStep::init();
}
diff --git a/src/plugins/projectexplorer/clangparser.cpp b/src/plugins/projectexplorer/clangparser.cpp
index cc62f32cf7..c1238a5cc2 100644
--- a/src/plugins/projectexplorer/clangparser.cpp
+++ b/src/plugins/projectexplorer/clangparser.cpp
@@ -76,7 +76,7 @@ void ClangParser::stdError(const QString &line)
m_expectSnippet = true;
newTask(CompileTask(Task::Unknown,
lne.trimmed(),
- FilePath::fromUserInput(match.captured(2)), /* filename */
+ absoluteFilePath(FilePath::fromUserInput(match.captured(2))),
match.captured(3).toInt() /* line */));
return;
}
@@ -90,7 +90,7 @@ void ClangParser::stdError(const QString &line)
lineNo = match.captured(5).toInt(&ok);
newTask(CompileTask(taskType(match.captured(7)),
match.captured(8),
- FilePath::fromUserInput(match.captured(1)), /* filename */
+ absoluteFilePath(FilePath::fromUserInput(match.captured(1))),
lineNo));
return;
}
diff --git a/src/plugins/projectexplorer/customparser.cpp b/src/plugins/projectexplorer/customparser.cpp
index 22ad09c307..b7b3cb1ef7 100644
--- a/src/plugins/projectexplorer/customparser.cpp
+++ b/src/plugins/projectexplorer/customparser.cpp
@@ -145,13 +145,6 @@ Core::Id CustomParser::id()
return Core::Id("ProjectExplorer.OutputParser.Custom");
}
-FilePath CustomParser::absoluteFilePath(const QString &filePath) const
-{
- if (workingDirectory().isEmpty())
- return FilePath::fromUserInput(filePath);
- return workingDirectory().resolvePath(filePath);
-}
-
bool CustomParser::hasMatch(const QString &line, CustomParserExpression::CustomParserChannel channel,
const CustomParserExpression &expression, Task::TaskType taskType)
{
@@ -165,7 +158,8 @@ bool CustomParser::hasMatch(const QString &line, CustomParserExpression::CustomP
if (!match.hasMatch())
return false;
- const FilePath fileName = absoluteFilePath(match.captured(expression.fileNameCap()));
+ const FilePath fileName = absoluteFilePath(FilePath::fromString(
+ match.captured(expression.fileNameCap())));
const int lineNumber = match.captured(expression.lineNumberCap()).toInt();
const QString message = match.captured(expression.messageCap());
@@ -475,7 +469,8 @@ void ProjectExplorerPlugin::testCustomOutputParsers()
CustomParser *parser = new CustomParser;
parser->setSettings(settings);
- parser->setWorkingDirectory(FilePath::fromString(workDir));
+ parser->addSearchDir(FilePath::fromString(workDir));
+ parser->skipFileExistsCheck();
OutputParserTester testbench;
testbench.appendOutputParser(parser);
diff --git a/src/plugins/projectexplorer/customparser.h b/src/plugins/projectexplorer/customparser.h
index 6435bc13fa..e1490baeab 100644
--- a/src/plugins/projectexplorer/customparser.h
+++ b/src/plugins/projectexplorer/customparser.h
@@ -94,7 +94,6 @@ public:
static Core::Id id();
private:
- Utils::FilePath absoluteFilePath(const QString &filePath) const;
bool hasMatch(const QString &line, CustomParserExpression::CustomParserChannel channel,
const CustomParserExpression &expression, Task::TaskType taskType);
bool parseLine(const QString &rawLine, CustomParserExpression::CustomParserChannel channel);
diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp
index 2fc6c4da44..dcfe8ffc53 100644
--- a/src/plugins/projectexplorer/gccparser.cpp
+++ b/src/plugins/projectexplorer/gccparser.cpp
@@ -113,7 +113,7 @@ void GccParser::stdError(const QString &line)
if (match.captured(5).startsWith(QLatin1Char('#')))
description = match.captured(5) + description;
- newTask(CompileTask(type, description, filename, lineno));
+ newTask(CompileTask(type, description, absoluteFilePath(filename), lineno));
return;
}
@@ -121,7 +121,7 @@ void GccParser::stdError(const QString &line)
if (match.hasMatch()) {
newTask(CompileTask(Task::Unknown,
lne.trimmed() /* description */,
- Utils::FilePath::fromUserInput(match.captured(1)) /* filename */,
+ absoluteFilePath(Utils::FilePath::fromUserInput(match.captured(1))),
match.captured(3).toInt() /* linenumber */));
return;
} else if (lne.startsWith(' ') && !m_currentTask.isNull()) {
diff --git a/src/plugins/projectexplorer/gnumakeparser.cpp b/src/plugins/projectexplorer/gnumakeparser.cpp
index c145344531..1e3616e627 100644
--- a/src/plugins/projectexplorer/gnumakeparser.cpp
+++ b/src/plugins/projectexplorer/gnumakeparser.cpp
@@ -29,7 +29,7 @@
#include "task.h"
#include <utils/qtcassert.h>
-#include <utils/temporarydirectory.h>
+#include <utils/temporaryfile.h>
#include <QDir>
#include <QFile>
@@ -68,9 +68,9 @@ void GnuMakeParser::stdOutput(const QString &line)
QRegularExpressionMatch match = m_makeDir.match(lne);
if (match.hasMatch()) {
if (match.captured(6) == QLatin1String("Leaving"))
- removeDirectory(match.captured(7));
+ dropSearchDir(FilePath::fromString(match.captured(7)));
else
- addDirectory(match.captured(7));
+ addSearchDir(FilePath::fromString(match.captured(7)));
return;
}
@@ -128,10 +128,9 @@ void GnuMakeParser::stdError(const QString &line)
if (res.isFatal)
++m_fatalErrorCount;
if (!m_suppressIssues) {
- taskAdded(BuildSystemTask(res.type, res.description,
- FilePath::fromUserInput(match.captured(1)) /* filename */,
- match.captured(4).toInt() /* line */),
- 1, 0);
+ emitTask(BuildSystemTask(res.type, res.description,
+ absoluteFilePath(FilePath::fromUserInput(match.captured(1))),
+ match.captured(4).toInt() /* line */));
}
return;
}
@@ -142,61 +141,18 @@ void GnuMakeParser::stdError(const QString &line)
if (res.isFatal)
++m_fatalErrorCount;
if (!m_suppressIssues)
- taskAdded(BuildSystemTask(res.type, res.description), 1, 0);
+ emitTask(BuildSystemTask(res.type, res.description));
return;
}
IOutputParser::stdError(line);
}
-void GnuMakeParser::addDirectory(const QString &dir)
+void GnuMakeParser::emitTask(const ProjectExplorer::Task &task)
{
- if (dir.isEmpty())
- return;
- m_directories.append(dir);
-}
-
-void GnuMakeParser::removeDirectory(const QString &dir)
-{
- m_directories.removeOne(dir);
-}
-
-void GnuMakeParser::taskAdded(const Task &task, int linkedLines, int skippedLines)
-{
- Task editable(task);
-
- if (task.type == Task::Error) {
- // assume that all make errors will be follow up errors:
+ if (task.type == Task::Error) // Assume that all make errors will be follow up errors.
m_suppressIssues = true;
- }
-
- QString filePath(task.file.toString());
-
- if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
- QFileInfoList possibleFiles;
- foreach (const QString &dir, searchDirectories()) {
- QFileInfo candidate(dir + QLatin1Char('/') + filePath);
- if (candidate.exists()
- && !possibleFiles.contains(candidate)) {
- possibleFiles << candidate;
- }
- }
- if (possibleFiles.size() == 1)
- editable.file = Utils::FilePath::fromFileInfo(possibleFiles.first());
- // Let the Makestep apply additional heuristics (based on
- // files in ther project) if we cannot uniquely
- // identify the file!
- }
-
- IOutputParser::taskAdded(editable, linkedLines, skippedLines);
-}
-
-QStringList GnuMakeParser::searchDirectories() const
-{
- QStringList dirs = m_directories;
- if (!workingDirectory().isEmpty())
- dirs << workingDirectory().toString();
- return dirs;
+ emit addTask(task, 1, 0);
}
} // ProjectExplorer
@@ -417,117 +373,52 @@ void ProjectExplorerPlugin::testGnuMakeParserParsing()
QFETCH(QString, outputLines);
QFETCH(QStringList, additionalSearchDirs);
- QStringList searchDirs = childParser->searchDirectories();
+ FilePaths searchDirs = childParser->searchDirectories();
// add extra directories:
foreach (const QString &dir, extraSearchDirs)
- childParser->addDirectory(dir);
+ childParser->addSearchDir(FilePath::fromString(dir));
testbench.testParsing(input, inputChannel,
tasks, childStdOutLines, childStdErrLines,
outputLines);
// make sure we still have all the original dirs
- QStringList newSearchDirs = tester->directories;
- foreach (const QString &dir, searchDirs) {
+ FilePaths newSearchDirs = tester->directories;
+ foreach (const FilePath &dir, searchDirs) {
QVERIFY(newSearchDirs.contains(dir));
newSearchDirs.removeOne(dir);
}
// make sure we have all additional dirs:
foreach (const QString &dir, additionalSearchDirs) {
- QVERIFY(newSearchDirs.contains(dir));
- newSearchDirs.removeOne(dir);
+ const FilePath fp = FilePath::fromString(dir);
+ QVERIFY(newSearchDirs.contains(fp));
+ newSearchDirs.removeOne(fp);
}
// make sure we have no extra cruft:
QVERIFY(newSearchDirs.isEmpty());
delete tester;
}
-void ProjectExplorerPlugin::testGnuMakeParserTaskMangling_data()
-{
- QTest::addColumn<QStringList>("files");
- QTest::addColumn<QStringList>("searchDirectories");
- QTest::addColumn<Task>("inputTask");
- QTest::addColumn<Task>("outputTask");
-
- QTest::newRow("no filename")
- << QStringList()
- << QStringList()
- << Task(CompileTask(Task::Error,
- "no filename, no mangling"))
- << Task(CompileTask(Task::Error,
- "no filename, no mangling"));
-
- QTest::newRow("no mangling")
- << QStringList()
- << QStringList()
- << Task(CompileTask(Task::Error,
- "unknown filename, no mangling",
- FilePath::fromUserInput("some/path/unknown.cpp")))
- << Task(CompileTask(Task::Error,
- "unknown filename, no mangling",
- FilePath::fromUserInput("some/path/unknown.cpp")));
-
- QTest::newRow("find file")
- << QStringList("test/file.cpp")
- << QStringList("test")
- << Task(CompileTask(Task::Error,
- "mangling",
- FilePath::fromUserInput("file.cpp"),
- 10))
- << Task(CompileTask(Task::Error,
- "mangling",
- FilePath::fromUserInput("$TMPDIR/test/file.cpp"),
- 10));
-}
-
void ProjectExplorerPlugin::testGnuMakeParserTaskMangling()
{
+ TemporaryFile theMakeFile("Makefile.XXXXXX");
+ QVERIFY2(theMakeFile.open(), qPrintable(theMakeFile.errorString()));
+ QFileInfo fi(theMakeFile);
+ QVERIFY2(fi.fileName().startsWith("Makefile"), qPrintable(theMakeFile.fileName()));
+
OutputParserTester testbench;
auto *childParser = new GnuMakeParser;
testbench.appendOutputParser(childParser);
-
- QFETCH(QStringList, files);
- QFETCH(QStringList, searchDirectories);
- QFETCH(Task, inputTask);
- QFETCH(Task, outputTask);
-
- // setup files:
- const QString tempdir
- = Utils::TemporaryDirectory::masterDirectoryPath() + '/' + QUuid::createUuid().toString() + '/';
- QDir filedir(tempdir);
- foreach (const QString &file, files) {
- Q_ASSERT(!file.startsWith('/'));
- Q_ASSERT(!file.contains("../"));
-
- filedir.mkpath(file.left(file.lastIndexOf('/')));
-
- QFile tempfile(tempdir + file);
- if (!tempfile.open(QIODevice::WriteOnly))
- continue;
- tempfile.write("Delete me again!");
- tempfile.close();
- }
-
- // setup search dirs:
- foreach (const QString &dir, searchDirectories) {
- Q_ASSERT(!dir.startsWith(QLatin1Char('/')));
- Q_ASSERT(!dir.contains(QLatin1String("../")));
- childParser->addDirectory(tempdir + dir);
- }
-
- // fix up output task file:
- QString filePath = outputTask.file.toString();
- if (filePath.startsWith(QLatin1String("$TMPDIR/")))
- outputTask.file = Utils::FilePath::fromString(filePath.replace(QLatin1String("$TMPDIR/"), tempdir));
-
- // test mangling:
- testbench.testTaskMangling(inputTask, outputTask);
-
- // clean up:
- foreach (const QString &file, files)
- filedir.rmpath(tempdir + file);
+ childParser->addSearchDir(FilePath::fromString(fi.absolutePath()));
+ testbench.testParsing(
+ fi.fileName() + ":360: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.",
+ OutputParserTester::STDERR,
+ {BuildSystemTask(Task::Error,
+ "missing separator (did you mean TAB instead of 8 spaces?). Stop.",
+ FilePath::fromString(theMakeFile.fileName()), 360)},
+ QString(), QString(), QString());
}
} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/gnumakeparser.h b/src/plugins/projectexplorer/gnumakeparser.h
index c2d126f30b..647fd5d950 100644
--- a/src/plugins/projectexplorer/gnumakeparser.h
+++ b/src/plugins/projectexplorer/gnumakeparser.h
@@ -42,23 +42,16 @@ public:
void stdOutput(const QString &line) override;
void stdError(const QString &line) override;
- QStringList searchDirectories() const;
-
bool hasFatalErrors() const override;
- void taskAdded(const ProjectExplorer::Task &task, int linkedLines, int skippedLines) override;
-
private:
- void addDirectory(const QString &dir);
- void removeDirectory(const QString &dir);
+ void emitTask(const ProjectExplorer::Task &task);
QRegularExpression m_makeDir;
QRegularExpression m_makeLine;
QRegularExpression m_threeStarError;
QRegularExpression m_errorInMakefile;
- QStringList m_directories;
-
bool m_suppressIssues = false;
int m_fatalErrorCount = 0;
@@ -77,7 +70,7 @@ public:
explicit GnuMakeParserTester(GnuMakeParser *parser, QObject *parent = nullptr);
void parserIsAboutToBeDeleted();
- QStringList directories;
+ Utils::FilePaths directories;
GnuMakeParser *parser;
};
#endif
diff --git a/src/plugins/projectexplorer/ioutputparser.cpp b/src/plugins/projectexplorer/ioutputparser.cpp
index 3190c52f1a..4abe41aa93 100644
--- a/src/plugins/projectexplorer/ioutputparser.cpp
+++ b/src/plugins/projectexplorer/ioutputparser.cpp
@@ -28,6 +28,9 @@
#include <utils/synchronousprocess.h>
+#include <QDir>
+#include <QFileInfo>
+
/*!
\class ProjectExplorer::IOutputParser
@@ -162,9 +165,10 @@ public:
IOutputParser *childParser = nullptr;
QList<Filter> filters;
- Utils::FilePath workingDir;
+ Utils::FilePaths searchDirs;
OutputChannelState stdoutState;
OutputChannelState stderrState;
+ bool skipFileExistsCheck = false;
};
IOutputParser::IOutputParser() : d(new IOutputParserPrivate(this))
@@ -197,7 +201,7 @@ void IOutputParser::appendOutputParser(IOutputParser *parser)
}
d->childParser = parser;
- connect(parser, &IOutputParser::addTask, this, &IOutputParser::taskAdded);
+ connect(parser, &IOutputParser::addTask, this, &IOutputParser::addTask);
}
IOutputParser *IOutputParser::childParser() const
@@ -211,7 +215,7 @@ void IOutputParser::setChildParser(IOutputParser *parser)
delete d->childParser;
d->childParser = parser;
if (parser)
- connect(parser, &IOutputParser::addTask, this, &IOutputParser::taskAdded);
+ connect(parser, &IOutputParser::addTask, this, &IOutputParser::addTask);
}
void IOutputParser::stdOutput(const QString &line)
@@ -226,28 +230,18 @@ void IOutputParser::stdError(const QString &line)
d->childParser->stdError(line);
}
-Utils::FilePath IOutputParser::workingDirectory() const { return d->workingDir; }
-
-void IOutputParser::taskAdded(const Task &task, int linkedOutputLines, int skipLines)
+void IOutputParser::skipFileExistsCheck()
{
- emit addTask(task, linkedOutputLines, skipLines);
+ d->skipFileExistsCheck = true;
}
-void IOutputParser::doFlush()
-{ }
+void IOutputParser::doFlush() { }
bool IOutputParser::hasFatalErrors() const
{
return d->childParser && d->childParser->hasFatalErrors();
}
-void IOutputParser::setWorkingDirectory(const Utils::FilePath &fn)
-{
- d->workingDir = fn;
- if (d->childParser)
- d->childParser->setWorkingDirectory(fn);
-}
-
void IOutputParser::flush()
{
flushTasks();
@@ -278,4 +272,40 @@ void IOutputParser::addFilter(const Filter &filter)
d->filters << filter;
}
+void IOutputParser::addSearchDir(const Utils::FilePath &dir)
+{
+ d->searchDirs << dir;
+ if (d->childParser)
+ d->childParser->addSearchDir(dir);
+}
+
+void IOutputParser::dropSearchDir(const Utils::FilePath &dir)
+{
+ const int idx = d->searchDirs.lastIndexOf(dir);
+ QTC_ASSERT(idx != -1, return);
+ d->searchDirs.removeAt(idx);
+ if (d->childParser)
+ d->childParser->dropSearchDir(dir);
+}
+
+const Utils::FilePaths IOutputParser::searchDirectories() const
+{
+ 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;
+}
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/ioutputparser.h b/src/plugins/projectexplorer/ioutputparser.h
index e288873fd3..9e8d980c1a 100644
--- a/src/plugins/projectexplorer/ioutputparser.h
+++ b/src/plugins/projectexplorer/ioutputparser.h
@@ -56,15 +56,16 @@ public:
using Filter = std::function<QString(const QString &)>;
void addFilter(const Filter &filter);
- void setWorkingDirectory(const Utils::FilePath &fn);
+ void addSearchDir(const Utils::FilePath &dir);
+ void dropSearchDir(const Utils::FilePath &dir);
+ const Utils::FilePaths searchDirectories() const;
+ void skipFileExistsCheck(); // For testing only
void flush(); // flush pending tasks & output
void flushTasks(); // flush pending tasks only
static QString rightTrimmed(const QString &in);
- virtual void taskAdded(const ProjectExplorer::Task &task, int linkedOutputLines = 0, int skipLines = 0);
-
signals:
void addTask(const ProjectExplorer::Task &task, int linkedOutputLines = 0, int skipLines = 0);
@@ -72,7 +73,7 @@ protected:
virtual void stdOutput(const QString &line);
virtual void stdError(const QString &line);
- Utils::FilePath workingDirectory() const;
+ Utils::FilePath absoluteFilePath(const Utils::FilePath &filePath);
private:
virtual void doFlush();
diff --git a/src/plugins/projectexplorer/ldparser.cpp b/src/plugins/projectexplorer/ldparser.cpp
index 9d8aee037f..1f86de8405 100644
--- a/src/plugins/projectexplorer/ldparser.cpp
+++ b/src/plugins/projectexplorer/ldparser.cpp
@@ -133,7 +133,7 @@ void LdParser::stdError(const QString &line)
type = Task::Warning;
description = description.mid(9);
}
- emit addTask(CompileTask(type, description, filename, lineno), 1);
+ emit addTask(CompileTask(type, description, absoluteFilePath(filename), lineno), 1);
return;
}
diff --git a/src/plugins/projectexplorer/linuxiccparser.cpp b/src/plugins/projectexplorer/linuxiccparser.cpp
index 95ccb4dfce..b6d417630f 100644
--- a/src/plugins/projectexplorer/linuxiccparser.cpp
+++ b/src/plugins/projectexplorer/linuxiccparser.cpp
@@ -85,7 +85,7 @@ void LinuxIccParser::stdError(const QString &line)
type = Task::Warning;
m_temporary = CompileTask(type,
m_firstLine.cap(6).trimmed(),
- Utils::FilePath::fromUserInput(m_firstLine.cap(1)),
+ absoluteFilePath(Utils::FilePath::fromUserInput(m_firstLine.cap(1))),
m_firstLine.cap(2).toInt());
m_lines = 1;
diff --git a/src/plugins/projectexplorer/lldparser.cpp b/src/plugins/projectexplorer/lldparser.cpp
index 179bd742d3..356ea74a02 100644
--- a/src/plugins/projectexplorer/lldparser.cpp
+++ b/src/plugins/projectexplorer/lldparser.cpp
@@ -64,7 +64,8 @@ void LldParser::stdError(const QString &line)
const int filePathLen = locOffset == -1 ? -1 : locOffset - filePathOffset;
const auto file = Utils::FilePath::fromUserInput(
trimmedLine.mid(filePathOffset, filePathLen).trimmed());
- emit addTask(CompileTask(Task::Unknown, trimmedLine.mid(4).trimmed(), file, lineNo));
+ emit addTask(CompileTask(Task::Unknown, trimmedLine.mid(4).trimmed(),
+ absoluteFilePath(file), lineNo));
return;
}
IOutputParser::stdError(line);
diff --git a/src/plugins/projectexplorer/makestep.cpp b/src/plugins/projectexplorer/makestep.cpp
index 807cb14f31..8a067cc1e1 100644
--- a/src/plugins/projectexplorer/makestep.cpp
+++ b/src/plugins/projectexplorer/makestep.cpp
@@ -106,7 +106,7 @@ bool MakeStep::init()
IOutputParser *parser = target()->kit()->createOutputParser();
if (parser)
appendOutputParser(parser);
- outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
+ outputParser()->addSearchDir(pp->effectiveWorkingDirectory());
return AbstractProcessStep::init();
}
diff --git a/src/plugins/projectexplorer/msvcparser.cpp b/src/plugins/projectexplorer/msvcparser.cpp
index 39a41f3663..145a02d5c2 100644
--- a/src/plugins/projectexplorer/msvcparser.cpp
+++ b/src/plugins/projectexplorer/msvcparser.cpp
@@ -142,7 +142,7 @@ void MsvcParser::stdOutput(const QString &line)
if (!match.captured(1).isEmpty())
description.chop(1); // Remove trailing quote
m_lastTask = CompileTask(Task::Unknown, description,
- FilePath::fromUserInput(match.captured(2)), /* fileName */
+ absoluteFilePath(FilePath::fromUserInput(match.captured(2))),
match.captured(3).toInt() /* linenumber */);
m_lines = 1;
return;
@@ -176,7 +176,7 @@ bool MsvcParser::processCompileLine(const QString &line)
QPair<FilePath, int> position = parseFileName(match.captured(1));
m_lastTask = CompileTask(taskType(match.captured(2)),
match.captured(3) + match.captured(4).trimmed(), // description
- position.first, position.second);
+ absoluteFilePath(position.first), position.second);
m_lines = 1;
return true;
}
@@ -257,7 +257,7 @@ void ClangClParser::stdError(const QString &lineIn)
doFlush();
const QPair<FilePath, int> position = parseFileName(match.captured(1));
m_lastTask = CompileTask(taskType(match.captured(2)), match.captured(3).trimmed(),
- position.first, position.second);
+ absoluteFilePath(position.first), position.second);
m_linkedLines = 1;
return;
}
diff --git a/src/plugins/projectexplorer/outputparser_test.cpp b/src/plugins/projectexplorer/outputparser_test.cpp
index ea7b9be7ce..9dfa5e4826 100644
--- a/src/plugins/projectexplorer/outputparser_test.cpp
+++ b/src/plugins/projectexplorer/outputparser_test.cpp
@@ -39,6 +39,13 @@ static inline QByteArray msgFileComparisonFail(const Utils::FilePath &f1, const
}
// test functions:
+OutputParserTester::OutputParserTester()
+{
+ connect(this, &IOutputParser::addTask, this, [this](const Task &t) {
+ m_receivedTasks.append(t);
+ });
+}
+
void OutputParserTester::testParsing(const QString &lines,
Channel inputChannel,
Tasks tasks,
@@ -79,38 +86,11 @@ void OutputParserTester::testParsing(const QString &lines,
}
}
-void OutputParserTester::testTaskMangling(const Task &input,
- const Task &output)
-{
- reset();
- childParser()->taskAdded(input);
-
- QVERIFY(m_receivedOutput.isNull());
- QVERIFY(m_receivedStdErrChildLine.isNull());
- QVERIFY(m_receivedStdOutChildLine.isNull());
- QVERIFY(m_receivedTasks.size() == 1);
- if (m_receivedTasks.size() == 1) {
- QCOMPARE(m_receivedTasks.at(0).category, output.category);
- QCOMPARE(m_receivedTasks.at(0).description, output.description);
- QVERIFY2(m_receivedTasks.at(0).file == output.file,
- msgFileComparisonFail(m_receivedTasks.at(0).file, output.file));
- QCOMPARE(m_receivedTasks.at(0).line, output.line);
- QCOMPARE(m_receivedTasks.at(0).type, output.type);
- }
-}
-
void OutputParserTester::setDebugEnabled(bool debug)
{
m_debug = debug;
}
-void OutputParserTester::taskAdded(const Task &task, int linkedLines, int skipLines)
-{
- Q_UNUSED(linkedLines)
- Q_UNUSED(skipLines)
- m_receivedTasks.append(task);
-}
-
void OutputParserTester::reset()
{
m_receivedStdErrChildLine.clear();
diff --git a/src/plugins/projectexplorer/outputparser_test.h b/src/plugins/projectexplorer/outputparser_test.h
index dec7e974d5..2525c36477 100644
--- a/src/plugins/projectexplorer/outputparser_test.h
+++ b/src/plugins/projectexplorer/outputparser_test.h
@@ -46,14 +46,14 @@ public:
STDERR
};
+ OutputParserTester();
+
// test functions:
void testParsing(const QString &lines, Channel inputChannel,
Tasks tasks,
const QString &childStdOutLines,
const QString &childStdErrLines,
const QString &outputLines);
- void testTaskMangling(const Task &input,
- const Task &output);
void setDebugEnabled(bool);
@@ -61,8 +61,6 @@ signals:
void aboutToDeleteParser();
private:
- void taskAdded(const ProjectExplorer::Task &task, int linkedLines, int skipLines) override;
-
void reset();
bool m_debug = false;
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index afc84671cb..c7b7a19f5e 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -229,7 +229,6 @@ private slots:
void testGnuMakeParserParsing_data();
void testGnuMakeParserParsing();
- void testGnuMakeParserTaskMangling_data();
void testGnuMakeParserTaskMangling();
void testXcodebuildParserParsing_data();
diff --git a/src/plugins/projectexplorer/xcodebuildparser.cpp b/src/plugins/projectexplorer/xcodebuildparser.cpp
index 13dc96ace9..5497641534 100644
--- a/src/plugins/projectexplorer/xcodebuildparser.cpp
+++ b/src/plugins/projectexplorer/xcodebuildparser.cpp
@@ -74,8 +74,8 @@ void XcodebuildParser::stdOutput(const QString &line)
if (lne.endsWith(QLatin1String(signatureChangeEndsWithPattern))) {
CompileTask task(Task::Warning,
tr("Replacing signature"),
- FilePath::fromString(
- lne.left(lne.size() - QLatin1String(signatureChangeEndsWithPattern).size())));
+ absoluteFilePath(FilePath::fromString(
+ lne.left(lne.size() - QLatin1String(signatureChangeEndsWithPattern).size()))));
emit addTask(task, 1);
return;
}
diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
index 038c8a1a6d..43034fd87d 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
+++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
@@ -376,7 +376,7 @@ void QbsBuildStep::handleProcessResult(
return;
if (m_parser)
- m_parser->setWorkingDirectory(workingDir);
+ m_parser->addSearchDir(workingDir);
emit addOutput(executable.toUserOutput() + ' ' + QtcProcess::joinArgs(arguments),
OutputFormat::Stdout);
for (const QString &line : stdErr) {
@@ -389,8 +389,10 @@ void QbsBuildStep::handleProcessResult(
m_parser->handleStdout(line + '\n');
emit addOutput(line, OutputFormat::Stdout);
}
- if (m_parser)
+ if (m_parser) {
m_parser->flush();
+ m_parser->dropSearchDir(workingDir);
+ }
}
void QbsBuildStep::createTaskAndOutput(ProjectExplorer::Task::TaskType type, const QString &message,
diff --git a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp
index 118df07c11..f3c85b388c 100644
--- a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp
@@ -171,7 +171,7 @@ bool QmakeMakeStep::init()
IOutputParser *parser = target()->kit()->createOutputParser();
if (parser)
appendOutputParser(parser);
- outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
+ outputParser()->addSearchDir(pp->effectiveWorkingDirectory());
appendOutputParser(new QMakeParser); // make may cause qmake to be run, add last to make sure
// it has a low priority.
diff --git a/src/plugins/qmakeprojectmanager/qmakeparser.cpp b/src/plugins/qmakeprojectmanager/qmakeparser.cpp
index 46ad10a0a0..bbc711e958 100644
--- a/src/plugins/qmakeprojectmanager/qmakeparser.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeparser.cpp
@@ -61,7 +61,7 @@ void QMakeParser::stdError(const QString &line)
type = Task::Error;
emit addTask(BuildSystemTask(type,
description,
- FilePath::fromUserInput(fileName),
+ absoluteFilePath(FilePath::fromUserInput(fileName)),
m_error.cap(2).toInt() /* line */),
1);
return;
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp
index 320a786af6..2faaa4e0cb 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp
@@ -338,7 +338,7 @@ void QMakeStep::runNextCommand()
case State::RUN_MAKE_QMAKE_ALL:
{
auto *parser = new GnuMakeParser;
- parser->setWorkingDirectory(processParameters()->workingDirectory());
+ parser->addSearchDir(processParameters()->workingDirectory());
setOutputParser(parser);
m_nextState = State::POST_PROCESS;
startOneCommand(m_makeCommand);
diff --git a/src/plugins/qtsupport/qtparser.cpp b/src/plugins/qtsupport/qtparser.cpp
index 7b01fb874d..364286c9f1 100644
--- a/src/plugins/qtsupport/qtparser.cpp
+++ b/src/plugins/qtsupport/qtparser.cpp
@@ -58,7 +58,7 @@ void QtParser::stdError(const QString &line)
if (level.compare(QLatin1String("Note"), Qt::CaseInsensitive) == 0)
type = Task::Unknown;
CompileTask task(type, m_mocRegExp.cap(5).trimmed() /* description */,
- Utils::FilePath::fromUserInput(m_mocRegExp.cap(1)) /* filename */,
+ absoluteFilePath(Utils::FilePath::fromUserInput(m_mocRegExp.cap(1))),
lineno);
emit addTask(task, 1);
return;
@@ -68,7 +68,7 @@ void QtParser::stdError(const QString &line)
if (m_translationRegExp.cap(1) == QLatin1String("Error"))
type = Task::Error;
CompileTask task(type, m_translationRegExp.cap(2),
- Utils::FilePath::fromUserInput(m_translationRegExp.cap(3)));
+ absoluteFilePath(Utils::FilePath::fromUserInput(m_translationRegExp.cap(3))));
emit addTask(task, 1);
return;
}
diff --git a/src/plugins/qtsupport/qttestparser.cpp b/src/plugins/qtsupport/qttestparser.cpp
index 40db932ca4..45a8602e2f 100644
--- a/src/plugins/qtsupport/qttestparser.cpp
+++ b/src/plugins/qtsupport/qttestparser.cpp
@@ -68,8 +68,8 @@ void QtTestParser::stdOutput(const QString &line)
QTC_CHECK(locationPattern.isValid());
const QRegularExpressionMatch match = locationPattern.match(theLine);
if (match.hasMatch()) {
- m_currentTask.file = FilePath::fromString(
- QDir::fromNativeSeparators(match.captured("file")));
+ m_currentTask.file = absoluteFilePath(FilePath::fromString(
+ QDir::fromNativeSeparators(match.captured("file"))));
m_currentTask.line = match.captured("line").toInt();
emitCurrentTask();
return;