x-lang

← Index

x/tool/lint

AST linter via the type-system write stacks: name-based def/use analysis + first/rest + tail-def-leak + pedantic (arity / non-callable / duplicate-def) checks.

Class Lint

%lint-sweep-at

Heap objects, live and garbage, past which the walk sweeps before the next top-level form

Static field: data held by Lint itself, not by its instances.

%lint-alloc-cell

The base’s count of allocated objects, live and garbage

Static field: data held by Lint itself, not by its instances.

(Lint %lint-sweep!)

%lint-class-siblings

Sibling method names of the class being walked

Static field: data held by Lint itself, not by its instances.

%lint-self-name

The name a (def NAME (fn …)) binds, for that fn’s self slot

Static field: data held by Lint itself, not by its instances.

%lint-carried

Parameter names the next fn walked carries from its call

Static field: data held by Lint itself, not by its instances.

%lint-no-shadow

Parameter names of the fn being entered that are no shadow

Static field: data held by Lint itself, not by its instances.

%lint-word-max

The largest integer a 4-byte word holds, as its digits

Static field: data held by Lint itself, not by its instances.

%lint-word-min

The digits of the smallest integer a 4-byte word holds

Static field: data held by Lint itself, not by its instances.

%lint-int-type

The integer type, whose read stack the arming pushes on

Static field: data held by Lint itself, not by its instances.

%lint-read-saved

The integer type’s read stack as it was before arming

Static field: data held by Lint itself, not by its instances.

(Lint %lint-digits-past? tok i n limit)

(Lint %lint-wide-token tok)

(Lint %lint-wide-of arg)

(Lint %lint-wide-args! args)

(Lint %lint-arm-source!)

(Lint %lint-disarm-source!)

(Lint %lint-fn-form? x)

(Lint %lint-after-self fn-form)

(Lint %lint-note-helper! form rest-forms)

(Lint %lint-calls-in name xs)

(Lint %lint-carried-of params calls)

(Lint %lint-module-of forms)

%lint-embedder-known

Embedder-contract names, announced before any file runs

Static field: data held by Lint itself, not by its instances.

%lint-block-selectors

Selectors carrying a block form (x/type/block); one entry per shipped wrap

Static field: data held by Lint itself, not by its instances.

(Lint %lint-all-syms? xs)

(Lint %lint-names-at? args)

(Lint %lint-new-names? xs)

(Lint %lint-resolves? sym)

(Lint %lint-block-send? sel args)

(Lint %lint-block-form? form)

(Lint %lint-block-form! form)

(Lint %lint-block-body args)

(Lint %lint-out-verb? form)

(Lint %ladder-keyed form var)

(Lint %env-known? name)

(Lint %lint-doc form)

(Lint %lint-class-methods clauses acc)

(Lint %lint-class-clause c)

(Lint %lint-method form)

(Lint %lint-class form)

(Lint %lint-class-prepass forms)

(Lint %lint-provide form)

(Lint %lint-computed-call form)

lint-forms

Walk top-level forms via the write stacks, collecting def/use names, first/rest issues, tail-position def leaks, and pedantic warnings (arity, non-callable calls, duplicate defs, malformed forms, lexical shadows, and unused locals). A first form (module NAME) names a loaded module whose environment resolves the file’s heads.

Returns: LIST — (defs uses issues leaks warnings) – defs/uses/issues/leaks are NAME STRINGS; warnings are (label . name) pairs for arity / call-nonfn / display-chain / dup-def / ladder / dispatch / malformed / match-multi / shadow / unused; ladder names carry the arm count as NAME/ARMS

Examples:

(import x/tool/lint lint-forms) (lint-forms '((def a 1) (def b (+ a c))) () ()) => (("b" "a") ("c" "a" "+") () () ())

lint-undefined

Compute undefined names: used but not in env or file defs.

Returns: LIST — Names used but not defined

Examples:

(import x/tool/lint lint-undefined) (lint-undefined (list "a") (list "a" "first" "zz-nope")) => ("zz-nope")

lint-unused

Compute unused names: defined but not referenced. Skips %-prefixed internals.

Returns: LIST — Names defined but never used

Examples:

(import x/tool/lint lint-unused) (lint-unused (list "a" "b" "%c") (list "a") #f) => ("b")
(import x/tool/lint lint-unused) (null? (lint-unused (list "a" "b") (list "a") #t)) => #t

lint-first-rest

Extract the first/rest-on-non-list findings from a lint-forms result.

Returns: LIST — Op names (first/rest) applied to a literal non-list

Examples:

(import x/tool/lint lint-forms lint-first-rest) (lint-first-rest (lint-forms '((first 'a)) () ())) => ("first")

lint-leaks

Extract the tail-position-def leak findings from a lint-forms result.

Returns: LIST — Def names that bind in tail position (leak to global; use let)

Examples:

(import x/tool/lint lint-forms lint-leaks) (lint-leaks (lint-forms '((def f (fn (_) (def y 1)))) () ())) => ("y")

lint-warnings

Extract all pedantic warnings (arity, call-nonfn, dup-def, …) from a result.

Returns: LIST — Pedantic findings as (label . name) pairs

Examples:

(import x/tool/lint lint-forms lint-warnings) (lint-warnings (lint-forms '((def a 1) (def a 2)) () ())) => (("dup-def" . "a"))

lint-warnings-of

Filter pedantic warnings to one label, returning their names.

Returns: LIST — The names for warnings of that label

Examples:

(import x/tool/lint lint-forms lint-warnings-of) (lint-warnings-of "dup-def" (lint-forms '((def a 1) (def a 2)) () ())) => ("a")

lint-has?

Test whether a name string is in a names list (string equality).

Returns: BOOL — #t if name is in names

Examples:

(import x/tool/lint lint-has?) (lint-has? "a" (list "b" "a")) => #t