Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion plugins/cpp_metrics/model/include/model/cppfilemetrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ struct CppFileMetrics
{
enum Type
{
EFFERENT_MODULE
EFFERENT_MODULE,
AFFERENT_MODULE
};

#pragma db id auto
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,26 @@ struct CppTypeDependencyMetricsPathView
object(CppAstNode = DependencyAstNode : CppTypeDependencyMetrics::dependencyHash == DependencyAstNode::entityHash \
&& DependencyAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
object(File = DependencyFile : DependencyAstNode::location.file == DependencyFile::id)
struct CppTypeDependencyMetricsPathViewDistinctCount
struct CppTypeDependencyMetrics_Distinct_D_Count
{
#pragma db column("count(distinct" + CppTypeDependencyMetrics::dependencyHash + ")")
std::size_t count;
};

#pragma db view \
object(CppTypeDependencyMetrics) \
object(CppAstNode = EntityAstNode : CppTypeDependencyMetrics::entityHash == EntityAstNode::entityHash \
&& EntityAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
object(File = EntityFile : EntityAstNode::location.file == EntityFile::id) \
object(CppAstNode = DependencyAstNode : CppTypeDependencyMetrics::dependencyHash == DependencyAstNode::entityHash \
&& DependencyAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
object(File = DependencyFile : DependencyAstNode::location.file == DependencyFile::id)
struct CppTypeDependencyMetrics_Distinct_E_Count
{
#pragma db column("count(distinct" + CppTypeDependencyMetrics::entityHash + ")")
std::size_t count;
};

} // model
} // cc

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class CppMetricsParser : public AbstractParser
void afferentTypeLevel();
// Calculate the efferent coupling at module level.
void efferentModuleLevel();
// Calculate the afferent coupling at module level.
void afferentModuleLevel();
// Returns module path query based on parser configuration.
odb::query<model::File> getModulePathsQuery();

Expand Down Expand Up @@ -207,6 +209,7 @@ class CppMetricsParser : public AbstractParser
static const int efferentCouplingTypesPartitionMultiplier = 5;
static const int afferentCouplingTypesPartitionMultiplier = 5;
static const int efferentCouplingModulesPartitionMultiplier = 5;
static const int afferentCouplingModulesPartitionMultiplier = 5;
};

} // parser
Expand Down
37 changes: 34 additions & 3 deletions plugins/cpp_metrics/parser/src/cppmetricsparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,12 +557,12 @@ void CppMetricsParser::efferentModuleLevel()
{
util::OdbTransaction{_ctx.db}([&, this]
{
typedef odb::query<model::CppTypeDependencyMetricsPathViewDistinctCount> TypeDependencyQuery;
typedef model::CppTypeDependencyMetricsPathViewDistinctCount TypeDependencyResult;
typedef odb::query<model::CppTypeDependencyMetrics_Distinct_D_Count> TypeDependencyQuery;
typedef model::CppTypeDependencyMetrics_Distinct_D_Count TypeDependencyResult;

for (const model::File& file : tasks)
{
TypeDependencyResult types = _ctx.db->query_value<model::CppTypeDependencyMetricsPathViewDistinctCount>(
TypeDependencyResult types = _ctx.db->query_value<model::CppTypeDependencyMetrics_Distinct_D_Count>(
TypeDependencyQuery::EntityFile::path.like(file.path + '%') &&
!TypeDependencyQuery::DependencyFile::path.like(file.path + '%'));

Expand All @@ -576,6 +576,35 @@ void CppMetricsParser::efferentModuleLevel()
});
}

void CppMetricsParser::afferentModuleLevel()
{
parallelCalcMetric<model::File>(
"Afferent coupling at module level",
_threadCount * afferentCouplingModulesPartitionMultiplier,// number of jobs; adjust for granularity
getModulePathsQuery(),
[&, this](const MetricsTasks<model::File>& tasks)
{
util::OdbTransaction{_ctx.db}([&, this]
{
typedef odb::query<model::CppTypeDependencyMetrics_Distinct_E_Count> TypeDependencyQuery;
typedef model::CppTypeDependencyMetrics_Distinct_E_Count TypeDependencyResult;

for (const model::File& file : tasks)
{
TypeDependencyResult types = _ctx.db->query_value<model::CppTypeDependencyMetrics_Distinct_E_Count>(
!TypeDependencyQuery::EntityFile::path.like(file.path + '%') &&
TypeDependencyQuery::DependencyFile::path.like(file.path + '%'));

model::CppFileMetrics metric;
metric.file = file.id;
metric.type = model::CppFileMetrics::Type::AFFERENT_MODULE;
metric.value = types.count;
_ctx.db->persist(metric);
}
});
});
}

bool CppMetricsParser::parse()
{
LOG(info) << "[cppmetricsparser] Computing function parameter count metric.";
Expand All @@ -594,6 +623,8 @@ bool CppMetricsParser::parse()
afferentTypeLevel();
LOG(info) << "[cppmetricsparser] Computing efferent coupling metric at module level.";
efferentModuleLevel(); // This metric needs to be calculated after efferentTypeLevel
LOG(info) << "[cppmetricsparser] Computing afferent coupling metric at module level.";
afferentModuleLevel(); // This metric needs to be calculated after afferentTypeLevel
return true;
}

Expand Down
15 changes: 15 additions & 0 deletions plugins/cpp_metrics/test/sources/parser/module_d/d1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef CC_CPP_MODULE_METRICS_TEST_D1
#define CC_CPP_MODULE_METRICS_TEST_D1

#include "../module_c/c1.h"
#include "../module_c/c2.h"

namespace CC_CPP_MODULE_METRICS_TEST
{
class D1 {
C1 c1;
C2 c2;
};
}

#endif
1 change: 1 addition & 0 deletions plugins/cpp_metrics/test/sources/parser/modulemetrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
#include "./module_b/b2.h"
#include "./module_c/c1.h"
#include "./module_c/c2.h"
#include "./module_d/d1.h"
38 changes: 36 additions & 2 deletions plugins/cpp_metrics/test/src/cppmetricsparsertest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,10 @@ class ParameterizedEfferentModuleCouplingTest
{};

std::vector<StringUintParam> paramEfferentModule = {
{"%/test/sources/parser/module_a", 1},
{"%/test/sources/parser/module_a", 1}, // B1
{"%/test/sources/parser/module_b", 0},
{"%/test/sources/parser/module_c", 2},
{"%/test/sources/parser/module_c", 2}, // A2, B1
{"%/test/sources/parser/module_d", 2}, // C1, C2
};

TEST_P(ParameterizedEfferentModuleCouplingTest, ModuleEfferentTest) {
Expand All @@ -353,3 +354,36 @@ INSTANTIATE_TEST_SUITE_P(
ParameterizedEfferentModuleCouplingTest,
::testing::ValuesIn(paramEfferentModule)
);

// Afferent coupling at module level

class ParameterizedAfferentModuleCouplingTest
: public CppMetricsParserTest,
public ::testing::WithParamInterface<StringUintParam>
{};

std::vector<StringUintParam> paramAfferentModule = {
{"%/test/sources/parser/module_a", 1}, // C2
{"%/test/sources/parser/module_b", 3}, // A2, C1, C2
{"%/test/sources/parser/module_c", 1}, // D1
{"%/test/sources/parser/module_d", 0},
};

TEST_P(ParameterizedAfferentModuleCouplingTest, ModuleAfferentTest) {
_transaction([&, this]() {

typedef odb::query<model::CppModuleMetricsForPathView> CppModuleMetricsQuery;

const auto metric = _db->query_value<model::CppModuleMetricsForPathView>(
CppModuleMetricsQuery::CppFileMetrics::type == model::CppFileMetrics::Type::AFFERENT_MODULE &&
CppModuleMetricsQuery::File::path.like(GetParam().first));

EXPECT_EQ(GetParam().second, metric.value);
});
}

INSTANTIATE_TEST_SUITE_P(
ParameterizedAfferentModuleCouplingTestSuite,
ParameterizedAfferentModuleCouplingTest,
::testing::ValuesIn(paramAfferentModule)
);
Loading