Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions plugins/cpp/model/include/model/cppastnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
86 changes: 79 additions & 7 deletions plugins/cpp_metrics/service/cxxmetrics.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,72 @@ include "project/project.thrift"
namespace cpp cc.service.cppmetrics
namespace java cc.service.cppmetrics

enum CppMetricsType
enum CppUnitType
Comment thread
mcserep marked this conversation as resolved.
Outdated
{
AstNodeUnit = 1,
FileUnit = 2
}

enum CppAstNodeMetricsType
{
ParameterCount = 1,
McCabe = 2,
LackOfCohesion = 3,
LackOfCohesionHS = 4
}

struct CppMetricsTypeName
enum CppModuleMetricsType
{
Placeholder = 1
}

struct CppAstNodeMetricsTypeName
{
1:CppAstNodeMetricsType type,
2:string name
}

struct CppModuleMetricsTypeName
{
1:CppMetricsType type,
1:CppModuleMetricsType type,
2:string name
}

struct CppMetricsAstNode
Comment thread
intjftw marked this conversation as resolved.
Outdated
{
1:CppMetricsType type,
1:CppAstNodeMetricsType type,
2:double value
}

struct CppAllMetricsAstNode
Comment thread
intjftw marked this conversation as resolved.
Outdated
{
1:common.AstNodeId id,
2:list<CppMetricsAstNode> metrics
}

struct CppMetricsModule
{
1:CppModuleMetricsType type,
2:double value
}

struct CppAllMetricsModule
{
1:common.FileId id,
2:list<CppMetricsModule> metrics
}
Comment thread
intjftw marked this conversation as resolved.
Outdated

// Thrift does not provide a union type,
// the ids can remain empty.
struct CppMetricsPath
Comment thread
intjftw marked this conversation as resolved.
Outdated
{
1:CppUnitType type
2:common.AstNodeId astNodeId
3:list<CppMetricsAstNode> astNodeIdMetrics
Comment thread
intjftw marked this conversation as resolved.
Outdated
4:common.FileId fileId
5:list<CppMetricsModule> fileMetrics
Comment thread
intjftw marked this conversation as resolved.
Outdated
}

service CppMetricsService
{
/**
Expand All @@ -32,7 +78,7 @@ service CppMetricsService
*/
double getSingleCppMetricForAstNode(
1:common.AstNodeId astNodeId,
2:CppMetricsType metric)
2:CppAstNodeMetricsType metric)

/**
* This function returns all available C++ metrics
Expand All @@ -42,7 +88,33 @@ service CppMetricsService
1:common.AstNodeId astNodeId)

/**
* This function returns the names of metrics.
* This function returns all available C++ metrics
* for a particular module.
*/
list<CppMetricsModule> getCppMetricsForModule(
1:common.FileId fileId)

/**
* This function returns all available C++ metrics
* (AST node-level) for a particular path.
*/
list<CppAllMetricsAstNode> getCppAstNodeMetricsForPath(
1:string path)

/**
* This function returns all available C++ metrics
* (file-level) for a particular path.
*/
list<CppAllMetricsModule> getCppFileMetricsForPath(
1:string path)

/**
* This function returns the names of AST node metrics.
*/
list<CppAstNodeMetricsTypeName> getCppAstNodeMetricsTypeNames()

/**
* This function returns the names of module-level metrics.
*/
list<CppMetricsTypeName> getCppMetricsTypeNames()
list<CppModuleMetricsTypeName> getCppModuleMetricsTypeNames()
Comment thread
intjftw marked this conversation as resolved.
Outdated
}
23 changes: 20 additions & 3 deletions plugins/cpp_metrics/service/include/service/cppmetricsservice.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <model/cppastnodemetrics-odb.hxx>
#include <model/cppastnode.h>
#include <model/cppastnode-odb.hxx>
#include <model/cppfilemetrics.h>
#include <model/cppfilemetrics-odb.hxx>

#include <odb/database.hxx>
#include <util/odbtransaction.h>
Expand All @@ -36,14 +38,29 @@ class CppMetricsServiceHandler : virtual public CppMetricsServiceIf

double getSingleCppMetricForAstNode(
const core::AstNodeId& astNodeId_,
CppMetricsType::type metric_) override;
CppAstNodeMetricsType::type metric_) override;

void getCppMetricsForAstNode(
std::vector<CppMetricsAstNode>& _return,
const core::AstNodeId& astNodeId_) override;

void getCppMetricsTypeNames(
std::vector<CppMetricsTypeName>& _return) override;
void getCppMetricsForModule(
std::vector<CppMetricsModule>& _return,
const core::FileId& fileId_) override;

void getCppAstNodeMetricsForPath(
std::vector<CppAllMetricsAstNode>& _return,
const std::string& path_) override;

void getCppFileMetricsForPath(
std::vector<CppAllMetricsModule>& _return,
const std::string& path_) override;

void getCppAstNodeMetricsTypeNames(
std::vector<CppAstNodeMetricsTypeName>& _return) override;

void getCppModuleMetricsTypeNames(
std::vector<CppModuleMetricsTypeName>& _return) override;

private:
std::shared_ptr<odb::database> _db;
Expand Down
138 changes: 129 additions & 9 deletions plugins/cpp_metrics/service/src/cppmetricsservice.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
#include <service/cppmetricsservice.h>
#include <util/dbutil.h>

#include <odb/query.hxx>

