/** * Convert execString to a call to $EXEC. * * @param primaryToken Original string token. * @return callNode to $EXEC. */ CallNode execString(final int primaryLine, final long primaryToken) { // Synthesize an ident to call $EXEC. final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME); // Skip over EXECSTRING. next(); // Set up argument list for call. // Skip beginning of edit string expression. expect(LBRACE); // Add the following expression to arguments. final List<Expression> arguments = Collections.singletonList(expression()); // Skip ending of edit string expression. expect(RBRACE); return new CallNode(primaryLine, primaryToken, finish, execIdent, arguments, false); }
/** * Check whether a call node may be a call to eval. In that case we * clone the args in order to create the following construct in * {@link CodeGenerator} * * <pre> * if (calledFuntion == buildInEval) { * eval(cloned arg); * } else { * cloned arg; * } * </pre> * * @param callNode call node to check if it's an eval */ private CallNode checkEval(final CallNode callNode) { if (callNode.getFunction() instanceof IdentNode) { final List<Expression> args = callNode.getArgs(); final IdentNode callee = (IdentNode)callNode.getFunction(); // 'eval' call with at least one argument if (args.size() >= 1 && EVAL.symbolName().equals(callee.getName())) { final List<Expression> evalArgs = new ArrayList<>(args.size()); for(final Expression arg: args) { evalArgs.add((Expression)ensureUniqueNamesIn(arg).accept(this)); } return callNode.setEvalArgs(new CallNode.EvalArgs(evalArgs, evalLocation(callee))); } } return callNode; }
private boolean hasApplies(final FunctionNode functionNode) { try { functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { @Override public boolean enterFunctionNode(final FunctionNode fn) { return fn == functionNode; } @Override public boolean enterCallNode(final CallNode callNode) { if (isApply(callNode)) { throw HAS_APPLIES; } return true; } }); } catch (final AppliesFoundException e) { return true; } log.fine("There are no applies in ", DebugLogger.quote(functionNode.getName()), " - nothing to do."); return false; // no applies }
private void markEvalInArrowParameterList(final ParserContextBlockNode parameterBlock) { final Iterator<ParserContextFunctionNode> iter = lc.getFunctions(); final ParserContextFunctionNode current = iter.next(); final ParserContextFunctionNode parent = iter.next(); if (parent.getFlag(FunctionNode.HAS_EVAL) != 0) { // we might have flagged has-eval in the parent function during parsing the parameter list, // if the parameter list contains eval; must tag arrow function as has-eval. for (final Statement st : parameterBlock.getStatements()) { st.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { @Override public boolean enterCallNode(final CallNode callNode) { if (callNode.getFunction() instanceof IdentNode && ((IdentNode) callNode.getFunction()).getName().equals("eval")) { current.setFlag(FunctionNode.HAS_EVAL); } return true; } }); } // TODO: function containing the arrow function should not be flagged has-eval } }
private boolean hasApplies(final FunctionNode functionNode) { try { functionNode.accept(new SimpleNodeVisitor() { @Override public boolean enterFunctionNode(final FunctionNode fn) { return fn == functionNode; } @Override public boolean enterCallNode(final CallNode callNode) { if (isApply(callNode)) { throw HAS_APPLIES; } return true; } }); } catch (final AppliesFoundException e) { return true; } log.fine("There are no applies in ", DebugLogger.quote(functionNode.getName()), " - nothing to do."); return false; // no applies }
/** * Convert execString to a call to $EXEC. * * @param primaryToken Original string token. * @return callNode to $EXEC. */ CallNode execString(final int primaryLine, final long primaryToken) { // Synthesize an ident to call $EXEC. final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME); // Skip over EXECSTRING. next(); // Set up argument list for call. // Skip beginning of edit string expression. expect(LBRACE); // Add the following expression to arguments. final List<Expression> arguments = Collections.singletonList(expression()); // Skip ending of edit string expression. expect(RBRACE); return new CallNode(primaryLine, primaryToken, finish, execIdent, arguments); }
/** * Check whether a call node may be a call to eval. In that case we * clone the args in order to create the following construct in * {@link CodeGenerator} * * <pre> * if (calledFuntion == buildInEval) { * eval(cloned arg); * } else { * cloned arg; * } * </pre> * * @param callNode call node to check if it's an eval */ private CallNode checkEval(final CallNode callNode) { if (callNode.getFunction() instanceof IdentNode) { final List<Expression> args = callNode.getArgs(); final IdentNode callee = (IdentNode)callNode.getFunction(); // 'eval' call with at least one argument if (args.size() >= 1 && EVAL.symbolName().equals(callee.getName())) { final FunctionNode currentFunction = lc.getCurrentFunction(); return callNode.setEvalArgs( new CallNode.EvalArgs( (Expression)ensureUniqueNamesIn(args.get(0)).accept(this), compilerConstant(THIS), evalLocation(callee), currentFunction.isStrict())); } } return callNode; }
/** * NewExpression : * MemberExpression * new NewExpression * * See 11.2 * * Parse new expression. * @return Expression node. */ private Expression newExpression() { final long newToken = token; // NEW is tested in caller. next(); // Get function base. final int callLine = line; final Expression constructor = memberExpression(); if (constructor == null) { return null; } // Get arguments. ArrayList<Expression> arguments; // Allow for missing arguments. if (type == LPAREN) { arguments = argumentList(); } else { arguments = new ArrayList<>(); } // Nashorn extension: This is to support the following interface implementation // syntax: // // var r = new java.lang.Runnable() { // run: function() { println("run"); } // }; // // The object literal following the "new Constructor()" expresssion // is passed as an additional (last) argument to the constructor. if (!env._no_syntax_extensions && type == LBRACE) { arguments.add(objectLiteral()); } final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, optimizeList(arguments), true); return new UnaryNode(newToken, callNode); }
@Override public boolean enterCallNode(final CallNode callNode) { enterDefault(callNode); type("CallExpression"); comma(); property("callee"); callNode.getFunction().accept(this); comma(); array("arguments", callNode.getArgs()); return leave(); }
@Override public Node leaveCallNode(final CallNode callNode) { //apply needs to be a global symbol or we don't allow it final List<IdentNode> newParams = explodedArguments.peek(); if (isApply(callNode)) { final List<Expression> newArgs = new ArrayList<>(); for (final Expression arg : callNode.getArgs()) { if (arg instanceof IdentNode && ARGUMENTS.equals(((IdentNode)arg).getName())) { newArgs.addAll(newParams); } else { newArgs.add(arg); } } changed.add(lc.getCurrentFunction().getId()); final CallNode newCallNode = callNode.setArgs(newArgs).setIsApplyToCall(); if (log.isEnabled()) { log.fine("Transformed ", callNode, " from apply to call => ", newCallNode, " in ", DebugLogger.quote(lc.getCurrentFunction().getName())); } return newCallNode; } return callNode; }
private void loadNEW(final UnaryNode unaryNode) { final CallNode callNode = (CallNode)unaryNode.getExpression(); final List<Expression> args = callNode.getArgs(); // Load function reference. loadExpressionAsObject(callNode.getFunction()); // must detect type error method.dynamicNew(1 + loadArgs(args), getCallSiteFlags()); }
@Override public boolean enterCallNode(final CallNode callNode) { curExpr = null; callNode.getFunction().accept(this); final ExpressionTree funcTree = curExpr; final List<? extends ExpressionTree> argTrees = translateExprs(callNode.getArgs()); curExpr = new FunctionCallTreeImpl(callNode, funcTree, argTrees); return false; }
FunctionCallTreeImpl(final CallNode node, final ExpressionTree function, final List<? extends ExpressionTree> arguments) { super(node); this.function = function; this.arguments = arguments; }
@Override public boolean enterCallNode(final CallNode callNode) { visitExpression(callNode.getFunction()); visitExpressions(callNode.getArgs()); final CallNode.EvalArgs evalArgs = callNode.getEvalArgs(); if (evalArgs != null) { visitExpressions(evalArgs.getArgs()); } return pushExpressionType(callNode); }
private void loadNEW(final UnaryNode unaryNode) { final CallNode callNode = (CallNode)unaryNode.getExpression(); final List<Expression> args = callNode.getArgs(); final Expression func = callNode.getFunction(); // Load function reference. loadExpressionAsObject(func); // must detect type error method.dynamicNew(1 + loadArgs(args), getCallSiteFlags(), func.toString(false)); }