Skip to content

Commit d60b3b9

Browse files
authored
Merge branch 'master' into relational_cohesion_modules
2 parents 1519c8a + dc03735 commit d60b3b9

File tree

7 files changed

+106
-8
lines changed

7 files changed

+106
-8
lines changed

plugins/cpp_metrics/model/include/model/cppfilemetrics.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct CppFileMetrics
1414
enum Type
1515
{
1616
EFFERENT_MODULE,
17+
AFFERENT_MODULE,
1718
RELATIONAL_COHESION_MODULE
1819
};
1920

plugins/cpp_metrics/model/include/model/cpptypedependencymetrics.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,26 @@ struct CppTypeDependencyMetrics_Count
7171
object(CppAstNode = DependencyAstNode : CppTypeDependencyMetrics::dependencyHash == DependencyAstNode::entityHash \
7272
&& DependencyAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
7373
object(File = DependencyFile : DependencyAstNode::location.file == DependencyFile::id)
74-
struct CppTypeDependencyMetricsPathViewDistinctCount
74+
struct CppTypeDependencyMetrics_Distinct_D_Count
7575
{
7676
#pragma db column("count(distinct" + CppTypeDependencyMetrics::dependencyHash + ")")
7777
std::size_t count;
7878
};
7979

80+
#pragma db view \
81+
object(CppTypeDependencyMetrics) \
82+
object(CppAstNode = EntityAstNode : CppTypeDependencyMetrics::entityHash == EntityAstNode::entityHash \
83+
&& EntityAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
84+
object(File = EntityFile : EntityAstNode::location.file == EntityFile::id) \
85+
object(CppAstNode = DependencyAstNode : CppTypeDependencyMetrics::dependencyHash == DependencyAstNode::entityHash \
86+
&& DependencyAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
87+
object(File = DependencyFile : DependencyAstNode::location.file == DependencyFile::id)
88+
struct CppTypeDependencyMetrics_Distinct_E_Count
89+
{
90+
#pragma db column("count(distinct" + CppTypeDependencyMetrics::entityHash + ")")
91+
std::size_t count;
92+
};
93+
8094
} // model
8195
} // cc
8296

plugins/cpp_metrics/parser/include/cppmetricsparser/cppmetricsparser.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class CppMetricsParser : public AbstractParser
8282
void afferentTypeLevel();
8383
// Calculate the efferent coupling at module level.
8484
void efferentModuleLevel();
85+
// Calculate the afferent coupling at module level.
86+
void afferentModuleLevel();
8587
// Calculate relational cohesion at module level.
8688
void relationalCohesionModuleLevel();
8789
// Returns module path query based on parser configuration.
@@ -209,7 +211,7 @@ class CppMetricsParser : public AbstractParser
209211
static const int efferentCouplingTypesPartitionMultiplier = 5;
210212
static const int afferentCouplingTypesPartitionMultiplier = 5;
211213
static const int efferentCouplingModulesPartitionMultiplier = 5;
212-
static const int relationalCohesionPartitionMultiplier = 5;
214+
static const int afferentCouplingModulesPartitionMultiplier = 5;
213215
};
214216

215217
} // parser

plugins/cpp_metrics/parser/src/cppmetricsparser.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -557,12 +557,12 @@ void CppMetricsParser::efferentModuleLevel()
557557
{
558558
util::OdbTransaction{_ctx.db}([&, this]
559559
{
560-
typedef odb::query<model::CppTypeDependencyMetricsPathViewDistinctCount> TypeDependencyQuery;
561-
typedef model::CppTypeDependencyMetricsPathViewDistinctCount TypeDependencyResult;
560+
typedef odb::query<model::CppTypeDependencyMetrics_Distinct_D_Count> TypeDependencyQuery;
561+
typedef model::CppTypeDependencyMetrics_Distinct_D_Count TypeDependencyResult;
562562

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

@@ -576,6 +576,35 @@ void CppMetricsParser::efferentModuleLevel()
576576
});
577577
}
578578

