Пример #1
0
 /**
  * Returns an expression containing the side effects of the given expression. The evaluated result
  * of the expression may differ from the original.
  */
 private Expression extractSideEffects(Expression expr) {
   switch (expr.getKind()) {
     case INFIX_EXPRESSION:
       {
         List<Expression> operands = ((InfixExpression) expr).getOperands();
         Expression lastOperand = operands.remove(operands.size() - 1);
         lastOperand = extractSideEffects(lastOperand);
         if (lastOperand != null) {
           operands.add(lastOperand);
         }
         if (operands.size() == 1) {
           return operands.remove(0);
         }
         return TreeUtil.remove(expr);
       }
     case PARENTHESIZED_EXPRESSION:
       {
         Expression sideEffects =
             extractSideEffects(((ParenthesizedExpression) expr).getExpression());
         if (sideEffects != null) {
           return ParenthesizedExpression.parenthesize(sideEffects);
         }
         return null;
       }
     default:
       return null;
   }
 }
Пример #2
0
 /**
  * Returns TRUE of FALSE if 'expr' is a boolean expression and its value is known statically. The
  * caller should be careful when replacing this expression as it may have side effects.
  */
 private Boolean getKnownValue(Expression expr) {
   Object value = expr.getConstantValue();
   if (value instanceof Boolean) {
     return (Boolean) value;
   }
   switch (expr.getKind()) {
     case BOOLEAN_LITERAL:
       return ((BooleanLiteral) expr).booleanValue();
     case INFIX_EXPRESSION:
       {
         InfixExpression infixExpr = (InfixExpression) expr;
         InfixExpression.Operator op = infixExpr.getOperator();
         if (op == CONDITIONAL_AND || op == CONDITIONAL_OR) {
           // We assume that this node has already been visited and pruned so
           // if it has a known value, it will be equal to the last operand.
           List<Expression> operands = infixExpr.getOperands();
           Boolean lastOperand = getKnownValue(operands.get(operands.size() - 1));
           if (lastOperand != null && lastOperand.booleanValue() == (op == CONDITIONAL_OR)) {
             return lastOperand;
           }
         }
         return null;
       }
     case PARENTHESIZED_EXPRESSION:
       return getKnownValue(((ParenthesizedExpression) expr).getExpression());
     default:
       return null;
   }
 }
Пример #3
0
 private ITypeBinding getDeclaredType(Expression expr) {
   IVariableBinding var = TreeUtil.getVariableBinding(expr);
   if (var != null) {
     return var.getVariableDeclaration().getType();
   }
   switch (expr.getKind()) {
     case CLASS_INSTANCE_CREATION:
       return typeEnv.resolveIOSType("id");
     case FUNCTION_INVOCATION:
       {
         ITypeBinding returnType =
             ((FunctionInvocation) expr).getFunctionBinding().getReturnType();
         if (returnType.isTypeVariable()) {
           return typeEnv.resolveIOSType("id");
         }
         return returnType;
       }
     case METHOD_INVOCATION:
       {
         MethodInvocation invocation = (MethodInvocation) expr;
         IMethodBinding method = invocation.getMethodBinding();
         // Object receiving the message, or null if it's a method in this class.
         Expression receiver = invocation.getExpression();
         ITypeBinding receiverType =
             receiver != null ? receiver.getTypeBinding() : method.getDeclaringClass();
         return getDeclaredReturnType(method, receiverType);
       }
     case PARENTHESIZED_EXPRESSION:
       return getDeclaredType(((ParenthesizedExpression) expr).getExpression());
     case SUPER_METHOD_INVOCATION:
       {
         SuperMethodInvocation invocation = (SuperMethodInvocation) expr;
         IMethodBinding method = invocation.getMethodBinding();
         if (invocation.getQualifier() != null) {
           // For a qualified super invocation, the statement generator will look
           // up the IMP using instanceMethodForSelector.
           if (!method.getReturnType().isPrimitive()) {
             return typeEnv.resolveIOSType("id");
           } else {
             return null;
           }
         }
         return getDeclaredReturnType(
             method, TreeUtil.getOwningType(invocation).getTypeBinding().getSuperclass());
       }
     default:
       return null;
   }
 }