1010#include < model/cppinheritance-odb.hxx>
1111#include < model/cpprecord.h>
1212#include < model/cpprecord-odb.hxx>
13-
13+ #include < model/cpptypedependencymetrics.h>
14+ #include < model/cpptypedependencymetrics-odb.hxx>
1415#include < model/cppastnode.h>
1516#include < model/cppastnode-odb.hxx>
17+ #include < model/file.h>
18+ #include < model/file-odb.hxx>
1619
1720#include < boost/filesystem.hpp>
1821
@@ -390,7 +393,9 @@ void CppMetricsParser::efferentTypeLevel()
390393 dependentTypes.clear ();
391394
392395 // Count parent types
393- auto inheritanceView = _ctx.db ->query <model::CppInheritanceCount>(
396+ auto inheritanceView = _ctx.db ->query <model::CppInheritance>(
397+ InheritanceQuery::derived == type.entityHash );
398+ auto inheritanceCount = _ctx.db ->query_value <model::CppInheritanceCount>(
394399 InheritanceQuery::derived == type.entityHash );
395400
396401 // Count unique attribute types
@@ -423,8 +428,26 @@ void CppMetricsParser::efferentTypeLevel()
423428 model::CppAstNodeMetrics metric;
424429 metric.astNodeId = type.astNodeId ;
425430 metric.type = model::CppAstNodeMetrics::Type::EFFERENT_TYPE;
426- metric.value = inheritanceView. begin ()-> count + dependentTypes.size ();
431+ metric.value = inheritanceCount. count + dependentTypes.size ();
427432 _ctx.db ->persist (metric);
433+
434+ auto typeRelationInserter = [this ](const std::uint64_t & entityHash, const std::uint64_t & dependencyHash)
435+ {
436+ model::CppTypeDependencyMetrics relation;
437+ relation.entityHash = entityHash;
438+ relation.dependencyHash = dependencyHash;
439+ _ctx.db ->persist (relation);
440+ };
441+
442+ // Insert type dependency relations
443+ for (const std::uint64_t & d : dependentTypes) {
444+ typeRelationInserter (type.entityHash , d);
445+ }
446+
447+ // Insert inheritance relations
448+ for (const model::CppInheritance& d : inheritanceView) {
449+ typeRelationInserter (type.entityHash , d.base );
450+ }
428451 }
429452 });
430453 });
@@ -513,6 +536,46 @@ void CppMetricsParser::afferentTypeLevel()
513536 });
514537}
515538
539+ odb::query<model::File> CppMetricsParser::getModulePathsQuery ()
540+ {
541+ if (_ctx.moduleDirectories .empty ()) {
542+ // No module directories specified, compute for all directories
543+ return odb::query<model::File>::type == cc::model::File::DIRECTORY_TYPE && getFilterPathsQuery<model::File>();
544+ } else {
545+ // Compute for module directories
546+ return odb::query<model::File>::path.in_range (_ctx.moduleDirectories .begin (), _ctx.moduleDirectories .end ());
547+ }
548+ }
549+
550+ void CppMetricsParser::efferentModuleLevel ()
551+ {
552+ parallelCalcMetric<model::File>(
553+ " Efferent coupling at module level" ,
554+ _threadCount * efferentCouplingModulesPartitionMultiplier,// number of jobs; adjust for granularity
555+ getModulePathsQuery (),
556+ [&, this ](const MetricsTasks<model::File>& tasks)
557+ {
558+ util::OdbTransaction{_ctx.db }([&, this ]
559+ {
560+ typedef odb::query<model::CppTypeDependencyMetricsPathViewDistinctCount> TypeDependencyQuery;
561+ typedef model::CppTypeDependencyMetricsPathViewDistinctCount TypeDependencyResult;
562+
563+ for (const model::File& file : tasks)
564+ {
565+ TypeDependencyResult types = _ctx.db ->query_value <model::CppTypeDependencyMetricsPathViewDistinctCount>(
566+ TypeDependencyQuery::EntityFile::path.like (file.path + ' %' ) &&
567+ !TypeDependencyQuery::DependencyFile::path.like (file.path + ' %' ));
568+
569+ model::CppFileMetrics metric;
570+ metric.file = file.id ;
571+ metric.type = model::CppFileMetrics::Type::EFFERENT_MODULE;
572+ metric.value = types.count ;
573+ _ctx.db ->persist (metric);
574+ }
575+ });
576+ });
577+ }
578+
516579bool CppMetricsParser::parse ()
517580{
518581 LOG (info) << " [cppmetricsparser] Computing function parameter count metric." ;
@@ -529,6 +592,8 @@ bool CppMetricsParser::parse()
529592 efferentTypeLevel ();
530593 LOG (info) << " [cppmetricsparser] Computing afferent coupling metric for types." ;
531594 afferentTypeLevel ();
595+ LOG (info) << " [cppmetricsparser] Computing efferent coupling metric at module level." ;
596+ efferentModuleLevel (); // This metric needs to be calculated after efferentTypeLevel
532597 return true ;
533598}
534599
0 commit comments