@@ -315,36 +315,61 @@ void CppMetricsParser::lackOfCohesion()
315315 // Record these fields for later use.
316316 fieldHashes.insert (field.entityHash );
317317 }
318- std::size_t fieldCount = fieldHashes.size ();
319318
320- std::size_t methodCount = 0 ;
321- std::size_t totalCohesion = 0 ;
322319 // Query all methods of the current type.
320+ std::vector<model::CohesionCppMethodView> methods;
321+ // Build a query for variable access that within ANY of the methods.
322+ odb::query<model::CohesionCppAstNodeView> nodeQuery (false );
323323 for (const model::CohesionCppMethodView& method
324324 : _ctx.db ->query <model::CohesionCppMethodView>(
325- QMethodTypeHash == type.entityHash
326- ))
325+ QMethodTypeHash == type.entityHash
326+ ))
327327 {
328328 // Do not consider methods with no explicit bodies.
329329 const model::Position start (method.startLine , method.startColumn );
330330 const model::Position end (method.endLine , method.endColumn );
331- if (start < end)
331+ if (!( start < end) )
332332 {
333- std::unordered_set<HashType> usedFields;
334-
335- // Query AST nodes that use a variable for reading or writing...
336- for (const model::CohesionCppAstNodeView& node
337- : _ctx.db ->query <model::CohesionCppAstNodeView>(
338- // ... in the same file as the current method
339- (QNodeFilePath == method.filePath &&
340- // ... within the textual scope of the current method's body.
341- (QNodeRange.start .line >= start.line
342- || (QNodeRange.start .line == start.line
333+ continue ;
334+ }
335+
336+ methods.push_back (method);
337+
338+ // Query AST nodes that use a variable for reading or writing...
339+ nodeQuery = nodeQuery ||
340+ // ... in the same file as the current method
341+ (QNodeFilePath == method.filePath &&
342+ // ... within the textual scope of the current method's body.
343+ (QNodeRange.start .line > start.line
344+ || (QNodeRange.start .line == start.line
343345 && QNodeRange.start .column >= start.column )) &&
344- (QNodeRange.end .line <= end.line
345- || (QNodeRange.end .line == end.line
346- && QNodeRange.end .column <= end.column )))
347- ))
346+ (QNodeRange.end .line < end.line
347+ || (QNodeRange.end .line == end.line
348+ && QNodeRange.end .column <= end.column )));
349+ }
350+
351+ // Query all nodes in a single operation
352+ auto nodes = _ctx.db ->query <model::CohesionCppAstNodeView>(nodeQuery);
353+
354+ // Counter variables.
355+ std::size_t fieldCount = fieldHashes.size ();
356+ std::size_t methodCount = methods.size ();
357+ std::size_t totalCohesion = 0 ;
358+
359+ // For each node, find the method it belongs to and check for field usage.
360+ for (const auto & method : methods) {
361+ model::Position start (method.startLine , method.startColumn );
362+ model::Position end (method.endLine , method.endColumn );
363+
364+ std::unordered_set<HashType> usedFields;
365+
366+ for (const auto & node : nodes) {
367+ // Filter AST nodes used in this method.
368+ if (node.filePath == method.filePath &&
369+ (node.startLine > start.line ||
370+ (node.startLine == start.line && node.startColumn >= start.column )) &&
371+ (node.endLine < end.line ||
372+ (node.endLine == end.line && node.endColumn <= end.column )))
348373 {
349374 // If this AST node is a reference to a field of the type...
350375 if (fieldHashes.find (node.entityHash ) != fieldHashes.end ())
@@ -353,10 +378,9 @@ void CppMetricsParser::lackOfCohesion()
353378 usedFields.insert (node.entityHash );
354379 }
355380 }
356-
357- ++methodCount;
358- totalCohesion += usedFields.size ();
359381 }
382+
383+ totalCohesion += usedFields.size ();
360384 }
361385
362386 // Calculate and record metrics.
0 commit comments