1 /*
   2  * Copyright (c) 2014, 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 package jdk.nashorn.internal.parser;
  26 
  27 import java.util.List;
  28 import jdk.nashorn.internal.codegen.Namespace;
  29 import jdk.nashorn.internal.ir.FunctionNode;
  30 import jdk.nashorn.internal.ir.IdentNode;
  31 
  32 /**
  33  * ParserContextNode that represents a function that is currently being parsed
  34  */
  35 class ParserContextFunctionNode extends ParserContextBaseNode {
  36 
  37     /** Function name */
  38     private final String name;
  39 
  40     /** Function identifier node */
  41     private final IdentNode ident;
  42 
  43     /** Name space for function */
  44     private final Namespace namespace;
  45 
  46     /** Line number for function declaration */
  47     private final int line;
  48 
  49     /** Function node kind, see {@link FunctionNode#Kind} */
  50     private final FunctionNode.Kind kind;
  51 
  52     /** List of parameter identifiers for function */
  53     private final List<IdentNode> parameters;
  54 
  55     /** Token for function start */
  56     private final long token;
  57 
  58     /** Last function token */
  59     private long lastToken;
  60 
  61     /** Opaque node for parser end state, see {@link Parser} */
  62     private Object endParserState;
  63 
  64     /**
  65      * @param token The token for the function
  66      * @param ident External function name
  67      * @param name  Internal name of the function
  68      * @param namespace Function's namespace
  69      * @param line  The source line of the function
  70      * @param kind  Function kind
  71      * @param parameters The parameters of the function
  72      */
  73     public ParserContextFunctionNode(final long token, final IdentNode ident, final String name, final Namespace namespace, final int line, final FunctionNode.Kind kind, final List<IdentNode> parameters) {
  74         this.ident      = ident;
  75         this.namespace  = namespace;
  76         this.line       = line;
  77         this.kind       = kind;
  78         this.name       = name;
  79         this.parameters = parameters;
  80         this.token      = token;
  81     }
  82 
  83     /**
  84      * @return Internal name of the function
  85      */
  86     public String getName() {
  87         return name;
  88     }
  89 
  90     /**
  91      * @return The external identifier for the function
  92      */
  93     public IdentNode getIdent() {
  94         return ident;
  95     }
  96 
  97     /**
  98      *
  99      * @return true if function is the program function
 100      */
 101     public boolean isProgram() {
 102         return getFlag(FunctionNode.IS_PROGRAM) != 0;
 103     }
 104 
 105     /**
 106      * @return if function in strict mode
 107      */
 108     public boolean isStrict() {
 109         return getFlag(FunctionNode.IS_STRICT) != 0;
 110     }
 111 
 112     /**
 113      * @return true if the function has nested evals
 114      */
 115     public boolean hasNestedEval() {
 116         return getFlag(FunctionNode.HAS_NESTED_EVAL) != 0;
 117     }
 118 
 119     /**
 120      * Returns true if any of the blocks in this function create their own scope.
 121      * @return true if any of the blocks in this function create their own scope.
 122      */
 123     public boolean hasScopeBlock() {
 124         return getFlag(FunctionNode.HAS_SCOPE_BLOCK) != 0;
 125     }
 126 
 127     /**
 128      * Create a unique name in the namespace of this FunctionNode
 129      * @param base prefix for name
 130      * @return base if no collision exists, otherwise a name prefix with base
 131      */
 132     public String uniqueName(final String base) {
 133         return namespace.uniqueName(base);
 134     }
 135 
 136     /**
 137      * @return line number of the function
 138      */
 139     public int getLineNumber() {
 140         return line;
 141     }
 142 
 143     /**
 144      * @return The kind if function
 145      */
 146     public FunctionNode.Kind getKind() {
 147         return kind;
 148     }
 149 
 150     /**
 151      * Get parameters
 152      * @return The parameters of the function
 153      */
 154     public List<IdentNode> getParameters() {
 155         return parameters;
 156     }
 157 
 158     /**
 159      * Set last token
 160      * @param token New last token
 161      */
 162     public void setLastToken(final long token) {
 163         this.lastToken = token;
 164 
 165     }
 166 
 167     /**
 168      * @return lastToken Function's last token
 169      */
 170     public long getLastToken() {
 171         return lastToken;
 172     }
 173 
 174     /**
 175      * Returns the ParserState of when the parsing of this function was ended
 176      * @return endParserState The end parser state
 177      */
 178     public Object getEndParserState() {
 179         return endParserState;
 180     }
 181 
 182     /**
 183      * Sets the ParserState of when the parsing of this function was ended
 184      * @param endParserState The end parser state
 185      */
 186     public void setEndParserState(final Object endParserState) {
 187         this.endParserState = endParserState;
 188     }
 189 
 190     /**
 191      * Returns the if of this function
 192      * @return The function id
 193      */
 194     public int getId() {
 195         return isProgram() ? -1 : Token.descPosition(token);
 196     }
 197 }