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