Difference between revisions of "Visitor"

From Liberty Eiffel Wiki
Jump to navigation Jump to search
(typos)
 
m (Object Menter URL no longer exits, adapted text accordingly)
 
(14 intermediate revisions by 4 users not shown)
Line 1: Line 1:
[[Category:Book]]
+
[[Category: Design Pattern]]
  +
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.
SmartEiffel vistors are a mechanism that let you reuse the SmartEiffel kernel in order to build new applicationss.
 
   
  +
The origin of visitors is a ''[[Glossary#DesignPattern|design pattern]]'', in fact the Acyclic Visitor developed by Robert C. Martin.
This is how [[eiffeldoc]], for example, can have been built without touching the system kernel.
 
   
  +
Liberty Eiffel adopted and adapted this design pattern. All the framework classes are in the <tt>SmartEiffel/tools/visitor</tt> directory.
The origin of visitors is a ''[[Glossary#DesignPattern|design pattern]]'', in fact the [http://www.objectmentor.com/resources/articles/acv.pdf acyclic visitor] developed by Robert C.&nbsp;Martin.
 
 
This design pattern has been adopted and adapted by SmartEiffel. All the framework classes are in the <tt>SmartEiffel/tools/visitor</tt> directory.
 
   
 
== Framework ==
 
== Framework ==
Line 13: Line 12:
 
Every visitable class inherits from [[library_class:VISITABLE|<tt>VISITABLE</tt>]]. With it are associated:
 
Every visitable class inherits from [[library_class:VISITABLE|<tt>VISITABLE</tt>]]. With it are associated:
 
* a class derived from [[library_class:VISITOR|<tt>VISITOR</tt>]],
 
* a class derived from [[library_class:VISITOR|<tt>VISITOR</tt>]],
* a [[Glossary#Feature|''feature'']] <tt>accept</tt> which has for its parameter an object of that class.
+
* a [[Glossary#Feature|feature]] <tt>accept</tt> which has for its parameter an object of that class.
   
 
== Visitable classes ==
 
== Visitable classes ==
Line 30: Line 29:
 
* inherits all the visitor classes of the framework (conforming inheritance)
 
* inherits all the visitor classes of the framework (conforming inheritance)
 
* also inherits from the [[library_class:VISITOR|<tt>VISITOR</tt>]] class itself (conforming inheritance)
 
* also inherits from the [[library_class:VISITOR|<tt>VISITOR</tt>]] class itself (conforming inheritance)
* defines all the <tt>visit_*</tt> ''features'' of the visitor classes.
+
* defines all the <tt>visit_*</tt> features of the visitor classes.
   
Usually, such a class also provides a [[Glossary#Feature|''feature'']] which lets you start a search. If that does not exist, it is enough to run the <tt>accept</tt> [[Glossary#Feature|''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.
+
Usually, such a class also provides a [[Glossary#Feature|feature]] which lets you start a search. If that does not exist, it is enough to run the <tt>accept</tt> [[Glossary#Feature|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 [[tool_class:AGENT_CREATION_HELPER|<tt>AGENT_CREATION_HELPER</tt>]] or again [[tool_class:HIDDEN_EXPRESSION_DETECTOR|<tt>HIDDEN_EXPRESSION_DETECTOR</tt>]].
 
For some examples, see [[tool_class:AGENT_CREATION_HELPER|<tt>AGENT_CREATION_HELPER</tt>]] or again [[tool_class:HIDDEN_EXPRESSION_DETECTOR|<tt>HIDDEN_EXPRESSION_DETECTOR</tt>]].
Line 40: Line 39:
 
[[tool_class:IN_OUT_VISITOR|<tt>IN_OUT_VISITOR</tt>]] is a class that lets you do a complete search of a class's syntactic tree, depth-first.
 
[[tool_class:IN_OUT_VISITOR|<tt>IN_OUT_VISITOR</tt>]] is a class that lets you do a complete search of a class's syntactic tree, depth-first.
   
Each node is visited by the following algorithm (the NODE class is imaginary):
+
The following algorithm visits each node (the NODE class is imaginary):
 
feature {NODE}
 
feature {NODE}
 
visit_node (a_node: NODE) is
 
visit_node (a_node: NODE) is

Latest revision as of 12:48, 25 December 2021

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:

  • a class derived from VISITOR,
  • a feature accept which has for its parameter an object of that class.

Visitable classes

The visitable classes are all the classes of the syntactic and semantic tree. There we find in particular

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.