1 /*
   2  * Copyright (c) 2015, 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.internal.ir;
  27 
  28 import java.util.Collections;
  29 import java.util.List;
  30 
  31 import jdk.nashorn.internal.codegen.types.Type;
  32 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
  33 
  34 /**
  35  * IR representation for class definitions.
  36  */
  37 public class ClassNode extends Expression {
  38     private static final long serialVersionUID = 1L;
  39 
  40     private final IdentNode ident;
  41     private final Expression classHeritage;
  42     private final PropertyNode constructor;
  43     private final List<PropertyNode> classElements;
  44     private final int line;
  45     private final boolean isStatement;
  46 
  47     /**
  48      * Constructor.
  49      *
  50      * @param line line number
  51      * @param token token
  52      * @param finish finish
  53      * @param ident ident
  54      * @param classHeritage class heritage
  55      * @param constructor constructor
  56      * @param classElements class elements
  57      * @param isStatement is this a statement or an expression?
  58      */
  59     public ClassNode(final int line, final long token, final int finish, final IdentNode ident, final Expression classHeritage, final PropertyNode constructor,
  60                      final List<PropertyNode> classElements, final boolean isStatement) {
  61         super(token, finish);
  62         this.line = line;
  63         this.ident = ident;
  64         this.classHeritage = classHeritage;
  65         this.constructor = constructor;
  66         this.classElements = classElements;
  67         this.isStatement = isStatement;
  68     }
  69 
  70     /**
  71      * Class identifier. Optional.
  72      *
  73      * @return the class identifier
  74      */
  75     public IdentNode getIdent() {
  76         return ident;
  77     }
  78 
  79     /**
  80      * The expression of the {@code extends} clause. Optional.
  81      *
  82      * @return the class heritage
  83      */
  84     public Expression getClassHeritage() {
  85         return classHeritage;
  86     }
  87 
  88     /**
  89      * Get the constructor method definition.
  90      *
  91      * @return the constructor
  92      */
  93     public PropertyNode getConstructor() {
  94         return constructor;
  95     }
  96 
  97     /**
  98      * Get method definitions except the constructor.
  99      *
 100      * @return the class elements
 101      */
 102     public List<PropertyNode> getClassElements() {
 103         return Collections.unmodifiableList(classElements);
 104     }
 105 
 106     /**
 107      * Returns if this class was a statement or an expression
 108      *
 109      * @return true if this class was a statement
 110      */
 111     public boolean isStatement() {
 112         return isStatement;
 113     }
 114 
 115     /**
 116      * Returns the line number.
 117      *
 118      * @return the line number
 119      */
 120     public int getLineNumber() {
 121         return line;
 122     }
 123 
 124     @Override
 125     public Type getType() {
 126         return Type.OBJECT;
 127     }
 128 
 129     @Override
 130     public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
 131         if (visitor.enterClassNode(this)) {
 132             return visitor.leaveClassNode(this);
 133         }
 134 
 135         return this;
 136     }
 137 
 138     @Override
 139     public void toString(final StringBuilder sb, final boolean printType) {
 140         sb.append("class");
 141         if (ident != null) {
 142             sb.append(' ');
 143             ident.toString(sb, printType);
 144         }
 145         if (classHeritage != null) {
 146             sb.append(" extends");
 147             classHeritage.toString(sb, printType);
 148         }
 149         sb.append(" {");
 150         if (constructor != null) {
 151             constructor.toString(sb, printType);
 152         }
 153         for (final PropertyNode classElement : classElements) {
 154             sb.append(" ");
 155             classElement.toString(sb, printType);
 156         }
 157         sb.append("}");
 158     }
 159 }