tools/deadcode.sh
Ref: Size: 2.1 KiB History
#!/bin/sh
# tools/deadcode.sh — NON-GATING dead-code report.
#
# Lists pub decls whose name appears in no .zig file other than the one
# that defines them. Zig has no mature dead-code tool, and lazy compilation
# makes the compiler silent about unreferenced container-level decls; this
# grep heuristic is a REVIEW PROMPT, not a failure — it always exits 0.
#
# Known false-positive classes (name-based, not semantic):
# - decls referenced only through @field or comptime-built names
# - wire-format API kept complete on purpose (protocol.zig codecs)
# - entrypoints the build system names (main, std_options, panic)
# - a name defined in two files: a reference to either hides both
set -u
cd "$(dirname "$0")/.."
# src/*/*.zig as well as src/*.zig: the code lives in domain folders, and a
# glob that stopped at the top level reported on the four files left there
# and called the other fifty clean.
for f in src/*.zig src/*/*.zig test/*.zig; do
grep -oE '^[[:space:]]*pub (inline )?(fn|const|var) [A-Za-z_][A-Za-z0-9_]*' "$f" \
| awk '{print $NF}' \
| while read -r name; do
case "$name" in main|panic|std_options) continue ;; esac
# The first grep lists the files the name appears in; the second
# asks whether ANY of those lines is a file other than this one,
# which is what `-v` on multi-line input means and is exactly the
# question here — the defining file is always in the list, so
# "referenced outside" is "some line is not $f".
#
# -xF, not "^$f\$": the pattern is a PATH, and a filename holding
# a `.` or a `[` would otherwise be a regex matching files that
# are not it. The names in $name are identifiers by construction
# and get -F for the same reason rather than a second exception.
if ! grep -rlwF --include='*.zig' -- "$name" src test build.zig \
| grep -qvxF -- "$f"; then
echo "$f: pub $name is referenced nowhere outside its file"
fi
done
done
exit 0