@@ -383,8 +383,6 @@ void CppMetricsParser::efferentTypeLevel()
383383 {
384384 typedef odb::query<cc::model::CppMemberType> MemTypeQuery;
385385 typedef odb::query<cc::model::CppInheritanceCount> InheritanceQuery;
386- typedef odb::query<cc::model::CppFunctionParamTypeView> ParamQuery;
387- typedef odb::query<cc::model::CppFunctionLocalTypeView> LocalQuery;
388386 typedef odb::query<cc::model::CppFunction> FuncQuery;
389387
390388 std::set<std::uint64_t > dependentTypes;
@@ -605,6 +603,53 @@ void CppMetricsParser::afferentModuleLevel()
605603 });
606604}
607605
606+ void CppMetricsParser::relationalCohesionModuleLevel ()
607+ {
608+ // Compute relational cohesion defined by CppDepend:
609+ // https://www.cppdepend.com/documentation/code-metrics#RelationalCohesion
610+
611+ parallelCalcMetric<model::File>(
612+ " Relational cohesion at module level" ,
613+ _threadCount * relationalCohesionPartitionMultiplier, // number of jobs; adjust for granularity
614+ getModulePathsQuery (),
615+ [&, this ](const MetricsTasks<model::File>& tasks)
616+ {
617+ util::OdbTransaction{_ctx.db }([&, this ]
618+ {
619+ typedef odb::query<model::CppTypeDependencyMetrics_Count> TypeDependencyQuery;
620+ typedef model::CppTypeDependencyMetrics_Count TypeDependencyResult;
621+ typedef odb::query<model::CohesionCppRecord_Count> RecordQuery;
622+ typedef model::CohesionCppRecord_Count RecordResult;
623+
624+ for (const model::File& file : tasks)
625+ {
626+ TypeDependencyResult dependencies = _ctx.db ->query_value <model::CppTypeDependencyMetrics_Count>(
627+ TypeDependencyQuery::EntityFile::path.like (file.path + ' %' ) &&
628+ TypeDependencyQuery::DependencyFile::path.like (file.path + ' %' ));
629+
630+ // Let R be the number of type relationships that are internal to a module
631+ // (i.e that do not connect to types outside the module)
632+ const std::size_t r = dependencies.count ;
633+
634+ RecordResult types = _ctx.db ->query_value <model::CohesionCppRecord_Count>(
635+ RecordQuery::File::path.like (file.path + ' %' ));
636+
637+ // Let N be the number of types within the module.
638+ const std::size_t n = types.count ;
639+
640+ // Relational cohesion
641+ const double h = (n != 0 ) ? (double )(r + 1 ) / n : 0 ;
642+
643+ model::CppFileMetrics metric;
644+ metric.file = file.id ;
645+ metric.type = model::CppFileMetrics::Type::RELATIONAL_COHESION_MODULE;
646+ metric.value = h;
647+ _ctx.db ->persist (metric);
648+ }
649+ });
650+ });
651+ }
652+
608653bool CppMetricsParser::parse ()
609654{
610655 LOG (info) << " [cppmetricsparser] Computing function parameter count metric." ;
@@ -625,6 +670,8 @@ bool CppMetricsParser::parse()
625670 efferentModuleLevel (); // This metric needs to be calculated after efferentTypeLevel
626671 LOG (info) << " [cppmetricsparser] Computing afferent coupling metric at module level." ;
627672 afferentModuleLevel (); // This metric needs to be calculated after afferentTypeLevel
673+ LOG (info) << " [cppmetricsparser] Computing relational cohesion metric at module level." ;
674+ relationalCohesionModuleLevel (); // This metric needs to be calculated after efferentTypeLevel
628675 return true ;
629676}
630677
0 commit comments