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
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
// 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.
// Per-language Cargo features (commit 7e96b466) let a downstream build
// only a subset of grammars. In such a build the code for the disabled
// languages — their macro-generated `*Code` / `*Parser` tags plus the
// getter / checker / metric helpers and shared plumbing only those
// languages reach — is compiled but never constructed, so `-D dead-code`
// fires on ~180 items that are all live in the default `all-languages`
// build. Relax dead-code to a warning only when the full language set is
// NOT enabled; the default build and `--all-features` (and thus the
// primary CI gate and `make pre-commit`) still hard-deny it, so genuine
// dead code is caught there. Fixes the long-red `features
// (no-default-features / minimal-langs (lib))` CI legs.
// docs.rs (and the local `doc-check-docsrs` gate) build with `--cfg docsrs`
// on nightly, enabling per-item "Available on crate feature …" badges for
// non-default surfaces such as `vcs`. Guarded so stable builds are unaffected.
//! 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`, upstream `tree-sitter-c`; owns `.c`)
//! - C/C++ (`cpp`, upstream `tree-sitter-cpp`; the default for `.cpp` /
//! `.cc` / `.h` and also exposes the internal `ccomment` / `preproc`
//! C-family helpers)
//! - C++, Firefox-internal "Mozcpp" (`mozcpp`, opt-in; owns no file
//! extensions — select it by name)
//! - C# (`csharp`)
//! - Objective-C (`objc`, upstream `tree-sitter-objc`; owns `.m`; `.mm`
//! Objective-C++ stays on C/C++)
//! - Elixir (`elixir`)
//! - Go (`go`)
//! - Groovy (`groovy`)
//! - F5 iRules (`irules`)
//! - 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 (`tsx`)
//! - 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.
// Production-only `unwrap()` ban. See `[workspace.lints.clippy]` in the
// root `Cargo.toml` for why this is a per-root attribute and not a
// Cargo lint (#1227).
// The parse and classification layer lives in `big-code-analysis-ast`
// (#1376). Its public names — the generated token enums, the `*Code` /
// `*Parser` tags, `Node`, `Ancestors`, `Checker`, `Getter`, the language
// helpers — are the working vocabulary every metric module reaches
// through `use crate::*`, so the whole crate root is glob-imported here
// at `pub(crate)`. Only the explicit `pub use` lines further down widen
// the published surface.
// The import half of the `allow(dead_code)` carve-out above, and for
// the same reason: per-language test gating (#1472) makes "is this
// import live" a function of the enabled feature set, which no `cfg` on
// the import itself can express. Partial builds only — `all-languages`
// is on by default and under `--all-features`, so the build CI gates on
// and the one a contributor runs still police every unused import. See
// `.claude/rules/testing.md`, "Why the import lint is off on a partial
// build".
pub use *;
// Fast hashing for the walk's integer-keyed maps. Shared by `spaces`
// (node ids) and `metrics::halstead` (grammar `kind_id`s); `metrics::loc`
// was the third until #1109 moved its line sets to a bitset. The module
// doc is the single place that lists them and says why the text-keyed
// collections are excluded — extend it, not this line, when a third
// arrives.
// The metric-side macros (`implement_metric_trait!`) plus re-exports of
// the kind-set and dispatch macros defined in `big-code-analysis-ast`.
// Parse-and-inspect shims shared by the per-metric test modules. Kept out
// of any production file so the self-scan gate does not spend a shipping
// module's metric budget on test-only code (#1066).
// Gated on the four grammars its tables name, so a build enabling none
// of them drops the module rather than tripping its `checked > 0`
// non-vacuity guard (`.claude/rules/testing.md`, #1286). The guard then
// covers only the residual case where `is_enabled` stops agreeing with
// the feature it compiled under.
// Drift guard for the crate-level `## Supported Languages` list above.
// --- Language identification (defined in `big-code-analysis-ast`) ---
pub use ;
// 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;
/// 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.
/// Plain, `Deserialize`-capable data-transfer structs mirroring the
/// serialized metric wire shape. The compute types' `Serialize` impls
/// delegate here, making these the single definition of the JSON / YAML /
/// TOML / CBOR output format and the canonical way to read `bca` output
/// back (`serde_json::from_str::<wire::FuncSpace>(…)`).
// --- Change-history (VCS) metrics ---
//
// The project's first language-agnostic, non-AST metric family
// (issue #328). Gated behind the `vcs-git` backend feature (the
// `vcs` umbrella turns it on); the generic surface is backend-neutral
// so future backends (#335) reuse it unchanged.
/// Change-history (VCS) metrics derived from version-control history:
/// churn, commit frequency, author count / ownership dilution, bug- and
/// security-fix history, and an ordinal composite risk score. See
/// [`vcs::build_history_index`].
///
/// Enable with the `vcs` Cargo feature (the umbrella over the current
/// `vcs-git` backend, which is what the availability badge names).
// --- Diagnostics ---
//
// The single place the library writes a `warning:` prefix; the CLI has
// its own severity ladder in `big-code-analysis-cli/src/diag.rs`.
// --- Errors ---
//
// `MetricsError` is the parse layer's error (every dispatch entry point
// returns it, including `LANG::tree_sitter_language`), so it is defined
// in `big-code-analysis-ast`; `FromPathError` wraps it for the
// file-backed `Ast::from_path` and stays here.
pub use MetricsError;
pub use crateFromPathError;
// --- Metric selection ---
pub use crate;
// --- Suppression markers ---
pub use crate;
/// Canonical metric catalog: offender sub-metric ids with their
/// long-form sentences, [`metric_catalog::Direction`] and
/// [`metric_catalog::Scale`], plus the family view rendered by
/// `bca list-metrics` and the metric-selector resolver
/// ([`metric_catalog::resolve_selector`]). Single source of truth
/// shared by the library's offender formatters, the CLI's threshold
/// engine (which pins its extractor ids to
/// [`metric_catalog::METRICS`] via a parity test), and the metric
/// selections of `bca metrics --metrics` and the Python `metrics=`.
/// [`metric_catalog::Threshold`] is the validated limit that answers
/// breach, severity, soft-tier, change and drift questions in the
/// metric's own direction and scale.
// "Did you mean?" suggestions. The resolver's error uses it in-crate;
// the hidden re-export exists only so the CLI's unknown-name errors
// share the one algorithm (#1614).
pub use crateformat_suggestion;
/// 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_code_climate`,
/// `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) ---
pub use Node;
// --- Language detection / I/O helpers ---
pub use ;
// --- Source walker ---
pub use crate;
// --- Per-file node counting (reached via the `Ast` seam) ---
pub use ;
pub use crate;
// --- AST dump ---
pub use ;
// --- Halstead operator/operand result type ---
pub use crateOps;
// --- Preprocessor handling (C/C++) ---
pub use ;
// --- Generic parser plumbing ---
//
// `Parser`, `ParserTrait`, `Filter`, `LanguageInfo`, `Checker`,
// `Getter` and `Alterator` are defined in `big-code-analysis-ast` and
// reach this crate through the glob import above. They are not
// re-exported: the single public analysis seam is [`Ast`], which wraps
// the language-dispatched `AnyParser` carrier. See STABILITY.md.
//
// The metric half of the parser contract; `ParserTrait` is the parse
// half. See `src/metric_suite.rs`.
pub use crateMetricSuite;
/// 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
/// [`Ast::from_tree_sitter`] 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`). The inner
/// node of a [`Node`] is reached the same way, through
/// [`Node::as_tree_sitter`], and carries the same value-not-stable
/// caveat.
pub use tree_sitter;
/// The version of this `big-code-analysis` library crate.
///
/// Sourced from the crate's own `CARGO_PKG_VERSION` at compile time.
/// Exposed so downstream surfaces (the REST `/v1/version` endpoint, the
/// Python `__version__` attribute, …) can report the exact library
/// version they were built against without re-deriving it from Cargo
/// metadata.
pub const VERSION: &str = env!;
/// 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.