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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
// Per-language metric and AST modules deliberately consume the macro-
// generated tree-sitter token enums via `use crate::*` and `use Foo::*`
// inside match expressions — explicit imports would list dozens of
// variants per arm and obscure the per-language token sets that are the
// point of these files. Allowed at the module level rather than per
// function so the per-language impl blocks stay readable.
//! big-code-analysis is a library to analyze and extract information
//! from source codes written in many different programming languages.
//!
//! You can find the source code of this software on
//! <a href="https://github.com/dekobon/big-code-analysis/" target="_blank">GitHub</a>,
//! while issues and feature requests can be posted on the respective
//! <a href="https://github.com/dekobon/big-code-analysis/issues/" target="_blank">GitHub Issue Tracker</a>.
//!
//! ## Quick start
//!
//! Most callers want the recommended entry points exposed in
//! [`prelude`]:
//!
//! ```no_run
//! use big_code_analysis::prelude::*;
//!
//! let source = b"fn main() {}";
//! let space = analyze(
//! Source::new(LANG::Rust, source),
//! MetricsOptions::default(),
//! ).expect("Rust source parses");
//! println!("cognitive sum: {}", space.metrics.cognitive.cognitive_sum());
//! ```
//!
//! ## Supported Languages
//!
//! Each grammar is gated behind a per-language Cargo feature; the
//! default `all-languages` feature enables every grammar so the
//! historical "every language compiled in" behaviour is preserved.
//! Library consumers that only need a subset can opt out of the
//! defaults — see [Per-language Cargo features][feat] in the book.
//!
//! - Bash (`bash`)
//! - C/C++ (`cpp`, also exposes the internal `Ccomment` / `Preproc` helpers)
//! - C# (`csharp`)
//! - Elixir (`elixir`)
//! - Go (`go`)
//! - Groovy (`groovy`)
//! - Java (`java`)
//! - JavaScript (`javascript`)
//! - JavaScript, Firefox-internal "MozJS" (`mozjs`)
//! - Kotlin (`kotlin`)
//! - Lua (`lua`)
//! - Perl (`perl`)
//! - PHP (`php`)
//! - Python (`python`)
//! - Ruby (`ruby`)
//! - Rust (`rust`)
//! - Tcl (`tcl`)
//! - TSX (`typescript`)
//! - TypeScript (`typescript`)
//!
//! [feat]: https://dekobon.github.io/big-code-analysis/library/cargo-features.html
//!
//! ## Supported Metrics
//!
//! - ABC: it measures the size of a source code based on
//! assignments, branches, and conditions.
//! - CC: it calculates the code complexity examining the control flow of a
//! program. Both standard and modified flavours are exposed: the
//! modified variant collapses all case/match arms inside a single
//! switch/match/when/select into one decision point.
//! - Cognitive Complexity: it measures how difficult it is
//! to understand a unit of code.
//! - SLOC: it counts the number of lines in a source file.
//! - PLOC: it counts the number of physical lines (instructions)
//! contained in a source file.
//! - LLOC: it counts the number of logical lines (statements)
//! contained in a source file.
//! - CLOC: it counts the number of comments in a source file.
//! - BLANK: it counts the number of blank lines in a source file.
//! - HALSTEAD: it is a suite that provides a series of information,
//! such as the effort required to maintain the analyzed code,
//! the size in bits to store the program, the difficulty to understand
//! the code, an estimate of the number of bugs present in the codebase,
//! and an estimate of the time needed to implement the software.
//! - MI: it is a suite that allows to evaluate the maintainability
//! of a software.
//! - NOM: it counts the number of functions and closures
//! in a file/trait/class.
//! - NEXITS: it counts the number of possible exit points
//! from a method/function.
//! - NARGS: it counts the number of arguments of a function/method.
//! - NPA: it counts the number of public attributes of a class.
//! - NPM: it counts the number of public methods of a class.
//! - WMC: it is the sum of the complexities of all methods
//! in a class.
// Internal-only modules. Nothing is re-exported from these.
// `langs` hosts the `mk_langs!` macro expansion. Every name produced
// there — `LANG`, the `action` / `get_function_spaces` dispatch
// helpers, per-language `<Lang>Code` tags and `<Lang>Parser` aliases —
// is enumerated explicitly in the curated re-exports below.
pub use crate;
// The path-positional `get_function_spaces*` shims are `#[deprecated]`
// at their definition sites; re-exporting them at the crate root keeps
// the previously-globbed surface intact, scoped with
// `#[allow(deprecated)]` so the re-export itself does not warn.
pub use crate;
// Internal crate-root re-exports. Hand-written per-language modules
// (`src/getter.rs`, `src/checker.rs`, `src/alterator.rs`, the
// per-language metric impls) use `use crate::*` to bring the
// macro-generated `<Lang>Code` token enums and per-language helper
// types into scope; the per-language token enums in
// `src/languages/language_*.rs` are also reached through the crate
// root. Re-exporting these as `pub(crate)` keeps internal compilation
// working without widening the published surface.
pub use crate*;
pub use crate*;
// Hand-written modules (`src/spaces.rs`, `src/output/dump_metrics.rs`,
// the metric macros) refer to per-metric submodules by their short
// crate-root path (`crate::abc`, `crate::cognitive`, ...). Re-export
// them under those names without widening the public surface.
pub use crate;
// Module declarations. Each `pub use` line below names exactly the
// items intended to be part of the public API surface; anything not
// listed stays out of the crate root. Per issue #255, glob re-exports
// (`pub use module::*`) are no longer used here because every newly
// `pub`-marked helper in any sub-module would silently leak into the
// published API.
// --- Core analysis entry points and result types (spaces.rs) ---
pub use crate;
// The path-positional `metrics` / `metrics_with_options` shims are
// `#[deprecated]` at their definition site; re-export them so the
// previously-globbed API surface keeps working, scoped with
// `#[allow(deprecated)]` to avoid lint noise at this seam.
// `metrics_inner` is consumed by feature-gated arms in `mk_action!`.
// With `--no-default-features` and no language feature, every arm
// compiles out and the re-export becomes nominally unused; the
// language-features that ship in the default set keep the symbol
// live in any normal build.
pub use cratemetrics_inner;
pub use crate;
pub use cratecheck_func_space;
/// Per-metric implementations.
///
/// Each sub-module owns one metric — its `Stats` accumulator, the
/// per-language trait implementations, and any small helpers used
/// only by tests. Most callers will not need these directly; reach
/// through [`CodeMetrics`] on a [`FuncSpace`] instead.
// --- Errors ---
pub use crateMetricsError;
// --- Metric selection ---
pub use crate;
// --- Suppression markers ---
pub use crate;
/// Output formatters: CSV, SARIF, Checkstyle, clang/MSVC warning
/// lines, and AST/metric pretty-dumps used by `bca` and the offender
/// reporters.
///
/// The most commonly used writers (`write_csv`, `write_sarif`,
/// `write_checkstyle`, `write_clang_warning`, `write_msvc_warning`)
/// and shared types (`OffenderRecord`, `Severity`, `TOOL_ID`,
/// `CSV_HEADER`, `CSV_EXTENSION`) are also re-exported at the crate
/// root.
pub use crate;
// --- AST plumbing (Node, Cursor) ---
pub use crate;
// --- Language detection / I/O helpers ---
pub use crate;
// --- Source walker ---
pub use crate;
// --- Comment removal ---
pub use crate;
// --- Per-function metric callbacks (CLI surface) ---
pub use crate;
pub use crate;
pub use crate;
// --- AST dump ---
pub use crate;
// --- Halstead operator/operand callback ---
pub use crate;
// --- Preprocessor handling (C/C++) ---
pub use crate;
// --- Alterator trait (per-language AST simplification) ---
pub use crateAlterator;
// --- Generic parser plumbing ---
//
// `Parser`, `ParserTrait`, `Filter`, `LanguageInfo`, and `Callback`
// are part of the value-not-stable surface — they are required for
// callers that want to feed pre-parsed trees through the metric
// pipeline or implement a custom `Callback`, but they are
// `#[doc(hidden)]` at their definition sites so they do not clutter
// the rendered rustdoc. See STABILITY.md.
pub use crate;
pub use crateSearch;
pub use crate;
/// Re-export of the underlying `tree-sitter` crate.
///
/// Lets callers build a [`tree_sitter::Tree`] (via
/// [`tree_sitter::Parser`]) against the exact grammar version this
/// library is pinned to, and feed it back through
/// [`Parser::from_tree`] / [`metrics_from_tree`] without taking a
/// separate `tree-sitter` dependency that may drift out of pin.
///
/// This is part of the value-not-stable surface: the underlying
/// pin may bump in any minor release (see `STABILITY.md`).
pub use tree_sitter;
/// Recommended entry points for the 90% case.
///
/// Star-import this module to get the curated set of types and
/// functions most callers need:
///
/// ```no_run
/// use big_code_analysis::prelude::*;
///
/// let source = b"fn main() {}";
/// let space = analyze(
/// Source::new(LANG::Rust, source),
/// MetricsOptions::default(),
/// ).expect("Rust source parses");
/// # let _ = space;
/// ```
///
/// Anything not exposed here can still be imported with its
/// fully-qualified name from the crate root (`use
/// big_code_analysis::Something;`). Items deliberately omitted from
/// the prelude are either deprecated, doc-hidden, or unlikely to
/// appear in typical caller code.