codelore-rca 0.24.0

Vendored fork of Mozilla rust-code-analysis for CodeLore
Documentation

codelore-rca: Vendored Mozilla rust-code-analysis

This crate is a maintained fork of mozilla/rust-code-analysis.

Upstream baseline

  • Source commit: 37e5d83c056c8cbf827223d5814a93c5218df1a9
  • Source date: 2026-01-20
  • Vendored on: 2026-06-06

Upstream layout notes

The upstream repository is structured as a Cargo workspace:

  • src/ — the main library crate (what we vendor)
  • rust-code-analysis-cli/ — CLI binary (NOT vendored)
  • rust-code-analysis-web/ — actix-web HTTP frontend (NOT vendored; this is the "web" drop)
  • tree-sitter-mozcpp/ — Mozilla tree-sitter-cpp fork (NOT vendored; external dep)
  • tree-sitter-mozjs/ — Mozilla tree-sitter-js fork (NOT vendored; external dep)
  • tree-sitter-ccomment/ / tree-sitter-preproc/ — custom grammars (NOT vendored; external deps)

Note: src/languages/language_mozcpp.rs does NOT exist in this upstream revision. The mozcpp grammar lives in the tree-sitter-mozcpp/ top-level crate and is accessed via macros.rs referencing tree_sitter_mozcpp::LANGUAGE. That external dep reference in src/macros.rs is kept as-is and will be resolved in Task 5 (Cargo.toml).

Modifications from upstream

The following were REMOVED from the vendored tree:

  • src/languages/language_mozjs.rs — Mozilla-specific tree-sitter-js fork (generated code, ~3000 lines of Mozjs enum variants). The pub mod language_mozjs and pub use language_mozjs::* declarations in src/languages/mod.rs were removed.

  • src/metrics/abc.rs — ABC metric (Assignments/Branches/Conditions). Java-only specialization.

  • src/metrics/wmc.rs — WMC metric (Weighted Methods per Class). Java-only specialization.

  • src/metrics/npa.rs — NPA metric (Number of Public Attributes). Java-only specialization.

  • src/metrics/npm.rs — NPM metric (Number of Public Methods). Java-only specialization. The pub mod abc, pub mod wmc, pub mod npa, pub mod npm declarations in src/metrics/mod.rs were removed.

Task 5 excision (completed 2026-06-06)

Option B chosen: fully excise Mozjs and dropped metrics.

The dangling references from Task 4's file drops were resolved by:

Mozjs excision

  • src/langs.rs — removed Mozjs entry from mk_langs!; moved js/jsm/mjs/jsx extensions to Javascript
  • src/macros.rs — restored mozcpp special-case for get_language!(tree_sitter_cpp); removed implement_metric_trait!(Abc, ...) and implement_metric_trait!(Wmc, ...) macro arms
  • src/checker.rs — removed impl Checker for MozjsCode block
  • src/getter.rs — removed impl Getter for MozjsCode block; fixed Mozjs::Pair / Mozjs::VariableDeclarator references in JS/TS/TSX impl blocks to use correct enum namespaces
  • src/alterator.rs — removed impl Alterator for MozjsCode block
  • src/metrics/cognitive.rs — removed impl Cognitive for MozjsCode; updated MozjsParser tests to use JavascriptParser. The re-pointed mozjs else-if test read sum 16 instead of 11 not because of a grammar difference but because the JavaScript is_else_if helper compared the wrong parent node kind and never matched, so else if branches were over-counted. The cognitive-complexity correctness fix (see the "Cognitive-complexity correctness" section) restores 11.
  • src/metrics/cyclomatic.rs — removed impl Cyclomatic for MozjsCode
  • src/metrics/exit.rs — removed impl Exit for MozjsCode
  • src/metrics/halstead.rs — removed impl Halstead for MozjsCode; updated MozjsParser test refs
  • src/metrics/loc.rs — removed impl Loc for MozjsCode; updated MozjsParser test refs
  • src/metrics/mi.rs — removed MozjsCode from implement_metric_trait!([Mi], ...)
  • src/metrics/nargs.rs — removed MozjsCode from implement_metric_trait!([NArgs], ...)
  • src/metrics/nom.rs — removed MozjsCode from implement_metric_trait!([Nom], ...)
  • src/ops.rs — removed mozjs_ops and mozjs_function_ops tests

