Class MetricLimits
Acceptable*OrError checkers fire on. Use these;
do NOT re-declare private static final int MAX_* inside a checker or an extractor.
Why this exists. These limits were previously duplicated: each checker held its own
MAX_* constant, and at least one enquiry extractor
(DiWiringExtractor.MAX_INJECTION_FIELDS) held a hand-copied mirror with a javadoc pointing
back at the checker — a textbook DRY drift with no textual fingerprint to grep. Folding them here
means (1) the checker and the MCP/IDE enquiry layer report the same number by construction, and
(2) the enforced quality thresholds become discoverable — an AI can ask "what does EK9 enforce, at
what value, per genus?" via ek9_query_metric_limits, which just serialises all().
Values and comparators are transcribed verbatim from the checkers (E11014-E11017, E11040,
E11042, E11043). Genus tables and their exemptions live with the metric here; the two
instance-level LCOM4 exemptions (built-in module, zero-field aggregate) are not genus
metadata and remain in AcceptableCohesionOrError.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final MetricLimit.ScalarLimitE11042 — component registrations in a single application.static final MetricLimit.ScalarLimitE11010 — arguments in a single call.static final MetricLimit.ScalarLimitE11010 — cyclomatic-style complexity of any callable construct (method / operator / function).static final MetricLimit.ScalarLimitE11021 — cognitive complexity of a callable.static final MetricLimit.RatioLimitE11020 — complexity and size together.static final MetricLimit.GenusLimitE11015 — construct efferent coupling, per genus.static final MetricLimit.ScalarLimitE11013 — complexity of a single expression.static final MetricLimit.GenusLimitE11019 — inheritance depth, per genus.static final MetricLimit.ScalarLimitE11043 — distinct injected types used within a single method.static final MetricLimit.ScalarLimitE11040 — injected fields on a single component.static final MetricLimit.GenusLimitE11014 — LCOM4 cohesion, per genus.static final MetricLimit.CompoundLimitE11017 — module cohesion: fires only when disconnected groups exceed BOTH an absolute cap (30) and a relative ratio (88% of constructs), and only once the module has at least 60 constructs.static final MetricLimit.ScalarLimitE11016 — module efferent coupling: distinct external modules a module depends on.static final MetricLimit.ScalarLimitE11027 — declared constructs in a single module.static final MetricLimit.ScalarLimitE11011 — nesting depth of control flow within a callable.static final MetricLimit.ScalarLimitE11012 — statement budget for a function; a standalone unit can be somewhat larger.static final MetricLimit.ScalarLimitE11012 — statement budget for a method; class methods should have a focused responsibility.static final MetricLimit.ScalarLimitE11012 — statement budget for an operator.static final MetricLimit.ScalarLimitE11012 — statement budget for a service operation; a web operation of moderate complexity.static final MetricLimit.ScalarLimitE11010 — aggregated complexity of a type (the sum of its members'). -
Method Summary
-
Field Details
-
MODULE_COUPLING
E11016 — module efferent coupling: distinct external modules a module depends on. Fires above 10. -
CONSTRUCT_COUPLING
E11015 — construct efferent coupling, per genus. Default (unlisted genera) is the class threshold. -
LCOM4
E11014 — LCOM4 cohesion, per genus. Traits/records/functions are exempt (single body or intentionally independent operators). Default (unlisted genera) is the class threshold. -
MODULE_COHESION
E11017 — module cohesion: fires only when disconnected groups exceed BOTH an absolute cap (30) and a relative ratio (88% of constructs), and only once the module has at least 60 constructs. -
MODULE_SIZE
E11027 — declared constructs in a single module. Fires above 250.Deliberately generous: it is a god-module backstop, not a design nudge (module cohesion E11017 is the real design signal, and fires on unrelated constructs long before a count does). For calibration, 250 is roughly the 99th percentile of real-world Java packages and ~1.6x the largest module in EK9's own corpus; the JDK's own hand-written packages top out around 160.
Counts SOURCE-DECLARED constructs only. Auto-generated monomorphised parameterised types (
List of Stringand friends) are created in the module that declares the GENERIC, so counting them would let usage elsewhere inflate a module its author does not control - and would make the limit unhittable-by-design for any module exporting a generic. The count comes fromModuleCohesionTracker, which is populated from the parse tree, so synthesised types are excluded by construction rather than by a filter that could drift. -
INJECTION_FIELDS
E11040 — injected fields on a single component. Fires above 4 (Single Responsibility smell). -
APP_REGISTRATIONS
E11042 — component registrations in a single application. Fires above 12. -
INJECTED_TYPES_PER_METHOD
E11043 — distinct injected types used within a single method. Fires at or above 5 (last legal 4). -
CALLABLE_COMPLEXITY
E11010 — cyclomatic-style complexity of any callable construct (method / operator / function). Fires above 45.Enforced by
AcceptableConstructComplexityOrErrorand re-used byAcceptableCombinedComplexitySizeOrErrorto normalise its complexity ratio — the two MUST agree for that ratio to mean anything. -
TYPE_COMPLEXITY
E11010 — aggregated complexity of a type (the sum of its members'). Deliberately large, so only a type accumulating very many even-moderately-complex methods trips it. Fires above 500. -
COGNITIVE_COMPLEXITY
E11021 — cognitive complexity of a callable. Fires above 35, twice the industry standard of 15: high enough to accommodate genuinely hard code such as parsing, low enough that guarded code at depth 6 (42 points) is over the line. -
NESTING_DEPTH
E11011 — nesting depth of control flow within a callable. Fires above 6. -
INHERITANCE_DEPTH
E11019 — inheritance depth, per genus. Slightly stricter than the industry 5-6 because EK9 hasbydelegation as the alternative. Genera not listed are not depth-checked at all. -
EXPRESSION_COMPLEXITY
E11013 — complexity of a single expression. Fires above 15, forcing intermediate variables. -
STATEMENTS_OPERATOR
E11012 — statement budget for an operator. Operators should be single-purpose and brief. -
STATEMENTS_METHOD
E11012 — statement budget for a method; class methods should have a focused responsibility. -
STATEMENTS_FUNCTION
E11012 — statement budget for a function; a standalone unit can be somewhat larger. -
STATEMENTS_SERVICE_OPERATION
E11012 — statement budget for a service operation; a web operation of moderate complexity. -
ARGUMENTS_PER_CALL
E11010 — arguments in a single call. A hard stop, distinct from the 3- and 5-argument points further down that merely ADD to a complexity score rather than failing anything. -
COMBINED_COMPLEXITY_SIZE
E11020 — complexity and size together. Neither operand is a gate on its own: the construct's complexity ratio times its statement ratio must exceed 0.50, so 70% of both passes and 72% of both does not. Expressed as a ratio because there is no count to compare against.
-
-
Method Details
-
all
-