1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! Per-metric implementations.
//!
//! Each submodule defines one maintainability metric, its per-language
//! traits, and its `Stats` accumulator. See the crate-level docs for an
//! overview of the metric suite.
use crateSpaceKind;
/// Assignment / Branch / Condition counts.
/// Cognitive complexity.
/// Cyclomatic complexity.
/// Halstead suite (operators, operands, volume, difficulty, effort).
/// Lines-of-code variants (SLOC, PLOC, LLOC, CLOC, blank).
/// Maintainability Index.
/// Number of arguments per function.
/// Exit-point counting.
/// Number of methods (functions + closures).
/// Number of public attributes.
/// Number of public methods.
/// Token count.
/// Weighted Methods per Class.
// Gated on the union of every feature any test in the module names —
// the `FIXTURES` rows plus the `bash` / `lua` / `c` row set that
// `a_language_with_no_member_construct_emits_neither_block` uses. The
// narrower `FIXTURES` union belongs on the four tests that read
// `FIXTURES`, not here: a module gate is an outer `cfg`, so naming only
// the `FIXTURES` features would delete that Bash/Lua/C test from a build
// enabling exactly the languages it exists to cover
// (`.claude/rules/testing.md`, #1286).
/// Divides a metric sum by a count, guarding the divisor with `.max(1)`.
///
/// Every "average over a count" metric routes through this helper so the
/// divide-by-zero guard added for [#428] is applied uniformly rather than
/// per call site. A `count` of `0` degrades to `sum / 1` (the sum itself)
/// instead of producing `inf`/`NaN`, so a never-observed or count-less
/// space still serializes a finite number.
///
/// The *meaning* of `count` is the caller's choice of denominator
/// convention; the project uses two:
///
/// - **Per-function** averages (`cognitive`, `cyclomatic`, `exit`,
/// `nargs`) divide by the function/closure count of the subtree, so the
/// value reads as "average complexity per function". `cognitive`/
/// `exit`/`nargs` source this count from `Nom`; `cyclomatic` counts its
/// own function/closure *spaces* (equal in the common case, but
/// independent of whether `Nom` is selected — see
/// `cyclomatic::Stats::function_spaces`).
/// - **Per-space** averages (`nom`, `loc`, `abc`, `tokens`) divide by the
/// total number of spaces (functions, closures, classes, the file unit,
/// …). These measure a property of each space rather than of each
/// function, so a per-function denominator would not match their
/// meaning (and for `nom` it would be circular — it *is* the function
/// count).
///
/// [#428]: https://github.com/dekobon/big-code-analysis/issues/428
// `count as f64` is exact for any realistic space count; the cast mirrors
// the per-metric modules' module-level allowance for count-to-float casts.
pub
/// Whether the object-oriented member metrics — `wmc`, `npm`, `npa` —
/// are meaningful on a space of a given [`SpaceKind`].
///
/// An extension trait rather than an inherent method because
/// `SpaceKind` is defined in `big-code-analysis-ast`, which knows
/// nothing about metrics: "does `wmc` apply here" is a question only
/// this crate can ask, so it is answered here (#1376).
pub