Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
21415ba
fix(getter/ts): bill member modifiers as operators
dekobon Oct 10, 2026
d3f058a
fix(getter/kotlin): bill six declaration keywords
dekobon Oct 10, 2026
5fd5d9b
fix(getter/java): bill every Java and Groovy modifier
dekobon Oct 10, 2026
4b2e686
fix(getter/java): bill a class literal's parts
dekobon Oct 10, 2026
41a6b0b
fix(halstead): bill type-enclosing angles as <>
dekobon Oct 10, 2026
5b5d540
fix(getter/groovy): bill primitive types as operators
dekobon Oct 10, 2026
18c28ca
fix(getter/csharp): bill no interpolation clause
dekobon Oct 10, 2026
023038d
chore(thresholds): re-measure halstead.effort
dekobon Oct 10, 2026
20cc3b5
docs(changelog): record the Halstead vocabulary batch
dekobon Oct 10, 2026
987b97e
docs(halstead): apply the batch review findings
dekobon Oct 10, 2026
bacb456
fix(getter/cpp): bill C-family declaration modifiers
dekobon Oct 10, 2026
34fd71c
fix(getter/objc): bill C and ObjC declaration modifiers
dekobon Oct 11, 2026
456c349
fix(perl): score a bareword key as a string
dekobon Oct 11, 2026
cd26f65
fix(elixir): score every section spelling alike
dekobon Oct 11, 2026
9e4fc2e
test(bench): add Perl and Bash scaling probes
dekobon Oct 11, 2026
9c372c5
perf(ast): read flat-ERROR siblings from the walk
dekobon Oct 11, 2026
5f97527
fix(perl): report each call once in find and count
dekobon Oct 11, 2026
07255db
fix(elixir): score receive like case
dekobon Oct 15, 2026
202d5d5
fix(elixir): score Kernel.and and Kernel.or
dekobon Oct 15, 2026
5f96b65
docs(elixir): note why the clause gate ignores its owner
dekobon Oct 15, 2026
5b68384
fix(elixir): apply review findings for #1581-#1583
dekobon Oct 15, 2026
9d4cd0f
fix(perl): skip an auto-quoted die/exit key in nexits
dekobon Oct 15, 2026
1c884c9
docs(changelog): record the batch follow-up fixes
dekobon Oct 15, 2026
e2978ec
fix(elixir): give receive one free arm, review items
dekobon Oct 15, 2026
8df5207
docs(lessons): record the vocabulary batch's traps
dekobon Oct 15, 2026
bda3ded
fix(halstead): apply the max code-review findings
dekobon Oct 15, 2026
1e1c035
fix(gates): fold root mod cfg into the lang-gate compare
dekobon Oct 15, 2026
763ca0f
docs: apply the review findings
dekobon Oct 15, 2026
655e2ba
fix(abc): preserve condition counts through transparent wrappers
dekobon Oct 15, 2026
42f90bd
fix(cognitive): preserve Bash sequences through unary tests
dekobon Oct 15, 2026
fe76014
fix(hooks): validate Python config with project tooling
dekobon Oct 15, 2026
521abff
fix(deps): resolve CI dependency audit failures
dekobon Oct 15, 2026
dcfdf2b
refactor(elixir): reuse call context and cover lookup boundaries
dekobon Oct 15, 2026
f3aedfc
ci(coverage): pin measurement tools and archive raw reports
dekobon Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .bca-baseline.toml
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ value = 42.0
path = "big-code-analysis-ast/src/parser.rs"
qualified = "Parser<T>::filters"
metric = "halstead.effort"
value = 87390.78947368421
value = 90363.0

[[entry]]
path = "big-code-analysis-ast/src/preproc.rs"
Expand Down Expand Up @@ -1065,7 +1065,7 @@ value = 6.0
path = "src/ops.rs"
qualified = "ops_inner"
metric = "halstead.effort"
value = 70903.25755192844
value = 84452.11438842113

[[entry]]
path = "src/output/checkstyle.rs"
Expand Down Expand Up @@ -1179,7 +1179,7 @@ value = 5.0
path = "src/spaces/compute.rs"
qualified = "compute_per_node"
metric = "halstead.effort"
value = 63645.7536117776
value = 64334.51855807396

[[entry]]
path = "src/spaces/compute.rs"
Expand All @@ -1191,7 +1191,7 @@ value = 7.0
path = "src/spaces/compute.rs"
qualified = "metrics_inner"
metric = "halstead.effort"
value = 121169.85621346734
value = 141885.98828207294

[[entry]]
path = "src/spaces/compute.rs"
Expand Down
3 changes: 3 additions & 0 deletions .claude/rules/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,9 @@ tree at `ref` as well (`git archive` into a scratch directory), computes
which single-language builds compile each test in each, and fails on a
test that still exists but stopped being built somewhere. The probe set
comes from the language table, so a new language extends it for free.
A test's membership includes the `cfg` on the `mod` line that loads its
file, so narrowing a root `mod` gate in a `tests/*/main.rs` is reported
too; before that, #1567's drop of `kotlin` from one went unseen.