Abc/Wmc/Npa/Npm excision

  • src/spaces.rs — removed imports, struct fields, merge/compute calls
  • src/traits.rs — removed Abc/Wmc/Npa/Npm from ParserTrait associated types
  • src/parser.rs — removed trait bounds and associated type assignments
  • src/output/dump_metrics.rs — removed imports and dump_abc/wmc/npm/npa functions

Files modified: 15 source files + Cargo.toml + UPSTREAM.md

Tree-sitter grammar version notes

The language_*.rs enum files were generated from specific grammar versions. Using mismatched grammar versions causes node-ID mismatches and silent metric failures. Pinned versions verified by checking root node kind_id against enum constants:

Grammar Version Key node
tree-sitter-javascript =0.23.1 program id=133
tree-sitter-typescript =0.23.1 program id=166/172
tree-sitter-python =0.23.6 module id=108
tree-sitter-java =0.23.5 program id=138
tree-sitter-rust =0.23.2 source_file id=155
tree-sitter-kotlin-ng 1.1.0 source_file id=142
bca-tree-sitter-mozcpp 1.1.0 translation_unit id=308
bca-tree-sitter-ccomment 1.1.0 (aliased as tree-sitter-ccomment)
bca-tree-sitter-preproc 1.1.0 (aliased as tree-sitter-preproc)

C++ uses bca-tree-sitter-mozcpp (aliased as tree-sitter-mozcpp) because language_cpp.rs was generated from the mozcpp grammar. The get_language!(tree_sitter_cpp) macro arm routes to tree_sitter_mozcpp::LANGUAGE.

When upgrading grammar versions in future, verify node IDs by running:

let root = tree.root_node();
println!("{} id: {}", root.kind(), root.kind_id());

and comparing against the enum constants in src/languages/language_*.rs.

Cognitive-complexity correctness

The cognitive-complexity visitors in src/metrics/cognitive.rs and their is_else_if helpers in src/checker.rs diverge from upstream to correct miscounts against the Campbell/SonarSource cognitive-complexity specification. Current behavior:

  • else if detection. is_else_if for JavaScript and TSX compares the parent node kind against else_clause. Upstream compared it against if_statement, which never matches because tree-sitter wraps the else branch in an else_clause; the result was that else if branches were counted as freshly-nested ifs. Java has no else_clause node, so its is_else_if matches an if_statement whose parent if_statement holds it as the alternative field.

  • Missing nesting constructs. The increase-nesting arm also covers Rust loop, Java enhanced-for and ternary, and Python match. case/switch arms add nothing on their own, matching upstream's treatment of switch.

  • finally is not a branch. Python finally does not increment; only else, elif, and except do. except/catch still counts via its own arm.

License

The upstream rust-code-analysis package declares license = "MPL-2.0" in its Cargo.toml. No LICENSE file was present at the repository root at the vendored commit; the LICENSE-MPL file in this directory contains the canonical MPL-2.0 text.

Original files retain their MPL-2.0 license as declared by upstream. New files added by bca contributors carry GPL-3.0-only headers.

SPDX (crate-level): MPL-2.0 AND GPL-3.0-only

See also: Mozilla's MPL combining guide.

Sync procedure

To pull upstream fixes:

  1. Fetch upstream commits since the SHA above.
  2. Cherry-pick correctness fixes and grammar bumps (avoid Mozilla-specific features).
  3. Update this file with the new SHA + date.
  4. Run cargo test -p codelore-rca to verify.

Year-1 maintenance budget: ~8 days (see spec §4.1).