diff --git a/outputview/outputfilteringstrategies.h b/outputview/outputfilteringstrategies.h --- a/outputview/outputfilteringstrategies.h +++ b/outputview/outputfilteringstrategies.h @@ -27,26 +27,23 @@ #include "ifilterstrategy.h" #include "outputformats.h" - -#include - #include -#define KDEVPLATFORMOUTPUTVIEW_TEST_EXPORT KDEVPLATFORMOUTPUTVIEW_EXPORT - #include #include #include #include namespace KDevelop { +struct CompilerFilterStrategyPrivate; + /** * This filter strategy is for not applying any filtering at all. Implementation of the * interface methods are basically noops **/ -class KDEVPLATFORMOUTPUTVIEW_TEST_EXPORT NoFilterStrategy final : public IFilterStrategy +class KDEVPLATFORMOUTPUTVIEW_EXPORT NoFilterStrategy : public IFilterStrategy { public: @@ -62,34 +59,27 @@ * This filter stategy checks if a given line contains output * that is defined as an error (or an action) from a compiler. **/ -class KDEVPLATFORMOUTPUTVIEW_TEST_EXPORT CompilerFilterStrategy final : public IFilterStrategy +class KDEVPLATFORMOUTPUTVIEW_EXPORT CompilerFilterStrategy : public IFilterStrategy { public: CompilerFilterStrategy(const QUrl& buildDir); + virtual ~CompilerFilterStrategy(); virtual FilteredItem errorInLine(const QString& line) override; virtual FilteredItem actionInLine(const QString& line) override; QVector getCurrentDirs(); private: - KDevelop::Path pathForFile( const QString& ) const; - bool isMultiLineCase(ErrorFormat curErrFilter) const; - void putDirAtEnd(const KDevelop::Path& pathToInsert); - - QVector m_currentDirs; - KDevelop::Path m_buildDir; - - using PositionMap = QHash; - PositionMap m_positionInCurrentDirs; + CompilerFilterStrategyPrivate* const d; }; /** * This filter stategy filters out errors (no actions) from Python and PHP scripts. **/ -class KDEVPLATFORMOUTPUTVIEW_TEST_EXPORT ScriptErrorFilterStrategy final : public IFilterStrategy +class KDEVPLATFORMOUTPUTVIEW_EXPORT ScriptErrorFilterStrategy : public IFilterStrategy { public: @@ -107,7 +97,7 @@ * This is especially useful for runtime output of Qt applications, for example lines such as: * "ASSERT: "errors().isEmpty()" in file /tmp/foo/bar.cpp", line 49" */ -class KDEVPLATFORMOUTPUTVIEW_TEST_EXPORT NativeAppErrorFilterStrategy final : public IFilterStrategy +class KDEVPLATFORMOUTPUTVIEW_EXPORT NativeAppErrorFilterStrategy : public IFilterStrategy { public: NativeAppErrorFilterStrategy(); @@ -119,7 +109,7 @@ /** * This filter stategy filters out errors (no actions) from Static code analysis tools (Cppcheck,) **/ -class KDEVPLATFORMOUTPUTVIEW_TEST_EXPORT StaticAnalysisFilterStrategy final : public IFilterStrategy +class KDEVPLATFORMOUTPUTVIEW_EXPORT StaticAnalysisFilterStrategy : public IFilterStrategy { public: diff --git a/outputview/outputfilteringstrategies.cpp b/outputview/outputfilteringstrategies.cpp --- a/outputview/outputfilteringstrategies.cpp +++ b/outputview/outputfilteringstrategies.cpp @@ -27,11 +27,10 @@ #include -using namespace KDevelop; +namespace KDevelop +{ -namespace { -template -FilteredItem match(const ErrorFormats& errorFormats, const QString& line) +FilteredItem match(const QVector& errorFormats, const QString& line) { FilteredItem item(line); for( const ErrorFormat& curErrFilter : errorFormats ) { @@ -58,7 +57,6 @@ } return item; } -} /// --- No filter strategy --- @@ -78,12 +76,28 @@ /// --- Compiler error filter strategy --- -CompilerFilterStrategy::CompilerFilterStrategy(const QUrl& buildDir) +/// Impl. of CompilerFilterStrategy. +struct CompilerFilterStrategyPrivate +{ + CompilerFilterStrategyPrivate(const QUrl& buildDir); + Path pathForFile( const QString& ) const; + bool isMultiLineCase(ErrorFormat curErrFilter) const; + void putDirAtEnd(const Path& pathToInsert); + + QVector m_currentDirs; + Path m_buildDir; + + using PositionMap = QHash; + PositionMap m_positionInCurrentDirs; +}; + + +CompilerFilterStrategyPrivate::CompilerFilterStrategyPrivate(const QUrl& buildDir) : m_buildDir(buildDir) { } -Path CompilerFilterStrategy::pathForFile(const QString& filename) const +Path CompilerFilterStrategyPrivate::pathForFile(const QString& filename) const { QFileInfo fi( filename ); Path currentPath; @@ -104,17 +118,17 @@ return currentPath; } -bool CompilerFilterStrategy::isMultiLineCase(KDevelop::ErrorFormat curErrFilter) const +bool CompilerFilterStrategyPrivate::isMultiLineCase(KDevelop::ErrorFormat curErrFilter) const { if(curErrFilter.compiler == QLatin1String("gfortran") || curErrFilter.compiler == QLatin1String("cmake")) { return true; } return false; } -void CompilerFilterStrategy::putDirAtEnd(const Path& pathToInsert) +void CompilerFilterStrategyPrivate::putDirAtEnd(const Path& pathToInsert) { - auto it = m_positionInCurrentDirs.find( pathToInsert ); + CompilerFilterStrategyPrivate::PositionMap::iterator it = m_positionInCurrentDirs.find( pathToInsert ); // Encountered new build directory? if (it == m_positionInCurrentDirs.end()) { m_currentDirs.push_back( pathToInsert ); @@ -127,11 +141,21 @@ } } +CompilerFilterStrategy::CompilerFilterStrategy(const QUrl& buildDir) +: d(new CompilerFilterStrategyPrivate( buildDir )) +{ +} + +CompilerFilterStrategy::~CompilerFilterStrategy() +{ + delete d; +} + QVector CompilerFilterStrategy::getCurrentDirs() { QVector ret; - ret.reserve(m_currentDirs.size()); - for (const auto& path : m_currentDirs) { + ret.reserve(d->m_currentDirs.size()); + for (const auto& path : d->m_currentDirs) { ret << path.pathOrUrl(); } return ret; @@ -187,8 +211,8 @@ if( curActFilter.tool == "cd" ) { const Path path(match.captured(curActFilter.fileGroup)); - m_currentDirs.push_back( path ); - m_positionInCurrentDirs.insert( path , m_currentDirs.size() - 1 ); + d->m_currentDirs.push_back( path ); + d->m_positionInCurrentDirs.insert( path , d->m_currentDirs.size() - 1 ); } // Special case for cmake: we parse the "Compiling " expression @@ -199,7 +223,7 @@ if ( curActFilter.fileGroup != -1 && curActFilter.tool == "cmake" && line.contains("Building")) { const auto objectFile = match.captured(curActFilter.fileGroup); const auto dir = objectFile.section(QStringLiteral("CMakeFiles/"), 0, 0); - putDirAtEnd(Path(m_buildDir, dir)); + d->putDirAtEnd(Path(d->m_buildDir, dir)); } break; } @@ -229,7 +253,7 @@ }; // A list of filters for possible compiler, linker, and make errors - static const ErrorFormat ERROR_FILTERS[] = { + static const QVector ERROR_FILTERS = { #ifdef Q_OS_WIN // MSVC ErrorFormat( QStringLiteral("^([a-zA-Z]:\\\\.+)\\(([1-9][0-9]*)\\): ((?:error|warning) .+\\:).*$"), 1, 2, 3 ), @@ -282,11 +306,11 @@ { if(curErrFilter.fileGroup > 0) { if( curErrFilter.compiler == "cmake" ) { // Unfortunately we cannot know if an error or an action comes first in cmake, and therefore we need to do this - if( m_currentDirs.empty() ) { - putDirAtEnd( m_buildDir.parent() ); + if( d->m_currentDirs.empty() ) { + d->putDirAtEnd( d->m_buildDir.parent() ); } } - item.url = pathForFile( match.captured( curErrFilter.fileGroup ) ).toUrl(); + item.url = d->pathForFile( match.captured( curErrFilter.fileGroup ) ).toUrl(); } item.lineNo = match.captured( curErrFilter.lineGroup ).toInt() - 1; if(curErrFilter.columnGroup >= 0) { @@ -313,7 +337,7 @@ if(item.type == FilteredItem::InvalidItem) { // If there are no error indicators in the line // maybe this is a multiline case - if(isMultiLineCase(curErrFilter)) { + if(d->isMultiLineCase(curErrFilter)) { item.type = FilteredItem::ErrorItem; } else { // Okay so we couldn't find anything to indicate an error, but we have file and lineGroup @@ -343,7 +367,7 @@ FilteredItem ScriptErrorFilterStrategy::errorInLine(const QString& line) { // A list of filters for possible Python and PHP errors - static const ErrorFormat SCRIPT_ERROR_FILTERS[] = { + static const QVector SCRIPT_ERROR_FILTERS = { ErrorFormat( QStringLiteral("^ File \"(.*)\", line ([0-9]+)(.*$|, in(.*)$)"), 1, 2, -1 ), ErrorFormat( QStringLiteral("^.*(/.*):([0-9]+).*$"), 1, 2, -1 ), ErrorFormat( QStringLiteral("^.* in (/.*) on line ([0-9]+).*$"), 1, 2, -1 ) @@ -365,7 +389,7 @@ FilteredItem NativeAppErrorFilterStrategy::errorInLine(const QString& line) { - static const ErrorFormat NATIVE_APPLICATION_ERROR_FILTERS[] = { + static const QVector NATIVE_APPLICATION_ERROR_FILTERS = { // BEGIN: C++ // a.out: test.cpp:5: int main(): Assertion `false' failed. @@ -417,7 +441,7 @@ FilteredItem StaticAnalysisFilterStrategy::errorInLine(const QString& line) { // A list of filters for static analysis tools (krazy2, cppcheck) - static const ErrorFormat STATIC_ANALYSIS_FILTERS[] = { + static const QVector STATIC_ANALYSIS_FILTERS = { // CppCheck ErrorFormat( QStringLiteral("^\\[(.*):([0-9]+)\\]:(.*)"), 1, 2, 3 ), // krazy2 @@ -428,3 +452,5 @@ return match(STATIC_ANALYSIS_FILTERS, line); } + +}