``linter``
==========

Logtalk provides a built-in linter tool that runs automatically when
compiling and loading source files. The lint warnings are controlled by
a `set of flags <../userman/programming.html#programming-flags-lint>`__.
The default values for these flags are defined in the backend Prolog
compiler adapter files and can be overriden from a settings file or from
a source file (e.g. a loader file). These flags can be set globally
using the
`set_logtalk_flag/2 <../refman/predicates/set_logtalk_flag_2.html>`__
built-in predicate. For (source file or entity) local scope, use instead
the
`set_logtalk_flag/2 <../refman/directives/set_logtalk_flag_2.html>`__
directive.

By loading the ``tutor`` tool, most lint warnings are expanded with
explanations and suggestions on how to fix the reported issues.

Note that, in some cases, the linter may generate false warnings due to
source code analysis limitations or special cases that, while valid when
intended, usually result from programming issues. When a code rewrite is
not a sensible solution to avoid the warning, the workaround is to turn
off locally the flag that controls the warning.

Lint checks include:

-  Missing directives (including scope, meta-predicate, dynamic,
   discontiguous, and multifile directives)
-  Duplicated directives, clauses, and grammar rules
-  Missing predicates (calls to non-declared and non-defined predicates)
-  Calls to declared but not defined static predicates
-  Non-portable predicate calls, predicate options, arithmetic function
   calls, directives, flags, and flag values
-  Suspicious calls (syntactically valid calls that are likely semantic
   errors; e.g. float comparisons using the standard arithmetic
   comparison operators)
-  Deprecated directives, predicates, control constructs, and flags
-  References to unknown entities (objects, protocols, categories, or
   modules)
-  Top-level shortcuts used as directives
-  Unification goals that will succeed without binding any variables
-  Unification goals that will succeed creating a cyclic term
-  Goals that are always true or always false
-  Trivial goal fails (due to no matching predicate clause)
-  Redefined built-in predicates
-  Redefined standard operators
-  Lambda expression unclassified variables and mixed up variables
-  Lambda expression with parameter variables used elsewhere in a clause
-  Singleton variables
-  If-then-else and soft cut control constructs without an else part
-  Cuts in clauses for multifile predicates
-  Missing cut in repeat loops
-  Possible non-steadfast predicate definitions
-  Non-tail recursive predicate definitions
-  Redundant calls to control constructs and built-in predicates
-  Calls to all-solutions predicates with existentially qualified
   variables not occurring in the qualified goal
-  Calls to all-solutions predicates with no shared variables between
   template and goal
-  Calls to ``bagof/3`` and ``setof/3`` where the goal argument contains
   singleton variables
-  Calls to ``findall/3`` used to backtrack over all solutions of a goal
-  Calls to standard predicates that have more efficient alternatives
-  Entity, predicate, and variable names not following official coding
   guidelines
-  Variable names that differ only on case

Additional checks are provided by the ``make`` and ``dead_code_scanner``
tools. For large projects, the data generated by the
``code_metrics tool`` may also be relevant in accessing the quality of
your code.

Experimental support for extending the linter with user-defined warnings
is available using the
`logtalk_linter_hook/7 <../refman/predicates/logtalk_linter_hook_7.html>`__
multifile hook predicate.
