1 /*
   2  * Copyright (c) 2016, 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 import java.util.List;
  29 
  30 /**
  31  * A simple implementation of the TreeVisitor for ECMAScript edition 6.
  32  *
  33  * <p>The visit methods corresponding to ES 6 language constructs walk the
  34  * "components" of the given tree by calling accept method passing the
  35  * current visitor and the additional parameter.
  36  *
  37  * <p>For constructs introduced in later versions, {@code visitUnknown}
  38  * is called instead which throws {@link UnknownTreeException}.
  39  *
  40  * <p> Methods in this class may be overridden subject to their
  41  * general contract.  Note that annotating methods in concrete
  42  * subclasses with {@link java.lang.Override @Override} will help
  43  * ensure that methods are overridden as intended.
  44  *
  45  * @param <R> the return type of this visitor's methods.  Use {@link
  46  *            Void} for visitors that do not need to return results.
  47  * @param <P> the type of the additional parameter to this visitor's
  48  *            methods.  Use {@code Void} for visitors that do not need an
  49  *            additional parameter.
  50  */
  51 public class SimpleTreeVisitorES6<R, P> extends SimpleTreeVisitorES5_1<R, P> {
  52     @Override
  53     public R visitCompilationUnit(final CompilationUnitTree node, final P r) {
  54         final ModuleTree mod = node.getModule();
  55         if (mod != null) {
  56             mod.accept(this, r);
  57         }
  58         return super.visitCompilationUnit(node, r);
  59     }
  60 
  61     /**
  62      * Visit Module tree.
  63      *
  64      * @param node node being visited
  65      * @param p extra parameter passed to the visitor
  66      * @return value from the visitor
  67      */
  68     @Override
  69     public R visitModule(final ModuleTree node, final P p) {
  70         node.getImportEntries().forEach(e -> visitImportEntry(e, p));
  71         node.getLocalExportEntries().forEach(e -> visitExportEntry(e, p));
  72         node.getIndirectExportEntries().forEach(e -> visitExportEntry(e, p));
  73         node.getStarExportEntries().forEach(e -> visitExportEntry(e, p));
  74         return null;
  75     }
  76 
  77     /**
  78      * Visit Module ExportEntry tree.
  79      *
  80      * @param node node being visited
  81      * @param p extra parameter passed to the visitor
  82      * @return value from the visitor
  83      */
  84     @Override
  85     public R visitExportEntry(final ExportEntryTree node, final P p) {
  86         return null;
  87     }
  88 
  89     /**
  90      * Visit Module ImportEntry tree.
  91      *
  92      * @param node node being visited
  93      * @param p extra parameter passed to the visitor
  94      * @return value from the visitor
  95      */
  96     @Override
  97     public R visitImportEntry(final ImportEntryTree node, final P p) {
  98         return null;
  99     }
 100 
 101    /**
 102     * Visit class statement tree.
 103     *
 104     * @param node node being visited
 105     * @param p extra parameter passed to the visitor
 106     * @return value from the visitor
 107     */
 108     @Override
 109     public R visitClassDeclaration(final ClassDeclarationTree node, final P p) {
 110         node.getName().accept(this, p);
 111         final ExpressionTree heritage = node.getClassHeritage();
 112         if (heritage != null) {
 113             heritage.accept(this, p);
 114         }
 115         final PropertyTree constructor = node.getConstructor();
 116         if (constructor != null) {
 117             constructor.accept(this, p);
 118         }
 119         final List<? extends PropertyTree> elements = node.getClassElements();
 120         if (elements != null) {
 121             for (final PropertyTree prop : elements) {
 122                 prop.accept(this, p);
 123             }
 124         }
 125 
 126         return null;
 127     }
 128 
 129     /**
 130      * Visit class expression tree.
 131      *
 132      * @param node node being visited
 133      * @param p extra parameter passed to the visitor
 134      * @return value from the visitor
 135      */
 136     @Override
 137     public R visitClassExpression(final ClassExpressionTree node, final P p) {
 138         node.getName().accept(this, p);
 139         final ExpressionTree heritage = node.getClassHeritage();
 140         if (heritage != null) {
 141             heritage.accept(this, p);
 142         }
 143         final PropertyTree constructor = node.getConstructor();
 144         if (constructor != null) {
 145             constructor.accept(this, p);
 146         }
 147         final List<? extends PropertyTree> elements = node.getClassElements();
 148         if (elements != null) {
 149             for (final PropertyTree prop : elements) {
 150                 prop.accept(this, p);
 151             }
 152         }
 153 
 154         return null;
 155     }
 156 
 157     /**
 158      * Visit for..of statement tree.
 159      *
 160      * @param node node being visited
 161      * @param p extra parameter passed to the visitor
 162      * @return value from the visitor
 163      */
 164     @Override
 165     public R visitForOfLoop(final ForOfLoopTree node, final P p) {
 166         node.getVariable().accept(this, p);
 167         node.getExpression().accept(this, p);
 168         final StatementTree stat = node.getStatement();
 169         if (stat != null) {
 170             stat.accept(this, p);
 171         }
 172         return null;
 173     }
 174 
 175     /**
 176      * Visit 'yield' expression tree.
 177      *
 178      * @param node node being visited
 179      * @param p extra parameter passed to the visitor
 180      * @return value from the visitor
 181      */
 182     @Override
 183     public R visitYield(final YieldTree node, final P p) {
 184         node.getExpression().accept(this, p);
 185         return null;
 186     }
 187 
 188     /**
 189      * Visit 'spread' expression tree.
 190      *
 191      * @param node node being visited
 192      * @param p extra parameter passed to the visitor
 193      * @return value from the visitor
 194      */
 195     @Override
 196     public R visitSpread(final SpreadTree node, final P p) {
 197         node.getExpression().accept(this, p);
 198         return null;
 199     }
 200 
 201    /**
 202     * Visit template literal tree.
 203     *
 204     * @param node node being visited
 205     * @param p extra parameter passed to the visitor
 206     * @return value from the visitor
 207     */
 208     @Override
 209     public R visitTemplateLiteral(final TemplateLiteralTree node, final P p) {
 210         final List<? extends ExpressionTree> expressions = node.getExpressions();
 211         for (final ExpressionTree expr : expressions) {
 212             expr.accept(this, p);
 213         }
 214         return null;
 215     }
 216 
 217     @Override
 218     public R visitVariable(final VariableTree node, final P r) {
 219         final ExpressionTree expr = node.getBinding();
 220         if (expr != null) {
 221             expr.accept(this, r);
 222         }
 223         super.visitVariable(node, r);
 224         return null;
 225     }
 226 }