CI runs it per pull request against the base branch head — the PR's
`base.sha`, not `git merge-base`, because the job checks out shallow and
Expand Down
33 changes: 28 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -320,21 +320,29 @@ jobs:
with:
fetch-depth: 1
submodules: recursive
# llvm-tools-preview supplies llvm-profdata/llvm-cov for source-based
# coverage instrumentation.
# Pin the measurement toolchain independently of the stable build jobs:
# compiler changes can move coverage regions without changing test coverage.
- uses: dtolnay/rust-toolchain@02cb101ec7c40f2c49e1d9714d64511d8e1b74de # stable tip
with:
toolchain: stable
toolchain: "1.99.1"
components: llvm-tools-preview
# Coverage builds carry -C instrument-coverage, so their artifacts are
# incompatible with the regular build cache; a distinct key keeps the
# two from thrashing each other.
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
key: coverage
key: coverage-1.99.1-llvm-cov-0.9.1
- uses: taiki-e/install-action@9983c65e42da123ff25d1f78505eb6de315aa172 # v2.87.20
with:
tool: cargo-nextest,cargo-llvm-cov
tool: cargo-nextest@0.9.146,cargo-llvm-cov@0.9.1
- name: Record coverage provenance
run: |
{
git rev-parse HEAD
rustc --version --verbose
cargo llvm-cov --version
cargo nextest --version
} > coverage-provenance.txt
# nextest is the same runner the `test` job uses, so instrumenting it
# keeps the coverage numbers aligned with what CI actually exercises.
# --no-report defers reporting so the same profile data can be emitted
Expand All @@ -344,6 +352,8 @@ jobs:
# nightly, and pairing nightly with the workflow-wide `-D warnings`
# would red-X CI on unrelated new nightly lints. The `test` job still
# runs doctests for correctness — only their coverage is omitted.
- name: Clean coverage data
run: cargo llvm-cov clean --workspace
- name: Run tests with coverage instrumentation
run: cargo llvm-cov --no-report nextest --all-features --workspace --locked
# Codecov's native format preserves region coverage (lcov would drop to
Expand All @@ -358,6 +368,19 @@ jobs:
# 103 files that are in fact ~98% covered. Keep the two in step.
- name: Generate Codecov report
run: cargo llvm-cov report --workspace --codecov --output-path codecov.json
- name: Generate raw LLVM coverage report
run: cargo llvm-cov report --workspace --json --output-path coverage-llvm.json
- name: Archive coverage reports
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-${{ github.sha }}
path: |
codecov.json
coverage-llvm.json
coverage-provenance.txt
if-no-files-found: error
retention-days: 30
# Per-file coverage table in the run's Summary tab, so reviewers can
# read coverage without leaving GitHub or waiting on the Codecov PR
# comment.
Expand Down
27 changes: 7 additions & 20 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ repos:
- id: check-symlinks
- id: check-yaml
- id: check-json
exclude: enums/templates/json.json
# Pyright accepts JSONC comments; py-typecheck validates its configuration.
exclude: ^(enums/templates/json\.json|big-code-analysis-py/pyrightconfig\.json)$
- repo: https://github.com/marco-c/taskcluster_yml_validator
rev: v0.0.12
hooks:
Expand Down Expand Up @@ -559,31 +560,17 @@ repos:
# because pre-commit's isolated venv cannot see the project's
# `maturin develop`'d `_native` extension or the rest of the
# dev environment — under that isolation, `--strict`'s whole-
# program analysis is silently meaningless. The system hook runs
# against the contributor's PATH-resolved `mypy`, same pattern
# as the clippy/udeps/test hooks above.
#
# pyright is intentionally NOT a pre-commit hook: it bundles a
# Node runtime that pre-commit cannot hermetically isolate and
# suffers the same isolated-venv problem mypy does. The CI
# `python-lint` job covers it.
# program analysis is silently meaningless. The Makefile resolves
# mypy and pyright from the bootstrapped project venv before PATH,
# matching the canonical gate without requiring manual activation.
- id: py-mypy
name: py-mypy
language: system
# Match both `.py` source and `.pyi` stubs — editing
# `_native.pyi` must also re-run mypy so the stub stays in
# sync with the Rust-side ABI it describes.
files: '^big-code-analysis-py/.*\.pyi?$'
# Use --config-file + absolute-ish paths so the invocation is
# cross-platform — `bash -c "cd X && ..."` fails on native
# Windows pre-commit (no bash on cmd/PowerShell PATH).
entry: mypy
args:
- --strict
- --config-file=big-code-analysis-py/pyproject.toml
- big-code-analysis-py/python
- big-code-analysis-py/tests
- big-code-analysis-py/examples
files: '^big-code-analysis-py/(.*\.pyi?|pyrightconfig\.json|pyproject\.toml)$'
entry: make py-typecheck
pass_filenames: false

default_language_version:
Expand Down
8 changes: 5 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,9 @@ stranded `.snap.new` drift that blocks CI on every subsequent change.
The limits `bca init` scaffolds are defined once, in
`big-code-analysis-cli/src/default_thresholds.rs`. They are derived
from published thresholds plus a 20-language corpus measurement (#1140),
and each carries its rationale inline. Change them there, not in a
and each carries its rationale inline. `halstead.effort` was re-measured
in #1569 on a rebuilt corpus recorded in
[`docs/development/threshold_corpus.md`](docs/development/threshold_corpus.md). Change them there, not in a
copy: the scaffolded `bca.toml` renders its `[thresholds]` block from
that table, so there is no second copy of the numbers to drift.

Expand Down Expand Up @@ -709,8 +711,8 @@ Three things to know before quoting a number at anyone:
- **These are language-agnostic defaults, and no language is
agnostic.** Measured 97.5th-percentile `cognitive` runs from 4 (C#)
to 50 (C). C, Tcl, Bash, Lua, Perl, and Go want roughly double the
defaults; Java, Ruby, Kotlin, C#, and Elixir sit far under them. The
per-language table lives in
`cognitive` default; Java, Ruby, Kotlin, C#, and Elixir sit far
under it. The per-language table lives in
[Choosing thresholds](big-code-analysis-book/src/recipes/thresholds.md).
- **The right limit depends on the job.** A blocking CI gate, an agent
edit loop, a legacy triage pass, and a safety-critical build want
Expand Down
Loading
Loading