Documentation
¶
Overview ¶
Package ruleslinter statically verifies that each rule which calls ctx.Resolver or (*oracle.CompositeResolver).Oracle() declares a matching capability in its api.Rule registration. The accepted declarations are NeedsResolver, NeedsOracle, or the unified NeedsTypeInfo (which subsumes both). The runtime dispatcher only wires the resolver / oracle when those bits are set, so a missing declaration silently drops findings. This gate catches the mistake at build time.
The same gate also enforces the NeedsConcurrent capability: a rule body that manages its own worker-local finding-collector concurrency (calls scanner.MergeCollectors, spawns goroutines with `go`, or uses sync.WaitGroup) must declare NeedsConcurrent in Meta(); conversely, a rule declaring NeedsConcurrent whose body contains none of those signals is flagged as declared-but-unused. The signal set is intentionally narrow — see scanBodyUsage below — and errs toward false negatives over false positives.
Scope is intentionally conservative:
- Analyzes one Go package (typically internal/rules) at a time.
- Resolves the Check expression to a single function body: a FuncLit, a package-level FuncDecl, or a method on the rule type bound in the surrounding { r := &FooRule{...}; api.Register(...) } block.
- Scans that body (and bodies of any same-package helpers it calls) for ctx.Resolver selector usage, zero-arg .Oracle() method calls, and the concurrent-state signals described above. No generics tracking, no cross-package analysis.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AdHocCacheException ¶
type AdHocCacheException struct {
File string // basename within the rules dir, e.g. "complexity.go"
Name string // identifier of the sync.Map var or field
}
AdHocCacheException identifies a sync.Map declaration that pre-dates the no-ad-hoc-cache gate and is allowed to exist temporarily. Each entry is keyed by file basename + var/field name. Removing an entry here is part of the migration of that cache to a shared facts layer (typically internal/filefacts/).
type Violation ¶
type Violation struct {
RuleID string // ID field from the api.Rule literal, if resolvable.
Position token.Position
Message string
}
Violation is a single linter failure.
func Analyze ¶
Analyze parses every .go file in dir as a single package and returns violations. The directory need not be a Go module; only syntactic parsing is performed.
func AnalyzeAdHocCaches ¶
AnalyzeAdHocCaches scans every .go file in dir for sync.Map declarations (package-level vars or struct fields) and returns one violation per unknown declaration. Known cases are listed in grandfatheredAdHocCaches; legitimate infrastructure files are listed in adHocCacheInfraFiles. Test files are skipped.
func AnalyzeSubpackageTopology ¶
AnalyzeSubpackageTopology enforces the per-domain rule subpackage dependency contract: every Go subpackage under internal/rules/ may import a curated set of foundation packages and must not import the parent rules package or any sibling subpackage. This keeps domains isolated from each other and from the registry plumbing in rules, preventing cross-domain helper accretion.
rulesParentDir should point at internal/rules. The function walks one level deep; nested subpackages (e.g. internal/rules/foo/bar) are not checked.
The allowed set is broad: every direct subpackage of internal/analyzers, plus internal/scanner, internal/rules/v2, internal/rules/base, internal/typeinfer, internal/oracle, internal/javafacts, internal/librarymodel, internal/experiment, internal/android, internal/module, internal/cache, internal/config, and the standard library. Anything else under github.com/kaeawc/krit/ is treated as forbidden — including internal/rules itself and any sibling domain.