Architecture¶
This section documents the most important architectural elements of gherlint.
Main Concept¶
The linting process is coordinated by GherkinLinter.
It constructs abstract syntax trees for each file and passes them to ASTWalker,
together with a list of checkers which where discovered by the CheckerRegistry.
The checker classes implement a Visitor pattern:
each checker can implement visit_nodetype() and leave_nodetype() methods for the elements it is interested.
The ASTWalker calls those methods on the checkers for each node while it traverses the tree.
The checkers themselves define one or several Message which are registered in a central MessageStore
and can be emitted through a class that inherits from Reporter (or defines the necessary methods).
Startup Phase¶
The user invokes gherlint through the command line, where he can specify additional options
like the Reporter class to use or what additional checkers to load.
The main() function constructs a Config object which is passed to GherkinLinter.
According to the configuration the GherkinLinter creates the reporter, checker instances and
the walker which will be necessary for running the linting operation.
The linting itself is described in the next section.
The linting process is started by calling the run() method on GherkinLinter.
For each file in the directory which was passed to the __init__() of GherkinLinter,
it will construct a Document object which contains the full abstract syntax tree (AST)
of the file. This root node is passed to the ASTWalker’s walk() method.
The ASTWalker will first call the visit_nodetype() method (where nodetype is
the lowertype class name of the node) on all checkers that implement them, before
it recursively calls walk(child_node)() for all the node’s children (if any) on itself.
Afterwards the leave_nodetype() method is called analogous to the enter_nodetype() method.
Message Handling¶
Each checker has a number of messages it can emit.
Message instances are stored in a central MessageStore.
The individual vist_ and leave_ methods are responsible to determine
whether a specific message shall be emitted. They use the Reporter to add a message to emit
by passing the name or id of the message. The Reporter looks up the message instance
through the MessageStore.