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