Example #1
0
 private boolean needsIdCast(Expression lhs, Expression rhs) {
   ITypeBinding lhsType = lhs.getTypeBinding();
   ITypeBinding rhsType = rhs.getTypeBinding();
   return !lhsType.isPrimitive()
       && !rhsType.isPrimitive()
       && !lhsType.isAssignmentCompatible(rhsType)
       && !rhsType.isAssignmentCompatible(lhsType);
 }
  /*
   * Evaluates possible return expressions. The favourite expression is returned.
   */
  private Expression evaluateReturnExpressions(
      AST ast, ITypeBinding returnBinding, int returnOffset) {
    CompilationUnit root = (CompilationUnit) fMethodDecl.getRoot();

    Expression result = null;
    if (returnBinding != null) {
      ScopeAnalyzer analyzer = new ScopeAnalyzer(root);
      IBinding[] bindings =
          analyzer.getDeclarationsInScope(
              returnOffset, ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY);
      for (int i = 0; i < bindings.length; i++) {
        IVariableBinding curr = (IVariableBinding) bindings[i];
        ITypeBinding type = curr.getType();
        if (type != null && type.isAssignmentCompatible(returnBinding) && testModifier(curr)) {
          if (result == null) {
            result = ast.newSimpleName(curr.getName());
          }
          addLinkedPositionProposal(RETURN_EXPRESSION_KEY, curr.getName(), null);
        }
      }
    }
    Expression defaultExpression =
        ASTNodeFactory.newDefaultExpression(
            ast, fMethodDecl.getReturnType2(), fMethodDecl.getExtraDimensions());
    addLinkedPositionProposal(RETURN_EXPRESSION_KEY, ASTNodes.asString(defaultExpression), null);
    if (result == null) {
      return defaultExpression;
    }
    return result;
  }
Example #3
0
 /**
  * Check if the method can be called with the given arguments. Used when we don't have a direct
  * link to the method that is invoked (for example: Action.create(...)).
  */
 public static boolean isApplicableToCall(Iterable<ITypeBinding> args, IMethodBinding meth) {
   int[] i = {0};
   ITypeBinding[] params = meth.getParameterTypes();
   for (ITypeBinding arg : args) {
     if (params.length <= i[0] || !arg.isAssignmentCompatible(params[i[0]++])) {
       return false;
     }
   }
   return true;
 }
Example #4
0
 private boolean needsCast(Expression expr, ITypeBinding expectedType, boolean shouldCastFromId) {
   ITypeBinding declaredType = getDeclaredType(expr);
   if (declaredType == null) {
     return false;
   }
   ITypeBinding exprType = typeEnv.mapType(expr.getTypeBinding());
   declaredType = typeEnv.mapType(declaredType);
   if (
   // In general we do not need to cast primitive types.
   exprType.isPrimitive()
       // In most cases we don't need to cast from an id type. However, if the
       // expression is being dereferenced then the compiler needs the type
       // info.
       || (typeEnv.isIdType(declaredType) && !shouldCastFromId)
       // If the declared type can be assigned into the actual type, or the
       // expected type, then the compiler already has sufficient type info.
       || typeEnv.isIdType(exprType)
       || typeEnv.isIdType(expectedType)
       || declaredType.isAssignmentCompatible(exprType)
       || declaredType.isAssignmentCompatible(expectedType)) {
     return false;
   }
   return true;
 }
Example #5
0
 /**
  * Given a JDT type binding created by the parser, either replace it with an iOS equivalent, or
  * return the given type.
  */
 public ITypeBinding mapType(ITypeBinding binding) {
   if (binding == null) { // happens when mapping a primitive type
     return null;
   }
   // getTypeDeclaration will return the canonical binding for the type with
   // type parameters and type annotations removed. Note that getErasure() does
   // not strip type annotations.
   binding = binding.getTypeDeclaration();
   if (binding.isArray()) {
     return resolveArrayType(binding.getComponentType());
   }
   ITypeBinding newBinding = typeMap.get(binding);
   if (newBinding == null && binding.isAssignmentCompatible(javaClassType)) {
     newBinding = typeMap.get(javaClassType);
   }
   return newBinding != null ? newBinding : binding;
 }
