package olint
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=5eeb73f6e31f5a36ea4471c22ed47e60dda8fefd55e6b680133efadc0cdb6374
doc/README.html
# olint
Think clippy for OCaml — which is only fair, given that Rust's original compiler was written in OCaml. We're simply returning the favour.
A linter for OCaml source files. Catches antipatterns, partial function misuse, naming violations, and the kind of code that works perfectly well until a Tuesday in March at 3am when it very much doesn't. Uses compiler-libs directly,no custom parser, no PPX dependency, no build step required. Just very firmly held opinions.
Install
opam pin add olint git+https://github.com/Zaneham/OlintOr, for those who enjoy the journey:
git clone https://github.com/Zaneham/Olint
cd olint
opam install cmdliner
dune build
dune installUsage
Point it at things. It will find fault.
olint src/
olint lib/ bin/ test/
olint --severity warn src/ # only the serious stuff
olint --format json src/ # for machines, who judge silently
olint --list-rules # know thy accuser
olint --lang lang/fr.txt src/Example Output
src/parser.ml:42:3 [W001] unused open: `open Printf` is not referenced
hint: remove the open or use a qualified name
src/eval.ml:87:5 [W003] List.length in comparison is O(n); compare against [] instead
hint: use `xs <> []` or `xs = []` for emptiness checks
src/main.ml:12:1 [W005] List.hd may raise; consider a safe alternative
hint: use List.hd_opt or pattern matching
src/util.ml:31:9 [W008] `if x then true else false` is redundant; use `x` directly
hint: remove the if/else and use the condition directlyExit codes: 0 clean, 1 warnings, 2 errors. An escalating scale of disappointment.
Rules
ID | Name | Sev | What it objects to |
|---|---|---|---|
W001 | unused-open | W |
|
W002 | redundant-match | W | Identity match — every arm returns its pattern, achieving nothing with great ceremony |
W003 | list-length-compare | W |
|
W004 | list-nth | W |
|
W005 | partial-function | W |
|
W006 | naming-convention | I | Enforces snake_case for values and PascalCase for modules, because convention is all that stands between us and barbarism |
W008 | bool-redundancy | W |
|
W009 | eta-reduce | I |
|
W010 | exn-control-flow | I |
|
Run olint --list-rules for the full catalogue of grievances.
Inline Suppression
Because the difference between a useful tool and an annoying one is the ability to say "yes, I know, shut up about it."
(* olint:disable W001 *)
open Printf (* no warning — you've made your choice *)
(* olint:enable W001 *)
(* olint:disable-next-line W005 *)
let first = List.hd xs (* just this once *)JSON Output
For CI pipelines, editors, and other systems that prefer their criticism in machine-readable form:
olint --format json src/[
{
"file": "src/parser.ml",
"line": 42,
"col": 3,
"rule": "W001",
"severity": "W",
"message": "unused open: `open Printf` is not referenced",
"hint": "remove the open or use a qualified name"
}
]Localisation
Every diagnostic has a stable ID (W001, W003). A developer in Osaka can Google "olint W003" regardless of what language the message is in. Architecture lifted wholesale from BarraCUDA's bc_err.c, because good ideas deserve to be stolen.
olint --lang lang/fr.txt src/Translation file format (one insult per line):
W001=open inutilisé: `open %s` n'est pas référencé
W001.hint=supprimez le open ou utilisez un nom qualifiéEnglish is compiled in as the default, largely because the errors were written in English first and we haven't got round to the others yet. PR's are accepted for other languages. Spanish and French speakers are warned that once my Duolingo hits 60, badly translated error messages are coming your way (so get in before then)
Architecture
- Parsetree-based:
Ast_iteratoron the untyped AST. No.cmtfiles, no build step.olint src/just works. - compiler-libs: Zero parsing code. The OCaml compiler parses; we merely pass judgement.
- OCaml 5.4.0: Adapted for the 5.4
Longident.LdotAPI change, which wrapped both arguments inLocation.locfor reasons best known to the compiler team. - Minimal deps:
compiler-libs.common+cmdliner.
License
Apache 2.0 — see LICENSE.