From 283185c38a46ef86576ded5ce9523fa7ef2ce79c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Cser=C3=A9p?= Date: Sun, 4 Feb 2024 15:45:35 +0100 Subject: [PATCH] Persist function param count and McCabe complexity metrics only for functions of the analyzed project. --- plugins/cpp/model/include/model/cppfunction.h | 25 +++++++++++++++---- .../cppmetricsparser/cppmetricsparser.h | 1 + .../parser/src/cppmetricsparser.cpp | 19 ++++++++++++-- util/include/util/filesystem.h | 13 ++++++++++ util/src/filesystem.cpp | 11 ++++++++ 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/plugins/cpp/model/include/model/cppfunction.h b/plugins/cpp/model/include/model/cppfunction.h index 00109db98..2492d9f07 100644 --- a/plugins/cpp/model/include/model/cppfunction.h +++ b/plugins/cpp/model/include/model/cppfunction.h @@ -41,15 +41,21 @@ struct CppFunctionParamCount }; #pragma db view \ - object(CppFunction) object(CppVariable = Parameters : CppFunction::parameters) \ - query((?) + "GROUP BY" + cc::model::CppEntity::astNodeId) + object(CppFunction) \ + object(CppVariable = Parameters : CppFunction::parameters) \ + object(CppAstNode : CppFunction::astNodeId == CppAstNode::id) \ + object(File : CppAstNode::location.file) \ + query((?) + "GROUP BY" + cc::model::CppEntity::astNodeId + "," + cc::model::File::path) struct CppFunctionParamCountWithId { - #pragma db column("CppEntity.astNodeId") + #pragma db column(CppEntity::astNodeId) CppAstNodeId id; #pragma db column("count(" + Parameters::id + ")") std::size_t count; + + #pragma db column(File::path) + std::string filePath; }; #pragma db view \ @@ -60,11 +66,20 @@ struct CppFunctionLocalCount std::size_t count; }; -#pragma db view object(CppFunction) -struct CppFunctionMcCabeWithId +#pragma db view \ + object(CppFunction) \ + object(CppAstNode : CppFunction::astNodeId == CppAstNode::id) \ + object(File : CppAstNode::location.file) +struct CppFunctionMcCabe { + #pragma db column(CppEntity::astNodeId) CppAstNodeId astNodeId; + + #pragma db column(CppFunction::mccabe) unsigned int mccabe; + + #pragma db column(File::path) + std::string filePath; }; } diff --git a/plugins/cpp_metrics/parser/include/cppmetricsparser/cppmetricsparser.h b/plugins/cpp_metrics/parser/include/cppmetricsparser/cppmetricsparser.h index 518361a25..6978d9aaf 100644 --- a/plugins/cpp_metrics/parser/include/cppmetricsparser/cppmetricsparser.h +++ b/plugins/cpp_metrics/parser/include/cppmetricsparser/cppmetricsparser.h @@ -30,6 +30,7 @@ class CppMetricsParser : public AbstractParser void functionParameters(); void functionMcCabe(); + std::vector _inputPaths; std::unordered_set _fileIdCache; std::unordered_map _astNodeIdCache; std::unique_ptr> _pool; diff --git a/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp b/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp index bbe3cfdf4..68f5b3c4d 100644 --- a/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp +++ b/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp @@ -10,6 +10,7 @@ #include +#include #include #include @@ -20,8 +21,14 @@ namespace cc namespace parser { +namespace fs = boost::filesystem; + CppMetricsParser::CppMetricsParser(ParserContext& ctx_): AbstractParser(ctx_) { + for (const std::string& path : + _ctx.options["input"].as>()) + _inputPaths.push_back(fs::canonical(path).string()); + util::OdbTransaction {_ctx.db} ([&, this] { for (const model::CppFileMetrics& fm : _ctx.db->query()) @@ -98,6 +105,10 @@ void CppMetricsParser::functionParameters() for (const model::CppFunctionParamCountWithId& paramCount : _ctx.db->query()) { + // Skip functions that were included from external libraries. + if (!cc::util::isRootedUnderAnyOf(_inputPaths, paramCount.filePath)) + continue; + model::CppAstNodeMetrics funcParams; funcParams.astNodeId = paramCount.id; funcParams.type = model::CppAstNodeMetrics::Type::PARAMETER_COUNT; @@ -111,9 +122,13 @@ void CppMetricsParser::functionMcCabe() { util::OdbTransaction {_ctx.db} ([&, this] { - for (const model::CppFunctionMcCabeWithId& function - : _ctx.db->query()) + for (const model::CppFunctionMcCabe& function + : _ctx.db->query()) { + // Skip functions that were included from external libraries. + if (!cc::util::isRootedUnderAnyOf(_inputPaths, function.filePath)) + continue; + model::CppAstNodeMetrics funcMcCabe; funcMcCabe.astNodeId = function.astNodeId; funcMcCabe.type = model::CppAstNodeMetrics::Type::MCCABE; diff --git a/util/include/util/filesystem.h b/util/include/util/filesystem.h index 7454b16c5..66f6f6369 100644 --- a/util/include/util/filesystem.h +++ b/util/include/util/filesystem.h @@ -22,6 +22,19 @@ std::string binaryPathToInstallDir(const char* path); */ std::string findCurrentExecutableDir(); +/** + * @brief Determines if the given path is rooted under + * any of the given other paths. + * + * @param paths_ A list of canonical paths. + * @param path_ A canonical path to match against the given paths. + * @return True if any of the paths in paths_ is a prefix of path_, + * otherwise false. +*/ +bool isRootedUnderAnyOf( + const std::vector& paths_, + const std::string& path_); + } // namespace util } // namespace cc diff --git a/util/src/filesystem.cpp b/util/src/filesystem.cpp index d18c16b8d..e459102af 100644 --- a/util/src/filesystem.cpp +++ b/util/src/filesystem.cpp @@ -64,5 +64,16 @@ std::string findCurrentExecutableDir() return fs::path(exePath).parent_path().string(); } +bool isRootedUnderAnyOf( + const std::vector& paths_, + const std::string& path_) +{ + auto it = paths_.begin(); + const auto end = paths_.end(); + while (it != end && path_.rfind(*it, 0) != 0) + ++it; + return it != end; +} + } // namespace util } // namespace cc