       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(final AssignmentTree node, final 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(final CompoundAssignmentTree node, final P r) {
      59         node.getVariable().accept(this, r);
      60         node.getExpression().accept(this, r);
      61         return null;
      62     }
      63
      64     /**
      65      * Visits a {@code ModuleTree} tree by calling {@code
      66      * visitUnknown}.
      67      *
      68      * @param node  {@inheritDoc}
      69      * @param p  {@inheritDoc}
      70      * @return the result of {@code visitUnknown}
      71      */
      72     @Override
      73     public R visitModule(final ModuleTree node, final P p) {
      74         return visitUnknown(node, p);
      75     }
      76
      77     /**
      78      * Visits an {@code ExportEntryTree} tree by calling {@code
      79      * visitUnknown}.
      80      *
      81      * @param node  {@inheritDoc}
      82      * @param p  {@inheritDoc}
      83      * @return the result of {@code visitUnknown}
      84      */
      85     @Override
      86     public R visitExportEntry(final ExportEntryTree node, final P p) {
      87         return visitUnknown(node, p);
      88     }
      89
      90     /**
      91      * Visits an {@code ImportEntryTree} tree by calling {@code
      92      * visitUnknown}.
      93      *
      94      * @param node  {@inheritDoc}
      95      * @param p  {@inheritDoc}
      96      * @return the result of {@code visitUnknown}
      97      */
      98     @Override
      99     public R visitImportEntry(final ImportEntryTree node, final P p) {
     100         return visitUnknown(node, p);
     101     }
     102
     103     @Override
     104     public R visitBinary(final BinaryTree node, final P r) {
     105         node.getLeftOperand().accept(this, r);
     106         node.getRightOperand().accept(this, r);
     107         return null;
     108     }
     109
     110     @Override
     111     public R visitBlock(final BlockTree node, final P r) {
     112         node.getStatements().forEach((tree) -> {
     113             tree.accept(this, r);
     114         });
     115         return null;
     116     }
     117
     118     @Override
     119     public R visitBreak(final BreakTree node, final P r) {
     120         return null;
     121     }
     122
     123     @Override
     124     public R visitCase(final CaseTree node, final P r) {
     125         final Tree caseVal = node.getExpression();
     126         if (caseVal != null) {
     127             caseVal.accept(this, r);
     128         }
     129
     130         node.getStatements().forEach((tree) -> {
     131             tree.accept(this, r);
     132         });
     133         return null;
     134     }
     135
     136     @Override
     137     public R visitCatch(final CatchTree node, final P r) {
     138         final Tree cond = node.getCondition();
     139         if (cond != null) {
     140             cond.accept(this, r);
     141         }
     142         node.getParameter().accept(this, r);
     143         node.getBlock().accept(this, r);
     144         return null;
     145     }
     146
     147     /**
     148      * Visits a {@code ClassDeclarationTree} tree by calling {@code
     149      * visitUnknown}.
     150      *
     151      * @param node  {@inheritDoc}
     152      * @param p  {@inheritDoc}
     153      * @return the result of {@code visitUnknown}
     154      */
     155     @Override
     156     public R visitClassDeclaration(final ClassDeclarationTree node, final P p) {
     157         return visitUnknown(node, p);
     158     }
     159
     160     /**
     161      * Visits a {@code ClassExpressionTree} tree by calling {@code
     162      * visitUnknown}.
     163      *
     164      * @param node  {@inheritDoc}
     165      * @param p  {@inheritDoc}
     166      * @return the result of {@code visitUnknown}
     167      */
     168     @Override
     169     public R visitClassExpression(final ClassExpressionTree node, final P p) {
     170         return visitUnknown(node, p);
     171     }
     172
     173     @Override
     174     public R visitConditionalExpression(final ConditionalExpressionTree node, final P r) {
     175         node.getCondition().accept(this, r);
     176         node.getTrueExpression().accept(this, r);
     177         node.getFalseExpression().accept(this, r);
     178         return null;
     179     }
     180
     181     @Override
     182     public R visitContinue(final ContinueTree node, final P r) {
     183         return null;
     184     }
     185
     186     @Override
     187     public R visitDebugger(final DebuggerTree node, final P r) {
     188         return null;
     189     }
     190
     191     @Override
     192     public R visitDoWhileLoop(final DoWhileLoopTree node, final P r) {
     193         node.getStatement().accept(this, r);
     194         node.getCondition().accept(this, r);
     195         return null;
     196     }
     197
     198     @Override
     199     public R visitErroneous(final ErroneousTree node, final P r) {
     200         return null;
     201     }
     202
     203     @Override
     204     public R visitExpressionStatement(final ExpressionStatementTree node, final P r) {
     205         node.getExpression().accept(this, r);
     206         return null;
     207     }
     208
     209     @Override
     210     public R visitForLoop(final ForLoopTree node, final P r) {
     211         final Tree init = node.getInitializer();
     212         if (init != null) {
     213             init.accept(this, r);
     214         }
     215
     216         final Tree cond = node.getCondition();
     217         if (cond != null) {
     218             cond.accept(this, r);
     219         }
     220
     221         final Tree update = node.getUpdate();
     222         if (update != null) {
     223             update.accept(this, r);
     224         }
     225
     226         node.getStatement().accept(this, r);
     227         return null;
     228     }
     229
     230     @Override
     231     public R visitForInLoop(final ForInLoopTree node, final P r) {
     232         node.getVariable().accept(this, r);
     233         node.getExpression().accept(this, r);
     234         final StatementTree stat = node.getStatement();
     235         if (stat != null) {
     236             stat.accept(this, r);
     237         }
     238         return null;
     239     }
     240
     241     /**
     242      * Visits a {@code ForOfLoopTree} tree by calling {@code
     243      * visitUnknown}.
     244      *
     245      * @param node  {@inheritDoc}
     246      * @param p  {@inheritDoc}
     247      * @return the result of {@code visitUnknown}
     248      */
     249     @Override
     250     public R visitForOfLoop(final ForOfLoopTree node, final P p) {
     251         return visitUnknown(node, p);
     252     }
     253
     254     @Override
     255     public R visitFunctionCall(final FunctionCallTree node, final P r) {
     256         node.getFunctionSelect().accept(this, r);
     257         node.getArguments().forEach((tree) -> {
     258             tree.accept(this, r);
     259         });
     260         return null;
     261     }
     262
     263     @Override
     264     public R visitFunctionDeclaration(final FunctionDeclarationTree node, final P r) {
     265         node.getParameters().forEach((tree) -> {
     266             tree.accept(this, r);
     267         });
     268         node.getBody().accept(this, r);
     269         return null;
     270     }
     271
     272     @Override
     273     public R visitFunctionExpression(final FunctionExpressionTree node, final P r) {
     274         node.getParameters().forEach((tree) -> {
     275             tree.accept(this, r);
     276         });
     277         node.getBody().accept(this, r);
     278         return null;
     279     }
     280
     281     @Override
     282     public R visitIdentifier(final IdentifierTree node, final P r) {
     283         return null;
     284     }
     285
     286     @Override
     287     public R visitIf(final IfTree node, final P r) {
     288         node.getCondition().accept(this, r);
     289         node.getThenStatement().accept(this, r);
     290         final Tree elseStat = node.getElseStatement();
     291         if (elseStat != null) {
     292             elseStat.accept(this, r);
     293         }
     294         return null;
     295     }
     296
     297     @Override
     298     public R visitArrayAccess(final ArrayAccessTree node, final P r) {
     299         node.getExpression().accept(this, r);
     300         node.getIndex().accept(this, r);
     301         return null;
     302     }
     303
     304     @Override
     305     public R visitArrayLiteral(final ArrayLiteralTree node, final P r) {
     306         node.getElements().stream().filter((tree) -> (tree != null)).forEach((tree) -> {
     307             tree.accept(this, r);
     308         });
     309         return null;
     310     }
     311
     312     @Override
     313     public R visitLabeledStatement(final LabeledStatementTree node, final P r) {
     314         node.getStatement().accept(this, r);
     315         return null;
     316     }
     317
     318     @Override
     319     public R visitLiteral(final LiteralTree node, final P r) {
     320         return null;
     321     }
     322
     323     @Override
     324     public R visitParenthesized(final ParenthesizedTree node, final P r) {
     325         node.getExpression().accept(this, r);
     326         return null;
     327     }
     328
     329     @Override
     330     public R visitReturn(final ReturnTree node, final P r) {
     331         final Tree retExpr = node.getExpression();
     332         if (retExpr != null) {
     333             retExpr.accept(this, r);
     334         }
     335         return null;
     336     }
     337
     338     @Override
     339     public R visitMemberSelect(final MemberSelectTree node, final P r) {
     340         node.getExpression().accept(this, r);
     341         return null;
     342     }
     343
     344     @Override
     345     public R visitNew(final NewTree node, final P r) {
     346         node.getConstructorExpression().accept(this, r);
     347         return null;
     348     }
     349
     350     @Override
     351     public R visitObjectLiteral(final ObjectLiteralTree node, final P r) {
     352         node.getProperties().forEach((tree) -> {
     353             tree.accept(this, r);
     354         });
     355         return null;
     356     }
     357
     358     @Override
     359     public R visitProperty(final PropertyTree node, final P r) {
     360         final FunctionExpressionTree getter = node.getGetter();
     361         if (getter != null) {
     362             getter.accept(this, r);
     363         }
     364         final ExpressionTree key = node.getKey();
     365         if (key != null) {
     366             key.accept(this, r);
     367         }
     368
     369         final FunctionExpressionTree setter = node.getSetter();
     370         if (setter != null) {
     371             setter.accept(this, r);
     372         }
     373
     374         final ExpressionTree value = node.getValue();
     375         if (value != null) {
     376             value.accept(this, r);
     377         }
     378         return null;
     379     }
     380
     381     @Override
     382     public R visitRegExpLiteral(final RegExpLiteralTree node, final P r) {
     383         return null;
     384     }
     385
     386     /**
     387      * Visits a {@code TemplateLiteralTree} tree by calling {@code
     388      * visitUnknown}.
     389      *
     390      * @param node  {@inheritDoc}
     391      * @param p  {@inheritDoc}
     392      * @return the result of {@code visitUnknown}
     393      */
     394     @Override
     395     public R visitTemplateLiteral(final TemplateLiteralTree node, final P p) {
     396         return visitUnknown(node, p);
     397     }
     398
     399     @Override
     400     public R visitEmptyStatement(final EmptyStatementTree node, final P r) {
     401         return null;
     402     }
     403
     404     /**
     405      * Visits a {@code SpreadTree} tree by calling {@code
     406      * visitUnknown}.
     407      *
     408      * @param node  {@inheritDoc}
     409      * @param p  {@inheritDoc}
     410      * @return the result of {@code visitUnknown}
     411      */
     412     @Override
     413     public R visitSpread(final SpreadTree node, final P p) {
     414         return visitUnknown(node, p);
     415     }
     416
     417     @Override
     418     public R visitSwitch(final SwitchTree node, final P r) {
     419         node.getExpression().accept(this, r);
     420         node.getCases().forEach((tree) -> {
     421             tree.accept(this, r);
     422         });
     423         return null;
     424     }
     425
     426     @Override
     427     public R visitThrow(final ThrowTree node, final P r) {
     428         node.getExpression().accept(this, r);
     429         return null;
     430     }
     431
     432     @Override
     433     public R visitCompilationUnit(final CompilationUnitTree node, final P r) {
     434         node.getSourceElements().forEach((tree) -> {
     435             tree.accept(this, r);
     436         });
     437         return null;
     438     }
     439
     440     @Override
     441     public R visitTry(final TryTree node, final P r) {
     442         node.getBlock().accept(this, r);
     443         node.getCatches().forEach((tree) -> {
     444             tree.accept(this, r);
     445         });
     446
     447         final Tree finallyBlock = node.getFinallyBlock();
     448         if (finallyBlock != null) {
     449             finallyBlock.accept(this, r);
     450         }
     451         return null;
     452     }
     453
     454     @Override
     455     public R visitInstanceOf(final InstanceOfTree node, final P r) {
     456         node.getType().accept(this, r);
     457         node.getExpression().accept(this, r);
     458         return null;
     459     }
     460
     461     @Override
     462     public R visitUnary(final UnaryTree node, final P r) {
     463         node.getExpression().accept(this, r);
     464         return null;
     465     }
     466
     467     @Override
     468     public R visitVariable(final VariableTree node, final P r) {
     469         if (node.getInitializer() != null) {
     470             node.getInitializer().accept(this, r);
     471         }
     472         return null;
     473     }
     474
     475     @Override
     476     public R visitWhileLoop(final WhileLoopTree node, final P r) {
     477         node.getCondition().accept(this, r);
     478         node.getStatement().accept(this, r);
     479         return null;
     480     }
     481
     482     @Override
     483     public R visitWith(final WithTree node, final P r) {
     484         node.getScope().accept(this, r);
     485         node.getStatement().accept(this, r);
     486         return null;
     487     }
     488
     489     /**
     490      * Visits a {@code YieldTree} tree by calling {@code
     491      * visitUnknown}.
     492      *
     493      * @param node  {@inheritDoc}
     494      * @param p  {@inheritDoc}
     495      * @return the result of {@code visitUnknown}
     496      */
     497     @Override
     498     public R visitYield(final YieldTree node, final P p) {
     499         return visitUnknown(node, p);
     500     }
     501
     502     /**
     503      * {@inheritDoc}
     504      *
     505      * @implSpec The default implementation of this method in {@code
     506      * SimpleTreeVisitorES5_1} will always throw {@code
     507      * UnknownTypeException}. This behavior is not required of a
     508      * subclass.
     509      *
     510      * @param node  {@inheritDoc}
     511      * @param p  {@inheritDoc}
     512      * @return abnormal return by throwing exception always
     513      * @throws UnknownTreeException
     514      *  a visitor implementation may optionally throw this exception
     515      */
     516     @Override
     517     public R visitUnknown(final Tree node, final P p) {
     518         // unknown in ECMAScript 5.1 edition
     519         throw new UnknownTreeException(node, p);
     520     }
     521 }
    --- EOF ---