fluff is an experimental Fortran linter and formatter built on the
FortFront AST and semantic APIs.
The project is useful as a FortFront-based tool prototype, but it is not yet a Ruff-equivalent production tool. Several CLI and formatter features are still tracked as open issues.
fluff is the deep static-analysis half of a two-tool split, in the shape Go
uses for go vet and staticcheck, Rust uses for cargo and clippy, and C and
C++ use for compiler warnings and clang-tidy.
fo owns the cheap tier: checks that need no parse tree, run on every
invocation, and work with nothing else installed. Today that is unused imports,
short-circuit reliance, and gfortran's own warnings.
fluff owns every rule that needs an abstract syntax tree, because it is built
on FortFront and fo is not. Type-aware rules, dead-code analysis, and
column-major access patterns belong here. fo lint --deep reaches them by
running fluff check --output-format json as a subprocess and merging the
findings (lazy-fortran/fo#59).
Two consequences worth stating explicitly:
- Do not reimplement
fo's native rules here. They must keep working whenfluffis not installed. - The subprocess boundary is deliberate. It keeps
fo's dependency closure free of FortFront, sofo buildandfo teststay available during bootstrap.
Before fo lint --deep can rely on this repository, #260, #261, #262, and #263
need to close. Take #262 first: while 28 test programs exit zero regardless of
what they find, a passing run here is not evidence that the other three were
fixed.
Implemented or partially implemented:
- style rules
F001toF015 - performance rules
P001toP007 - correctness rule
C001 - formatter built on FortFront
emit_fortran - basic LSP components
- JSON/SARIF/GitHub-style output code paths
- CLI:
--select,--ignore,--exclude,--statistics,--quiet,--show-fixes, theruleslisting, and stdin input via-
Known limits:
fluff formatis not idempotent: it prepends a space to the first line and writesprint * , iforprint *, i(#260)- the test suite cannot detect either of the above, because 28 of its 94 programs exit zero no matter what they find (#262), and two more resolve the binary under test by globbing fpm's build layout, so they can exercise a stale artifact instead of the current tree (#265)
- formatter can still move inline comments in unsafe ways (#244)
- configuration support has open regressions
- AST caching is disabled in the linter path because FortFront arena/context
copies are not yet safe enough
(
src/fluff_linter/fluff_linter.f90:83), which leavesfluff_analysis_cache.f90compiled but unreachable
git clone git@github.com:lazy-fortran/fluff.git
cd fluff
fpm build --profile releasefluff check src/
fluff format src/
fluff check --output-format json src/Use fluff --help for the options supported by the current build.
fluff should not parse Fortran text itself. The intended flow is:
- read source
- parse with FortFront tooling APIs
- run FortFront semantic analysis
- execute AST-based lint rules
- format through FortFront code emission plus local cleanup passes
This keeps parser and semantic behavior aligned with FortFront and avoids regex-based language analysis.
See ROADMAP.md and the open issues. The short version:
- fix formatter safety first
- finish CLI parity needed for daily use
- repair configuration loading
- only then improve cache/LSP polish
- fortfront: parser, AST, semantic analysis, formatter emission.
- standard: target language-mode behavior for LFortran Standard and Infer.
MIT. See LICENSE.