@Override public boolean enterReturnNode(final ReturnNode returnNode) { enterDefault(returnNode); type("ReturnStatement"); comma(); final Node arg = returnNode.getExpression(); property("argument"); if (arg != null) { arg.accept(this); } else { nullValue(); } return leave(); }
@Override public boolean enterReturnNode(final ReturnNode returnNode) { if(!reachable) { return false; } final Expression returnExpr = returnNode.getExpression(); final Type returnExprType; if(returnExpr != null) { returnExpr.accept(this); returnExprType = getType(returnExpr); } else { returnExprType = Type.UNDEFINED; } returnType = Type.widestReturnType(returnType, returnExprType); doesNotContinueSequentially(); return false; }
@Override public boolean enterReturnNode(final ReturnNode returnNode) { if(!method.isReachable()) { return false; } enterStatement(returnNode); method.registerReturn(); final Type returnType = lc.getCurrentFunction().getReturnType(); final Expression expression = returnNode.getExpression(); if (expression != null) { loadExpressionUnbounded(expression); } else { method.loadUndefined(returnType); } method._return(returnType); return false; }
@Override public boolean enterReturnNode(final ReturnNode returnNode) { if(!reachable) { return false; } final Expression returnExpr = returnNode.getExpression(); final Type returnExprType; if(returnExpr != null) { returnExprType = visitExpressionOnEmptyStack(returnExpr).type; } else { assertTypeStackIsEmpty(); returnExprType = Type.UNDEFINED; } returnType = Type.widestReturnType(returnType, returnExprType); doesNotContinueSequentially(); return false; }
@Override public boolean enterReturnNode(final ReturnNode returnNode) { if(!method.isReachable()) { return false; } enterStatement(returnNode); final Type returnType = lc.getCurrentFunction().getReturnType(); final Expression expression = returnNode.getExpression(); if (expression != null) { loadExpressionUnbounded(expression); } else { method.loadUndefined(returnType); } method._return(returnType); return false; }
@Override public Node leaveReturnNode(final ReturnNode returnNode) { final Expression expr = returnNode.getExpression(); final Type returnType; if (expr != null) { //we can't do parameter specialization if we return something that hasn't been typed yet final Symbol symbol = expr.getSymbol(); if (expr.getType().isUnknown() && symbol.isParam()) { symbol.setType(Type.OBJECT); } returnType = widestReturnType(returnTypes.pop(), symbol.getSymbolType()); } else { returnType = Type.OBJECT; //undefined } LOG.info("Returntype is now ", returnType); returnTypes.push(returnType); end(returnNode); return returnNode; }
@Override public Node leaveBlock(final Block block) { //now we have committed the entire statement list to the block, but we need to truncate //whatever is after the last terminal. block append won't append past it if (lc.isFunctionBody()) { final FunctionNode currentFunction = lc.getCurrentFunction(); final boolean isProgram = currentFunction.isProgram(); final Statement last = lc.getLastStatement(); final ReturnNode returnNode = new ReturnNode( last == null ? currentFunction.getLineNumber() : last.getLineNumber(), //TODO? currentFunction.getToken(), currentFunction.getFinish(), isProgram ? compilerConstant(RETURN) : LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)); returnNode.accept(this); } return block; }
@Override public boolean enterReturnNode(final ReturnNode returnNode) { lineNumber(returnNode); method.registerReturn(); final Type returnType = lc.getCurrentFunction().getReturnType(); final Expression expression = returnNode.getExpression(); if (expression != null) { load(expression); } else { method.loadUndefined(returnType); } method._return(returnType); return false; }
@Override public Node leaveReturnNode(final ReturnNode returnNode) { final Expression expr = returnNode.getExpression(); final Type returnType; if (expr != null) { //we can't do parameter specialization if we return something that hasn't been typed yet final Symbol symbol = expr.getSymbol(); if (expr.getType().isUnknown() && symbol.isParam()) { symbol.setType(Type.OBJECT); } returnType = Type.widest(returnTypes.pop(), symbol.getSymbolType()); } else { returnType = Type.OBJECT; //undefined } LOG.info("Returntype is now ", returnType); returnTypes.push(returnType); end(returnNode); return returnNode; }
/** * ReturnStatement : * return Expression? ; // [no LineTerminator here] * * See 12.9 * * Parse RETURN statement. */ private void returnStatement() { // check for return outside function if (lc.getCurrentFunction().getKind() == FunctionNode.Kind.SCRIPT) { throw error(AbstractParser.message("invalid.return")); } // Capture RETURN token. final int returnLine = line; final long returnToken = token; // RETURN tested in caller. nextOrEOL(); Expression expression = null; // SEMICOLON or expression. switch (type) { case RBRACE: case SEMICOLON: case EOL: case EOF: break; default: expression = expression(); break; } endOfLine(); // Construct and add RETURN node. appendStatement(new ReturnNode(returnLine, returnToken, finish, expression)); }
/** * YieldStatement : * yield Expression? ; // [no LineTerminator here] * * JavaScript 1.8 * * Parse YIELD statement. */ private void yieldStatement() { // Capture YIELD token. final int yieldLine = line; final long yieldToken = token; // YIELD tested in caller. nextOrEOL(); Expression expression = null; // SEMICOLON or expression. switch (type) { case RBRACE: case SEMICOLON: case EOL: case EOF: break; default: expression = expression(); break; } endOfLine(); // Construct and add YIELD node. appendStatement(new ReturnNode(yieldLine, yieldToken, finish, expression)); }
@Override public Node leaveReturnNode(final ReturnNode returnNode) { if(inSplitNode()) { appendStatement(new SetSplitState(RETURN_STATE, returnNode.getLineNumber())); getCurrentSplitState().hasReturn = true; } appendStatement(returnNode); return returnNode; }
private void createSyntheticReturn(final Block body) { final FunctionNode functionNode = lc.getCurrentFunction(); final long token = functionNode.getToken(); final int finish = functionNode.getFinish(); final List<Statement> statements = body.getStatements(); final int lineNumber = statements.isEmpty() ? functionNode.getLineNumber() : statements.get(statements.size() - 1).getLineNumber(); final IdentNode returnExpr; if(functionNode.isProgram()) { returnExpr = new IdentNode(token, finish, RETURN.symbolName()).setSymbol(getCompilerConstantSymbol(functionNode, RETURN)); } else { returnExpr = null; } syntheticReturn = new ReturnNode(lineNumber, token, finish, returnExpr); syntheticReturn.accept(this); }
/** * ReturnStatement : * return Expression? ; // [no LineTerminator here] * * See 12.9 * * Parse RETURN statement. */ private void returnStatement() { // check for return outside function if (lc.getCurrentFunction().getKind() == FunctionNode.Kind.SCRIPT || lc.getCurrentFunction().getKind() == FunctionNode.Kind.MODULE) { throw error(AbstractParser.message("invalid.return")); } // Capture RETURN token. final int returnLine = line; final long returnToken = token; // RETURN tested in caller. nextOrEOL(); Expression expression = null; // SEMICOLON or expression. switch (type) { case RBRACE: case SEMICOLON: case EOL: case EOF: break; default: expression = expression(); break; } endOfLine(); // Construct and add RETURN node. appendStatement(new ReturnNode(returnLine, returnToken, finish, expression)); }