@@ -315,36 +315,56 @@ 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
343- && QNodeRange.start .column >= start.column )) &&
344- (QNodeRange.end .line <= end.line
345- || (QNodeRange.end .line == end.line
346- && QNodeRange.end .column <= end.column )))
347- ))
333+ continue ;
334+ }
335+
336+ methods.push_back (method);
337+ nodeQuery = nodeQuery ||
338+ (QNodeFilePath == method.filePath &&
339+ QNodeRange.start .line >= start.line &&
340+ (QNodeRange.end .line < end.line ||
341+ (QNodeRange.end .line == end.line && QNodeRange.end .column <= end.column )) &&
342+ (QNodeRange.start .line > start.line ||
343+ (QNodeRange.start .line == start.line && QNodeRange.start .column >= start.column )));
344+ }
345+
346+ // Query all nodes in a single operation
347+ auto nodes = _ctx.db ->query <model::CohesionCppAstNodeView>(nodeQuery);
348+
349+ // Counter variables.
350+ std::size_t fieldCount = fieldHashes.size ();
351+ std::size_t methodCount = methods.size ();
352+ std::size_t totalCohesion = 0 ;
353+
354+ // For each node, find the method it belongs to and check for field usage.
355+ for (const auto & method : methods) {
356+ model::Position start (method.startLine , method.startColumn );
357+ model::Position end (method.endLine , method.endColumn );
358+
359+ std::unordered_set<HashType> usedFields;
360+
361+ for (const auto & node : nodes) {
362+ // Filter AST nodes used in this method...
363+ if (node.filePath == method.filePath &&
364+ (node.startLine > start.line ||
365+ (node.startLine == start.line && node.startColumn >= start.column )) &&
366+ (node.endLine < end.line ||
367+ (node.endLine == end.line && node.endColumn <= end.column )))
348368 {
349369 // If this AST node is a reference to a field of the type...
350370 if (fieldHashes.find (node.entityHash ) != fieldHashes.end ())
@@ -353,10 +373,9 @@ void CppMetricsParser::lackOfCohesion()
353373 usedFields.insert (node.entityHash );
354374 }
355375 }
356-
357- ++methodCount;
358- totalCohesion += usedFields.size ();
359376 }
377+
378+ totalCohesion += usedFields.size ();
360379 }
361380
362381 // Calculate and record metrics.
0 commit comments