// This transforms actions that are assignments into one or two parts: if the action depends on a
 // previous property value,
 // it generates a variable declaration that is initialized to the value before the said action.
 // This is the "pre" statement.
 // The second "post" statement is the action converted to an assert that checks if the results are
 // correct.
 // Post and pre increments and decrements and compound assign operators are expanded to simple
 // assigns
 private static List<ActionCheck> generateActionChecks(
     String action, Map<String, Integer> usedVarNames) {
   final List<ActionCheck> checks = new ArrayList<ActionCheck>();
   final List<Statement> statements = actionAsStatements(action);
   for (Statement statement : statements) {
     // We're looking for an action that is an assign expression statement
     if (!(statement instanceof ExpressionStmt)) {
       continue;
     }
     Expression expression = ((ExpressionStmt) statement).getExpression();
     if (!(expression instanceof AssignExpr)) {
       // Check if this is actually a decrement or increment operator
       if (expression instanceof UnaryExpr) {
         final UnaryExpr unary = (UnaryExpr) expression;
         final Operator operator;
         switch (unary.getOperator()) {
           case preDecrement:
           case posDecrement:
             operator = Operator.minus;
             break;
           case preIncrement:
           case posIncrement:
             operator = Operator.plus;
             break;
           default:
             continue;
         }
         // If this is the case, expand it and keep going
         final Expression target = unary.getExpr();
         expression =
             new AssignExpr(
                 target,
                 new BinaryExpr(target, new IntegerLiteralExpr("1"), operator),
                 AssignExpr.Operator.assign);
       } else {
         continue;
       }
     }
     AssignExpr assign = (AssignExpr) expression;
     if (assign.getOperator() != AssignExpr.Operator.assign) {
       // This is a compound assign, so expand it to a simple assign
       final Expression target = assign.getTarget();
       assign =
           new AssignExpr(
               target,
               new BinaryExpr(
                   target,
                   new EnclosedExpr(assign.getValue()),
                   getExpandedOperator(assign.getOperator())),
               AssignExpr.Operator.assign);
     }
     // Generate the check code for the assignment
     checks.add(new ActionCheck(assign, usedVarNames));
   }
   return checks;
 }
 // This logically inverts a condition expression, simplifying the AST if possible
 private static Expression invertCondition(Expression expression) {
   if (expression instanceof UnaryExpr) {
     final UnaryExpr unary = (UnaryExpr) expression;
     // Unary not expression, just remove the not
     if (unary.getOperator() == UnaryExpr.Operator.not) {
       return unary.getExpr();
     } else {
       // Else wrap it in a not
       return new UnaryExpr(expression, UnaryExpr.Operator.not);
     }
   } else if (expression instanceof BinaryExpr) {
     final BinaryExpr binary = (BinaryExpr) expression;
     final Operator inverted;
     // For binary compare operators, just use the opposite operator
     // Boolean operators use De Morgan's law
     // Other operators use a not operator, but are also enclosed in ()
     switch (binary.getOperator()) {
       case equals:
         inverted = Operator.notEquals;
         break;
       case notEquals:
         inverted = Operator.equals;
         break;
       case less:
         inverted = Operator.greaterEquals;
         break;
       case greater:
         inverted = Operator.lessEquals;
         break;
       case lessEquals:
         inverted = Operator.greater;
         break;
       case greaterEquals:
         inverted = Operator.less;
         break;
       case or:
         return new BinaryExpr(
             invertCondition(binary.getLeft()), invertCondition(binary.getRight()), Operator.and);
       case and:
         return new BinaryExpr(
             invertCondition(binary.getLeft()), invertCondition(binary.getRight()), Operator.or);
       default:
         return new UnaryExpr(new EnclosedExpr(binary), UnaryExpr.Operator.not);
     }
     return new BinaryExpr(binary.getLeft(), binary.getRight(), inverted);
   } else if (expression instanceof AssignExpr
       || expression instanceof ConditionalExpr
       || expression instanceof InstanceOfExpr) {
     // This expressions have lower precedence so they need to be enclosed in ()
     return new UnaryExpr(new EnclosedExpr(expression), UnaryExpr.Operator.not);
   } else {
     // These are higher precedence, no need for ()
     return new UnaryExpr(expression, UnaryExpr.Operator.not);
   }
 }
Example #3
0
  @Override
  public Boolean visit(final UnaryExpr n1, final Node arg) {
    final UnaryExpr n2 = (UnaryExpr) arg;

    if (n1.getOperator() != n2.getOperator()) {
      return Boolean.FALSE;
    }

    if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
      return Boolean.FALSE;
    }

    return Boolean.TRUE;
  }
 @Override
 public void visit(final UnaryExpr n, final A arg) {
   visitComment(n.getComment(), arg);
   n.getExpr().accept(this, arg);
 }