/** * DemeterF Main package: transformation/traversals with optional arguments. * *
Traversals are parametrized by a function objects. * Each function class (FC) implements combine and/or * update methods, which are called by a traversal when walking a * structure.
* *Note: update methods are only called when the Traversal * traverse(Object o, Object a) method is called; i.e., when the * original traversal is passed a starting context. See * {@link edu.neu.ccs.demeterf.examples Examples} for, well... some examples.
* *
* Ret combine(Target t, ..., Arg a)
*
* for datatypes to be
* reconstructed, after the traversal of any subobjects.
*
* Ret
is (of course) the return type, Target
* should be replaced by the type (or a supertype) at which the method will be
* called, and Arg
should be the expected traversal context type.
* The [...
] should be a list of types and bindings
* (i.e., formal method parameters) that are expected from sub-traversals of
* the (Target) datatype's fields; no fields? no extra parameters
* needed.
All parameters are optional, but order matters: e.g., if a method * accepts less than the number of actual parameters available, then it may still * be called if the types match. See {@link edu.neu.ccs.demeterf.dispatch Dispatch} * for method matching/dispatch description.
* Ret update(Target t, Target.field f, Arg a)
*
* for datatypes where the traversal argument needs to be modified for
* subtraversals. Ret
should be the new argument type (it can be
* different), Target
is where this method should be called (on the
* way down), Arg
is the type of the previous traversal argument, and
* Target.field
is an encoding of which field of Target
* we are about to traverse.
* We encode the field to be traversed by using an inner public static
* class
that shares the name of the field. There must be a
* public
path (the outer classes must be public, all the way up) in
* order for the encoding to work. The DemeterF
class generator does
* this automatically... see examples package for some hand-coded examples.
The Arg
and Ret
types should generally be the
* same type (or share a common supertype), but anything is possible.
* e.g., implementing:
*
* Object update(Object o){ return o; }
*
* will give each combine
method access to its parent as a traversal
* context.
*