diff --git a/model/include/model/file.h b/model/include/model/file.h index f03c88571..1c308bd85 100644 --- a/model/include/model/file.h +++ b/model/include/model/file.h @@ -87,6 +87,16 @@ struct FileIdView { FileId id; }; + +#pragma db view object(File) +struct FilePathView +{ + #pragma db column(File::id) + FileId id; + + #pragma db column(File::path) + std::string path; +}; #pragma db view object(File) query((?) + " GROUP BY " + File::type) struct FileTypeView diff --git a/plugins/cpp/model/include/model/cppastnode.h b/plugins/cpp/model/include/model/cppastnode.h index 67f93507b..717437e27 100644 --- a/plugins/cpp/model/include/model/cppastnode.h +++ b/plugins/cpp/model/include/model/cppastnode.h @@ -230,6 +230,18 @@ struct AstCountGroupByFiles std::size_t count; }; +#pragma db view \ + object(CppAstNode) \ + object(File = LocFile : CppAstNode::location.file) +struct CppAstNodeFilePath +{ + #pragma db column(CppAstNode::id) + CppAstNodeId id; + + #pragma db column(LocFile::path) + std::string path; +}; + #pragma db view object(CppAstNode) struct CppAstCount { diff --git a/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h b/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h index f95b4a6e1..5c2f5b452 100644 --- a/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h +++ b/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h @@ -45,6 +45,25 @@ struct CppRecordMetricsView double value; }; +#pragma db view \ + object(CppAstNodeMetrics) \ + object(CppAstNode : CppAstNodeMetrics::astNodeId == CppAstNode::id) \ + object(File = LocFile : CppAstNode::location.file) +struct CppAstNodeMetricsForPathView +{ + #pragma db column(CppAstNodeMetrics::astNodeId) + CppAstNodeId astNodeId; + + #pragma db column(LocFile::path) + std::string path; + + #pragma db column(CppAstNodeMetrics::type) + CppAstNodeMetrics::Type type; + + #pragma db column(CppAstNodeMetrics::value) + double value; +}; + } //model } //cc diff --git a/plugins/cpp_metrics/model/include/model/cppfilemetrics.h b/plugins/cpp_metrics/model/include/model/cppfilemetrics.h index 357eb5cb5..eebedbc46 100644 --- a/plugins/cpp_metrics/model/include/model/cppfilemetrics.h +++ b/plugins/cpp_metrics/model/include/model/cppfilemetrics.h @@ -29,6 +29,24 @@ struct CppFileMetrics unsigned value; }; +#pragma db view \ + object(CppFileMetrics) \ + object(File : CppFileMetrics::file == File::id) +struct CppModuleMetricsForPathView +{ + #pragma db column(CppFileMetrics::file) + FileId fileId; + + #pragma db column(File::path) + std::string path; + + #pragma db column(CppFileMetrics::type) + CppFileMetrics::Type type; + + #pragma db column(CppFileMetrics::value) + unsigned value; +}; + } //model } //cc diff --git a/plugins/cpp_metrics/service/cxxmetrics.thrift b/plugins/cpp_metrics/service/cxxmetrics.thrift index 0762ac534..099ec69a2 100644 --- a/plugins/cpp_metrics/service/cxxmetrics.thrift +++ b/plugins/cpp_metrics/service/cxxmetrics.thrift @@ -4,7 +4,7 @@ include "project/project.thrift" namespace cpp cc.service.cppmetrics namespace java cc.service.cppmetrics -enum CppMetricsType +enum CppAstNodeMetricsType { ParameterCount = 1, McCabe = 2, @@ -12,16 +12,47 @@ enum CppMetricsType LackOfCohesionHS = 4 } -struct CppMetricsTypeName +enum CppModuleMetricsType { - 1:CppMetricsType type, + Placeholder = 1 +} + +struct CppAstNodeMetricsTypeName +{ + 1:CppAstNodeMetricsType type, + 2:string name +} + +struct CppModuleMetricsTypeName +{ + 1:CppModuleMetricsType type, 2:string name } -struct CppMetricsAstNode +struct CppMetricsAstNodeSingle +{ + 1:string path, + 2:CppAstNodeMetricsType type, + 3:double value +} + +struct CppMetricsAstNodeAll +{ + 1:common.AstNodeId id, + 2:list metrics +} + +struct CppMetricsModuleSingle +{ + 1:string path, + 2:CppModuleMetricsType type, + 3:double value +} + +struct CppMetricsModuleAll { - 1:CppMetricsType type, - 2:double value + 1:common.FileId id, + 2:list metrics } service CppMetricsService @@ -32,17 +63,47 @@ service CppMetricsService */ double getSingleCppMetricForAstNode( 1:common.AstNodeId astNodeId, - 2:CppMetricsType metric) + 2:CppAstNodeMetricsType metric) /** * This function returns all available C++ metrics * for a particular AST node. */ - list getCppMetricsForAstNode( + list getCppMetricsForAstNode( 1:common.AstNodeId astNodeId) /** - * This function returns the names of metrics. + * This function returns all available C++ metrics + * for a particular module (file or directory). + */ + list getCppMetricsForModule( + 1:common.FileId fileId) + + /** + * This function returns all available C++ metrics + * (AST node-level) for a particular path. + * + * The given path is a handled as a prefix. + */ + map> getCppAstNodeMetricsForPath( + 1:string path) + + /** + * This function returns all available C++ metrics + * (file-level) for a particular path. + * + * The given path is a handled as a prefix. + */ + map> getCppFileMetricsForPath( + 1:string path) + + /** + * This function returns the names of the AST node-level C++ metrics. + */ + list getCppAstNodeMetricsTypeNames() + + /** + * This function returns the names of module-level C++ metrics. */ - list getCppMetricsTypeNames() + list getCppModuleMetricsTypeNames() } \ No newline at end of file diff --git a/plugins/cpp_metrics/service/include/service/cppmetricsservice.h b/plugins/cpp_metrics/service/include/service/cppmetricsservice.h index 4a65bd306..6257e95a1 100644 --- a/plugins/cpp_metrics/service/include/service/cppmetricsservice.h +++ b/plugins/cpp_metrics/service/include/service/cppmetricsservice.h @@ -3,6 +3,7 @@ #include #include +#include #include @@ -12,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -36,14 +39,29 @@ class CppMetricsServiceHandler : virtual public CppMetricsServiceIf double getSingleCppMetricForAstNode( const core::AstNodeId& astNodeId_, - CppMetricsType::type metric_) override; + CppAstNodeMetricsType::type metric_) override; void getCppMetricsForAstNode( - std::vector& _return, + std::vector& _return, const core::AstNodeId& astNodeId_) override; - void getCppMetricsTypeNames( - std::vector& _return) override; + void getCppMetricsForModule( + std::vector& _return, + const core::FileId& fileId_) override; + + void getCppAstNodeMetricsForPath( + std::map>& _return, + const std::string& path_) override; + + void getCppFileMetricsForPath( + std::map>& _return, + const std::string& path_) override; + + void getCppAstNodeMetricsTypeNames( + std::vector& _return) override; + + void getCppModuleMetricsTypeNames( + std::vector& _return) override; private: std::shared_ptr _db; diff --git a/plugins/cpp_metrics/service/src/cppmetricsservice.cpp b/plugins/cpp_metrics/service/src/cppmetricsservice.cpp index d1b7c5556..6089133e4 100644 --- a/plugins/cpp_metrics/service/src/cppmetricsservice.cpp +++ b/plugins/cpp_metrics/service/src/cppmetricsservice.cpp @@ -1,6 +1,10 @@ #include #include +#include +#include +#include + namespace cc { namespace service @@ -8,6 +12,9 @@ namespace service namespace cppmetrics { +typedef odb::query AstQuery; +typedef odb::result AstResult; + CppMetricsServiceHandler::CppMetricsServiceHandler( std::shared_ptr db_, std::shared_ptr datadir_, @@ -16,33 +23,43 @@ CppMetricsServiceHandler::CppMetricsServiceHandler( { } -void CppMetricsServiceHandler::getCppMetricsTypeNames( - std::vector& _return) +void CppMetricsServiceHandler::getCppAstNodeMetricsTypeNames( + std::vector& _return) { - CppMetricsTypeName typeName; + CppAstNodeMetricsTypeName typeName; - typeName.type = CppMetricsType::ParameterCount; + typeName.type = CppAstNodeMetricsType::ParameterCount; typeName.name = "Number of function parameters"; _return.push_back(typeName); - typeName.type = CppMetricsType::McCabe; + typeName.type = CppAstNodeMetricsType::McCabe; typeName.name = "McCabe metric"; _return.push_back(typeName); - typeName.type = CppMetricsType::LackOfCohesion; + typeName.type = CppAstNodeMetricsType::LackOfCohesion; typeName.name = "Lack of cohesion of function"; _return.push_back(typeName); - typeName.type = CppMetricsType::LackOfCohesionHS; + typeName.type = CppAstNodeMetricsType::LackOfCohesionHS; typeName.name = "Lack of cohesion of function (Henderson-Sellers variant)"; _return.push_back(typeName); } +void CppMetricsServiceHandler::getCppModuleMetricsTypeNames( + std::vector& _return) +{ + CppModuleMetricsTypeName typeName; + + typeName.type = CppModuleMetricsType::Placeholder; + typeName.name = "Placeholder"; + _return.push_back(typeName); +} + void CppMetricsServiceHandler::getCppMetricsForAstNode( - std::vector& _return, + std::vector& _return, const core::AstNodeId& astNodeId_) { - CppMetricsAstNode metric; + CppMetricsAstNodeSingle metric; _transaction([&, this](){ typedef odb::query CppAstNodeMetricsQuery; @@ -52,7 +69,7 @@ void CppMetricsServiceHandler::getCppMetricsForAstNode( for (const auto& nodeMetric : nodeMetrics) { - metric.type = static_cast(nodeMetric.type); + metric.type = static_cast(nodeMetric.type); metric.value = nodeMetric.value; _return.push_back(metric); } @@ -61,7 +78,7 @@ void CppMetricsServiceHandler::getCppMetricsForAstNode( double CppMetricsServiceHandler::getSingleCppMetricForAstNode( const core::AstNodeId& astNodeId_, - CppMetricsType::type metric_) + CppAstNodeMetricsType::type metric_) { return _transaction([&, this]() -> std::double_t { typedef odb::query CppAstNodeMetricsQuery; @@ -81,6 +98,93 @@ double CppMetricsServiceHandler::getSingleCppMetricForAstNode( }); } +void CppMetricsServiceHandler::getCppMetricsForModule( + std::vector& _return, + const core::FileId& fileId_) +{ + CppMetricsModuleSingle metric; + + _transaction([&, this](){ + typedef odb::query CppModuleMetricsQuery; + + auto moduleMetrics = _db->query( + CppModuleMetricsQuery::file == std::stoull(fileId_)); + + for (const auto& moduleMetric : moduleMetrics) + { + metric.type = static_cast(moduleMetric.type); + metric.value = moduleMetric.value; + _return.push_back(metric); + } + }); +} + +void CppMetricsServiceHandler::getCppAstNodeMetricsForPath( + std::map>& _return, + const std::string& path_) +{ + _transaction([&, this](){ + typedef odb::query CppAstNodeFilePathQuery; + typedef odb::result CppAstNodeFilePathResult; + typedef odb::query CppAstNodeMetricsForPathViewQuery; + typedef odb::result CppAstNodeMetricsForPathViewResult; + + auto nodes = _db->query( + CppAstNodeFilePathQuery::LocFile::path.like(path_ + '%')); + + for (const auto& node : nodes) + { + CppMetricsAstNodeSingle metric; + metric.path = node.path; + metric.type = static_cast(node.type); + metric.value = node.value; + + if (_return.count(std::to_string(node.astNodeId))) + { + _return[std::to_string(node.astNodeId)].push_back(metric); + } + else + { + std::vector metricsList; + metricsList.push_back(metric); + _return.insert(std::make_pair(std::to_string(node.astNodeId), metricsList)); + } + } + }); +} + +void CppMetricsServiceHandler::getCppFileMetricsForPath( + std::map>& _return, + const std::string& path_) +{ + _transaction([&, this](){ + typedef odb::query CppModuleMetricsQuery; + typedef odb::result CppModuleMetricsResult; + + auto files = _db->query( + CppModuleMetricsQuery::File::path.like(path_ + '%')); + + for (const auto& file : files) + { + CppMetricsModuleSingle metric; + metric.path = file.path; + metric.type = static_cast(file.type); + metric.value = file.value; + + if (_return.count(std::to_string(file.fileId))) + { + _return[std::to_string(file.fileId)].push_back(metric); + } + else + { + std::vector metricsList; + metricsList.push_back(metric); + _return.insert(std::make_pair(std::to_string(file.fileId), metricsList)); + } + } + }); +} + } // cppmetrics } // service } // cc