< prev index next >
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java
Print this page
@@ -43,10 +43,11 @@
import jdk.nashorn.internal.ir.BlockStatement;
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;
import jdk.nashorn.internal.ir.Expression;
import jdk.nashorn.internal.ir.ExpressionStatement;
@@ -68,18 +69,21 @@
import jdk.nashorn.internal.ir.Statement;
import jdk.nashorn.internal.ir.SwitchNode;
import jdk.nashorn.internal.ir.Symbol;
import jdk.nashorn.internal.ir.ThrowNode;
import jdk.nashorn.internal.ir.TryNode;
+import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.ir.VarNode;
import jdk.nashorn.internal.ir.WhileNode;
import jdk.nashorn.internal.ir.WithNode;
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
import jdk.nashorn.internal.ir.visitor.SimpleNodeVisitor;
import jdk.nashorn.internal.parser.Token;
import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable;
import jdk.nashorn.internal.runtime.logging.Logger;
@@ -96,10 +100,11 @@
@Logger(name="lower")
final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Loggable {
private final DebugLogger log;
private final boolean es6;
+ private final Source source;
// Conservative pattern to test if element names consist of characters valid for identifiers.
// This matches any non-zero length alphanumeric string including _ and $ and not starting with a digit.
private static final Pattern SAFE_PROPERTY_NAME = Pattern.compile("[a-zA-Z_$][\\w$]*");
@@ -144,10 +149,11 @@
}
});
this.log = initLogger(compiler.getContext());
this.es6 = compiler.getScriptEnvironment()._es6;
+ this.source = compiler.getSource();
}
@Override
public DebugLogger getLogger() {
return log;
@@ -239,10 +245,14 @@
compilerConstant(RETURN),
expr));
}
}
+ if (es6 && expressionStatement.destructuringDeclarationType() != null) {
+ throwNotImplementedYet("es6.destructuring", expressionStatement);
+ }
+
return addStatement(node);
}
@Override
public Node leaveBlockStatement(final BlockStatement blockStatement) {
@@ -268,10 +278,33 @@
}
return newForNode;
}
@Override
+ public boolean enterFunctionNode(final FunctionNode functionNode) {
+ if (es6) {
+ if (functionNode.getKind() == FunctionNode.Kind.MODULE) {
+ throwNotImplementedYet("es6.module", functionNode);
+ }
+
+ if (functionNode.getKind() == FunctionNode.Kind.GENERATOR) {
+ throwNotImplementedYet("es6.generator", functionNode);
+ }
+
+ int numParams = functionNode.getNumOfParams();
+ if (numParams > 1) {
+ final IdentNode lastParam = functionNode.getParameter(numParams - 1);
+ if (lastParam.isRestParameter()) {
+ throwNotImplementedYet("es6.rest.param", lastParam);
+ }
+ }
+ }
+
+ return super.enterFunctionNode(functionNode);
+ }
+
+ @Override
public Node leaveFunctionNode(final FunctionNode functionNode) {
log.info("END FunctionNode: ", functionNode.getName());
return functionNode;
}
@@ -576,10 +609,25 @@
newCatchBlocks.add(catchAllBlock(tryNode));
return tryNode.setCatchBlocks(lc, newCatchBlocks);
}
@Override
+ public boolean enterUnaryNode(final UnaryNode unaryNode) {
+ if (es6) {
+ if (unaryNode.isTokenType(TokenType.YIELD) ||
+ unaryNode.isTokenType(TokenType.YIELD_STAR)) {
+ throwNotImplementedYet("es6.yield", unaryNode);
+ } else if (unaryNode.isTokenType(TokenType.SPREAD_ARGUMENT) ||
+ unaryNode.isTokenType(TokenType.SPREAD_ARRAY)) {
+ throwNotImplementedYet("es6.spread", unaryNode);
+ }
+ }
+
+ return super.enterUnaryNode(unaryNode);
+ }
+
+ @Override
public Node leaveVarNode(final VarNode varNode) {
addStatement(varNode);
if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION)
&& lc.getCurrentFunction().isProgram()
&& ((FunctionNode) varNode.getInit()).isAnonymous()) {
@@ -606,10 +654,16 @@
@Override
public Node leaveWithNode(final WithNode withNode) {
return addStatement(withNode);
}
+ @Override
+ public boolean enterClassNode(final ClassNode classNode) {
+ throwNotImplementedYet("es6.class", classNode);
+ return super.enterClassNode(classNode);
+ }
+
/**
* Given a function node that is a callee in a CallNode, replace it with
* the appropriate marker function. This is used by {@link CodeGenerator}
* for fast scope calls
*
@@ -764,6 +818,15 @@
return ((IdentNode)lhs).getName().equals(RETURN.symbolName());
}
}
return false;
}
+
+ private void throwNotImplementedYet(final String msgId, final Node node) {
+ final long token = node.getToken();
+ final int line = source.getLine(node.getStart());
+ final int column = source.getColumn(node.getStart());
+ final String message = ECMAErrors.getMessage("unimplemented." + msgId);
+ final String formatted = ErrorManager.format(message, source, line, column, token);
+ throw new RuntimeException(formatted);
+ }
}
< prev index next >