NodeVisitor.java revision 1204:9597425b6b38
1/*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.nashorn.internal.ir.visitor;
27
28import jdk.nashorn.internal.ir.AccessNode;
29import jdk.nashorn.internal.ir.BinaryNode;
30import jdk.nashorn.internal.ir.Block;
31import jdk.nashorn.internal.ir.BlockStatement;
32import jdk.nashorn.internal.ir.BreakNode;
33import jdk.nashorn.internal.ir.CallNode;
34import jdk.nashorn.internal.ir.CaseNode;
35import jdk.nashorn.internal.ir.CatchNode;
36import jdk.nashorn.internal.ir.ContinueNode;
37import jdk.nashorn.internal.ir.DebuggerNode;
38import jdk.nashorn.internal.ir.EmptyNode;
39import jdk.nashorn.internal.ir.ErrorNode;
40import jdk.nashorn.internal.ir.ExpressionStatement;
41import jdk.nashorn.internal.ir.ForNode;
42import jdk.nashorn.internal.ir.FunctionNode;
43import jdk.nashorn.internal.ir.GetSplitState;
44import jdk.nashorn.internal.ir.IdentNode;
45import jdk.nashorn.internal.ir.IfNode;
46import jdk.nashorn.internal.ir.IndexNode;
47import jdk.nashorn.internal.ir.JoinPredecessorExpression;
48import jdk.nashorn.internal.ir.JumpToInlinedFinally;
49import jdk.nashorn.internal.ir.LabelNode;
50import jdk.nashorn.internal.ir.LexicalContext;
51import jdk.nashorn.internal.ir.LiteralNode;
52import jdk.nashorn.internal.ir.Node;
53import jdk.nashorn.internal.ir.ObjectNode;
54import jdk.nashorn.internal.ir.PropertyNode;
55import jdk.nashorn.internal.ir.ReturnNode;
56import jdk.nashorn.internal.ir.RuntimeNode;
57import jdk.nashorn.internal.ir.SetSplitState;
58import jdk.nashorn.internal.ir.SplitNode;
59import jdk.nashorn.internal.ir.SplitReturn;
60import jdk.nashorn.internal.ir.SwitchNode;
61import jdk.nashorn.internal.ir.TernaryNode;
62import jdk.nashorn.internal.ir.ThrowNode;
63import jdk.nashorn.internal.ir.TryNode;
64import jdk.nashorn.internal.ir.UnaryNode;
65import jdk.nashorn.internal.ir.VarNode;
66import jdk.nashorn.internal.ir.WhileNode;
67import jdk.nashorn.internal.ir.WithNode;
68
69/**
70 * Visitor used to navigate the IR.
71 * @param <T> lexical context class used by this visitor
72 */
73public abstract class NodeVisitor<T extends LexicalContext> {
74    /** lexical context in use */
75    protected final T lc;
76
77    /**
78     * Constructor
79     *
80     * @param lc a custom lexical context
81     */
82    public NodeVisitor(final T lc) {
83        this.lc = lc;
84    }
85
86    /**
87     * Get the lexical context of this node visitor
88     * @return lexical context
89     */
90    public T getLexicalContext() {
91        return lc;
92    }
93
94    /**
95     * Override this method to do a double inheritance pattern, e.g. avoid
96     * using
97     * <p>
98     * if (x instanceof NodeTypeA) {
99     *    ...
100     * } else if (x instanceof NodeTypeB) {
101     *    ...
102     * } else {
103     *    ...
104     * }
105     * <p>
106     * Use a NodeVisitor instead, and this method contents forms the else case.
107     *
108     * @see NodeVisitor#leaveDefault(Node)
109     * @param node the node to visit
110     * @return true if traversal should continue and node children be traversed, false otherwise
111     */
112    protected boolean enterDefault(final Node node) {
113        return true;
114    }
115
116    /**
117     * Override this method to do a double inheritance pattern, e.g. avoid
118     * using
119     * <p>
120     * if (x instanceof NodeTypeA) {
121     *    ...
122     * } else if (x instanceof NodeTypeB) {
123     *    ...
124     * } else {
125     *    ...
126     * }
127     * <p>
128     * Use a NodeVisitor instead, and this method contents forms the else case.
129     *
130     * @see NodeVisitor#enterDefault(Node)
131     * @param node the node to visit
132     * @return the node
133     */
134    protected Node leaveDefault(final Node node) {
135        return node;
136    }
137
138    /**
139     * Callback for entering an AccessNode
140     *
141     * @param  accessNode the node
142     * @return true if traversal should continue and node children be traversed, false otherwise
143     */
144    public boolean enterAccessNode(final AccessNode accessNode) {
145        return enterDefault(accessNode);
146    }
147
148    /**
149     * Callback for entering an AccessNode
150     *
151     * @param  accessNode the node
152     * @return processed node, null if traversal should end
153     */
154    public Node leaveAccessNode(final AccessNode accessNode) {
155        return leaveDefault(accessNode);
156    }
157
158    /**
159     * Callback for entering a Block
160     *
161     * @param  block     the node
162     * @return true if traversal should continue and node children be traversed, false otherwise
163     */
164    public boolean enterBlock(final Block block) {
165        return enterDefault(block);
166    }
167
168    /**
169     * Callback for leaving a Block
170     *
171     * @param  block the node
172     * @return processed node, which will replace the original one, or the original node
173     */
174    public Node leaveBlock(final Block block) {
175        return leaveDefault(block);
176    }
177
178    /**
179     * Callback for entering a BinaryNode
180     *
181     * @param  binaryNode  the node
182     * @return processed   node
183     */
184    public boolean enterBinaryNode(final BinaryNode binaryNode) {
185        return enterDefault(binaryNode);
186    }
187
188    /**
189     * Callback for leaving a BinaryNode
190     *
191     * @param  binaryNode the node
192     * @return processed node, which will replace the original one, or the original node
193     */
194    public Node leaveBinaryNode(final BinaryNode binaryNode) {
195        return leaveDefault(binaryNode);
196    }
197
198    /**
199     * Callback for entering a BreakNode
200     *
201     * @param  breakNode the node
202     * @return true if traversal should continue and node children be traversed, false otherwise
203     */
204    public boolean enterBreakNode(final BreakNode breakNode) {
205        return enterDefault(breakNode);
206    }
207
208    /**
209     * Callback for leaving a BreakNode
210     *
211     * @param  breakNode the node
212     * @return processed node, which will replace the original one, or the original node
213     */
214    public Node leaveBreakNode(final BreakNode breakNode) {
215        return leaveDefault(breakNode);
216    }
217
218    /**
219     * Callback for entering a CallNode
220     *
221     * @param  callNode  the node
222     * @return true if traversal should continue and node children be traversed, false otherwise
223     */
224    public boolean enterCallNode(final CallNode callNode) {
225        return enterDefault(callNode);
226    }
227
228    /**
229     * Callback for leaving a CallNode
230     *
231     * @param  callNode the node
232     * @return processed node, which will replace the original one, or the original node
233     */
234    public Node leaveCallNode(final CallNode callNode) {
235        return leaveDefault(callNode);
236    }
237
238    /**
239     * Callback for entering a CaseNode
240     *
241     * @param  caseNode  the node
242     * @return true if traversal should continue and node children be traversed, false otherwise
243     */
244    public boolean enterCaseNode(final CaseNode caseNode) {
245        return enterDefault(caseNode);
246    }
247
248    /**
249     * Callback for leaving a CaseNode
250     *
251     * @param  caseNode the node
252     * @return processed node, which will replace the original one, or the original node
253     */
254    public Node leaveCaseNode(final CaseNode caseNode) {
255        return leaveDefault(caseNode);
256    }
257
258    /**
259     * Callback for entering a CatchNode
260     *
261     * @param  catchNode the node
262     * @return true if traversal should continue and node children be traversed, false otherwise
263     */
264    public boolean enterCatchNode(final CatchNode catchNode) {
265        return enterDefault(catchNode);
266    }
267
268    /**
269     * Callback for leaving a CatchNode
270     *
271     * @param  catchNode the node
272     * @return processed node, which will replace the original one, or the original node
273     */
274    public Node leaveCatchNode(final CatchNode catchNode) {
275        return leaveDefault(catchNode);
276    }
277
278    /**
279     * Callback for entering a ContinueNode
280     *
281     * @param  continueNode the node
282     * @return true if traversal should continue and node children be traversed, false otherwise
283     */
284    public boolean enterContinueNode(final ContinueNode continueNode) {
285        return enterDefault(continueNode);
286    }
287
288    /**
289     * Callback for leaving a ContinueNode
290     *
291     * @param  continueNode the node
292     * @return processed node, which will replace the original one, or the original node
293     */
294    public Node leaveContinueNode(final ContinueNode continueNode) {
295        return leaveDefault(continueNode);
296    }
297
298
299    /**
300     * Callback for entering a DebuggerNode
301     *
302     * @param  debuggerNode the node
303     * @return true if traversal should continue and node children be traversed, false otherwise
304     */
305    public boolean enterDebuggerNode(final DebuggerNode debuggerNode) {
306        return enterDefault(debuggerNode);
307    }
308
309    /**
310     * Callback for leaving a DebuggerNode
311     *
312     * @param  debuggerNode the node
313     * @return processed node, which will replace the original one, or the original node
314     */
315    public Node leaveDebuggerNode(final DebuggerNode debuggerNode) {
316        return leaveDefault(debuggerNode);
317    }
318
319    /**
320     * Callback for entering an EmptyNode
321     *
322     * @param  emptyNode   the node
323     * @return true if traversal should continue and node children be traversed, false otherwise
324     */
325    public boolean enterEmptyNode(final EmptyNode emptyNode) {
326        return enterDefault(emptyNode);
327    }
328
329    /**
330     * Callback for leaving an EmptyNode
331     *
332     * @param  emptyNode the node
333     * @return processed node, which will replace the original one, or the original node
334     */
335    public Node leaveEmptyNode(final EmptyNode emptyNode) {
336        return leaveDefault(emptyNode);
337    }
338
339    /**
340     * Callback for entering an ErrorNode
341     *
342     * @param  errorNode   the node
343     * @return true if traversal should continue and node children be traversed, false otherwise
344     */
345    public boolean enterErrorNode(final ErrorNode errorNode) {
346        return enterDefault(errorNode);
347    }
348
349    /**
350     * Callback for leaving an ErrorNode
351     *
352     * @param  errorNode the node
353     * @return processed node, which will replace the original one, or the original node
354     */
355    public Node leaveErrorNode(final ErrorNode errorNode) {
356        return leaveDefault(errorNode);
357    }
358
359    /**
360     * Callback for entering an ExpressionStatement
361     *
362     * @param  expressionStatement the node
363     * @return true if traversal should continue and node children be traversed, false otherwise
364     */
365    public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
366        return enterDefault(expressionStatement);
367    }
368
369    /**
370     * Callback for leaving an ExpressionStatement
371     *
372     * @param  expressionStatement the node
373     * @return processed node, which will replace the original one, or the original node
374     */
375    public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) {
376        return leaveDefault(expressionStatement);
377    }
378
379    /**
380     * Callback for entering a BlockStatement
381     *
382     * @param  blockStatement the node
383     * @return true if traversal should continue and node children be traversed, false otherwise
384     */
385    public boolean enterBlockStatement(final BlockStatement blockStatement) {
386        return enterDefault(blockStatement);
387    }
388
389    /**
390     * Callback for leaving a BlockStatement
391     *
392     * @param  blockStatement the node
393     * @return processed node, which will replace the original one, or the original node
394     */
395    public Node leaveBlockStatement(final BlockStatement blockStatement) {
396        return leaveDefault(blockStatement);
397    }
398
399    /**
400     * Callback for entering a ForNode
401     *
402     * @param  forNode   the node
403     * @return true if traversal should continue and node children be traversed, false otherwise
404     */
405    public boolean enterForNode(final ForNode forNode) {
406        return enterDefault(forNode);
407    }
408
409    /**
410     * Callback for leaving a ForNode
411     *
412     * @param  forNode the node
413     * @return processed node, which will replace the original one, or the original node
414     */
415    public Node leaveForNode(final ForNode forNode) {
416        return leaveDefault(forNode);
417    }
418
419    /**
420     * Callback for entering a FunctionNode
421     *
422     * @param  functionNode the node
423     * @return true if traversal should continue and node children be traversed, false otherwise
424     */
425    public boolean enterFunctionNode(final FunctionNode functionNode) {
426        return enterDefault(functionNode);
427    }
428
429    /**
430     * Callback for leaving a FunctionNode
431     *
432     * @param  functionNode the node
433     * @return processed node, which will replace the original one, or the original node
434     */
435    public Node leaveFunctionNode(final FunctionNode functionNode) {
436        return leaveDefault(functionNode);
437    }
438
439    /**
440     * Callback for entering a {@link GetSplitState}.
441     *
442     * @param  getSplitState the get split state expression
443     * @return true if traversal should continue and node children be traversed, false otherwise
444     */
445    public boolean enterGetSplitState(final GetSplitState getSplitState) {
446        return enterDefault(getSplitState);
447    }
448
449    /**
450     * Callback for leaving a {@link GetSplitState}.
451     *
452     * @param  getSplitState the get split state expression
453     * @return processed node, which will replace the original one, or the original node
454     */
455    public Node leaveGetSplitState(final GetSplitState getSplitState) {
456        return leaveDefault(getSplitState);
457    }
458
459    /**
460     * Callback for entering an IdentNode
461     *
462     * @param  identNode the node
463     * @return true if traversal should continue and node children be traversed, false otherwise
464     */
465    public boolean enterIdentNode(final IdentNode identNode) {
466        return enterDefault(identNode);
467    }
468
469    /**
470     * Callback for leaving an IdentNode
471     *
472     * @param  identNode the node
473     * @return processed node, which will replace the original one, or the original node
474     */
475    public Node leaveIdentNode(final IdentNode identNode) {
476        return leaveDefault(identNode);
477    }
478
479    /**
480     * Callback for entering an IfNode
481     *
482     * @param  ifNode the node
483     * @return true if traversal should continue and node children be traversed, false otherwise
484     */
485    public boolean enterIfNode(final IfNode ifNode) {
486        return enterDefault(ifNode);
487    }
488
489    /**
490     * Callback for leaving an IfNode
491     *
492     * @param  ifNode the node
493     * @return processed node, which will replace the original one, or the original node
494     */
495    public Node leaveIfNode(final IfNode ifNode) {
496        return leaveDefault(ifNode);
497    }
498
499    /**
500     * Callback for entering an IndexNode
501     *
502     * @param  indexNode  the node
503     * @return true if traversal should continue and node children be traversed, false otherwise
504     */
505    public boolean enterIndexNode(final IndexNode indexNode) {
506        return enterDefault(indexNode);
507    }
508
509    /**
510     * Callback for leaving an IndexNode
511     *
512     * @param  indexNode the node
513     * @return processed node, which will replace the original one, or the original node
514     */
515    public Node leaveIndexNode(final IndexNode indexNode) {
516        return leaveDefault(indexNode);
517    }
518
519    /**
520     * Callback for entering a JumpToInlinedFinally
521     *
522     * @param  jumpToInlinedFinally the node
523     * @return true if traversal should continue and node children be traversed, false otherwise
524     */
525    public boolean enterJumpToInlinedFinally(final JumpToInlinedFinally jumpToInlinedFinally) {
526        return enterDefault(jumpToInlinedFinally);
527    }
528
529    /**
530     * Callback for leaving a JumpToInlinedFinally
531     *
532     * @param  jumpToInlinedFinally the node
533     * @return processed node, which will replace the original one, or the original node
534     */
535    public Node leaveJumpToInlinedFinally(final JumpToInlinedFinally jumpToInlinedFinally) {
536        return leaveDefault(jumpToInlinedFinally);
537    }
538
539    /**
540     * Callback for entering a LabelNode
541     *
542     * @param  labelNode the node
543     * @return true if traversal should continue and node children be traversed, false otherwise
544     */
545    public boolean enterLabelNode(final LabelNode labelNode) {
546        return enterDefault(labelNode);
547    }
548
549    /**
550     * Callback for leaving a LabelNode
551     *
552     * @param  labelNode the node
553     * @return processed node, which will replace the original one, or the original node
554     */
555    public Node leaveLabelNode(final LabelNode labelNode) {
556        return leaveDefault(labelNode);
557    }
558
559    /**
560     * Callback for entering a LiteralNode
561     *
562     * @param  literalNode the node
563     * @return true if traversal should continue and node children be traversed, false otherwise
564     */
565    public boolean enterLiteralNode(final LiteralNode<?> literalNode) {
566        return enterDefault(literalNode);
567    }
568
569    /**
570     * Callback for leaving a LiteralNode
571     *
572     * @param  literalNode the node
573     * @return processed node, which will replace the original one, or the original node
574     */
575    public Node leaveLiteralNode(final LiteralNode<?> literalNode) {
576        return leaveDefault(literalNode);
577    }
578
579    /**
580     * Callback for entering an ObjectNode
581     *
582     * @param  objectNode the node
583     * @return true if traversal should continue and node children be traversed, false otherwise
584     */
585    public boolean enterObjectNode(final ObjectNode objectNode) {
586        return enterDefault(objectNode);
587    }
588
589    /**
590     * Callback for leaving an ObjectNode
591     *
592     * @param  objectNode the node
593     * @return processed node, which will replace the original one, or the original node
594     */
595    public Node leaveObjectNode(final ObjectNode objectNode) {
596        return leaveDefault(objectNode);
597    }
598
599    /**
600     * Callback for entering a PropertyNode
601     *
602     * @param  propertyNode the node
603     * @return true if traversal should continue and node children be traversed, false otherwise
604     */
605    public boolean enterPropertyNode(final PropertyNode propertyNode) {
606        return enterDefault(propertyNode);
607    }
608
609    /**
610     * Callback for leaving a PropertyNode
611     *
612     * @param  propertyNode the node
613     * @return processed node, which will replace the original one, or the original node
614     */
615    public Node leavePropertyNode(final PropertyNode propertyNode) {
616        return leaveDefault(propertyNode);
617    }
618
619    /**
620     * Callback for entering a ReturnNode
621     *
622     * @param  returnNode the node
623     * @return true if traversal should continue and node children be traversed, false otherwise
624     */
625    public boolean enterReturnNode(final ReturnNode returnNode) {
626        return enterDefault(returnNode);
627    }
628
629    /**
630     * Callback for leaving a ReturnNode
631     *
632     * @param  returnNode the node
633     * @return processed node, which will replace the original one, or the original node
634     */
635    public Node leaveReturnNode(final ReturnNode returnNode) {
636        return leaveDefault(returnNode);
637    }
638
639    /**
640     * Callback for entering a RuntimeNode
641     *
642     * @param  runtimeNode the node
643     * @return true if traversal should continue and node children be traversed, false otherwise
644     */
645    public boolean enterRuntimeNode(final RuntimeNode runtimeNode) {
646        return enterDefault(runtimeNode);
647    }
648
649    /**
650     * Callback for leaving a RuntimeNode
651     *
652     * @param  runtimeNode the node
653     * @return processed node, which will replace the original one, or the original node
654     */
655    public Node leaveRuntimeNode(final RuntimeNode runtimeNode) {
656        return leaveDefault(runtimeNode);
657    }
658
659    /**
660     * Callback for entering a {@link SetSplitState}.
661     *
662     * @param  setSplitState the set split state statement
663     * @return true if traversal should continue and node children be traversed, false otherwise
664     */
665    public boolean enterSetSplitState(final SetSplitState setSplitState) {
666        return enterDefault(setSplitState);
667    }
668
669    /**
670     * Callback for leaving a {@link SetSplitState}.
671     *
672     * @param  setSplitState the set split state expression
673     * @return processed node, which will replace the original one, or the original node
674     */
675    public Node leaveSetSplitState(final SetSplitState setSplitState) {
676        return leaveDefault(setSplitState);
677    }
678
679    /**
680     * Callback for entering a SplitNode
681     *
682     * @param  splitNode the node
683     * @return true if traversal should continue and node children be traversed, false otherwise
684     */
685    public boolean enterSplitNode(final SplitNode splitNode) {
686        return enterDefault(splitNode);
687    }
688
689    /**
690     * Callback for leaving a SplitNode
691     *
692     * @param  splitNode the node
693     * @return processed node, which will replace the original one, or the original node
694     */
695    public Node leaveSplitNode(final SplitNode splitNode) {
696        return leaveDefault(splitNode);
697    }
698
699    /**
700     * Callback for entering a SplitReturn
701     *
702     * @param  splitReturn the node
703     * @return true if traversal should continue and node children be traversed, false otherwise
704     */
705    public boolean enterSplitReturn(final SplitReturn splitReturn) {
706        return enterDefault(splitReturn);
707    }
708
709    /**
710     * Callback for leaving a SplitReturn
711     *
712     * @param  splitReturn the node
713     * @return processed node, which will replace the original one, or the original node
714     */
715    public Node leaveSplitReturn(final SplitReturn splitReturn) {
716        return leaveDefault(splitReturn);
717    }
718
719    /**
720     * Callback for entering a SwitchNode
721     *
722     * @param  switchNode the node
723     * @return true if traversal should continue and node children be traversed, false otherwise
724     */
725    public boolean enterSwitchNode(final SwitchNode switchNode) {
726        return enterDefault(switchNode);
727    }
728
729    /**
730     * Callback for leaving a SwitchNode
731     *
732     * @param  switchNode the node
733     * @return processed node, which will replace the original one, or the original node
734     */
735    public Node leaveSwitchNode(final SwitchNode switchNode) {
736        return leaveDefault(switchNode);
737    }
738
739    /**
740     * Callback for entering a TernaryNode
741     *
742     * @param  ternaryNode the node
743     * @return true if traversal should continue and node children be traversed, false otherwise
744     */
745    public boolean enterTernaryNode(final TernaryNode ternaryNode) {
746        return enterDefault(ternaryNode);
747    }
748
749    /**
750     * Callback for leaving a TernaryNode
751     *
752     * @param  ternaryNode the node
753     * @return processed node, which will replace the original one, or the original node
754     */
755    public Node leaveTernaryNode(final TernaryNode ternaryNode) {
756        return leaveDefault(ternaryNode);
757    }
758
759    /**
760     * Callback for entering a ThrowNode
761     *
762     * @param  throwNode the node
763     * @return true if traversal should continue and node children be traversed, false otherwise
764     */
765    public boolean enterThrowNode(final ThrowNode throwNode) {
766        return enterDefault(throwNode);
767    }
768
769    /**
770     * Callback for leaving a ThrowNode
771     *
772     * @param  throwNode the node
773     * @return processed node, which will replace the original one, or the original node
774     */
775    public Node leaveThrowNode(final ThrowNode throwNode) {
776        return leaveDefault(throwNode);
777    }
778
779    /**
780     * Callback for entering a TryNode
781     *
782     * @param  tryNode the node
783     * @return true if traversal should continue and node children be traversed, false otherwise
784     */
785    public boolean enterTryNode(final TryNode tryNode) {
786        return enterDefault(tryNode);
787    }
788
789    /**
790     * Callback for leaving a TryNode
791     *
792     * @param  tryNode the node
793     * @return processed node, which will replace the original one, or the original node
794     */
795    public Node leaveTryNode(final TryNode tryNode) {
796        return leaveDefault(tryNode);
797    }
798
799    /**
800     * Callback for entering a UnaryNode
801     *
802     * @param  unaryNode the node
803     * @return true if traversal should continue and node children be traversed, false otherwise
804     */
805    public boolean enterUnaryNode(final UnaryNode unaryNode) {
806        return enterDefault(unaryNode);
807    }
808
809    /**
810     * Callback for leaving a UnaryNode
811     *
812     * @param  unaryNode the node
813     * @return processed node, which will replace the original one, or the original node
814     */
815    public Node leaveUnaryNode(final UnaryNode unaryNode) {
816        return leaveDefault(unaryNode);
817    }
818
819    /**
820     * Callback for entering a {@link JoinPredecessorExpression}.
821     *
822     * @param  expr the join predecessor expression
823     * @return true if traversal should continue and node children be traversed, false otherwise
824     */
825    public boolean enterJoinPredecessorExpression(final JoinPredecessorExpression expr) {
826        return enterDefault(expr);
827    }
828
829    /**
830     * Callback for leaving a {@link JoinPredecessorExpression}.
831     *
832     * @param  expr the join predecessor expression
833     * @return processed node, which will replace the original one, or the original node
834     */
835    public Node leaveJoinPredecessorExpression(final JoinPredecessorExpression expr) {
836        return leaveDefault(expr);
837    }
838
839
840    /**
841     * Callback for entering a VarNode
842     *
843     * @param  varNode   the node
844     * @return true if traversal should continue and node children be traversed, false otherwise
845     */
846    public boolean enterVarNode(final VarNode varNode) {
847        return enterDefault(varNode);
848    }
849
850    /**
851     * Callback for leaving a VarNode
852     *
853     * @param  varNode the node
854     * @return processed node, which will replace the original one, or the original node
855     */
856    public Node leaveVarNode(final VarNode varNode) {
857        return leaveDefault(varNode);
858    }
859
860    /**
861     * Callback for entering a WhileNode
862     *
863     * @param  whileNode the node
864     * @return true if traversal should continue and node children be traversed, false otherwise
865     */
866    public boolean enterWhileNode(final WhileNode whileNode) {
867        return enterDefault(whileNode);
868    }
869
870    /**
871     * Callback for leaving a WhileNode
872     *
873     * @param  whileNode the node
874     * @return processed node, which will replace the original one, or the original node
875     */
876    public Node leaveWhileNode(final WhileNode whileNode) {
877        return leaveDefault(whileNode);
878    }
879
880    /**
881     * Callback for entering a WithNode
882     *
883     * @param  withNode  the node
884     * @return true if traversal should continue and node children be traversed, false otherwise
885     */
886    public boolean enterWithNode(final WithNode withNode) {
887        return enterDefault(withNode);
888    }
889
890    /**
891     * Callback for leaving a WithNode
892     *
893     * @param  withNode  the node
894     * @return processed node, which will replace the original one, or the original node
895     */
896    public Node leaveWithNode(final WithNode withNode) {
897        return leaveDefault(withNode);
898    }
899
900
901}
902