579+
void CppMetricsParser::afferentModuleLevel()
580+
{
581+
parallelCalcMetric<model::File>(
582+
"Afferent coupling at module level",
583+
_threadCount * afferentCouplingModulesPartitionMultiplier,// number of jobs; adjust for granularity
584+
getModulePathsQuery(),
585+
[&, this](const MetricsTasks<model::File>& tasks)
586+
{
587+
util::OdbTransaction{_ctx.db}([&, this]
588+
{
589+
typedef odb::query<model::CppTypeDependencyMetrics_Distinct_E_Count> TypeDependencyQuery;
590+
typedef model::CppTypeDependencyMetrics_Distinct_E_Count TypeDependencyResult;
591+
592+
for (const model::File& file : tasks)
593+
{
594+
TypeDependencyResult types = _ctx.db->query_value<model::CppTypeDependencyMetrics_Distinct_E_Count>(
595+
!TypeDependencyQuery::EntityFile::path.like(file.path + '%') &&
596+
TypeDependencyQuery::DependencyFile::path.like(file.path + '%'));
597+
598+
model::CppFileMetrics metric;
599+
metric.file = file.id;
600+
metric.type = model::CppFileMetrics::Type::AFFERENT_MODULE;
601+
metric.value = types.count;
602+
_ctx.db->persist(metric);
603+
}
604+
});
605+
});
606+
}
607+
579608
void CppMetricsParser::relationalCohesionModuleLevel()
580609
{
581610
// Compute relational cohesion defined by CppDepend:
@@ -641,6 +670,8 @@ bool CppMetricsParser::parse()
641670
afferentTypeLevel();
642671
LOG(info) << "[cppmetricsparser] Computing efferent coupling metric at module level.";
643672
efferentModuleLevel(); // This metric needs to be calculated after efferentTypeLevel
673+
LOG(info) << "[cppmetricsparser] Computing afferent coupling metric at module level.";
674+
afferentModuleLevel(); // This metric needs to be calculated after afferentTypeLevel
644675
LOG(info) << "[cppmetricsparser] Computing relational cohesion metric at module level.";
645676
relationalCohesionModuleLevel(); // This metric needs to be calculated after efferentTypeLevel
646677
return true;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef CC_CPP_MODULE_METRICS_TEST_D1
2+
#define CC_CPP_MODULE_METRICS_TEST_D1
3+
4+
#include "../module_c/c1.h"
5+
#include "../module_c/c2.h"
6+
7+
namespace CC_CPP_MODULE_METRICS_TEST
8+
{
9+
class D1 {
10+
C1 c1;
11+
C2 c2;
12+
};
13+
}
14+
15+
#endif

plugins/cpp_metrics/test/sources/parser/modulemetrics.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "./module_b/b2.h"
55
#include "./module_c/c1.h"
66
#include "./module_c/c2.h"
7+
#include "./module_d/d1.h"
78

89
#include "./rc_module_a/a1.h"
910
#include "./rc_module_a/a2.h"

plugins/cpp_metrics/test/src/cppmetricsparsertest.cpp

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,10 @@ class ParameterizedEfferentModuleCouplingTest
331331
{};
332332

333333
std::vector<StringUintParam> paramEfferentModule = {
334-
{"%/test/sources/parser/module_a", 1},
334+
{"%/test/sources/parser/module_a", 1}, // B1
335335
{"%/test/sources/parser/module_b", 0},
336-
{"%/test/sources/parser/module_c", 2},
336+
{"%/test/sources/parser/module_c", 2}, // A2, B1
337+
{"%/test/sources/parser/module_d", 2}, // C1, C2
337338
};
338339

339340
TEST_P(ParameterizedEfferentModuleCouplingTest, ModuleEfferentTest) {
@@ -355,6 +356,39 @@ INSTANTIATE_TEST_SUITE_P(
355356
::testing::ValuesIn(paramEfferentModule)
356357
);
357358

359+
// Afferent coupling at module level
360+
361+
class ParameterizedAfferentModuleCouplingTest
362+
: public CppMetricsParserTest,
363+
public ::testing::WithParamInterface<StringUintParam>
364+
{};
365+
366+
std::vector<StringUintParam> paramAfferentModule = {
367+
{"%/test/sources/parser/module_a", 1}, // C2
368+
{"%/test/sources/parser/module_b", 3}, // A2, C1, C2
369+
{"%/test/sources/parser/module_c", 1}, // D1
370+
{"%/test/sources/parser/module_d", 0},
371+
};
372+
373+
TEST_P(ParameterizedAfferentModuleCouplingTest, ModuleAfferentTest) {
374+
_transaction([&, this]() {
375+
376+
typedef odb::query<model::CppModuleMetricsForPathView> CppModuleMetricsQuery;
377+
378+
const auto metric = _db->query_value<model::CppModuleMetricsForPathView>(
379+
CppModuleMetricsQuery::CppFileMetrics::type == model::CppFileMetrics::Type::AFFERENT_MODULE &&
380+
CppModuleMetricsQuery::File::path.like(GetParam().first));
381+
382+
EXPECT_EQ(GetParam().second, metric.value);
383+
});
384+
}
385+
386+
INSTANTIATE_TEST_SUITE_P(
387+
ParameterizedAfferentModuleCouplingTestSuite,
388+
ParameterizedAfferentModuleCouplingTest,
389+
::testing::ValuesIn(paramAfferentModule)
390+
);
391+
358392
// Relational cohesion at module level
359393

360394
class ParameterizedRelationalCohesionTest
@@ -391,4 +425,4 @@ INSTANTIATE_TEST_SUITE_P(
391425
ParameterizedRelationalCohesionTestSuite,
392426
ParameterizedRelationalCohesionTest,
393427
::testing::ValuesIn(paramRelationalCohesion)
394-
);
428+
);

0 commit comments

Comments
 (0)