Example #6
0
  @Override
  public void endVisit(CastExpression node) {
    ITypeBinding type = node.getType().getTypeBinding();
    Expression expr = node.getExpression();
    ITypeBinding exprType = expr.getTypeBinding();

    // TODO(kirbs): Implement correct conversion of Java 8 intersection types to Objective-C.
    if (node.getType().isIntersectionType() && !Options.isJava8Translator()) {
      // Technically we can't currently get here, but as we add support and change flags in the
      // future this should alert us to implement intersection types.
      assert false : "not implemented yet";
    }

    if (BindingUtil.isFloatingPoint(exprType)) {
      assert type.isPrimitive(); // Java wouldn't allow a cast from primitive to non-primitive.
      switch (type.getBinaryName().charAt(0)) {
        case 'J':
          node.replaceWith(rewriteFloatToIntegralCast(type, expr, "JreFpToLong", type));
          return;
        case 'C':
          node.replaceWith(rewriteFloatToIntegralCast(type, expr, "JreFpToChar", type));
          return;
        case 'B':
        case 'S':
        case 'I':
          node.replaceWith(
              rewriteFloatToIntegralCast(type, expr, "JreFpToInt", typeEnv.resolveJavaType("int")));
          return;
      }
      // else fall-through.
    }

    // Lean on Java's type-checking.
    if (!type.isPrimitive() && exprType.isAssignmentCompatible(type.getErasure())) {
      node.replaceWith(TreeUtil.remove(expr));
      return;
    }

    FunctionInvocation castCheck = createCastCheck(type, expr);
    if (castCheck != null) {
      node.setExpression(castCheck);
    }
  }
  /*(non-Javadoc)
   * @see org.eclipse.jdt.internal.ui.text.correction.ASTRewriteCorrectionProposal#getRewrite()
   */
  @Override
  protected ASTRewrite getRewrite() {
    AST ast = fMethodDecl.getAST();

    ITypeBinding returnBinding = getReturnTypeBinding();

    if (fExistingReturn != null) {
      ASTRewrite rewrite = ASTRewrite.create(ast);

      Expression expression =
          evaluateReturnExpressions(ast, returnBinding, fExistingReturn.getStartPosition());
      if (expression != null) {
        rewrite.set(fExistingReturn, ReturnStatement.EXPRESSION_PROPERTY, expression, null);

        addLinkedPosition(rewrite.track(expression), true, RETURN_EXPRESSION_KEY);
      }
      return rewrite;
    } else {
      ASTRewrite rewrite = ASTRewrite.create(ast);

      Block block = fMethodDecl.getBody();

      List<Statement> statements = block.statements();
      int nStatements = statements.size();
      ASTNode lastStatement = null;
      if (nStatements > 0) {
        lastStatement = statements.get(nStatements - 1);
      }

      if (returnBinding != null
          && lastStatement instanceof ExpressionStatement
          && lastStatement.getNodeType() != ASTNode.ASSIGNMENT) {
        Expression expression = ((ExpressionStatement) lastStatement).getExpression();
        ITypeBinding binding = expression.resolveTypeBinding();
        if (binding != null && binding.isAssignmentCompatible(returnBinding)) {
          Expression placeHolder = (Expression) rewrite.createMoveTarget(expression);

          ReturnStatement returnStatement = ast.newReturnStatement();
          returnStatement.setExpression(placeHolder);

          rewrite.replace(lastStatement, returnStatement, null);
          return rewrite;
        }
      }

      int offset;
      if (lastStatement == null) {
        offset = block.getStartPosition() + 1;
      } else {
        offset = lastStatement.getStartPosition() + lastStatement.getLength();
      }
      ReturnStatement returnStatement = ast.newReturnStatement();
      Expression expression = evaluateReturnExpressions(ast, returnBinding, offset);

      returnStatement.setExpression(expression);

      rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertLast(returnStatement, null);

      addLinkedPosition(
          rewrite.track(returnStatement.getExpression()), true, RETURN_EXPRESSION_KEY);
      return rewrite;
    }
  }