diff options
Diffstat (limited to 'src/plugins')
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; |