Writing Additional Rules

We will write a lint rule for this:

StringMatchQ takes 2 arguments and we will write a rule that will catch StringMatchQ called with 3 or more arguments.

First load the packages we will need

See how the input looks with abstract syntax

This pattern will match what we want

Here is a rule function that we can use.

The signature of rule functions is func[pos_List, ast_] where ast is the AST of the entire expression and pos is the position within ast that we are matching.

Rule functions must return a list of Lints.

The ast that is passed in can be very large, so rule functions often use a combination of HoldRest and setting a Module variable to ast. This will prevent lexical substitution and speed up the function.

Rules are Associations with patterns for keys and functions for values
See our new rule

But we run into problems like this:

StringMatchQ may take options.

We will write a pattern that matches 1 or more non-Option arguments, and then allows 0 or more Option arguments.

Now options are handled

We may also see this problem:

The pattern that we wrote does not handle the use of named pattern variables like opts when used in other code.

We use a heuristic to match symbols with names that match *opts*.

Now named pattern variables like opts are handled also