--- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IRTranslator.java 2020-04-15 18:46:10.000000000 +0530 +++ /dev/null 2020-04-15 18:46:10.000000000 +0530 @@ -1,624 +0,0 @@ -/* - * 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. 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.api.tree; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import jdk.nashorn.internal.ir.AccessNode; -import jdk.nashorn.internal.ir.BinaryNode; -import jdk.nashorn.internal.ir.Block; -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.ErrorNode; -import jdk.nashorn.internal.ir.Expression; -import jdk.nashorn.internal.ir.ExpressionStatement; -import jdk.nashorn.internal.ir.ForNode; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.IfNode; -import jdk.nashorn.internal.ir.IndexNode; -import jdk.nashorn.internal.ir.LabelNode; -import jdk.nashorn.internal.ir.LiteralNode; -import jdk.nashorn.internal.ir.Node; -import jdk.nashorn.internal.ir.ObjectNode; -import jdk.nashorn.internal.ir.PropertyNode; -import jdk.nashorn.internal.ir.ReturnNode; -import jdk.nashorn.internal.ir.RuntimeNode; -import jdk.nashorn.internal.ir.SplitNode; -import jdk.nashorn.internal.ir.Statement; -import jdk.nashorn.internal.ir.SwitchNode; -import jdk.nashorn.internal.ir.TemplateLiteral; -import jdk.nashorn.internal.ir.TernaryNode; -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.SimpleNodeVisitor; -import jdk.nashorn.internal.parser.Lexer; -import jdk.nashorn.internal.parser.TokenType; - -/** - * This class translates from nashorn IR Node objects - * to nashorn parser API Tree objects. - */ -final class IRTranslator extends SimpleNodeVisitor { - - public IRTranslator() { - } - - // currently translated Statement - private StatementTreeImpl curStat; - // currently translated Expression - private ExpressionTreeImpl curExpr; - - // entry point for translator - CompilationUnitTree translate(final FunctionNode node) { - if (node == null) { - return null; - } - - assert node.getKind() == FunctionNode.Kind.SCRIPT || - node.getKind() == FunctionNode.Kind.MODULE : - "script or module function expected"; - - final Block body = node.getBody(); - return new CompilationUnitTreeImpl(node, - translateStats(body != null? getOrderedStatements(body.getStatements()) : null), - translateModule(node)); - } - - @Override - public boolean enterAccessNode(final AccessNode accessNode) { - curExpr = new MemberSelectTreeImpl(accessNode, translateExpr(accessNode.getBase())); - return false; - } - - @Override - public boolean enterBlock(final Block block) { - return handleBlock(block, false); - } - - @Override - public boolean enterBinaryNode(final BinaryNode binaryNode) { - if (binaryNode.isAssignment()) { - final ExpressionTree srcTree = translateExpr(binaryNode.getAssignmentSource()); - final ExpressionTree destTree = translateExpr(binaryNode.getAssignmentDest()); - - if (binaryNode.isTokenType(TokenType.ASSIGN)) { - curExpr = new AssignmentTreeImpl(binaryNode, destTree, srcTree); - } else { - curExpr = new CompoundAssignmentTreeImpl(binaryNode, destTree, srcTree); - } - } else { - final ExpressionTree leftTree = translateExpr(binaryNode.lhs()); - final ExpressionTree rightTree = translateExpr(binaryNode.rhs()); - - if (binaryNode.isTokenType(TokenType.INSTANCEOF)) { - curExpr = new InstanceOfTreeImpl(binaryNode, leftTree, rightTree); - } else { - curExpr = new BinaryTreeImpl(binaryNode, leftTree, rightTree); - } - } - - return false; - } - - @Override - public boolean enterBreakNode(final BreakNode breakNode) { - curStat = new BreakTreeImpl(breakNode); - return false; - } - - @Override - public boolean enterCallNode(final CallNode callNode) { - curExpr = null; - callNode.getFunction().accept(this); - final ExpressionTree funcTree = curExpr; - final List argTrees = translateExprs(callNode.getArgs()); - curExpr = new FunctionCallTreeImpl(callNode, funcTree, argTrees); - return false; - } - - @Override - public boolean enterCaseNode(final CaseNode caseNode) { - assert false : "should not reach here!"; - return false; - } - - @Override - public boolean enterCatchNode(final CatchNode catchNode) { - assert false : "should not reach here"; - return false; - } - - @Override - public boolean enterContinueNode(final ContinueNode continueNode) { - curStat = new ContinueTreeImpl(continueNode); - return false; - } - - @Override - public boolean enterDebuggerNode(final DebuggerNode debuggerNode) { - curStat = new DebuggerTreeImpl(debuggerNode); - return false; - } - - @Override - public boolean enterEmptyNode(final EmptyNode emptyNode) { - curStat = new EmptyStatementTreeImpl(emptyNode); - return false; - } - - @Override - public boolean enterErrorNode(final ErrorNode errorNode) { - curExpr = new ErroneousTreeImpl(errorNode); - return false; - } - - @Override - public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) { - if (expressionStatement.destructuringDeclarationType() != null) { - final ExpressionTree expr = translateExpr(expressionStatement.getExpression()); - assert expr instanceof AssignmentTree : "destructuring decl. statement does not have assignment"; - final AssignmentTree assign = (AssignmentTree)expr; - curStat = new DestructuringDeclTreeImpl(expressionStatement, assign.getVariable(), assign.getExpression()); - } else { - curStat = new ExpressionStatementTreeImpl(expressionStatement, - translateExpr(expressionStatement.getExpression())); - } - return false; - } - - @Override - public boolean enterBlockStatement(final BlockStatement blockStatement) { - final Block block = blockStatement.getBlock(); - if (blockStatement.isSynthetic()) { - assert block != null && block.getStatements() != null && block.getStatements().size() == 1; - curStat = translateStat(block.getStatements().get(0)); - } else { - curStat = new BlockTreeImpl(blockStatement, - translateStats(block != null? block.getStatements() : null)); - } - return false; - } - - @Override - public boolean enterForNode(final ForNode forNode) { - if (forNode.isForIn()) { - curStat = new ForInLoopTreeImpl(forNode, - translateExpr(forNode.getInit()), - translateExpr(forNode.getModify()), - translateBlock(forNode.getBody())); - } else if (forNode.isForOf()) { - curStat = new ForOfLoopTreeImpl(forNode, - translateExpr(forNode.getInit()), - translateExpr(forNode.getModify()), - translateBlock(forNode.getBody())); - } else { - curStat = new ForLoopTreeImpl(forNode, - translateExpr(forNode.getInit()), - translateExpr(forNode.getTest()), - translateExpr(forNode.getModify()), - translateBlock(forNode.getBody())); - } - - return false; - } - - @Override - public boolean enterFunctionNode(final FunctionNode functionNode) { - assert !functionNode.isDeclared() || functionNode.isAnonymous() : "should not reach here for function declaration"; - - final List paramTrees = translateParameters(functionNode); - final BlockTree blockTree = (BlockTree) translateBlock(functionNode.getBody(), true); - curExpr = new FunctionExpressionTreeImpl(functionNode, paramTrees, blockTree); - - return false; - } - - @Override - public boolean enterIdentNode(final IdentNode identNode) { - curExpr = new IdentifierTreeImpl(identNode); - return false; - } - - @Override - public boolean enterIfNode(final IfNode ifNode) { - curStat = new IfTreeImpl(ifNode, - translateExpr(ifNode.getTest()), - translateBlock(ifNode.getPass()), - translateBlock(ifNode.getFail())); - return false; - } - - @Override - public boolean enterIndexNode(final IndexNode indexNode) { - curExpr = new ArrayAccessTreeImpl(indexNode, - translateExpr(indexNode.getBase()), - translateExpr(indexNode.getIndex())); - return false; - } - - @Override - public boolean enterLabelNode(final LabelNode labelNode) { - curStat = new LabeledStatementTreeImpl(labelNode, - translateBlock(labelNode.getBody())); - return false; - } - - @Override - public boolean enterLiteralNode(final LiteralNode literalNode) { - final Object value = literalNode.getValue(); - if (value instanceof Lexer.RegexToken) { - curExpr = new RegExpLiteralTreeImpl(literalNode); - } else if (literalNode.isArray()) { - final List exprNodes = literalNode.getElementExpressions(); - final List exprTrees = new ArrayList<>(exprNodes.size()); - for (final Node node : exprNodes) { - if (node == null) { - exprTrees.add(null); - } else { - curExpr = null; - node.accept(this); - assert curExpr != null : "null for " + node; - exprTrees.add(curExpr); - } - } - curExpr = new ArrayLiteralTreeImpl(literalNode, exprTrees); - } else { - curExpr = new LiteralTreeImpl(literalNode); - } - - return false; - } - - @Override - public boolean enterObjectNode(final ObjectNode objectNode) { - final List propNodes = objectNode.getElements(); - final List propTrees = translateProperties(propNodes); - curExpr = new ObjectLiteralTreeImpl(objectNode, propTrees); - return false; - } - - @Override - public boolean enterPropertyNode(final PropertyNode propertyNode) { - assert false : "should not reach here!"; - return false; - } - - @Override - public boolean enterReturnNode(final ReturnNode returnNode) { - curStat = new ReturnTreeImpl(returnNode, - translateExpr(returnNode.getExpression())); - return false; - } - - @Override - public boolean enterRuntimeNode(final RuntimeNode runtimeNode) { - assert false : "should not reach here: RuntimeNode"; - return false; - } - - @Override - public boolean enterSplitNode(final SplitNode splitNode) { - assert false : "should not reach here!"; - return false; - } - - @Override - public boolean enterSwitchNode(final SwitchNode switchNode) { - final List caseNodes = switchNode.getCases(); - final List caseTrees = new ArrayList<>(caseNodes.size()); - for (final CaseNode caseNode : caseNodes) { - final Block body = caseNode.getBody(); - caseTrees.add( - new CaseTreeImpl(caseNode, - translateExpr(caseNode.getTest()), - translateStats(body != null? body.getStatements() : null))); - } - - curStat = new SwitchTreeImpl(switchNode, - translateExpr(switchNode.getExpression()), - caseTrees); - return false; - } - - @Override - public boolean enterTemplateLiteral(final TemplateLiteral templateLiteral) { - curExpr = new TemplateLiteralTreeImpl(templateLiteral, translateExprs(templateLiteral.getExpressions())); - return false; - } - - @Override - public boolean enterTernaryNode(final TernaryNode ternaryNode) { - curExpr = new ConditionalExpressionTreeImpl(ternaryNode, - translateExpr(ternaryNode.getTest()), - translateExpr(ternaryNode.getTrueExpression()), - translateExpr(ternaryNode.getFalseExpression())); - return false; - } - - @Override - public boolean enterThrowNode(final ThrowNode throwNode) { - curStat = new ThrowTreeImpl(throwNode, - translateExpr(throwNode.getExpression())); - return false; - } - - @Override - public boolean enterTryNode(final TryNode tryNode) { - final List catchNodes = tryNode.getCatches(); - final List catchTrees = new ArrayList<>(catchNodes.size()); - for (final CatchNode catchNode : catchNodes) { - catchTrees.add(new CatchTreeImpl(catchNode, - translateExpr(catchNode.getException()), - (BlockTree) translateBlock(catchNode.getBody()), - translateExpr(catchNode.getExceptionCondition()))); - } - - curStat = new TryTreeImpl(tryNode, - (BlockTree) translateBlock(tryNode.getBody()), - catchTrees, - (BlockTree) translateBlock(tryNode.getFinallyBody())); - - return false; - } - - @Override - public boolean enterUnaryNode(final UnaryNode unaryNode) { - if (unaryNode.isTokenType(TokenType.NEW)) { - curExpr = new NewTreeImpl(unaryNode, - translateExpr(unaryNode.getExpression())); - } else if (unaryNode.isTokenType(TokenType.YIELD) || - unaryNode.isTokenType(TokenType.YIELD_STAR)) { - curExpr = new YieldTreeImpl(unaryNode, - translateExpr(unaryNode.getExpression())); - } else if (unaryNode.isTokenType(TokenType.SPREAD_ARGUMENT) || - unaryNode.isTokenType(TokenType.SPREAD_ARRAY)) { - curExpr = new SpreadTreeImpl(unaryNode, - translateExpr(unaryNode.getExpression())); - } else { - curExpr = new UnaryTreeImpl(unaryNode, - translateExpr(unaryNode.getExpression())); - } - return false; - } - - @Override - public boolean enterVarNode(final VarNode varNode) { - final Expression initNode = varNode.getInit(); - if (initNode instanceof FunctionNode && ((FunctionNode)initNode).isDeclared()) { - final FunctionNode funcNode = (FunctionNode) initNode; - - final List paramTrees = translateParameters(funcNode); - final BlockTree blockTree = (BlockTree) translateBlock(funcNode.getBody(), true); - curStat = new FunctionDeclarationTreeImpl(varNode, paramTrees, blockTree); - } else if (initNode instanceof ClassNode && ((ClassNode)initNode).isStatement()) { - final ClassNode classNode = (ClassNode) initNode; - - curStat = new ClassDeclarationTreeImpl(varNode, - translateIdent(classNode.getIdent()), - translateExpr(classNode.getClassHeritage()), - translateProperty(classNode.getConstructor()), - translateProperties(classNode.getClassElements())); - } else { - curStat = new VariableTreeImpl(varNode, translateIdent(varNode.getName()), translateExpr(initNode)); - } - - return false; - } - - @Override - public boolean enterWhileNode(final WhileNode whileNode) { - final ExpressionTree condTree = translateExpr(whileNode.getTest()); - final StatementTree statTree = translateBlock(whileNode.getBody()); - - if (whileNode.isDoWhile()) { - curStat = new DoWhileLoopTreeImpl(whileNode, condTree, statTree); - } else { - curStat = new WhileLoopTreeImpl(whileNode, condTree, statTree); - } - - return false; - } - - @Override - public boolean enterWithNode(final WithNode withNode) { - curStat = new WithTreeImpl(withNode, - translateExpr(withNode.getExpression()), - translateBlock(withNode.getBody())); - - return false; - } - - /** - * Callback for entering a ClassNode - * - * @param classNode the node - * @return true if traversal should continue and node children be traversed, false otherwise - */ - @Override - public boolean enterClassNode(final ClassNode classNode) { - assert !classNode.isStatement(): "should not reach here for class declaration"; - final IdentNode className = classNode.getIdent(); - curExpr = new ClassExpressionTreeImpl(classNode, - className != null? translateIdent(className) : null, - translateExpr(classNode.getClassHeritage()), - translateProperty(classNode.getConstructor()), - translateProperties(classNode.getClassElements())); - - return false; - } - - private StatementTree translateBlock(final Block blockNode) { - return translateBlock(blockNode, false); - } - - private StatementTree translateBlock(final Block blockNode, final boolean sortStats) { - if (blockNode == null) { - return null; - } - curStat = null; - handleBlock(blockNode, sortStats); - return curStat; - } - - private boolean handleBlock(final Block block, final boolean sortStats) { - // FIXME: revisit this! - if (block.isSynthetic()) { - final int statCount = block.getStatementCount(); - switch (statCount) { - case 0: { - final EmptyNode emptyNode = new EmptyNode(-1, block.getToken(), block.getFinish()); - curStat = new EmptyStatementTreeImpl(emptyNode); - return false; - } - case 1: { - curStat = translateStat(block.getStatements().get(0)); - return false; - } - default: { - // fall through - break; - } - } - } - - final List stats = block.getStatements(); - curStat = new BlockTreeImpl(block, - translateStats(sortStats? getOrderedStatements(stats) : stats)); - return false; - } - - private List getOrderedStatements(final List stats) { - final List statList = new ArrayList<>(stats); - statList.sort(Comparator.comparingInt(Node::getSourceOrder)); - return statList; - } - - private List translateStats(final List stats) { - if (stats == null) { - return null; - } - final List statTrees = new ArrayList<>(stats.size()); - for (final Statement stat : stats) { - curStat = null; - stat.accept(this); - assert curStat != null; - statTrees.add(curStat); - } - return statTrees; - } - - private List translateParameters(final FunctionNode func) { - final Map paramExprs = func.getParameterExpressions(); - if (paramExprs != null) { - final List params = func.getParameters(); - final List exprTrees = new ArrayList<>(params.size()); - for (final IdentNode ident : params) { - final Expression expr = paramExprs.containsKey(ident)? paramExprs.get(ident) : ident; - curExpr = null; - expr.accept(this); - assert curExpr != null; - exprTrees.add(curExpr); - } - return exprTrees; - } else { - return translateExprs(func.getParameters()); - } - } - - private List translateExprs(final List exprs) { - if (exprs == null) { - return null; - } - final List exprTrees = new ArrayList<>(exprs.size()); - for (final Expression expr : exprs) { - curExpr = null; - expr.accept(this); - assert curExpr != null; - exprTrees.add(curExpr); - } - return exprTrees; - } - - private ExpressionTreeImpl translateExpr(final Expression expr) { - if (expr == null) { - return null; - } - - curExpr = null; - expr.accept(this); - assert curExpr != null : "null for " + expr; - return curExpr; - } - - private StatementTreeImpl translateStat(final Statement stat) { - if (stat == null) { - return null; - } - - curStat = null; - stat.accept(this); - assert curStat != null : "null for " + stat; - return curStat; - } - - private static IdentifierTree translateIdent(final IdentNode ident) { - return new IdentifierTreeImpl(ident); - } - - private List translateProperties(final List propNodes) { - final List propTrees = new ArrayList<>(propNodes.size()); - for (final PropertyNode propNode : propNodes) { - propTrees.add(translateProperty(propNode)); - } - return propTrees; - } - - private PropertyTree translateProperty(final PropertyNode propNode) { - return new PropertyTreeImpl(propNode, - translateExpr(propNode.getKey()), - translateExpr(propNode.getValue()), - (FunctionExpressionTree) translateExpr(propNode.getGetter()), - (FunctionExpressionTree) translateExpr(propNode.getSetter())); - } - - private ModuleTree translateModule(final FunctionNode func) { - return func.getKind() == FunctionNode.Kind.MODULE? - ModuleTreeImpl.create(func) : null; - } -}