private Result assertThat(String expr, String type, String decls)
      throws UnableToCompleteException {
    ConstantsAssumption.Updater updater =
        new ConstantsAssumption.Updater(new ConstantsAssumption());

    String codeSnippet = decls;
    codeSnippet += "return " + expr + ";";
    JProgram program = compileSnippet(type, codeSnippet);
    JMethod mainMethod = findMainMethod(program);
    JBlock block = ((JMethodBody) mainMethod.getBody()).getBlock();

    List<JStatement> statements = block.getStatements();
    // TODO: not a pretty assumption detection.
    for (JStatement stmt : statements) {
      if (!(stmt instanceof JDeclarationStatement)) {
        continue;
      }
      JDeclarationStatement decl = (JDeclarationStatement) stmt;
      if (decl.getInitializer() != null) {
        updater.set(decl.getVariableRef().getTarget(), (JValueLiteral) decl.getInitializer());
      }
    }

    JReturnStatement returnStatement = (JReturnStatement) statements.get(statements.size() - 1);
    return new Result(ExpressionEvaluator.evaluate(returnStatement.getExpr(), updater.unwrap()));
  }
示例#2
0
 @Override
 public void endVisit(JDeclarationStatement x, Context ctx) {
   super.endVisit(x, ctx);
   lValues.pop();
   // The variable may have been pruned.
   if (isVariablePruned(x.getVariableRef().getTarget())) {
     JExpression replacement =
         makeReplacementForAssignment(x.getSourceInfo(), x.getVariableRef(), x.getInitializer());
     ctx.replaceMe(replacement.makeStatement());
   }
 }
示例#3
0
    /**
     * 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;
    }
示例#4
0
 @Override
 public boolean visit(JDeclarationStatement x, Context ctx) {
   super.visit(x, ctx);
   lValues.push(x.getVariableRef());
   return true;
 }