/** * Creates a JMultiExpression from a set of JExpressionStatements, optionally terminated by a * JReturnStatement. If the method doesn't match this pattern, it returns <code>null</code>. * * <p>If a method has a non-void return statement and can be represented as a multi-expression, * the output of the multi-expression will be the return expression of the method. If the method * is void, the output of the multi-expression should be considered undefined. */ private JMultiExpression createMultiExpressionFromBody( JMethodBody body, boolean ignoringReturnValue) { JMultiExpression multi = new JMultiExpression(body.getSourceInfo()); CloneCalleeExpressionVisitor cloner = new CloneCalleeExpressionVisitor(); for (JStatement stmt : body.getStatements()) { if (stmt instanceof JExpressionStatement) { JExpressionStatement exprStmt = (JExpressionStatement) stmt; JExpression expr = exprStmt.getExpr(); JExpression clone = cloner.cloneExpression(expr); multi.addExpressions(clone); } else if (stmt instanceof JReturnStatement) { JReturnStatement returnStatement = (JReturnStatement) stmt; JExpression expr = returnStatement.getExpr(); if (expr != null) { if (!ignoringReturnValue || expr.hasSideEffects()) { JExpression clone = cloner.cloneExpression(expr); clone = maybeCast(clone, body.getMethod().getType()); multi.addExpressions(clone); } } // We hit an unconditional return; no need to evaluate anything else. break; } else { // Any other kind of statement won't be inlinable. return null; } } return multi; }
/** * Creates a JMultiExpression from a set of JExpressionStatements, optionally terminated by a * JReturnStatement. If the method doesn't match this pattern, it returns <code>null</code>. * * <p>If a method has a non-void return statement and can be represented as a multi-expression, * the output of the multi-expression will be the return expression of the method. If the method * is void, the output of the multi-expression should be considered undefined. */ private List<JExpression> extractExpressionsFromBody(JMethodBody body) { List<JExpression> expressions = Lists.newArrayList(); CloneCalleeExpressionVisitor cloner = new CloneCalleeExpressionVisitor(); for (JStatement stmt : body.getStatements()) { if (stmt instanceof JDeclarationStatement) { JDeclarationStatement declStatement = (JDeclarationStatement) stmt; if (!(declStatement.getVariableRef() instanceof JLocalRef)) { return null; } JExpression initializer = declStatement.getInitializer(); if (initializer == null) { continue; } JLocal local = (JLocal) declStatement.getVariableRef().getTarget(); JExpression clone = new JBinaryOperation( stmt.getSourceInfo(), local.getType(), JBinaryOperator.ASG, new JLocalRef(declStatement.getVariableRef().getSourceInfo(), local), cloner.cloneExpression(initializer)); expressions.add(clone); } else if (stmt instanceof JExpressionStatement) { JExpressionStatement exprStmt = (JExpressionStatement) stmt; JExpression expr = exprStmt.getExpr(); JExpression clone = cloner.cloneExpression(expr); expressions.add(clone); } else if (stmt instanceof JReturnStatement) { JReturnStatement returnStatement = (JReturnStatement) stmt; JExpression expr = returnStatement.getExpr(); if (expr != null) { JExpression clone = cloner.cloneExpression(expr); clone = maybeCast(clone, body.getMethod().getType()); expressions.add(clone); } // We hit an unconditional return; no need to evaluate anything else. break; } else { // Any other kind of statement won't be inlinable. return null; } } return expressions; }
@Override public boolean visit(JExpressionStatement x, Context ctx) { expressionsWhoseValuesAreIgnored.push(x.getExpr()); return true; }
@Override public boolean visit(JExpressionStatement x, Context ctx) { ignoringReturnValueFor = x.getExpr(); return true; }