ek9_query_module_cohesion
Answers first: status, programState, moduleCount, then modules[] {name, moduleCohesion (E11017 disconnected groups), cohesionRatio, lcom4 (E11014 over-limit constructs)}; symbol:'Type' drills to one construct's LCOM4.
When to use it
'Should this module be split, and which constructs do too many unrelated things' is one call with no arguments, or moduleFilter:['mod'] for one module.
When not to use it
- how modules depend on each other, the coupling side (use
ek9_query_module_coupling) - the workspace-wide module map to pick WHICH module to inspect (use
ek9_query_module_landscapefirst, then drill here) - COMPONENT cohesion — EK9 components hold only fields/methods, not nested constructs; the cohesion unit is the MODULE, so there is no component-cohesion tool
Details
Per-construct LCOM4 (E11014) is a zero-recompute READ of the checker's own squirrelled COHESION value; module disconnected-groups (E11017) is RE-DERIVED (basis:'toolWalk') because the checker's value is not persisted, so it carries gate thresholds not enforced:true and can differ from the gate (this walk unwraps generics, the gate does not). E11017 fires only when groups>maxGroups AND ratio>maxRatio AND constructs>=minConstructs; band is over/approaching/ok/info. cohesionRatio (internal vs external edges) is advisory-only, never a gate; ratio:null when the module has no edges.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
moduleFilter | array of string | Restrict to these modules - exact names; an entry ending in '*' is a prefix ('com.acme.*'). A single string is accepted. Omit for workspace-wide. | |
symbol | string | A construct NAME ('OrderService' or 'com.acme.orders::OrderService') — drill straight to its LCOM4 (E11014) instead of the per-module view. |
Recorded calls
Real calls, recorded against small projects and checked on every build - a changed answer fails it.
Lcom4 drill
Request
{
"symbol" : "sample.arch.orders::Order"
}
Response
{
"construct" : {
"file" : "orders.ek9",
"fullyQualifiedName" : "sample.arch.orders::Order",
"genus" : "CLASS",
"lcom4" : {
"band" : "ok",
"comparator" : ">",
"enforced" : true,
"limit" : 8,
"rule" : "E11014",
"value" : 1
},
"line" : 10,
"module" : "sample.arch.orders",
"name" : "Order"
},
"meta" : {
"serverMs" : "<timing>"
},
"programState" : "clean",
"status" : "ok"
}
Cohesion shape
Request
{ }
Response
{
"meta" : {
"serverMs" : "<timing>"
},
"moduleCount" : 3,
"modules" : [ {
"cohesionRatio" : {
"enforced" : false,
"externalEdges" : 0,
"internalEdges" : 0,
"ratio" : null
},
"constructs" : 2,
"lcom4" : {
"checked" : 0,
"overLimit" : [ ],
"rule" : "E11014",
"worst" : 0
},
"moduleCohesion" : {
"band" : "info",
"basis" : "toolWalk",
"disconnectedGroups" : 2,
"disconnectionRatio" : 1.0,
...
Cut short here: 73 more lines. The whole recorded call.