Merge
This commit is contained in:
commit
b66d02e59c
@ -4310,7 +4310,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
* @param ident identifier for block or function where applicable
|
||||
*/
|
||||
private void printSymbols(final Block block, final FunctionNode function, final String ident) {
|
||||
if (compiler.getScriptEnvironment()._print_symbols || function.getFlag(FunctionNode.IS_PRINT_SYMBOLS)) {
|
||||
if (compiler.getScriptEnvironment()._print_symbols || function.getDebugFlag(FunctionNode.DEBUG_PRINT_SYMBOLS)) {
|
||||
final PrintWriter out = compiler.getScriptEnvironment().getErr();
|
||||
out.println("[BLOCK in '" + ident + "']");
|
||||
if (!block.printSymbols(out)) {
|
||||
|
@ -278,12 +278,12 @@ abstract class CompilationPhase {
|
||||
final PrintWriter err = senv.getErr();
|
||||
|
||||
//TODO separate phase for the debug printouts for abstraction and clarity
|
||||
if (senv._print_lower_ast || fn.getFlag(FunctionNode.IS_PRINT_LOWER_AST)) {
|
||||
if (senv._print_lower_ast || fn.getDebugFlag(FunctionNode.DEBUG_PRINT_LOWER_AST)) {
|
||||
err.println("Lower AST for: " + quote(newFunctionNode.getName()));
|
||||
err.println(new ASTWriter(newFunctionNode));
|
||||
}
|
||||
|
||||
if (senv._print_lower_parse || fn.getFlag(FunctionNode.IS_PRINT_LOWER_PARSE)) {
|
||||
if (senv._print_lower_parse || fn.getDebugFlag(FunctionNode.DEBUG_PRINT_LOWER_PARSE)) {
|
||||
err.println("Lower AST for: " + quote(newFunctionNode.getName()));
|
||||
err.println(new PrintVisitor(newFunctionNode));
|
||||
}
|
||||
|
@ -175,7 +175,9 @@ final class SplitIntoFunctions extends NodeVisitor<BlockLexicalContext> {
|
||||
// we still use IS_SPLIT as the criteria in CompilationPhase.SERIALIZE_SPLIT_PHASE.
|
||||
FunctionNode.IS_ANONYMOUS | FunctionNode.USES_ANCESTOR_SCOPE | FunctionNode.IS_SPLIT,
|
||||
body,
|
||||
null
|
||||
null,
|
||||
originalFn.getModule(),
|
||||
originalFn.getDebugFlags()
|
||||
)
|
||||
.setCompileUnit(lc, splitNode.getCompileUnit());
|
||||
|
||||
|
@ -435,7 +435,7 @@ final class WeighNodes extends NodeOperatorVisitor<LexicalContext> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node leaveBIND(final BinaryNode binaryNode) {
|
||||
public Node leaveARROW(final BinaryNode binaryNode) {
|
||||
return binaryNodeWeight(binaryNode);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2016, 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
|
||||
@ -48,12 +48,13 @@ public final class AccessNode extends BaseNode {
|
||||
* @param property property
|
||||
*/
|
||||
public AccessNode(final long token, final int finish, final Expression base, final String property) {
|
||||
super(token, finish, base, false);
|
||||
super(token, finish, base, false, false);
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
private AccessNode(final AccessNode accessNode, final Expression base, final String property, final boolean isFunction, final Type type, final int id) {
|
||||
super(accessNode, base, isFunction, type, id);
|
||||
private AccessNode(final AccessNode accessNode, final Expression base, final String property, final boolean isFunction,
|
||||
final Type type, final int id, final boolean isSuper) {
|
||||
super(accessNode, base, isFunction, type, id, isSuper);
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
@ -105,7 +106,7 @@ public final class AccessNode extends BaseNode {
|
||||
if (this.base == base) {
|
||||
return this;
|
||||
}
|
||||
return new AccessNode(this, base, property, isFunction(), type, programPoint);
|
||||
return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -113,7 +114,7 @@ public final class AccessNode extends BaseNode {
|
||||
if (this.type == type) {
|
||||
return this;
|
||||
}
|
||||
return new AccessNode(this, base, property, isFunction(), type, programPoint);
|
||||
return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -121,7 +122,7 @@ public final class AccessNode extends BaseNode {
|
||||
if (this.programPoint == programPoint) {
|
||||
return this;
|
||||
}
|
||||
return new AccessNode(this, base, property, isFunction(), type, programPoint);
|
||||
return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -129,6 +130,14 @@ public final class AccessNode extends BaseNode {
|
||||
if (isFunction()) {
|
||||
return this;
|
||||
}
|
||||
return new AccessNode(this, base, property, true, type, programPoint);
|
||||
return new AccessNode(this, base, property, true, type, programPoint, isSuper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessNode setIsSuper() {
|
||||
if (isSuper()) {
|
||||
return this;
|
||||
}
|
||||
return new AccessNode(this, base, property, isFunction(), type, programPoint, true);
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,9 @@ public abstract class BaseNode extends Expression implements FunctionCall, Optim
|
||||
/** Program point id */
|
||||
protected final int programPoint;
|
||||
|
||||
/** Super property access. */
|
||||
private final boolean isSuper;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -59,13 +62,15 @@ public abstract class BaseNode extends Expression implements FunctionCall, Optim
|
||||
* @param finish finish
|
||||
* @param base base node
|
||||
* @param isFunction is this a function
|
||||
* @param isSuper is this a super property access
|
||||
*/
|
||||
public BaseNode(final long token, final int finish, final Expression base, final boolean isFunction) {
|
||||
public BaseNode(final long token, final int finish, final Expression base, final boolean isFunction, final boolean isSuper) {
|
||||
super(token, base.getStart(), finish);
|
||||
this.base = base;
|
||||
this.isFunction = isFunction;
|
||||
this.type = null;
|
||||
this.programPoint = INVALID_PROGRAM_POINT;
|
||||
this.isSuper = isSuper;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,13 +80,15 @@ public abstract class BaseNode extends Expression implements FunctionCall, Optim
|
||||
* @param isFunction is this a function
|
||||
* @param callSiteType the callsite type for this base node, either optimistic or conservative
|
||||
* @param programPoint program point id
|
||||
* @param isSuper is this a super property access
|
||||
*/
|
||||
protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction, final Type callSiteType, final int programPoint) {
|
||||
protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction, final Type callSiteType, final int programPoint, final boolean isSuper) {
|
||||
super(baseNode);
|
||||
this.base = base;
|
||||
this.isFunction = isFunction;
|
||||
this.type = callSiteType;
|
||||
this.programPoint = programPoint;
|
||||
this.isSuper = isSuper;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,4 +143,17 @@ public abstract class BaseNode extends Expression implements FunctionCall, Optim
|
||||
*/
|
||||
public abstract BaseNode setIsFunction();
|
||||
|
||||
/**
|
||||
* @return {@code true} if a SuperProperty access.
|
||||
*/
|
||||
public boolean isSuper() {
|
||||
return isSuper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this node as being a SuperProperty access.
|
||||
*
|
||||
* @return a base node identical to this one in all aspects except with its super flag set.
|
||||
*/
|
||||
public abstract BaseNode setIsSuper();
|
||||
}
|
||||
|
@ -65,24 +65,39 @@ public class Block extends Node implements BreakableNode, Terminal, Flags<Block>
|
||||
private final LocalVariableConversion conversion;
|
||||
|
||||
/** Flag indicating that this block needs scope */
|
||||
public static final int NEEDS_SCOPE = 1 << 0;
|
||||
public static final int NEEDS_SCOPE = 1 << 0;
|
||||
|
||||
/**
|
||||
* Is this block tagged as terminal based on its contents
|
||||
* (usually the last statement)
|
||||
*/
|
||||
public static final int IS_TERMINAL = 1 << 2;
|
||||
public static final int IS_TERMINAL = 1 << 2;
|
||||
|
||||
/**
|
||||
* Is this block the eager global scope - i.e. the original program. This isn't true for the
|
||||
* outermost level of recompiles
|
||||
*/
|
||||
public static final int IS_GLOBAL_SCOPE = 1 << 3;
|
||||
public static final int IS_GLOBAL_SCOPE = 1 << 3;
|
||||
|
||||
/**
|
||||
* Is this block a synthetic one introduced by Parser?
|
||||
*/
|
||||
public static final int IS_SYNTHETIC = 1 << 4;
|
||||
public static final int IS_SYNTHETIC = 1 << 4;
|
||||
|
||||
/**
|
||||
* Is this the function body block? May not be the first, if parameter list contains expressions.
|
||||
*/
|
||||
public static final int IS_BODY = 1 << 5;
|
||||
|
||||
/**
|
||||
* Is this the parameter initialization block? If present, must be the first block, immediately wrapping the function body block.
|
||||
*/
|
||||
public static final int IS_PARAMETER_BLOCK = 1 << 6;
|
||||
|
||||
/**
|
||||
* Marks the variable declaration block for case clauses of a switch statement.
|
||||
*/
|
||||
public static final int IS_SWITCH_BLOCK = 1 << 7;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -489,4 +504,31 @@ public class Block extends Node implements BreakableNode, Terminal, Flags<Block>
|
||||
public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
|
||||
return Acceptor.accept(this, visitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a function body.
|
||||
*
|
||||
* @return true if the function body flag is set
|
||||
*/
|
||||
public boolean isFunctionBody() {
|
||||
return getFlag(IS_BODY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a parameter block.
|
||||
*
|
||||
* @return true if the parameter block flag is set
|
||||
*/
|
||||
public boolean isParameterBlock() {
|
||||
return getFlag(IS_PARAMETER_BLOCK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this is a switch block.
|
||||
*
|
||||
* @return true if this is a switch block
|
||||
*/
|
||||
public boolean isSwitchBlock() {
|
||||
return getFlag(IS_SWITCH_BLOCK);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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.ir;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.nashorn.internal.codegen.types.Type;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||
|
||||
/**
|
||||
* IR representation for class definitions.
|
||||
*/
|
||||
public class ClassNode extends Expression {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final IdentNode ident;
|
||||
private final Expression classHeritage;
|
||||
private final PropertyNode constructor;
|
||||
private final List<PropertyNode> classElements;
|
||||
private final int line;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param line line number
|
||||
* @param token token
|
||||
* @param finish finish
|
||||
* @param ident ident
|
||||
* @param classHeritage class heritage
|
||||
* @param constructor constructor
|
||||
* @param classElements class elements
|
||||
*/
|
||||
public ClassNode(final int line, final long token, final int finish, final IdentNode ident, final Expression classHeritage, final PropertyNode constructor,
|
||||
final List<PropertyNode> classElements) {
|
||||
super(token, finish);
|
||||
this.line = line;
|
||||
this.ident = ident;
|
||||
this.classHeritage = classHeritage;
|
||||
this.constructor = constructor;
|
||||
this.classElements = classElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class identifier. Optional.
|
||||
*
|
||||
* @return the class identifier
|
||||
*/
|
||||
public IdentNode getIdent() {
|
||||
return ident;
|
||||
}
|
||||
|
||||
/**
|
||||
* The expression of the {@code extends} clause. Optional.
|
||||
*
|
||||
* @return the class heritage
|
||||
*/
|
||||
public Expression getClassHeritage() {
|
||||
return classHeritage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the constructor method definition.
|
||||
*
|
||||
* @return the constructor
|
||||
*/
|
||||
public PropertyNode getConstructor() {
|
||||
return constructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get method definitions except the constructor.
|
||||
*
|
||||
* @return the class elements
|
||||
*/
|
||||
public List<PropertyNode> getClassElements() {
|
||||
return Collections.unmodifiableList(classElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the line number.
|
||||
*
|
||||
* @return the line number
|
||||
*/
|
||||
public int getLineNumber() {
|
||||
return line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.OBJECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
|
||||
if (visitor.enterClassNode(this)) {
|
||||
return visitor.leaveClassNode(this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toString(final StringBuilder sb, final boolean printType) {
|
||||
sb.append("class");
|
||||
if (ident != null) {
|
||||
sb.append(' ');
|
||||
ident.toString(sb, printType);
|
||||
}
|
||||
if (classHeritage != null) {
|
||||
sb.append(" extends");
|
||||
classHeritage.toString(sb, printType);
|
||||
}
|
||||
sb.append(" {");
|
||||
if (constructor != null) {
|
||||
constructor.toString(sb, printType);
|
||||
}
|
||||
for (final PropertyNode classElement : classElements) {
|
||||
sb.append(" ");
|
||||
classElement.toString(sb, printType);
|
||||
}
|
||||
sb.append("}");
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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.ir;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.nashorn.internal.codegen.types.Type;
|
||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||
|
||||
/**
|
||||
* IR for CoverParenthesizedExpressionAndArrowParameterList, used only during parsing.
|
||||
*/
|
||||
public final class ExpressionList extends Expression {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final List<Expression> expressions;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param token token
|
||||
* @param finish finish
|
||||
* @param expressions expression
|
||||
*/
|
||||
public ExpressionList(final long token, final int finish, final List<Expression> expressions) {
|
||||
super(token, finish);
|
||||
this.expressions = expressions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of expressions.
|
||||
*
|
||||
* @return the list of expressions
|
||||
*/
|
||||
public List<Expression> getExpressions() {
|
||||
return Collections.unmodifiableList(expressions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toString(StringBuilder sb, boolean printType) {
|
||||
sb.append("(");
|
||||
boolean first = true;
|
||||
for (Expression expression : expressions) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
sb.append(", ");
|
||||
}
|
||||
expression.toString(sb, printType);
|
||||
}
|
||||
sb.append(")");
|
||||
}
|
||||
}
|
@ -90,7 +90,6 @@ public final class ForNode extends LoopNode {
|
||||
this.init = init;
|
||||
this.modify = modify;
|
||||
this.iterator = null;
|
||||
|
||||
}
|
||||
|
||||
private ForNode(final ForNode forNode, final Expression init, final JoinPredecessorExpression test,
|
||||
|
@ -69,7 +69,13 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
/** a getter, @see {@link UserAccessorProperty} */
|
||||
GETTER,
|
||||
/** a setter, @see {@link UserAccessorProperty} */
|
||||
SETTER
|
||||
SETTER,
|
||||
/** an arrow function */
|
||||
ARROW,
|
||||
/** a generator function */
|
||||
GENERATOR,
|
||||
/** a module function */
|
||||
MODULE
|
||||
}
|
||||
|
||||
/** Source of entity. */
|
||||
@ -122,6 +128,12 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
/** Root class for function */
|
||||
private final Class<?> rootClass;
|
||||
|
||||
/** The ES6 module */
|
||||
private final Module module;
|
||||
|
||||
/** The debug flags */
|
||||
private final int debugFlags;
|
||||
|
||||
/** Is anonymous function flag. */
|
||||
public static final int IS_ANONYMOUS = 1 << 0;
|
||||
|
||||
@ -172,49 +184,21 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
/**
|
||||
* Is this function the top-level program?
|
||||
*/
|
||||
public static final int IS_PROGRAM = 1 << 13;
|
||||
public static final int IS_PROGRAM = 1 << 13;
|
||||
|
||||
/**
|
||||
* Flag indicating whether this function uses the local variable symbol for itself. Only named function expressions
|
||||
* can have this flag set if they reference themselves (e.g. "(function f() { return f })". Declared functions will
|
||||
* use the symbol in their parent scope instead when they reference themselves by name.
|
||||
*/
|
||||
public static final int USES_SELF_SYMBOL = 1 << 14;
|
||||
public static final int USES_SELF_SYMBOL = 1 << 14;
|
||||
|
||||
/** Does this function use the "this" keyword? */
|
||||
public static final int USES_THIS = 1 << 15;
|
||||
public static final int USES_THIS = 1 << 15;
|
||||
|
||||
/** Is this declared in a dynamic context */
|
||||
public static final int IN_DYNAMIC_CONTEXT = 1 << 16;
|
||||
public static final int IN_DYNAMIC_CONTEXT = 1 << 16;
|
||||
|
||||
/**
|
||||
* The following flags are derived from directive comments within this function.
|
||||
* Note that even IS_STRICT is one such flag but that requires special handling.
|
||||
*/
|
||||
|
||||
/** parser, print parse tree */
|
||||
public static final int IS_PRINT_PARSE = 1 << 17;
|
||||
/** parser, print lower parse tree */
|
||||
public static final int IS_PRINT_LOWER_PARSE = 1 << 18;
|
||||
/** parser, print AST */
|
||||
public static final int IS_PRINT_AST = 1 << 19;
|
||||
/** parser, print lower AST */
|
||||
public static final int IS_PRINT_LOWER_AST = 1 << 20;
|
||||
/** parser, print symbols */
|
||||
public static final int IS_PRINT_SYMBOLS = 1 << 21;
|
||||
|
||||
// callsite tracing, profiling within this function
|
||||
/** profile callsites in this function? */
|
||||
public static final int IS_PROFILE = 1 << 22;
|
||||
|
||||
/** trace callsite enterexit in this function? */
|
||||
public static final int IS_TRACE_ENTEREXIT = 1 << 23;
|
||||
|
||||
/** trace callsite misses in this function? */
|
||||
public static final int IS_TRACE_MISSES = 1 << 24;
|
||||
|
||||
/** trace callsite values in this function? */
|
||||
public static final int IS_TRACE_VALUES = 1 << 25;
|
||||
|
||||
/**
|
||||
* Whether this function needs the callee {@link ScriptFunction} instance passed to its code as a
|
||||
@ -222,18 +206,41 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
* Rather, it is always calculated (see {@link #needsCallee()}). {@link RecompilableScriptFunctionData}
|
||||
* will, however, cache the value of this flag.
|
||||
*/
|
||||
public static final int NEEDS_CALLEE = 1 << 26;
|
||||
public static final int NEEDS_CALLEE = 1 << 17;
|
||||
|
||||
/**
|
||||
* Is the function node cached?
|
||||
*/
|
||||
public static final int IS_CACHED = 1 << 27;
|
||||
public static final int IS_CACHED = 1 << 18;
|
||||
|
||||
/** extension callsite flags mask */
|
||||
public static final int EXTENSION_CALLSITE_FLAGS = IS_PRINT_PARSE |
|
||||
IS_PRINT_LOWER_PARSE | IS_PRINT_AST | IS_PRINT_LOWER_AST |
|
||||
IS_PRINT_SYMBOLS | IS_PROFILE | IS_TRACE_ENTEREXIT |
|
||||
IS_TRACE_MISSES | IS_TRACE_VALUES;
|
||||
/**
|
||||
* Does this function contain a super call? (cf. ES6 14.3.5 Static Semantics: HasDirectSuper)
|
||||
*/
|
||||
public static final int ES6_HAS_DIRECT_SUPER = 1 << 19;
|
||||
|
||||
/**
|
||||
* Does this function use the super binding?
|
||||
*/
|
||||
public static final int ES6_USES_SUPER = 1 << 20;
|
||||
|
||||
/**
|
||||
* Is this function a (class or object) method?
|
||||
*/
|
||||
public static final int ES6_IS_METHOD = 1 << 21;
|
||||
|
||||
/**
|
||||
* Is this the constructor method?
|
||||
*/
|
||||
public static final int ES6_IS_CLASS_CONSTRUCTOR = 1 << 22;
|
||||
|
||||
/** Is this the constructor of a subclass (i.e., a class with an extends declaration)? */
|
||||
public static final int ES6_IS_SUBCLASS_CONSTRUCTOR = 1 << 23;
|
||||
|
||||
/** is this a strong mode function? */
|
||||
public static final int ES6_IS_STRONG = 1 << 24;
|
||||
|
||||
/** Does this function use new.target? */
|
||||
public static final int ES6_USES_NEW_TARGET = 1 << 25;
|
||||
|
||||
/** Does this function or any nested functions contain an eval? */
|
||||
private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
|
||||
@ -247,8 +254,44 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
/** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep eval, or it's the program. */
|
||||
public static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_EVAL | IS_PROGRAM;
|
||||
|
||||
|
||||
/**
|
||||
* The following flags are derived from directive comments within this function.
|
||||
* Note that even IS_STRICT is one such flag but that requires special handling.
|
||||
*/
|
||||
|
||||
/** parser, print parse tree */
|
||||
public static final int DEBUG_PRINT_PARSE = 1 << 0;
|
||||
/** parser, print lower parse tree */
|
||||
public static final int DEBUG_PRINT_LOWER_PARSE = 1 << 1;
|
||||
/** parser, print AST */
|
||||
public static final int DEBUG_PRINT_AST = 1 << 2;
|
||||
/** parser, print lower AST */
|
||||
public static final int DEBUG_PRINT_LOWER_AST = 1 << 3;
|
||||
/** parser, print symbols */
|
||||
public static final int DEBUG_PRINT_SYMBOLS = 1 << 4;
|
||||
|
||||
// callsite tracing, profiling within this function
|
||||
/** profile callsites in this function? */
|
||||
public static final int DEBUG_PROFILE = 1 << 5;
|
||||
|
||||
/** trace callsite enterexit in this function? */
|
||||
public static final int DEBUG_TRACE_ENTEREXIT = 1 << 6;
|
||||
|
||||
/** trace callsite misses in this function? */
|
||||
public static final int DEBUG_TRACE_MISSES = 1 << 7;
|
||||
|
||||
/** trace callsite values in this function? */
|
||||
public static final int DEBUG_TRACE_VALUES = 1 << 8;
|
||||
|
||||
/** extension callsite flags mask */
|
||||
public static final int DEBUG_CALLSITE_FLAGS = DEBUG_PRINT_PARSE |
|
||||
DEBUG_PRINT_LOWER_PARSE | DEBUG_PRINT_AST | DEBUG_PRINT_LOWER_AST |
|
||||
DEBUG_PRINT_SYMBOLS | DEBUG_PROFILE | DEBUG_TRACE_ENTEREXIT |
|
||||
DEBUG_TRACE_MISSES | DEBUG_TRACE_VALUES;
|
||||
|
||||
/** What is the return type of this function? */
|
||||
private Type returnType = Type.UNKNOWN;
|
||||
public Type returnType = Type.UNKNOWN;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -267,6 +310,8 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
* @param flags initial flags
|
||||
* @param body body of the function
|
||||
* @param endParserState The parser state at the end of the parsing.
|
||||
* @param module the module
|
||||
* @param debugFlags the debug flags
|
||||
*/
|
||||
public FunctionNode(
|
||||
final Source source,
|
||||
@ -282,7 +327,9 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
final FunctionNode.Kind kind,
|
||||
final int flags,
|
||||
final Block body,
|
||||
final Object endParserState) {
|
||||
final Object endParserState,
|
||||
final Module module,
|
||||
final int debugFlags) {
|
||||
super(token, finish);
|
||||
|
||||
this.source = source;
|
||||
@ -299,7 +346,9 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
this.body = body;
|
||||
this.thisProperties = 0;
|
||||
this.rootClass = null;
|
||||
this.endParserState = endParserState;
|
||||
this.endParserState = endParserState;
|
||||
this.module = module;
|
||||
this.debugFlags = debugFlags;
|
||||
}
|
||||
|
||||
private FunctionNode(
|
||||
@ -335,6 +384,8 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
this.ident = functionNode.ident;
|
||||
this.kind = functionNode.kind;
|
||||
this.firstToken = functionNode.firstToken;
|
||||
this.module = functionNode.module;
|
||||
this.debugFlags = functionNode.debugFlags;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -366,23 +417,23 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
}
|
||||
|
||||
// quick check for extension callsite flags turned on by directives.
|
||||
if ((flags & EXTENSION_CALLSITE_FLAGS) == 0) {
|
||||
if ((debugFlags & DEBUG_CALLSITE_FLAGS) == 0) {
|
||||
return callsiteFlags;
|
||||
}
|
||||
|
||||
if (getFlag(IS_PROFILE)) {
|
||||
if (getDebugFlag(DEBUG_PROFILE)) {
|
||||
callsiteFlags |= CALLSITE_PROFILE;
|
||||
}
|
||||
|
||||
if (getFlag(IS_TRACE_MISSES)) {
|
||||
if (getDebugFlag(DEBUG_TRACE_MISSES)) {
|
||||
callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_MISSES;
|
||||
}
|
||||
|
||||
if (getFlag(IS_TRACE_VALUES)) {
|
||||
if (getDebugFlag(DEBUG_TRACE_VALUES)) {
|
||||
callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_ENTEREXIT | CALLSITE_TRACE_VALUES;
|
||||
}
|
||||
|
||||
if (getFlag(IS_TRACE_ENTEREXIT)) {
|
||||
if (getDebugFlag(DEBUG_TRACE_ENTEREXIT)) {
|
||||
callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_ENTEREXIT;
|
||||
}
|
||||
|
||||
@ -466,23 +517,23 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
public static int getDirectiveFlag(final String directive) {
|
||||
switch (directive) {
|
||||
case "nashorn callsite trace enterexit":
|
||||
return IS_TRACE_ENTEREXIT;
|
||||
return DEBUG_TRACE_ENTEREXIT;
|
||||
case "nashorn callsite trace misses":
|
||||
return IS_TRACE_MISSES;
|
||||
return DEBUG_TRACE_MISSES;
|
||||
case "nashorn callsite trace objects":
|
||||
return IS_TRACE_VALUES;
|
||||
return DEBUG_TRACE_VALUES;
|
||||
case "nashorn callsite profile":
|
||||
return IS_PROFILE;
|
||||
return DEBUG_PROFILE;
|
||||
case "nashorn print parse":
|
||||
return IS_PRINT_PARSE;
|
||||
return DEBUG_PRINT_PARSE;
|
||||
case "nashorn print lower parse":
|
||||
return IS_PRINT_LOWER_PARSE;
|
||||
return DEBUG_PRINT_LOWER_PARSE;
|
||||
case "nashorn print ast":
|
||||
return IS_PRINT_AST;
|
||||
return DEBUG_PRINT_AST;
|
||||
case "nashorn print lower ast":
|
||||
return IS_PRINT_LOWER_AST;
|
||||
return DEBUG_PRINT_LOWER_AST;
|
||||
case "nashorn print symbols":
|
||||
return IS_PRINT_SYMBOLS;
|
||||
return DEBUG_PRINT_SYMBOLS;
|
||||
default:
|
||||
// unknown/unsupported directive
|
||||
return 0;
|
||||
@ -578,6 +629,25 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
return setFlags(lc, flags | flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the debug flags for this function.
|
||||
*
|
||||
* @return the debug flags
|
||||
*/
|
||||
public int getDebugFlags() {
|
||||
return debugFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a debug flag is set for this function.
|
||||
*
|
||||
* @param debugFlag the debug flag
|
||||
* @return true if the flag is set
|
||||
*/
|
||||
public boolean getDebugFlag(final int debugFlag) {
|
||||
return (debugFlags & debugFlag) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the function is the top-level program.
|
||||
* @return True if this function node represents the top-level program.
|
||||
@ -1065,6 +1135,86 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
|
||||
return setFlag(lc, IS_CACHED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the function is generated in strong mode.
|
||||
*
|
||||
* @return true if strong mode enabled for function
|
||||
*/
|
||||
public boolean isStrong() {
|
||||
return getFlag(ES6_IS_STRONG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is an ES6 method.
|
||||
*
|
||||
* @return true if the ES6 method flag is set
|
||||
*/
|
||||
public boolean isMethod() {
|
||||
return getFlag(ES6_IS_METHOD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this function uses the ES6 super binding.
|
||||
*
|
||||
* @return true if the ES6 super flag is set
|
||||
*/
|
||||
public boolean usesSuper() {
|
||||
return getFlag(ES6_USES_SUPER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this function directly uses the super binding.
|
||||
*
|
||||
* @return true if the ES6 has-direct-super flag is set
|
||||
*/
|
||||
public boolean hasDirectSuper() {
|
||||
return getFlag(ES6_HAS_DIRECT_SUPER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is an ES6 class constructor.
|
||||
*
|
||||
* @return true if the ES6 class constructor flag is set
|
||||
*/
|
||||
public boolean isClassConstructor() {
|
||||
return getFlag(ES6_IS_CLASS_CONSTRUCTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is an ES6 subclass constructor.
|
||||
*
|
||||
* @return true if the ES6 subclass constructor flag is set
|
||||
*/
|
||||
public boolean isSubclassConstructor() {
|
||||
return getFlag(ES6_IS_SUBCLASS_CONSTRUCTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this function uses the ES6 new-targert.
|
||||
*
|
||||
* @return true if the ES6 new-target flag is set
|
||||
*/
|
||||
public boolean usesNewTarget() {
|
||||
return getFlag(ES6_USES_NEW_TARGET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is an ES6 module.
|
||||
*
|
||||
* @return true if this is an ES6 module
|
||||
*/
|
||||
public boolean isModule() {
|
||||
return kind == Kind.MODULE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the functions's ES6 module.
|
||||
*
|
||||
* @return the module, or null if this function is not part of one
|
||||
*/
|
||||
public Module getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the compile unit used to compile this function
|
||||
|
@ -49,6 +49,11 @@ public final class IdentNode extends Expression implements PropertyKey, Function
|
||||
private static final int FUTURESTRICT_NAME = 1 << 3;
|
||||
private static final int IS_DECLARED_HERE = 1 << 4;
|
||||
private static final int IS_DEAD = 1 << 5;
|
||||
private static final int DIRECT_SUPER = 1 << 6;
|
||||
private static final int REST_PARAMETER = 1 << 7;
|
||||
private static final int PROTO_PROPERTY = 1 << 8;
|
||||
private static final int DEFAULT_PARAMETER = 1 << 9;
|
||||
private static final int DESTRUCTURED_PARAMETER = 1 << 10;
|
||||
|
||||
/** Identifier. */
|
||||
private final String name;
|
||||
@ -382,4 +387,94 @@ public final class IdentNode extends Expression implements PropertyKey, Function
|
||||
public LocalVariableConversion getLocalVariableConversion() {
|
||||
return conversion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a direct super identifier
|
||||
*
|
||||
* @return true if the direct super flag is set
|
||||
*/
|
||||
public boolean isDirectSuper() {
|
||||
return (flags & DIRECT_SUPER) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new identifier with the direct super flag set.
|
||||
*
|
||||
* @return the new identifier
|
||||
*/
|
||||
public IdentNode setIsDirectSuper() {
|
||||
return new IdentNode(this, name, type, flags | DIRECT_SUPER, programPoint, conversion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a rest parameter
|
||||
*
|
||||
* @return true if the rest parameter flag is set
|
||||
*/
|
||||
public boolean isRestParameter() {
|
||||
return (flags & REST_PARAMETER) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new identifier with the rest parameter flag set.
|
||||
*
|
||||
* @return the new identifier
|
||||
*/
|
||||
public IdentNode setIsRestParameter() {
|
||||
return new IdentNode(this, name, type, flags | REST_PARAMETER, programPoint, conversion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a proto property name.
|
||||
*
|
||||
* @return true if this is the proto property name
|
||||
*/
|
||||
public boolean isProtoPropertyName() {
|
||||
return (flags & PROTO_PROPERTY) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new identifier with the proto property name flag set.
|
||||
*
|
||||
* @return the new identifier
|
||||
*/
|
||||
public IdentNode setIsProtoPropertyName() {
|
||||
return new IdentNode(this, name, type, flags | PROTO_PROPERTY, programPoint, conversion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this is a default parameter.
|
||||
*
|
||||
* @return true if this is a default parameter
|
||||
*/
|
||||
public boolean isDefaultParameter() {
|
||||
return (flags & DEFAULT_PARAMETER) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new identifier with the default parameter flag set.
|
||||
*
|
||||
* @return the new identifier
|
||||
*/
|
||||
public IdentNode setIsDefaultParameter() {
|
||||
return new IdentNode(this, name, type, flags | DEFAULT_PARAMETER, programPoint, conversion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this is a destructured parameter.
|
||||
*
|
||||
* @return true if this is a destructured parameter
|
||||
*/
|
||||
public boolean isDestructuredParameter() {
|
||||
return (flags & DESTRUCTURED_PARAMETER) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new identifier with the destructured parameter flag set.
|
||||
*
|
||||
* @return the new identifier
|
||||
*/
|
||||
public IdentNode setIsDestructuredParameter() {
|
||||
return new IdentNode(this, name, type, flags | DESTRUCTURED_PARAMETER, programPoint, conversion);
|
||||
}
|
||||
}
|
||||
|
@ -47,12 +47,13 @@ public final class IndexNode extends BaseNode {
|
||||
* @param index index for access
|
||||
*/
|
||||
public IndexNode(final long token, final int finish, final Expression base, final Expression index) {
|
||||
super(token, finish, base, false);
|
||||
super(token, finish, base, false, false);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
private IndexNode(final IndexNode indexNode, final Expression base, final Expression index, final boolean isFunction, final Type type, final int programPoint) {
|
||||
super(indexNode, base, isFunction, type, programPoint);
|
||||
private IndexNode(final IndexNode indexNode, final Expression base, final Expression index, final boolean isFunction,
|
||||
final Type type, final int programPoint, final boolean isSuper) {
|
||||
super(indexNode, base, isFunction, type, programPoint, isSuper);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@ -101,7 +102,7 @@ public final class IndexNode extends BaseNode {
|
||||
if (this.base == base) {
|
||||
return this;
|
||||
}
|
||||
return new IndexNode(this, base, index, isFunction(), type, programPoint);
|
||||
return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,7 +114,7 @@ public final class IndexNode extends BaseNode {
|
||||
if(this.index == index) {
|
||||
return this;
|
||||
}
|
||||
return new IndexNode(this, base, index, isFunction(), type, programPoint);
|
||||
return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -121,7 +122,7 @@ public final class IndexNode extends BaseNode {
|
||||
if (this.type == type) {
|
||||
return this;
|
||||
}
|
||||
return new IndexNode(this, base, index, isFunction(), type, programPoint);
|
||||
return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -129,7 +130,7 @@ public final class IndexNode extends BaseNode {
|
||||
if (isFunction()) {
|
||||
return this;
|
||||
}
|
||||
return new IndexNode(this, base, index, true, type, programPoint);
|
||||
return new IndexNode(this, base, index, true, type, programPoint, isSuper());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -137,6 +138,14 @@ public final class IndexNode extends BaseNode {
|
||||
if (this.programPoint == programPoint) {
|
||||
return this;
|
||||
}
|
||||
return new IndexNode(this, base, index, isFunction(), type, programPoint);
|
||||
return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexNode setIsSuper() {
|
||||
if (isSuper()) {
|
||||
return this;
|
||||
}
|
||||
return new IndexNode(this, base, index, isFunction(), type, programPoint, true);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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.ir;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ES6 Module information.
|
||||
*/
|
||||
public final class Module {
|
||||
|
||||
/** The synthetic binding name assigned to export default declarations with unnamed expressions. */
|
||||
public static final String DEFAULT_EXPORT_BINDING_NAME = "*default*";
|
||||
|
||||
/** The {@code export default} name. */
|
||||
public static final String DEFAULT_NAME = "default";
|
||||
|
||||
/** The {@code export *} name. */
|
||||
public static final String STAR_NAME = "*";
|
||||
|
||||
/**
|
||||
* A module ExportEntry record.
|
||||
*
|
||||
* @link http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records
|
||||
*/
|
||||
public static final class ExportEntry {
|
||||
private final String exportName;
|
||||
private final String moduleRequest;
|
||||
private final String importName;
|
||||
private final String localName;
|
||||
|
||||
private ExportEntry(final String exportName, final String moduleRequest, final String importName, final String localName) {
|
||||
this.exportName = exportName;
|
||||
this.moduleRequest = moduleRequest;
|
||||
this.importName = importName;
|
||||
this.localName = localName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code export *} export entry.
|
||||
*
|
||||
* @param moduleRequest the module request
|
||||
* @return the export entry
|
||||
*/
|
||||
public static ExportEntry exportStarFrom(final String moduleRequest) {
|
||||
return new ExportEntry(null, moduleRequest, STAR_NAME, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code export default} export entry.
|
||||
*
|
||||
* @return the export entry
|
||||
*/
|
||||
public static ExportEntry exportDefault() {
|
||||
return exportDefault(DEFAULT_EXPORT_BINDING_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code export default} export entry with a local name.
|
||||
*
|
||||
* @param localName the local name
|
||||
* @return the export entry
|
||||
*/
|
||||
public static ExportEntry exportDefault(final String localName) {
|
||||
return new ExportEntry(DEFAULT_NAME, null, null, localName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a export entry with a local name and export name.
|
||||
*
|
||||
* @param exportName the export name
|
||||
* @param localName the local name
|
||||
* @return the export entry
|
||||
*/
|
||||
public static ExportEntry exportSpecifier(final String exportName, final String localName) {
|
||||
return new ExportEntry(exportName, null, null, localName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a export entry with an export name.
|
||||
*
|
||||
* @param exportName the export name
|
||||
* @return the export entry
|
||||
*/
|
||||
public static ExportEntry exportSpecifier(final String exportName) {
|
||||
return exportSpecifier(exportName, exportName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of this entry with the specified {@code module request} string.
|
||||
*
|
||||
* @param moduleRequest the module request
|
||||
* @return the new export entry
|
||||
*/
|
||||
public ExportEntry withFrom(@SuppressWarnings("hiding") final String moduleRequest) {
|
||||
return new ExportEntry(exportName, moduleRequest, localName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry's export name.
|
||||
*
|
||||
* @return the export name
|
||||
*/
|
||||
public String getExportName() {
|
||||
return exportName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry's module request.
|
||||
*
|
||||
* @return the module request
|
||||
*/
|
||||
public String getModuleRequest() {
|
||||
return moduleRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry's import name.
|
||||
*
|
||||
* @return the import name
|
||||
*/
|
||||
public String getImportName() {
|
||||
return importName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry's local name.
|
||||
*
|
||||
* @return the local name
|
||||
*/
|
||||
public String getLocalName() {
|
||||
return localName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ExportEntry [exportName=" + exportName + ", moduleRequest=" + moduleRequest + ", importName=" + importName + ", localName=" + localName + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An ImportEntry record.
|
||||
*
|
||||
* @link http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records
|
||||
*/
|
||||
public static final class ImportEntry {
|
||||
private final String moduleRequest;
|
||||
private final String importName;
|
||||
private final String localName;
|
||||
|
||||
private ImportEntry(final String moduleRequest, final String importName, final String localName) {
|
||||
this.moduleRequest = moduleRequest;
|
||||
this.importName = importName;
|
||||
this.localName = localName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an import entry with default name.
|
||||
*
|
||||
* @param localName the local name
|
||||
* @return the import entry
|
||||
*/
|
||||
public static ImportEntry importDefault(final String localName) {
|
||||
return new ImportEntry(null, DEFAULT_NAME, localName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an import entry with {@code *} import name.
|
||||
*
|
||||
* @param localName the local name
|
||||
* @return the import entry
|
||||
*/
|
||||
public static ImportEntry importStarAsNameSpaceFrom(final String localName) {
|
||||
return new ImportEntry(null, STAR_NAME, localName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an import entry with the given import and local names.
|
||||
*
|
||||
* @param importName the import name
|
||||
* @param localName the local name
|
||||
* @return the import entry
|
||||
*/
|
||||
public static ImportEntry importSpecifier(final String importName, final String localName) {
|
||||
return new ImportEntry(null, importName, localName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new import entry with the given import name.
|
||||
*
|
||||
* @param importName the import name
|
||||
* @return the import entry
|
||||
*/
|
||||
public static ImportEntry importSpecifier(final String importName) {
|
||||
return importSpecifier(importName, importName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this import entry with the given module request.
|
||||
*
|
||||
* @param moduleRequest the module request
|
||||
* @return the new import entry
|
||||
*/
|
||||
public ImportEntry withFrom(@SuppressWarnings("hiding") final String moduleRequest) {
|
||||
return new ImportEntry(moduleRequest, importName, localName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry's module request.
|
||||
*
|
||||
* @return the module request
|
||||
*/
|
||||
public String getModuleRequest() {
|
||||
return moduleRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry's import name.
|
||||
*
|
||||
* @return the import name
|
||||
*/
|
||||
public String getImportName() {
|
||||
return importName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry's local name.
|
||||
*
|
||||
* @return the local name
|
||||
*/
|
||||
public String getLocalName() {
|
||||
return localName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ImportEntry [moduleRequest=" + moduleRequest + ", importName=" + importName + ", localName=" + localName + "]";
|
||||
}
|
||||
}
|
||||
|
||||
private final List<String> requestedModules;
|
||||
private final List<ImportEntry> importEntries;
|
||||
private final List<ExportEntry> localExportEntries;
|
||||
private final List<ExportEntry> indirectExportEntries;
|
||||
private final List<ExportEntry> starExportEntries;
|
||||
|
||||
/**
|
||||
* Creates a module with the specified requested modules and import and export entries.
|
||||
*
|
||||
* @param requestedModules the requested modules
|
||||
* @param importEntries the import entries
|
||||
* @param localExportEntries local export entries
|
||||
* @param indirectExportEntries indirect export entries
|
||||
* @param starExportEntries star export entries
|
||||
*/
|
||||
public Module(final List<String> requestedModules, final List<ImportEntry> importEntries, final List<ExportEntry> localExportEntries,
|
||||
final List<ExportEntry> indirectExportEntries, final List<ExportEntry> starExportEntries) {
|
||||
this.requestedModules = requestedModules;
|
||||
this.importEntries = importEntries;
|
||||
this.localExportEntries = localExportEntries;
|
||||
this.indirectExportEntries = indirectExportEntries;
|
||||
this.starExportEntries = starExportEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of requested modules.
|
||||
*
|
||||
* @return the requested modules
|
||||
*/
|
||||
public List<String> getRequestedModules() {
|
||||
return requestedModules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of import entries.
|
||||
*
|
||||
* @return the import entries
|
||||
*/
|
||||
public List<ImportEntry> getImportEntries() {
|
||||
return importEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of local export entries.
|
||||
*
|
||||
* @return the local export entries
|
||||
*/
|
||||
public List<ExportEntry> getLocalExportEntries() {
|
||||
return localExportEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of indirect export entries.
|
||||
*
|
||||
* @return the indirect export entries
|
||||
*/
|
||||
public List<ExportEntry> getIndirectExportEntries() {
|
||||
return indirectExportEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of star export entries.
|
||||
*
|
||||
* @return the star export entries
|
||||
*/
|
||||
public List<ExportEntry> getStarExportEntries() {
|
||||
return starExportEntries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Module [requestedModules=" + requestedModules + ", importEntries=" + importEntries + ", localExportEntries=" + localExportEntries + ", indirectExportEntries=" +
|
||||
indirectExportEntries + ", starExportEntries=" + starExportEntries + "]";
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ public final class PropertyNode extends Node {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** Property key. */
|
||||
private final PropertyKey key;
|
||||
private final Expression key;
|
||||
|
||||
/** Property value. */
|
||||
private final Expression value;
|
||||
@ -47,6 +47,12 @@ public final class PropertyNode extends Node {
|
||||
/** Property getter. */
|
||||
private final FunctionNode setter;
|
||||
|
||||
/** static property flag */
|
||||
private final boolean isStatic;
|
||||
|
||||
/** Computed property flag */
|
||||
private final boolean computed;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -56,21 +62,27 @@ public final class PropertyNode extends Node {
|
||||
* @param value the value of this property
|
||||
* @param getter getter function body
|
||||
* @param setter setter function body
|
||||
* @param isStatic is this a static property?
|
||||
* @param computed is this a computed property?
|
||||
*/
|
||||
public PropertyNode(final long token, final int finish, final PropertyKey key, final Expression value, final FunctionNode getter, final FunctionNode setter) {
|
||||
public PropertyNode(final long token, final int finish, final Expression key, final Expression value, final FunctionNode getter, final FunctionNode setter, final boolean isStatic, final boolean computed) {
|
||||
super(token, finish);
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
this.isStatic = isStatic;
|
||||
this.computed = computed;
|
||||
}
|
||||
|
||||
private PropertyNode(final PropertyNode propertyNode, final PropertyKey key, final Expression value, final FunctionNode getter, final FunctionNode setter) {
|
||||
private PropertyNode(final PropertyNode propertyNode, final Expression key, final Expression value, final FunctionNode getter, final FunctionNode setter, final boolean isStatic, final boolean computed) {
|
||||
super(propertyNode);
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
this.isStatic = isStatic;
|
||||
this.computed = computed;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,14 +90,14 @@ public final class PropertyNode extends Node {
|
||||
* @return key name
|
||||
*/
|
||||
public String getKeyName() {
|
||||
return key.getPropertyName();
|
||||
return key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
|
||||
if (visitor.enterPropertyNode(this)) {
|
||||
return visitor.leavePropertyNode(
|
||||
setKey((PropertyKey)((Node)key).accept(visitor)).
|
||||
setKey((Expression) key.accept(visitor)).
|
||||
setValue(value == null ? null : (Expression)value.accept(visitor)).
|
||||
setGetter(getter == null ? null : (FunctionNode)getter.accept(visitor)).
|
||||
setSetter(setter == null ? null : (FunctionNode)setter.accept(visitor)));
|
||||
@ -134,7 +146,7 @@ public final class PropertyNode extends Node {
|
||||
if (this.getter == getter) {
|
||||
return this;
|
||||
}
|
||||
return new PropertyNode(this, key, value, getter, setter);
|
||||
return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,14 +154,14 @@ public final class PropertyNode extends Node {
|
||||
* @return the key
|
||||
*/
|
||||
public Expression getKey() {
|
||||
return (Expression)key;
|
||||
return key;
|
||||
}
|
||||
|
||||
private PropertyNode setKey(final PropertyKey key) {
|
||||
private PropertyNode setKey(final Expression key) {
|
||||
if (this.key == key) {
|
||||
return this;
|
||||
}
|
||||
return new PropertyNode(this, key, value, getter, setter);
|
||||
return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,7 +181,7 @@ public final class PropertyNode extends Node {
|
||||
if (this.setter == setter) {
|
||||
return this;
|
||||
}
|
||||
return new PropertyNode(this, key, value, getter, setter);
|
||||
return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -189,6 +201,24 @@ public final class PropertyNode extends Node {
|
||||
if (this.value == value) {
|
||||
return this;
|
||||
}
|
||||
return new PropertyNode(this, key, value, getter, setter);
|
||||
}
|
||||
return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a static property.
|
||||
*
|
||||
* @return true if static flag is set
|
||||
*/
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a computed property.
|
||||
*
|
||||
* @return true if the computed flag is set
|
||||
*/
|
||||
public boolean isComputed() {
|
||||
return computed;
|
||||
}
|
||||
}
|
||||
|
@ -133,8 +133,8 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
return enterASSIGN_SHR(binaryNode);
|
||||
case ASSIGN_SUB:
|
||||
return enterASSIGN_SUB(binaryNode);
|
||||
case BIND:
|
||||
return enterBIND(binaryNode);
|
||||
case ARROW:
|
||||
return enterARROW(binaryNode);
|
||||
case BIT_AND:
|
||||
return enterBIT_AND(binaryNode);
|
||||
case BIT_OR:
|
||||
@ -217,8 +217,8 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
return leaveASSIGN_SHR(binaryNode);
|
||||
case ASSIGN_SUB:
|
||||
return leaveASSIGN_SUB(binaryNode);
|
||||
case BIND:
|
||||
return leaveBIND(binaryNode);
|
||||
case ARROW:
|
||||
return leaveARROW(binaryNode);
|
||||
case BIT_AND:
|
||||
return leaveBIT_AND(binaryNode);
|
||||
case BIT_OR:
|
||||
@ -735,22 +735,22 @@ public abstract class NodeOperatorVisitor<T extends LexicalContext> extends Node
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary enter - callback for entering a bind operator
|
||||
* Binary enter - callback for entering a arrow operator
|
||||
*
|
||||
* @param binaryNode the node
|
||||
* @return true if traversal should continue and node children be traversed, false otherwise
|
||||
*/
|
||||
public boolean enterBIND(final BinaryNode binaryNode) {
|
||||
public boolean enterARROW(final BinaryNode binaryNode) {
|
||||
return enterDefault(binaryNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary leave - callback for leaving a bind operator
|
||||
* Binary leave - callback for leaving a arrow operator
|
||||
*
|
||||
* @param binaryNode the node
|
||||
* @return processed node, which will replace the original one, or the original node
|
||||
*/
|
||||
public Node leaveBIND(final BinaryNode binaryNode) {
|
||||
public Node leaveARROW(final BinaryNode binaryNode) {
|
||||
return leaveDefault(binaryNode);
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ import jdk.nashorn.internal.ir.BreakNode;
|
||||
import jdk.nashorn.internal.ir.CallNode;
|
||||
import jdk.nashorn.internal.ir.CaseNode;
|
||||
import jdk.nashorn.internal.ir.CatchNode;
|
||||
import jdk.nashorn.internal.ir.ClassNode;
|
||||
import jdk.nashorn.internal.ir.ContinueNode;
|
||||
import jdk.nashorn.internal.ir.DebuggerNode;
|
||||
import jdk.nashorn.internal.ir.EmptyNode;
|
||||
@ -897,5 +898,23 @@ public abstract class NodeVisitor<T extends LexicalContext> {
|
||||
return leaveDefault(withNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for entering a ClassNode
|
||||
*
|
||||
* @param classNode the node
|
||||
* @return true if traversal should continue and node children be traversed, false otherwise
|
||||
*/
|
||||
public boolean enterClassNode(final ClassNode classNode) {
|
||||
return enterDefault(classNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for leaving a ClassNode
|
||||
*
|
||||
* @param classNode the node
|
||||
* @return processed node, which will replace the original one, or the original node
|
||||
*/
|
||||
public Node leaveClassNode(final ClassNode classNode) {
|
||||
return leaveDefault(classNode);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -278,7 +278,12 @@ class ParserContext {
|
||||
return new NodeIterator<>(ParserContextFunctionNode.class);
|
||||
}
|
||||
|
||||
private class NodeIterator <T extends ParserContextNode> implements Iterator<T> {
|
||||
public ParserContextModuleNode getCurrentModule() {
|
||||
final Iterator<ParserContextModuleNode> iter = new NodeIterator<>(ParserContextModuleNode.class, getCurrentFunction());
|
||||
return iter.hasNext() ? iter.next() : null;
|
||||
}
|
||||
|
||||
private class NodeIterator<T extends ParserContextNode> implements Iterator<T> {
|
||||
private int index;
|
||||
private T next;
|
||||
private final Class<T> clazz;
|
||||
|
@ -24,10 +24,12 @@
|
||||
*/
|
||||
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
|
||||
@ -46,11 +48,11 @@ class ParserContextFunctionNode extends ParserContextBaseNode {
|
||||
/** Line number for function declaration */
|
||||
private final int line;
|
||||
|
||||
/** Function node kind, see {@link FunctionNode#Kind} */
|
||||
/** Function node kind, see {@link FunctionNode.Kind} */
|
||||
private final FunctionNode.Kind kind;
|
||||
|
||||
/** List of parameter identifiers for function */
|
||||
private final List<IdentNode> parameters;
|
||||
private List<IdentNode> parameters;
|
||||
|
||||
/** Token for function start */
|
||||
private final long token;
|
||||
@ -61,6 +63,14 @@ class ParserContextFunctionNode extends ParserContextBaseNode {
|
||||
/** Opaque node for parser end state, see {@link Parser} */
|
||||
private Object endParserState;
|
||||
|
||||
private HashSet<String> 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
|
||||
@ -155,6 +165,10 @@ class ParserContextFunctionNode extends ParserContextBaseNode {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
void setParameters(List<IdentNode> parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set last token
|
||||
* @param token New last token
|
||||
@ -194,4 +208,70 @@ class ParserContextFunctionNode extends ParserContextBaseNode {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.nashorn.internal.ir.Module;
|
||||
import jdk.nashorn.internal.ir.Module.ExportEntry;
|
||||
import jdk.nashorn.internal.ir.Module.ImportEntry;
|
||||
|
||||
/**
|
||||
* ParserContextNode that represents a module.
|
||||
*/
|
||||
class ParserContextModuleNode extends ParserContextBaseNode {
|
||||
|
||||
/** Module name. */
|
||||
private final String name;
|
||||
|
||||
private List<String> requestedModules = new ArrayList<>();
|
||||
private List<ImportEntry> importEntries = new ArrayList<>();
|
||||
private List<ExportEntry> localExportEntries = new ArrayList<>();
|
||||
private List<ExportEntry> indirectExportEntries = new ArrayList<>();
|
||||
private List<ExportEntry> starExportEntries = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param name name of the module
|
||||
*/
|
||||
ParserContextModuleNode(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the module.
|
||||
*
|
||||
* @return name of the module
|
||||
*/
|
||||
public String getModuleName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void addModuleRequest(final String moduleRequest) {
|
||||
requestedModules.add(moduleRequest);
|
||||
}
|
||||
|
||||
public void addImportEntry(final ImportEntry importEntry) {
|
||||
importEntries.add(importEntry);
|
||||
}
|
||||
|
||||
public void addLocalExportEntry(final ExportEntry exportEntry) {
|
||||
localExportEntries.add(exportEntry);
|
||||
}
|
||||
|
||||
public void addIndirectExportEntry(final ExportEntry exportEntry) {
|
||||
indirectExportEntries.add(exportEntry);
|
||||
}
|
||||
|
||||
public void addStarExportEntry(final ExportEntry exportEntry) {
|
||||
starExportEntries.add(exportEntry);
|
||||
}
|
||||
|
||||
public Module createModule() {
|
||||
return new Module(requestedModules, importEntries, localExportEntries, indirectExportEntries, starExportEntries);
|
||||
}
|
||||
}
|
@ -82,7 +82,7 @@ public enum TokenType {
|
||||
ASSIGN (BINARY, "=", 2, false),
|
||||
EQ (BINARY, "==", 9, true),
|
||||
EQ_STRICT (BINARY, "===", 9, true),
|
||||
BIND (BINARY, "=>", 9, true),
|
||||
ARROW (BINARY, "=>", 2, true),
|
||||
GT (BINARY, ">", 10, true),
|
||||
GE (BINARY, ">=", 10, true),
|
||||
SAR (BINARY, ">>", 11, true),
|
||||
@ -100,6 +100,7 @@ public enum TokenType {
|
||||
OR (BINARY, "||", 4, true),
|
||||
RBRACE (BRACKET, "}"),
|
||||
BIT_NOT (UNARY, "~", 14, false),
|
||||
ELLIPSIS (UNARY, "..."),
|
||||
|
||||
// ECMA 7.6.1.1 Keywords, 7.6.1.2 Future Reserved Words.
|
||||
// All other Java keywords are commented out.
|
||||
@ -190,7 +191,10 @@ public enum TokenType {
|
||||
|
||||
COMMALEFT (IR, null),
|
||||
DECPOSTFIX (IR, null),
|
||||
INCPOSTFIX (IR, null);
|
||||
INCPOSTFIX (IR, null),
|
||||
SPREAD_ARGUMENT(IR, null),
|
||||
SPREAD_ARRAY (IR, null),
|
||||
YIELD_STAR (IR, null);
|
||||
|
||||
/** Next token kind in token lookup table. */
|
||||
private TokenType next;
|
||||
@ -251,7 +255,6 @@ public enum TokenType {
|
||||
return kind == BINARY && (!noIn || this != IN) && precedence != 0;
|
||||
}
|
||||
|
||||
|
||||
public int getLength() {
|
||||
assert name != null : "Token name not set";
|
||||
return name.length();
|
||||
|
@ -1403,11 +1403,11 @@ public final class Context {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (env._print_ast || functionNode.getFlag(FunctionNode.IS_PRINT_AST)) {
|
||||
if (env._print_ast || functionNode.getDebugFlag(FunctionNode.DEBUG_PRINT_AST)) {
|
||||
getErr().println(new ASTWriter(functionNode));
|
||||
}
|
||||
|
||||
if (env._print_parse || functionNode.getFlag(FunctionNode.IS_PRINT_PARSE)) {
|
||||
if (env._print_parse || functionNode.getDebugFlag(FunctionNode.DEBUG_PRINT_PARSE)) {
|
||||
getErr().println(new PrintVisitor(functionNode, true, false));
|
||||
}
|
||||
}
|
||||
|
@ -176,6 +176,8 @@ public class DtoaBuffer {
|
||||
buffer.append('0');
|
||||
}
|
||||
buffer.append(chars, 0, length);
|
||||
} else {
|
||||
decimalPoint = 1;
|
||||
}
|
||||
} else if (decimalPoint >= length) {
|
||||
// large integer, add trailing zeroes
|
||||
|
@ -63,6 +63,27 @@ parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON
|
||||
parser.error.missing.const.assignment=Missing assignment to constant "{0}"
|
||||
parser.error.unterminated.template.expression=Expected } after expression in template literal
|
||||
|
||||
# ES6 mode error messages
|
||||
parser.error.multiple.constructors=Class contains more than one constructor
|
||||
parser.error.generator.constructor=Class constructor must not be a generator
|
||||
parser.error.accessor.constructor=Class constructor must not be an accessor
|
||||
parser.error.static.prototype.method=Static class method must not be named 'prototype'
|
||||
parser.error.missing.destructuring.assignment=Missing assignment in destructuring declaration
|
||||
parser.error.let.binding.for='let' is not a valid binding name in a for loop
|
||||
parser.error.invalid.export=invalid export declaration
|
||||
parser.error.expected.binding=expected BindingIdentifier or BindingPattern
|
||||
parser.error.multiple.proto.key=property name __proto__ appears more than once in object literal
|
||||
parser.error.new.target.in.function=new.target expression is only allowed in functions
|
||||
parser.error.expected.target=expected 'target'
|
||||
parser.error.invalid.super=invalid use of keyword super
|
||||
parser.error.expected.arrow.parameter=expected arrow function parameter list
|
||||
parser.error.invalid.arrow.parameter=invalid arrow function parameter
|
||||
parser.error.expected.named.import=expected NameSpaceImport or NamedImports
|
||||
parser.error.expected.import=expected ImportClause or ModuleSpecifier
|
||||
parser.error.expected.as=expected 'as'
|
||||
parser.error.expected.binding.identifier=expected BindingIdentifier
|
||||
parser.error.expected.from=expected 'from'
|
||||
|
||||
# strict mode error messages
|
||||
parser.error.strict.no.with="with" statement cannot be used in strict mode
|
||||
parser.error.strict.name="{0}" cannot be used as {1} in strict mode
|
||||
|
@ -438,6 +438,9 @@ public class Shell implements PartialParser {
|
||||
final File file = new File(fileName);
|
||||
final ScriptFunction script = context.compileScript(sourceFor(fileName, file), global);
|
||||
if (script == null || errors.getNumberOfErrors() != 0) {
|
||||
if (context.getEnv()._parse_only && !errors.hasErrors()) {
|
||||
continue; // No error, continue to consume all files in list
|
||||
}
|
||||
return COMPILATION_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 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
|
||||
@ -21,14 +21,17 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Check yield keyword is parsed and yield statement does nothing (yet).
|
||||
* JDK-8155025: 0.001.toFixed(2) should return "0.00" not "0"
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
function func() {
|
||||
yield 2;
|
||||
for (var i = 0, zeros=""; i <= 9; i++, zeros += "0") {
|
||||
var n = Number("0." + zeros + "1");
|
||||
for (var j = 1; j <= i + 3; j++) {
|
||||
print(n + ".toFixed(" + j + ")=" + n.toFixed(j));
|
||||
}
|
||||
}
|
||||
|
75
nashorn/test/script/basic/JDK-8155025.js.EXPECTED
Normal file
75
nashorn/test/script/basic/JDK-8155025.js.EXPECTED
Normal file
@ -0,0 +1,75 @@
|
||||
0.1.toFixed(1)=0.1
|
||||
0.1.toFixed(2)=0.10
|
||||
0.1.toFixed(3)=0.100
|
||||
0.01.toFixed(1)=0.0
|
||||
0.01.toFixed(2)=0.01
|
||||
0.01.toFixed(3)=0.010
|
||||
0.01.toFixed(4)=0.0100
|
||||
0.001.toFixed(1)=0.0
|
||||
0.001.toFixed(2)=0.00
|
||||
0.001.toFixed(3)=0.001
|
||||
0.001.toFixed(4)=0.0010
|
||||
0.001.toFixed(5)=0.00100
|
||||
0.0001.toFixed(1)=0.0
|
||||
0.0001.toFixed(2)=0.00
|
||||
0.0001.toFixed(3)=0.000
|
||||
0.0001.toFixed(4)=0.0001
|
||||
0.0001.toFixed(5)=0.00010
|
||||
0.0001.toFixed(6)=0.000100
|
||||
0.00001.toFixed(1)=0.0
|
||||
0.00001.toFixed(2)=0.00
|
||||
0.00001.toFixed(3)=0.000
|
||||
0.00001.toFixed(4)=0.0000
|
||||
0.00001.toFixed(5)=0.00001
|
||||
0.00001.toFixed(6)=0.000010
|
||||
0.00001.toFixed(7)=0.0000100
|
||||
0.000001.toFixed(1)=0.0
|
||||
0.000001.toFixed(2)=0.00
|
||||
0.000001.toFixed(3)=0.000
|
||||
0.000001.toFixed(4)=0.0000
|
||||
0.000001.toFixed(5)=0.00000
|
||||
0.000001.toFixed(6)=0.000001
|
||||
0.000001.toFixed(7)=0.0000010
|
||||
0.000001.toFixed(8)=0.00000100
|
||||
1e-7.toFixed(1)=0.0
|
||||
1e-7.toFixed(2)=0.00
|
||||
1e-7.toFixed(3)=0.000
|
||||
1e-7.toFixed(4)=0.0000
|
||||
1e-7.toFixed(5)=0.00000
|
||||
1e-7.toFixed(6)=0.000000
|
||||
1e-7.toFixed(7)=0.0000001
|
||||
1e-7.toFixed(8)=0.00000010
|
||||
1e-7.toFixed(9)=0.000000100
|
||||
1e-8.toFixed(1)=0.0
|
||||
1e-8.toFixed(2)=0.00
|
||||
1e-8.toFixed(3)=0.000
|
||||
1e-8.toFixed(4)=0.0000
|
||||
1e-8.toFixed(5)=0.00000
|
||||
1e-8.toFixed(6)=0.000000
|
||||
1e-8.toFixed(7)=0.0000000
|
||||
1e-8.toFixed(8)=0.00000001
|
||||
1e-8.toFixed(9)=0.000000010
|
||||
1e-8.toFixed(10)=0.0000000100
|
||||
1e-9.toFixed(1)=0.0
|
||||
1e-9.toFixed(2)=0.00
|
||||
1e-9.toFixed(3)=0.000
|
||||
1e-9.toFixed(4)=0.0000
|
||||
1e-9.toFixed(5)=0.00000
|
||||
1e-9.toFixed(6)=0.000000
|
||||
1e-9.toFixed(7)=0.0000000
|
||||
1e-9.toFixed(8)=0.00000000
|
||||
1e-9.toFixed(9)=0.000000001
|
||||
1e-9.toFixed(10)=0.0000000010
|
||||
1e-9.toFixed(11)=0.00000000100
|
||||
1e-10.toFixed(1)=0.0
|
||||
1e-10.toFixed(2)=0.00
|
||||
1e-10.toFixed(3)=0.000
|
||||
1e-10.toFixed(4)=0.0000
|
||||
1e-10.toFixed(5)=0.00000
|
||||
1e-10.toFixed(6)=0.000000
|
||||
1e-10.toFixed(7)=0.0000000
|
||||
1e-10.toFixed(8)=0.00000000
|
||||
1e-10.toFixed(9)=0.000000000
|
||||
1e-10.toFixed(10)=0.0000000001
|
||||
1e-10.toFixed(11)=0.00000000010
|
||||
1e-10.toFixed(12)=0.000000000100
|
94
nashorn/test/script/basic/es6/parser-es6.js
Normal file
94
nashorn/test/script/basic/es6/parser-es6.js
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* JDK-8134503: support ES6 parsing in Nashorn
|
||||
*
|
||||
* @test
|
||||
* @option --language=es6
|
||||
* @option --parse-only
|
||||
*/
|
||||
|
||||
|
||||
[].map(v => v + 1);
|
||||
|
||||
class A extends B.C {
|
||||
constructor(a, b) {
|
||||
super(a, b);
|
||||
}
|
||||
someMethod(c) {
|
||||
super.someMethod();
|
||||
}
|
||||
get g() {
|
||||
return this.g;
|
||||
}
|
||||
set s(t) {
|
||||
this.t = t;
|
||||
}
|
||||
static m() {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
|
||||
var obj = {
|
||||
__proto__: theProtoObj,
|
||||
handler,
|
||||
r() {
|
||||
return super.m();
|
||||
},
|
||||
[ '__' + (() => 'x')() ]: 1,
|
||||
*q (x, y) {
|
||||
yield 1;
|
||||
}
|
||||
};
|
||||
|
||||
var [a, , b] = [1, 2, 3];
|
||||
|
||||
var { x: a, y: { z: b }, w: c } = abc();
|
||||
|
||||
var {a, b, c} = abc();
|
||||
|
||||
var o = { x, y };
|
||||
|
||||
function g({name: x}) {
|
||||
return x;
|
||||
}
|
||||
|
||||
foo(a, ...b);
|
||||
|
||||
var c = [ ...s ];
|
||||
|
||||
var [a] = [];
|
||||
|
||||
var [a = 1] = [];
|
||||
|
||||
|
||||
var f = {
|
||||
[Symbol.iterator]: function*() {
|
||||
var cur = 1;
|
||||
for (;;) {
|
||||
yield cur;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,3 +1,3 @@
|
||||
test/script/error/NASHORN-154/function_mult_params_in_strict.js:38:14 strict mode function cannot have duplicate parameter name "x"
|
||||
test/script/error/NASHORN-154/function_mult_params_in_strict.js:38:17 strict mode function cannot have duplicate parameter name "x"
|
||||
function func(x, x) {}
|
||||
^
|
||||
^
|
||||
|
@ -100,7 +100,7 @@
|
||||
"startPosition": "1181",
|
||||
"properties": [
|
||||
{
|
||||
"endPosition": "1185",
|
||||
"endPosition": "1187",
|
||||
"kind": "PROPERTY",
|
||||
"value": {
|
||||
"endPosition": "1187",
|
||||
@ -2386,7 +2386,7 @@
|
||||
"startPosition": "1139",
|
||||
"properties": [
|
||||
{
|
||||
"endPosition": "1143",
|
||||
"endPosition": "1146",
|
||||
"kind": "PROPERTY",
|
||||
"value": {
|
||||
"endPosition": "1146",
|
||||
@ -2403,7 +2403,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"endPosition": "1150",
|
||||
"endPosition": "1152",
|
||||
"kind": "PROPERTY",
|
||||
"value": {
|
||||
"endPosition": "1152",
|
||||
@ -2443,7 +2443,7 @@
|
||||
"startPosition": "1160",
|
||||
"properties": [
|
||||
{
|
||||
"endPosition": "1166",
|
||||
"endPosition": "1169",
|
||||
"kind": "PROPERTY",
|
||||
"value": {
|
||||
"endPosition": "1169",
|
||||
@ -2460,7 +2460,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"endPosition": "1175",
|
||||
"endPosition": "1177",
|
||||
"kind": "PROPERTY",
|
||||
"value": {
|
||||
"endPosition": "1177",
|
||||
@ -2914,7 +2914,7 @@
|
||||
"startPosition": "1178",
|
||||
"properties": [
|
||||
{
|
||||
"endPosition": "1182",
|
||||
"endPosition": "1184",
|
||||
"kind": "PROPERTY",
|
||||
"value": {
|
||||
"endPosition": "1184",
|
||||
@ -3395,7 +3395,7 @@
|
||||
"startPosition": "1200",
|
||||
"properties": [
|
||||
{
|
||||
"endPosition": "1206",
|
||||
"endPosition": "1214",
|
||||
"kind": "PROPERTY",
|
||||
"value": {
|
||||
"endPosition": "1214",
|
||||
@ -4709,11 +4709,11 @@
|
||||
,
|
||||
{
|
||||
"fileName": "parsernegativetests/strict_repeatparam.js",
|
||||
"code": "ident (1119, 1)",
|
||||
"columnNumber": "14",
|
||||
"code": "ident (1122, 1)",
|
||||
"columnNumber": "17",
|
||||
"kind": "ERROR",
|
||||
"position": "1119",
|
||||
"message": "parsernegativetests/strict_repeatparam.js:31:14 strict mode function cannot have duplicate parameter name \"x\"\nfunction func(x, x) {}\n ^",
|
||||
"position": "1122",
|
||||
"message": "parsernegativetests/strict_repeatparam.js:31:17 strict mode function cannot have duplicate parameter name \"x\"\nfunction func(x, x) {}\n ^",
|
||||
"lineNumber": "31"
|
||||
}
|
||||
,
|
||||
|
@ -6,10 +6,10 @@ with_stat.js:2:7 Expected ; but found )
|
||||
|
||||
with({}) {}
|
||||
^
|
||||
repeat_param.js:2:15 strict mode function cannot have duplicate parameter name "x"
|
||||
repeat_param.js:2:18 strict mode function cannot have duplicate parameter name "x"
|
||||
|
||||
function func(x, x) {}
|
||||
^
|
||||
^
|
||||
repeat_prop.js:2:22 Property "foo" already defined
|
||||
|
||||
var obj = { foo: 34, foo: 'hello' };
|
||||
|
@ -74,7 +74,7 @@
|
||||
"properties": [
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "74",
|
||||
"endPosition": "76",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
|
@ -6,7 +6,7 @@
|
||||
"properties": [
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "8",
|
||||
"endPosition": "12",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
@ -38,7 +38,7 @@
|
||||
"properties": [
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "34",
|
||||
"endPosition": "37",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
@ -57,7 +57,7 @@
|
||||
},
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "41",
|
||||
"endPosition": "43",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
@ -83,7 +83,7 @@
|
||||
"properties": [
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "57",
|
||||
"endPosition": "60",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
@ -102,7 +102,7 @@
|
||||
},
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "66",
|
||||
"endPosition": "68",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
|
@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "17",
|
||||
"endPosition": "22",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
@ -20,7 +20,7 @@
|
||||
},
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "31",
|
||||
"endPosition": "38",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
@ -45,7 +45,7 @@
|
||||
},
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "46",
|
||||
"endPosition": "61",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
@ -72,7 +72,7 @@
|
||||
},
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "69",
|
||||
"endPosition": "72",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
|
@ -80,7 +80,7 @@
|
||||
"properties": [
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "97",
|
||||
"endPosition": "105",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
|
@ -49,7 +49,7 @@
|
||||
"properties": [
|
||||
{
|
||||
"getter": "null",
|
||||
"endPosition": "34",
|
||||
"endPosition": "39",
|
||||
"kind": "PROPERTY",
|
||||
"setter": "null",
|
||||
"value": {
|
||||
|
@ -194,9 +194,9 @@ public final class ScriptRunnable extends AbstractScriptRunnable implements ITes
|
||||
pb.redirectError(errorFileHandle);
|
||||
final Process process = pb.start();
|
||||
|
||||
process.waitFor();
|
||||
final int exitCode = process.waitFor();
|
||||
|
||||
if (errorFileHandle.length() > 0) {
|
||||
if (exitCode != 0 || errorFileHandle.length() > 0) {
|
||||
if (expectRunFailure) {
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user