/* * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package jdk.nashorn.internal.parser; import java.util.HashSet; import java.util.List; import jdk.nashorn.internal.codegen.Namespace; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.IdentNode; import jdk.nashorn.internal.ir.Module; /** * ParserContextNode that represents a function that is currently being parsed */ class ParserContextFunctionNode extends ParserContextBaseNode { /** Function name */ private final String name; /** Function identifier node */ private final IdentNode ident; /** Name space for function */ private final Namespace namespace; /** Line number for function declaration */ private final int line; /** Function node kind, see {@link FunctionNode.Kind} */ private final FunctionNode.Kind kind; /** List of parameter identifiers for function */ private List parameters; /** Token for function start */ private final long token; /** Last function token */ private long lastToken; /** Opaque node for parser end state, see {@link Parser} */ private Object endParserState; private HashSet parameterBoundNames; private IdentNode duplicateParameterBinding; private boolean simpleParameterList = true; private Module module; private int debugFlags; /** * @param token The token for the function * @param ident External function name * @param name Internal name of the function * @param namespace Function's namespace * @param line The source line of the function * @param kind Function kind * @param parameters The parameters of the function */ public ParserContextFunctionNode(final long token, final IdentNode ident, final String name, final Namespace namespace, final int line, final FunctionNode.Kind kind, final List parameters) { this.ident = ident; this.namespace = namespace; this.line = line; this.kind = kind; this.name = name; this.parameters = parameters; this.token = token; } /** * @return Internal name of the function */ public String getName() { return name; } /** * @return The external identifier for the function */ public IdentNode getIdent() { return ident; } /** * * @return true if function is the program function */ public boolean isProgram() { return getFlag(FunctionNode.IS_PROGRAM) != 0; } /** * @return if function in strict mode */ public boolean isStrict() { return getFlag(FunctionNode.IS_STRICT) != 0; } /** * @return true if the function has nested evals */ public boolean hasNestedEval() { return getFlag(FunctionNode.HAS_NESTED_EVAL) != 0; } /** * Returns true if any of the blocks in this function create their own scope. * @return true if any of the blocks in this function create their own scope. */ public boolean hasScopeBlock() { return getFlag(FunctionNode.HAS_SCOPE_BLOCK) != 0; } /** * Create a unique name in the namespace of this FunctionNode * @param base prefix for name * @return base if no collision exists, otherwise a name prefix with base */ public String uniqueName(final String base) { return namespace.uniqueName(base); } /** * @return line number of the function */ public int getLineNumber() { return line; } /** * @return The kind if function */ public FunctionNode.Kind getKind() { return kind; } /** * Get parameters * @return The parameters of the function */ public List getParameters() { return parameters; } void setParameters(List parameters) { this.parameters = parameters; } /** * Set last token * @param token New last token */ public void setLastToken(final long token) { this.lastToken = token; } /** * @return lastToken Function's last token */ public long getLastToken() { return lastToken; } /** * Returns the ParserState of when the parsing of this function was ended * @return endParserState The end parser state */ public Object getEndParserState() { return endParserState; } /** * Sets the ParserState of when the parsing of this function was ended * @param endParserState The end parser state */ public void setEndParserState(final Object endParserState) { this.endParserState = endParserState; } /** * Returns the if of this function * @return The function id */ public int getId() { return isProgram() ? -1 : Token.descPosition(token); } /** * Returns the debug flags for this function. * * @return the debug flags */ int getDebugFlags() { return debugFlags; } /** * Sets a debug flag for this function. * * @param debugFlag the debug flag */ void setDebugFlag(final int debugFlag) { debugFlags |= debugFlag; } public boolean isMethod() { return getFlag(FunctionNode.ES6_IS_METHOD) != 0; } public boolean isClassConstructor() { return getFlag(FunctionNode.ES6_IS_CLASS_CONSTRUCTOR) != 0; } public boolean isSubclassConstructor() { return getFlag(FunctionNode.ES6_IS_SUBCLASS_CONSTRUCTOR) != 0; } boolean addParameterBinding(final IdentNode bindingIdentifier) { if (Parser.isArguments(bindingIdentifier)) { setFlag(FunctionNode.DEFINES_ARGUMENTS); } if (parameterBoundNames == null) { parameterBoundNames = new HashSet<>(); } if (parameterBoundNames.add(bindingIdentifier.getName())) { return true; } else { duplicateParameterBinding = bindingIdentifier; return false; } } public IdentNode getDuplicateParameterBinding() { return duplicateParameterBinding; } public boolean isSimpleParameterList() { return simpleParameterList; } public void setSimpleParameterList(final boolean simpleParameterList) { this.simpleParameterList = simpleParameterList; } public Module getModule() { return module; } public void setModule(final Module module) { this.module = module; } }