66#include < model/cppcohesionmetrics-odb.hxx>
77#include < model/cppfilemetrics.h>
88#include < model/cppfilemetrics-odb.hxx>
9+ #include < model/cppinheritance.h>
10+ #include < model/cppinheritance-odb.hxx>
911
1012#include < model/cppastnode.h>
1113#include < model/cppastnode-odb.hxx>
@@ -364,6 +366,68 @@ void CppMetricsParser::lackOfCohesion()
364366 });
365367}
366368
369+ void CppMetricsParser::efferentTypeLevel ()
370+ {
371+ parallelCalcMetric<model::CohesionCppRecordView>(
372+ " Efferent coupling of types" ,
373+ _threadCount * efferentCouplingTypesPartitionMultiplier,// number of jobs; adjust for granularity
374+ getFilterPathsQuery<model::CohesionCppRecordView>(),
375+ [&, this ](const MetricsTasks<model::CohesionCppRecordView>& tasks)
376+ {
377+ util::OdbTransaction{_ctx.db }([&, this ]
378+ {
379+ typedef odb::query<cc::model::CppMemberType> MemTypeQuery;
380+ typedef odb::query<cc::model::CppInheritanceCount> InheritanceQuery;
381+ typedef odb::query<cc::model::CppFunctionParamTypeView> ParamQuery;
382+ typedef odb::query<cc::model::CppFunctionLocalTypeView> LocalQuery;
383+ typedef odb::query<cc::model::CppFunction> FuncQuery;
384+
385+ std::set<std::uint64_t > dependentTypes;
386+ for (const model::CohesionCppRecordView& type : tasks)
387+ {
388+ dependentTypes.clear ();
389+
390+ // Count parent types
391+ auto inheritanceView = _ctx.db ->query <model::CppInheritanceCount>(
392+ InheritanceQuery::derived == type.entityHash );
393+
394+ // Count unique attribute types
395+ // and unique types in function parameters and local variables
396+ for (const model::CppMemberType& mem: _ctx.db ->query <model::CppMemberType>(
397+ MemTypeQuery::typeHash == type.entityHash ))
398+ {
399+ auto funcAstNodeId = mem.memberAstNode .load ()->id ;
400+
401+ if (mem.kind == cc::model::CppMemberType::Field)
402+ {
403+ dependentTypes.insert (mem.memberTypeHash );
404+ }
405+ else
406+ {
407+ for (const auto & param: _ctx.db ->query <model::CppFunctionParamTypeView>(
408+ FuncQuery::astNodeId == funcAstNodeId))
409+ {
410+ dependentTypes.insert (param.paramTypeHash );
411+ }
412+
413+ for (const auto & local: _ctx.db ->query <model::CppFunctionLocalTypeView>(
414+ FuncQuery::astNodeId == funcAstNodeId))
415+ {
416+ dependentTypes.insert (local.paramTypeHash );
417+ }
418+ }
419+ }
420+
421+ model::CppAstNodeMetrics metric;
422+ metric.astNodeId = type.astNodeId ;
423+ metric.type = model::CppAstNodeMetrics::Type::EFFERENT_TYPE;
424+ metric.value = inheritanceView.begin ()->count + dependentTypes.size ();
425+ _ctx.db ->persist (metric);
426+ }
427+ });
428+ });
429+ }
430+
367431bool CppMetricsParser::parse ()
368432{
369433 LOG (info) << " [cppmetricsparser] Computing function parameter count metric." ;
@@ -376,6 +440,8 @@ bool CppMetricsParser::parse()
376440 typeMcCabe ();
377441 LOG (info) << " [cppmetricsparser] Computing Lack of Cohesion metric for types." ;
378442 lackOfCohesion ();
443+ LOG (info) << " [cppmetricsparser] Computing efferent coupling metric for types." ;
444+ efferentTypeLevel ();
379445 return true ;
380446}
381447
0 commit comments