1 /*
   2  * Copyright (c) 2015, 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.api.tree;
  27 
  28 /**
  29  * A simple implementation of the TreeVisitor for ECMAScript edition 5.1.
  30  *
  31  * <p>The visit methods corresponding to ES 5.1 language constructs walk the
  32  * "components" of the given tree by calling accept method passing the
  33  * current visitor and the additional parameter.
  34  *
  35  * <p>For constructs introduced in later versions, {@code visitUnknown}
  36  * is called instead which throws {@link UnknownTreeException}.
  37  *
  38  * <p> Methods in this class may be overridden subject to their
  39  * general contract.  Note that annotating methods in concrete
  40  * subclasses with {@link java.lang.Override @Override} will help
  41  * ensure that methods are overridden as intended.
  42  *
  43  * @param <R> the return type of this visitor's methods.  Use {@link
  44  *            Void} for visitors that do not need to return results.
  45  * @param <P> the type of the additional parameter to this visitor's
  46  *            methods.  Use {@code Void} for visitors that do not need an
  47  *            additional parameter.
  48  */
  49 public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
  50     @Override
  51     public R visitAssignment(AssignmentTree node, P r) {
  52         node.getVariable().accept(this, r);
  53         node.getExpression().accept(this, r);
  54         return null;
  55     }
  56 
  57     @Override
  58     public R visitCompoundAssignment(CompoundAssignmentTree node, P r) {
  59         node.getVariable().accept(this, r);
  60         node.getExpression().accept(this, r);
  61         return null;
  62     }
  63 
  64     @Override
  65     public R visitBinary(BinaryTree node, P r) {
  66         node.getLeftOperand().accept(this, r);
  67         node.getRightOperand().accept(this, r);
  68         return null;
  69     }
  70 
  71     @Override
  72     public R visitBlock(BlockTree node, P r) {
  73         node.getStatements().stream().forEach((tree) -> {
  74             tree.accept(this, r);
  75         });
  76         return null;
  77     }
  78 
  79     @Override
  80     public R visitBreak(BreakTree node, P r) {
  81         return null;
  82     }
  83 
  84     @Override
  85     public R visitCase(CaseTree node, P r) {
  86         final Tree caseVal = node.getExpression();
  87         if (caseVal != null) {
  88             caseVal.accept(this, r);
  89         }
  90 
  91         node.getStatements().stream().forEach((tree) -> {
  92             tree.accept(this, r);
  93         });
  94         return null;
  95     }
  96 
  97     @Override
  98     public R visitCatch(CatchTree node, P r) {
  99         final Tree cond = node.getCondition();
 100         if (cond != null) {
 101             cond.accept(this, r);
 102         }
 103         node.getParameter().accept(this, r);
 104         node.getBlock().accept(this, r);
 105         return null;
 106     }
 107 
 108     @Override
 109     public R visitConditionalExpression(ConditionalExpressionTree node, P r) {
 110         node.getCondition().accept(this, r);
 111         node.getTrueExpression().accept(this, r);
 112         node.getFalseExpression().accept(this, r);
 113         return null;
 114     }
 115 
 116     @Override
 117     public R visitContinue(ContinueTree node, P r) {
 118         return null;
 119     }
 120 
 121     @Override
 122     public R visitDebugger(DebuggerTree node, P r) {
 123         return null;
 124     }
 125 
 126     @Override
 127     public R visitDoWhileLoop(DoWhileLoopTree node, P r) {
 128         node.getStatement().accept(this, r);
 129         node.getCondition().accept(this, r);
 130         return null;
 131     }
 132 
 133     @Override
 134     public R visitErroneous(ErroneousTree node, P r) {
 135         return null;
 136     }
 137 
 138     @Override
 139     public R visitExpressionStatement(ExpressionStatementTree node, P r) {
 140         node.getExpression().accept(this, r);
 141         return null;
 142     }
 143 
 144     @Override
 145     public R visitForLoop(ForLoopTree node, P r) {
 146         final Tree init = node.getInitializer();
 147         if (init != null) {
 148             init.accept(this, r);
 149         }
 150 
 151         final Tree cond = node.getCondition();
 152         if (cond != null) {
 153             cond.accept(this, r);
 154         }
 155 
 156         final Tree update = node.getUpdate();
 157         if (update != null) {
 158             update.accept(this, r);
 159         }
 160 
 161         node.getStatement().accept(this, r);
 162         return null;
 163     }
 164 
 165     @Override
 166     public R visitForInLoop(ForInLoopTree node, P r) {
 167         node.getVariable().accept(this, r);
 168         node.getExpression().accept(this, r);
 169         node.getStatement().accept(this, r);
 170         return null;
 171     }
 172 
 173     @Override
 174     public R visitFunctionCall(FunctionCallTree node, P r) {
 175         node.getFunctionSelect().accept(this, r);
 176         node.getArguments().stream().forEach((tree) -> {
 177             tree.accept(this, r);
 178         });
 179         return null;
 180     }
 181 
 182     @Override
 183     public R visitFunctionDeclaration(FunctionDeclarationTree node, P r) {
 184         node.getParameters().stream().forEach((tree) -> {
 185             tree.accept(this, r);
 186         });
 187         node.getBody().accept(this, r);
 188         return null;
 189     }
 190 
 191     @Override
 192     public R visitFunctionExpression(FunctionExpressionTree node, P r) {
 193         node.getParameters().stream().forEach((tree) -> {
 194             tree.accept(this, r);
 195         });
 196         node.getBody().accept(this, r);
 197         return null;
 198     }
 199 
 200     @Override
 201     public R visitIdentifier(IdentifierTree node, P r) {
 202         return null;
 203     }
 204 
 205     @Override
 206     public R visitIf(IfTree node, P r) {
 207         node.getCondition().accept(this, r);
 208         node.getThenStatement().accept(this, r);
 209         final Tree elseStat = node.getElseStatement();
 210         if (elseStat != null) {
 211             elseStat.accept(this, r);
 212         }
 213         return null;
 214     }
 215 
 216     @Override
 217     public R visitArrayAccess(ArrayAccessTree node, P r) {
 218         node.getExpression().accept(this, r);
 219         node.getIndex().accept(this, r);
 220         return null;
 221     }
 222 
 223     @Override
 224     public R visitArrayLiteral(ArrayLiteralTree node, P r) {
 225         node.getElements().stream().filter((tree) -> (tree != null)).forEach((tree) -> {
 226             tree.accept(this, r);
 227         });
 228         return null;
 229     }
 230 
 231     @Override
 232     public R visitLabeledStatement(LabeledStatementTree node, P r) {
 233         node.getStatement().accept(this, r);
 234         return null;
 235     }
 236 
 237     @Override
 238     public R visitLiteral(LiteralTree node, P r) {
 239         return null;
 240     }
 241 
 242     @Override
 243     public R visitParenthesized(ParenthesizedTree node, P r) {
 244         node.getExpression().accept(this, r);
 245         return null;
 246     }
 247 
 248     @Override
 249     public R visitReturn(ReturnTree node, P r) {
 250         final Tree retExpr = node.getExpression();
 251         if (retExpr != null) {
 252             retExpr.accept(this, r);
 253         }
 254         return null;
 255     }
 256 
 257     @Override
 258     public R visitMemberSelect(MemberSelectTree node, P r) {
 259         node.getExpression().accept(this, r);
 260         return null;
 261     }
 262 
 263     @Override
 264     public R visitNew(NewTree node, P r) {
 265         node.getConstructorExpression().accept(this, r);
 266         return null;
 267     }
 268 
 269     @Override
 270     public R visitObjectLiteral(ObjectLiteralTree node, P r) {
 271         node.getProperties().stream().forEach((tree) -> {
 272             tree.accept(this, r);
 273         });
 274         return null;
 275     }
 276 
 277     @Override
 278     public R visitProperty(PropertyTree node, P r) {
 279         FunctionExpressionTree getter = node.getGetter();
 280         if (getter != null) {
 281             getter.accept(this, r);
 282         }
 283         ExpressionTree key = node.getKey();
 284         if (key != null) {
 285             key.accept(this, r);
 286         }
 287 
 288         FunctionExpressionTree setter = node.getSetter();
 289         if (setter != null) {
 290             setter.accept(this, r);
 291         }
 292 
 293         ExpressionTree value = node.getValue();
 294         if (value != null) {
 295             value.accept(this, r);
 296         }
 297         return null;
 298     }
 299 
 300     @Override
 301     public R visitRegExpLiteral(RegExpLiteralTree node, P r) {
 302         return null;
 303     }
 304 
 305     @Override
 306     public R visitEmptyStatement(EmptyStatementTree node, P r) {
 307         return null;
 308     }
 309 
 310     @Override
 311     public R visitSwitch(SwitchTree node, P r) {
 312         node.getExpression().accept(this, r);
 313         node.getCases().stream().forEach((tree) -> {
 314             tree.accept(this, r);
 315         });
 316         return null;
 317     }
 318 
 319     @Override
 320     public R visitThrow(ThrowTree node, P r) {
 321         node.getExpression().accept(this, r);
 322         return null;
 323     }
 324 
 325     @Override
 326     public R visitCompilationUnit(CompilationUnitTree node, P r) {
 327         node.getSourceElements().stream().forEach((tree) -> {
 328             tree.accept(this, r);
 329         });
 330         return null;
 331     }
 332 
 333     @Override
 334     public R visitTry(TryTree node, P r) {
 335         node.getBlock().accept(this, r);
 336         node.getCatches().stream().forEach((tree) -> {
 337             tree.accept(this, r);
 338         });
 339 
 340         final Tree finallyBlock = node.getFinallyBlock();
 341         if (finallyBlock != null) {
 342             finallyBlock.accept(this, r);
 343         }
 344         return null;
 345     }
 346 
 347     @Override
 348     public R visitInstanceOf(InstanceOfTree node, P r) {
 349         node.getType().accept(this, r);
 350         node.getExpression().accept(this, r);
 351         return null;
 352     }
 353 
 354     @Override
 355     public R visitUnary(UnaryTree node, P r) {
 356         node.getExpression().accept(this, r);
 357         return null;
 358     }
 359 
 360     @Override
 361     public R visitVariable(VariableTree node, P r) {
 362         if (node.getInitializer() != null) {
 363             node.getInitializer().accept(this, r);
 364         }
 365         return null;
 366     }
 367 
 368     @Override
 369     public R visitWhileLoop(WhileLoopTree node, P r) {
 370         node.getCondition().accept(this, r);
 371         node.getStatement().accept(this, r);
 372         return null;
 373     }
 374 
 375     @Override
 376     public R visitWith(WithTree node, P r) {
 377         node.getScope().accept(this, r);
 378         node.getStatement().accept(this, r);
 379         return null;
 380     }
 381 
 382     @Override
 383     public R visitUnknown(Tree node, P r) {
 384         // unknown in ECMAScript 5.1 edition
 385         throw new UnknownTreeException(node, r);
 386     }
 387 }