Next: guile-tools make-module-catalog, Previous: guile-tools lexer-repl, Up: Miscellaneous Tools
Usage: lint [options] FILE1 FILE2 ...
Perform various preemptive checks for coding errors in Guile Scheme
code. Options are:
-m, --module NAME -- use NAME as the module name, for files
that do not have a `define-module' form;
default: `(guile-user)'
Here are the available checks (in order of application):
*exists
*readable
*topsyn
*borders
freevars
unused
roaming
The * means that if the check fails, lint skips further tests.
The rest of this help message explains the checks in more detail.
Readability
-----------
This checks for file readability as well as the absense of `#.'
(hash-dot) reader macros, which is a risky practice.
Top-level syntax
----------------
This checks for a shell-script header (recognized when the first two
characters of the file are "#!" and a later line begins with "!#"),
and also that the top-level forms can be `read' without syntax error.
Imports and exports
-------------------
This checks #:autoload and #:use-module clauses in a `define-module'
form, as well as top-level `use-modules' forms. For autoloads, each
trigger is checked against the module's exports list. For the other
forms, referenced bindings from the #:select sub-clause are checked
against the module's exports list.
Unresolved free variables
-------------------------
Unresolved free variables are symbols that have no binding in any of
the environments in which it could be defined. Relevant environments
start with the smallest (closest) scope defined by `lambda' and
friends, and move outward, to include the top-level forms "in" the
module (if the file has a `define-module' form); in the file; in the
interface imported from upstream modules; and finally, in the base
(also called the "builtin") environment that Guile itself provides.
It isn't guaranteed that the scan will find absolutely all such
errors. Quoted expressions are skipped, so code that is explicitly
evaluated using `eval' will not be checked. For example, in the
form: `(eval-in-module 'missing (current-module))', `missing' would
be missed.
False positives are also possible. Firstly, the tool doesn't
understand all possible forms of implicit quoting; in particular,
it doesn't detect and expand uses of macros. Secondly, it picks up
explicit compatibility code like `(if (defined? 'x) (define y x))'.
Thirdly, there are occasional oddities like `next-method'.
Unused definitions
------------------
This checks for definitions that are not used anywhere, either
internally, or exported, or named as the shell-script header
entry-point (via "guile -e ENTRY-POINT").
Roaming guests
--------------
This is like the check for Unused definitions above, applied to
imports from #:use-modules clauses or inferred (where possible).
A "roaming guest" is an imported but unused binding. (A binding
named in #:re-export is not considered to be roaming.) If there
are no roaming guests, lint displays nothing. Otherwise, it
lists the bindings, one per line, in the form: STATUS MODULE NAME.
STATUS is either "+" to mean "seated" or "-" to mean "roaming",
MODULE is the module name, and NAME is the binding name.
Usage from a Scheme program:
(lint filename [tests...]) => alist
TESTS, a list of symbols, specifies tests to run. If omitted,
run all tests. ALIST maps each test name to its result.