Repository navigation
v2.62.0 - parallel analyze, incremental churn cache, class-member globs
fallow 2.62.0 ships a parallel analyze stage, an incremental git churn cache, the missing duplication row in the --performance table, and four bug fixes around dynamic imports, class-member globs, and circular-dependency suppression.
Highlights
analyze runs in parallel
The pipeline's analyze stage now schedules its ten independent detectors across rayon worker threads. On a synthetic 24,320-file monorepo the stage drops from ~6.75s to under half a second on a 14-core machine. Real-world fixtures (next.js, preact) show a ~2x speedup with byte-identical output.
Incremental git churn cache
.fallow/churn.bin now records per-commit events keyed by last_indexed_sha. When HEAD advances from the cached SHA, fallow runs git log <cached>..HEAD --numstat and merges the delta instead of re-shelling out for the entire churn window. CI runs that fallow on every push and pre-commit hooks now hit the cache for the bulk of the work, paying only the marginal-commit cost.
usedClassMembers accepts globs
Member strings containing * or ? now compile as glob matchers, so a single rule can cover the entire family of methods a framework dispatches reflectively. "*" matches every member on a heritage-matching class, "enter*" / "*Handler" cover prefix or suffix patterns, and "on*Event" combines both. Designed for parser-generator listeners (ANTLR), code-generated bridges (protoc-ts, openapi-typescript, graphql-codegen), and abstract framework bases. Glob patterns matching zero members emit a WARN so dead allowlist entries surface.
Added
usedClassMembersglob patterns, see Highlights above. Thanks @OmerGronich for the report. (Closes #254)overrides[].rules.circular-dependency: "off"suppresses cycles whose files all match the override glob. A cycle is suppressed when every file in the cycle resolves toSeverity::Offforcircular-dependencyviaoverrides[]. Cycles touching even one non-overridden file remain reported. Thanks @OmerGronich for the report. (Closes #255)- First-class blast-radius and importance sections on
fallow coverage analyze. New--blast-radiusand--importanceflags surface runtime-weighted blast-radius and importance findings in the human output. - Runtime coverage
--topflag. Limits the runtime findings + hot-path display to the top N entries.
Changed
analyzestage runs detectors in parallel, see Highlights above. Thanks @OmerGronich for the report. (Closes #259)- Git churn cache is incremental, see Highlights above. Thanks @OmerGronich for the report. (Closes #258)
--performancetable includes the duplication stage. The combined-modePipeline Performancetable now prints aduplication: <ms>row alongside the other stages instead of leaving the cost as an easy-to-miss parenthetical. Thanks @OmerGronich for the report. (Closes #257)
Fixed
circular-dependencyline-level inline directives now actually suppress.// fallow-ignore-next-line circular-dependencyon the offending import line previously landed instale_suppressionsand the cycle still appeared in the output, even thoughfallow dead-code --format jsonrecommended exactly that comment. Singular and plural slug aliases (circular-dependencyvscircular-dependencies) are now interchangeable across inline directives,rules, andoverrides[].rules. Thanks @pippenz for the report. (Closes #256)- Bare
() => import('./X')route callbacks credit the default export. Object-literal properties namedcomponent,loadChildren, orloadComponentwhose value is() => import('./X')(or a function-expression equivalent) now credit the target module's default export as used, even when no.then(m => m.default)is spelled. Fixes theunused-exportfalse positive on the standard Angular Router and Vue Router lazy-loading shapes. Thanks @OmerGronich for the report. (Closes #253) - CSS
@import 'pkg/subpath.css'resolves throughnode_modules. Tailwind v4@import 'tailwindcss/theme.css'and@import 'tailwindcss/utilities.css'patterns no longer surface as unresolved imports or as unused-dependency ontailwindcss.
Full Changelog: v2.61.0...v2.62.0
{ "usedClassMembers": [ { "extends": "GrammarBaseListener", "members": ["enter*", "exit*"] } ] }