| 24 | { |
| 25 | |
| 26 | void includesForItem(KDevelop::ProjectBaseItem* parent, QSet<KDevelop::Path>& includes) |
| 27 | { |
| 28 | // FIXME: only one build system manager - QMakeManager - ever returns a nonempty include directory list |
| 29 | // for a target item. With any other project build system manager, cppcheck::Parameters::m_includeDirectories |
| 30 | // is always empty. For example, during the loop below CMakeManager prints the following debug message: |
| 31 | // kdevelop.plugins.cmake: no information found for "" |
| 32 | // because a target item's path() is always empty. |
| 33 | // The algorithm here attempts to collect include directories for all project targets and use them to analyze any |
| 34 | // file. This algorithm can be patched up by passing the first child of a target item instead of the target item |
| 35 | // itself to IBuildSystemManager::includeDirectories(). However, the include directories would needlessly contain |
| 36 | // include paths for all unit tests then. Also each file in a target can potentially have different include paths. |
| 37 | // So perhaps the current algorithm should be replaced with something else altogether: |
| 38 | // 1. When KDevelop runs cppcheck on a single file, that file's project item should be passed to |
| 39 | // IBuildSystemManager::includeDirectories(). |
| 40 | // 2. When KDevelop runs cppcheck on an entire project, it passes the project's root directory to cppcheck |
| 41 | // on the command line. cppcheck checks all source files in the given directory recursively. |
| 42 | // db0d8027749ba8c94702981ccb3062fa6c6006eb even implemented a workaround to skip cppcheck-ing files in |
| 43 | // <current build dir>/CMakeFiles/. That workaround is not perfect: what if there are multiple build |
| 44 | // subdirectories (e.g. debug and release) within the project's directory? Instead of running a single |
| 45 | // cppcheck command, we could run a separate cppcheck command for each not-filtered-out source file in |
| 46 | // the project. This way we could pass each file's project item to IBuildSystemManager::includeDirectories() |
| 47 | // and use a separate include directory list to analyze every file. But this would require determining which |
| 48 | // files should and which shouldn't be analyzed (C and C++ MIME types?), and might be slower. |
| 49 | // Apparently fixing this issue properly requires substantial refactoring and testing effort. |
| 50 | |
| 51 | const auto children = parent->children(); |
| 52 | for (auto* child : children) { |
| 53 | if (child->type() == KDevelop::ProjectBaseItem::ProjectItemType::File) { |
| 54 | continue; |
| 55 | } |
| 56 | |
| 57 | else if (child->type() == KDevelop::ProjectBaseItem::ProjectItemType::ExecutableTarget || |
| 58 | child->type() == KDevelop::ProjectBaseItem::ProjectItemType::LibraryTarget || |
| 59 | child->type() == KDevelop::ProjectBaseItem::ProjectItemType::Target) { |
| 60 | |
| 61 | if (auto buildSystemManager = child->project()->buildSystemManager()) { |
| 62 | const auto includeDirectories = buildSystemManager->includeDirectories(child); |
| 63 | for (auto& dir : includeDirectories) { |
| 64 | includes.insert(dir); |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | includesForItem(child, includes); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | QList<KDevelop::Path> includesForProject(KDevelop::IProject* project) |
| 74 | { |
no test coverage detected