Visitor
Liberty Eiffel visitors are a mechanism that let you reuse the Liberty Eiffel kernel in order to build new applications.
This is how eiffeldoc, for example, was built without the need to touch the system kernel.
The origin of visitors is a design pattern, in fact the acyclic visitor developed by Robert C. Martin.
Liberty Eiffel adopted and adapted this design pattern. All the framework classes are in the SmartEiffel/tools/visitor directory.
Framework
Every visitable class inherits from VISITABLE. With it are associated:
Visitable classes
The visitable classes are all the classes of the syntactic and semantic tree. There we find in particular
- EXPRESSION, INSTRUCTION (syntactic classes)
- TYPE, FEATURE_STAMP, LIVE_TYPE... (semantic classes)
Using visitors
Simple cases
Each visitor can be used separately, but you can also use several in the same class; this is the most common case.
To use visitors, you have to create a visitor class. This class will have the following properties:
- inherits all the visitor classes of the framework (conforming inheritance)
- also inherits from the VISITOR class itself (conforming inheritance)
- defines all the visit_* features of the visitor classes.
Usually, such a class also provides a feature which lets you start a search. If that does not exist, it is enough to run the accept feature on a visitable object. Of course, that object must be visitable by that visitor, in other words, that visitor must inherit from the framework visitor class which is able to visit the object.
For some examples, see AGENT_CREATION_HELPER or again HIDDEN_EXPRESSION_DETECTOR.
Using IN_OUT_VISITOR
IN_OUT_VISITOR is a class that lets you do a complete search of a class's syntactic tree, depth-first.
The following algorithm visits each node (the NODE class is imaginary):
feature {NODE} visit_node (a_node: NODE) is do if enter_node(a_node) then node.child.accept(Current); exit_node(a_node); end end feature {} enter_node (a_node: NODE): BOOLEAN is do Result := True end exit_node (a_node: NODE) is do end
The interesting point is that a class inheriting from IN_OUT_VISITOR has to redefine only what is strictly necessary.
See, for example, EIFFELDOC_SHORTER_CLASSDOC and EIFFELDOC_SHORTER_FIND_CLIENTS.