Java Reference
In-Depth Information
written in a single class, and not distributed among the various node types
(see Exercise 20).
A phase is thus crafted by writing
methods in the phase's class—one
for each kind of node for which some action must be performed. An example
of this style of code is shown in Figure 2.14 on page 52. A phase
visit
f
then
performs its work for a particular node n in response to the method call:
f . visit( AbstractNode n )
Most object-oriented languages use single dispatch to determine which
visit
method should be invoked in response to the above method call. The dispatch
is based on the actual type of the receiver object f . Unfortunately, single dispatch
finds a match for
based on the declared type of its parameters at the call
site. Thus, if a phase contained a method
visit
( IfNode n ), that method would
not be invoked on an actual IfNode, because the match is based on the declared
type (AbstractNode)ofthesuppliedparameter.
While other solutions are possible (see Exercises 20 and 21), invoking
visit
visit
based on the compiler's phase fand a the supplied node n 's actual type requires
double dispatch (a limited form of multiple dispatch ). The visitor pattern
achieves a formof double dispatch for languages that o
er only single dispatch.
The visitor pattern enables phase- and node-specific code to be invoked cleanly,
while aggregating the functionality of a phase in a single class. Figure 7.23
illustrates the application of the visitor pattern for our example. The code is
organized as follows:
ff
Every phase extends the Visitor class, as shown at Marker 30 ,sothatit
inherits the
visit
(AbstractNode n )method.
Every concrete node class includes the method shown at Markers 31 ,
32 ,and 34 that accepts a visitor and accomplishes double dispatch as
described below.
While the inclusion of the
method in every node class seems
redundant, it cannot be factored into a common superclass, because the
type of this must be specific to the visited node.
accept
As an example, consider the invocation of f . visit(AbstractNode n )when f
is an instance of TypeChecking and n is an instance of PlusNode. Multiple
dispatch is accomplished as follows:
The inherited method
(AbstractNode n )atMarker 28 is invoked,
with this bound to the TypeCheckingphase.
visit
Marker 29 invokes n . accept( this ). Although n is declared of type
AbstractNode, single dispatch will invoke the
accept
method that is
most specialized to the actual type of n .
 
Search WWH ::




Custom Search