namespace cc
{
namespace service
{
namespace cppmetrics
{

typedef odb::query<cc::model::CppAstNode> AstQuery;
typedef odb::result<cc::model::CppAstNode> AstResult;

CppMetricsServiceHandler::CppMetricsServiceHandler(
std::shared_ptr<odb::database> db_,
std::shared_ptr<std::string> datadir_,
Expand All @@ -16,28 +21,38 @@ CppMetricsServiceHandler::CppMetricsServiceHandler(
{
}

void CppMetricsServiceHandler::getCppMetricsTypeNames(
std::vector<CppMetricsTypeName>& _return)
void CppMetricsServiceHandler::getCppAstNodeMetricsTypeNames(
std::vector<CppAstNodeMetricsTypeName>& _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<CppModuleMetricsTypeName>& _return)
{
CppModuleMetricsTypeName typeName;

typeName.type = CppModuleMetricsType::Placeholder;
typeName.name = "Placeholder";
_return.push_back(typeName);
}

void CppMetricsServiceHandler::getCppMetricsForAstNode(
std::vector<CppMetricsAstNode>& _return,
const core::AstNodeId& astNodeId_)
Expand All @@ -52,7 +67,7 @@ void CppMetricsServiceHandler::getCppMetricsForAstNode(

for (const auto& nodeMetric : nodeMetrics)
{
metric.type = static_cast<CppMetricsType::type>(nodeMetric.type);
metric.type = static_cast<CppAstNodeMetricsType::type>(nodeMetric.type);
metric.value = nodeMetric.value;
_return.push_back(metric);
}
Expand All @@ -61,7 +76,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<model::CppAstNodeMetrics> CppAstNodeMetricsQuery;
Expand All @@ -81,6 +96,111 @@ double CppMetricsServiceHandler::getSingleCppMetricForAstNode(
});
}

void CppMetricsServiceHandler::getCppMetricsForModule(
std::vector<CppMetricsModule>& _return,
const core::FileId& fileId_)
{
CppMetricsModule metric;

_transaction([&, this](){
typedef odb::query<model::CppFileMetrics> CppModuleMetricsQuery;

auto moduleMetrics = _db->query<model::CppFileMetrics>(
CppModuleMetricsQuery::file == std::stoull(fileId_));

for (const auto& moduleMetric : moduleMetrics)
{
metric.type = static_cast<CppModuleMetricsType::type>(moduleMetric.type);
metric.value = moduleMetric.value;
_return.push_back(metric);
}
});
}

void CppMetricsServiceHandler::getCppAstNodeMetricsForPath(
std::vector<CppAllMetricsAstNode>& _return,
const std::string& path_)
{
_transaction([&, this]()
{
typedef odb::query<model::CppAstNodeMetrics> CppAstNodeMetricsQuery;
typedef odb::result<model::CppAstNodeMetrics> CppAstNodeMetricsResult;
typedef odb::query<model::CppAstNodeFilePath> CppAstNodeFilePathQuery;
typedef odb::result<model::CppAstNodeFilePath> CppAstNodeFilePathResult;

CppAstNodeFilePathResult nodes = _db->query<model::CppAstNodeFilePath>(
CppAstNodeFilePathQuery::LocFile::path.like(path_ + '%'));
Comment thread
mcserep marked this conversation as resolved.
Outdated

if (nodes.empty())
{
core::InvalidInput ex;
ex.__set_msg("Invalid metric type for path: " + path_);
Comment thread
intjftw marked this conversation as resolved.
Outdated
throw ex;
}

for (const auto& node : nodes)
{
auto metricsQuery = _db->query<model::CppAstNodeMetrics>(
CppAstNodeMetricsQuery::astNodeId == node.id);
std::vector<CppMetricsAstNode> metrics;

CppMetricsAstNode metricsAstNode;
for (const auto& metric : metricsQuery)
{
metricsAstNode.type = static_cast<CppAstNodeMetricsType::type>(metric.type);
metricsAstNode.value = metric.value;
}
Comment thread
intjftw marked this conversation as resolved.
Outdated

CppAllMetricsAstNode nodeMetric;
nodeMetric.id = std::to_string(node.id);
nodeMetric.metrics = metrics;
_return.push_back(nodeMetric);
}
});
}

void CppMetricsServiceHandler::getCppFileMetricsForPath(
std::vector<CppAllMetricsModule>& _return,
const std::string& path_)
{
_transaction([&, this]()
{
typedef odb::query<model::File> FileQuery;
typedef odb::result<model::File> FileResult;
typedef odb::query<model::CppFileMetrics> CppFileMetricsQuery;
typedef odb::result<model::CppFileMetrics> CppFileMetricsResult;

FileResult descendants = _db->query<model::File>(
FileQuery::path.like(path_ + '%'));
Comment thread
mcserep marked this conversation as resolved.
Outdated

if (descendants.empty())
{
core::InvalidInput ex;
ex.__set_msg("Invalid metric type for path: " + path_);
Comment thread
intjftw marked this conversation as resolved.
Outdated
throw ex;
}

for (const auto& file : descendants)
{
CppFileMetricsResult metricsQuery = _db->query<model::CppFileMetrics>(
CppFileMetricsQuery::file == file.id);
std::vector<CppMetricsModule> metrics;

CppMetricsModule metricsModule;
for (const auto& metric : metricsQuery)
{
metricsModule.type = static_cast<CppModuleMetricsType::type>(metric.type);
metricsModule.value = metric.value;
}
Comment thread
intjftw marked this conversation as resolved.
Outdated

CppAllMetricsModule nodeMetric;
nodeMetric.id = std::to_string(file.id);
nodeMetric.metrics = metrics;
_return.push_back(nodeMetric);
}
});
}

} // cppmetrics
} // service
} // cc