private static void reportCastMayFail(ProblemsHolder holder, TypeCastInstruction instruction) {
   PsiTypeCastExpression typeCast = instruction.getCastExpression();
   PsiExpression operand = typeCast.getOperand();
   PsiTypeElement castType = typeCast.getCastType();
   assert castType != null;
   assert operand != null;
   holder.registerProblem(
       castType, InspectionsBundle.message("dataflow.message.cce", operand.getText()));
 }
 static boolean isComplexArrayExpression(PsiExpression expression) {
   expression = ParenthesesUtils.stripParentheses(expression);
   if (expression == null) {
     return false;
   }
   if (expression instanceof PsiNewExpression) {
     final PsiNewExpression newExpression = (PsiNewExpression) expression;
     final PsiArrayInitializerExpression arrayInitializer = newExpression.getArrayInitializer();
     return isComplexArrayExpression(arrayInitializer);
   } else if (expression instanceof PsiArrayInitializerExpression) {
     final PsiArrayInitializerExpression arrayInitializerExpression =
         (PsiArrayInitializerExpression) expression;
     for (PsiExpression initializer : arrayInitializerExpression.getInitializers()) {
       if (isComplexArrayExpression(initializer)) {
         return true;
       }
     }
     return false;
   } else if (expression instanceof PsiReferenceExpression) {
     return expression.getType() instanceof PsiArrayType;
   } else if (expression instanceof PsiArrayAccessExpression) {
     return true;
   } else if (expression instanceof PsiTypeCastExpression) {
     final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression) expression;
     return isComplexArrayExpression(typeCastExpression.getOperand());
   } else if (expression instanceof PsiConditionalExpression) {
     final PsiConditionalExpression conditionalExpression =
         (PsiConditionalExpression) expression;
     return isComplexArrayExpression(conditionalExpression.getThenExpression())
         || isComplexArrayExpression(conditionalExpression.getElseExpression());
   } else if (expression instanceof PsiMethodCallExpression) {
     final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) expression;
     final PsiMethod method = methodCallExpression.resolveMethod();
     if (method == null) {
       return true;
     }
     if (CloneUtils.isClone(method)) {
       return false;
     }
     @NonNls final String name = method.getName();
     if ("copyOf".equals(name) || "copyOfRange".equals(name)) {
       final PsiClass aClass = method.getContainingClass();
       if (aClass != null
           && CommonClassNames.JAVA_UTIL_ARRAYS.equals(aClass.getQualifiedName())) {
         return false;
       }
     } else if ("toArray".equals(name)
         && InheritanceUtil.isInheritor(method.getContainingClass(), "java.util.Collection")) {
       return false;
     }
     return true;
   }
   return true;
 }
  @Nullable
  private ProblemDescriptor createDescription(
      @NotNull PsiTypeCastExpression cast, @NotNull InspectionManager manager, boolean onTheFly) {
    PsiExpression operand = cast.getOperand();
    PsiTypeElement castType = cast.getCastType();
    if (operand == null || castType == null) return null;
    PsiElement parent = cast.getParent();
    while (parent instanceof PsiParenthesizedExpression) {
      parent = parent.getParent();
    }
    if (parent instanceof PsiReferenceExpression) {
      if (IGNORE_ANNOTATED_METHODS) {
        final PsiElement gParent = parent.getParent();
        if (gParent instanceof PsiMethodCallExpression) {
          final PsiMethod psiMethod = ((PsiMethodCallExpression) gParent).resolveMethod();
          if (psiMethod != null && NullableNotNullManager.isNotNull(psiMethod)) {
            final PsiClass superClass = PsiUtil.resolveClassInType(operand.getType());
            final PsiClass containingClass = psiMethod.getContainingClass();
            if (containingClass != null
                && superClass != null
                && containingClass.isInheritor(superClass, true)) {
              for (PsiMethod method : psiMethod.findSuperMethods(superClass)) {
                if (NullableNotNullManager.isNullable(method)) {
                  return null;
                }
              }
            }
          }
        }
      }
    } else if (parent instanceof PsiExpressionList) {
      final PsiElement gParent = parent.getParent();
      if (gParent instanceof PsiMethodCallExpression && IGNORE_SUSPICIOUS_METHOD_CALLS) {
        final String message =
            SuspiciousCollectionsMethodCallsInspection.getSuspiciousMethodCallMessage(
                (PsiMethodCallExpression) gParent,
                operand.getType(),
                true,
                new ArrayList<PsiMethod>(),
                new IntArrayList());
        if (message != null) {
          return null;
        }
      }
    }

    String message =
        InspectionsBundle.message(
            "inspection.redundant.cast.problem.descriptor",
            "<code>" + operand.getText() + "</code>",
            "<code>#ref</code> #loc");
    return manager.createProblemDescriptor(
        castType, message, myQuickFixAction, ProblemHighlightType.LIKE_UNUSED_SYMBOL, onTheFly);
  }
 private static boolean typeCastExpressionsAreEquivalent(
     @NotNull PsiTypeCastExpression typeCastExpression1,
     @NotNull PsiTypeCastExpression typeCastExpression2) {
   final PsiTypeElement typeElement1 = typeCastExpression1.getCastType();
   final PsiTypeElement typeElement2 = typeCastExpression2.getCastType();
   if (!typeElementsAreEquivalent(typeElement1, typeElement2)) {
     return false;
   }
   final PsiExpression operand1 = typeCastExpression1.getOperand();
   final PsiExpression operand2 = typeCastExpression2.getOperand();
   return expressionsAreEquivalent(operand1, operand2);
 }
 @Override
 protected final void doFix(Project project, ProblemDescriptor descriptor)
     throws IncorrectOperationException {
   final PsiElement element = descriptor.getPsiElement();
   final PsiTypeElement castTypeElement;
   final PsiReferenceExpression reference;
   if (element instanceof PsiTypeCastExpression) {
     final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression) element;
     castTypeElement = typeCastExpression.getCastType();
     final PsiExpression operand = typeCastExpression.getOperand();
     if (!(operand instanceof PsiReferenceExpression)) {
       return;
     }
     reference = (PsiReferenceExpression) operand;
   } else if (element instanceof PsiMethodCallExpression) {
     final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) element;
     final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
     final PsiExpression qualifier = methodExpression.getQualifierExpression();
     if (!(qualifier instanceof PsiClassObjectAccessExpression)) {
       return;
     }
     final PsiClassObjectAccessExpression classObjectAccessExpression =
         (PsiClassObjectAccessExpression) qualifier;
     castTypeElement = classObjectAccessExpression.getOperand();
     final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
     final PsiExpression[] arguments = argumentList.getExpressions();
     if (arguments.length != 1) {
       return;
     }
     final PsiExpression argument = arguments[0];
     if (!(argument instanceof PsiReferenceExpression)) {
       return;
     }
     reference = (PsiReferenceExpression) argument;
   } else {
     return;
   }
   if (castTypeElement == null) {
     return;
   }
   final PsiInstanceOfExpression conflictingInstanceof =
       InstanceOfUtils.getConflictingInstanceof(castTypeElement.getType(), reference, element);
   final PsiTypeElement instanceofTypeElement = conflictingInstanceof.getCheckType();
   if (instanceofTypeElement == null) {
     return;
   }
   final PsiElement newElement = replace(castTypeElement, instanceofTypeElement);
   final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
   codeStyleManager.shortenClassReferences(newElement);
 }
 private static void removeParensFromTypeCastExpression(
     @NotNull PsiTypeCastExpression typeCastExpression, boolean ignoreClarifyingParentheses) {
   final PsiExpression operand = typeCastExpression.getOperand();
   if (operand != null) {
     removeParentheses(operand, ignoreClarifyingParentheses);
   }
 }
 private static boolean typecastExpressionsAreEquivalent(
     @NotNull PsiTypeCastExpression typecastExp1, @NotNull PsiTypeCastExpression typecastExp2) {
   final PsiTypeElement typeElement1 = typecastExp1.getCastType();
   final PsiTypeElement typeElement2 = typecastExp2.getCastType();
   if (typeElement1 == null && typeElement2 == null) {
     return true;
   }
   if (typeElement1 == null || typeElement2 == null) {
     return false;
   }
   final PsiType type1 = typeElement1.getType();
   final PsiType type2 = typeElement2.getType();
   if (!typesAreEquivalent(type1, type2)) {
     return false;
   }
   final PsiExpression operand1 = typecastExp1.getOperand();
   final PsiExpression operand2 = typecastExp2.getOperand();
   return expressionsAreEquivalent(operand1, operand2);
 }
 private boolean isIteratorNext(
   PsiElement element, String iteratorName, PsiType contentType) {
   if (element == null) {
     return false;
   }
   if (element instanceof PsiTypeCastExpression) {
     final PsiTypeCastExpression castExpression =
       (PsiTypeCastExpression)element;
     final PsiType type = castExpression.getType();
     if (type == null) {
       return false;
     }
     if (!type.equals(contentType)) {
       return false;
     }
     final PsiExpression operand =
       castExpression.getOperand();
     return isIteratorNext(operand, iteratorName, contentType);
   }
   if (!(element instanceof PsiMethodCallExpression)) {
     return false;
   }
   final PsiMethodCallExpression callExpression =
     (PsiMethodCallExpression)element;
   final PsiExpressionList argumentList =
     callExpression.getArgumentList();
   final PsiExpression[] args = argumentList.getExpressions();
   if (args.length != 0) {
     return false;
   }
   final PsiReferenceExpression reference =
     callExpression.getMethodExpression();
   final PsiExpression qualifier = reference.getQualifierExpression();
   if (qualifier == null) {
     return false;
   }
   if (!iteratorName.equals(qualifier.getText())) {
     return false;
   }
   final String referenceName = reference.getReferenceName();
   return HardcodedMethodConstants.NEXT.equals(referenceName);
 }
 @Override
 public void doFix(Project project, ProblemDescriptor descriptor)
     throws IncorrectOperationException {
   final PsiElement castTypeElement = descriptor.getPsiElement();
   final PsiTypeCastExpression expression = (PsiTypeCastExpression) castTypeElement.getParent();
   if (expression == null) {
     return;
   }
   final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, true);
   if (expectedType == null) {
     return;
   }
   final PsiExpression operand = expression.getOperand();
   if (operand == null) {
     return;
   }
   @NonNls
   final String newExpression = '(' + expectedType.getCanonicalText() + ')' + operand.getText();
   replaceExpressionAndShorten(expression, newExpression);
 }
  static PsiExpression createCastExpression(
      PsiExpression originalExpression, Project project, PsiType type)
      throws IncorrectOperationException {
    // remove nested casts
    PsiElement element = PsiUtil.deparenthesizeExpression(originalExpression);
    PsiElementFactory factory =
        JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory();

    PsiTypeCastExpression typeCast =
        (PsiTypeCastExpression) factory.createExpressionFromText("(Type)value", null);
    typeCast = (PsiTypeCastExpression) CodeStyleManager.getInstance(project).reformat(typeCast);
    typeCast.getCastType().replace(factory.createTypeElement(type));

    if (element instanceof PsiConditionalExpression) {
      // we'd better cast one branch of ternary expression if we could
      PsiConditionalExpression expression = (PsiConditionalExpression) element.copy();
      PsiExpression thenE = expression.getThenExpression();
      PsiExpression elseE = expression.getElseExpression();
      PsiType thenType = thenE == null ? null : thenE.getType();
      PsiType elseType = elseE == null ? null : elseE.getType();
      if (elseType != null && thenType != null) {
        boolean replaceThen = !TypeConversionUtil.isAssignable(type, thenType);
        boolean replaceElse = !TypeConversionUtil.isAssignable(type, elseType);
        if (replaceThen != replaceElse) {
          if (replaceThen) {
            typeCast.getOperand().replace(thenE);
            thenE.replace(typeCast);
          } else {
            typeCast.getOperand().replace(elseE);
            elseE.replace(typeCast);
          }
          return expression;
        }
      }
    }
    typeCast.getOperand().replace(element);
    return typeCast;
  }
 @Override
 public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) {
   super.visitTypeCastExpression(expression);
   final PsiTypeElement castType = expression.getCastType();
   if (castType == null) {
     return;
   }
   final PsiType type = castType.getType();
   final PsiExpression operand = expression.getOperand();
   if (!(operand instanceof PsiReferenceExpression)) {
     return;
   }
   final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) operand;
   final PsiInstanceOfExpression conflictingInstanceof =
       InstanceOfUtils.getConflictingInstanceof(type, referenceExpression, expression);
   if (conflictingInstanceof == null) {
     return;
   }
   final PsiTypeElement instanceofTypeElement = conflictingInstanceof.getCheckType();
   if (instanceofTypeElement == null) {
     return;
   }
   registerError(expression, referenceExpression, castType, instanceofTypeElement);
 }
 @Override
 public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) {
   super.visitTypeCastExpression(expression);
   final PsiExpression operand = expression.getOperand();
   if (operand == null) {
     return;
   }
   final PsiType operandType = operand.getType();
   if (operandType == null) {
     return;
   }
   final PsiType type = expression.getType();
   if (type == null) {
     return;
   }
   final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, true);
   if (expectedType == null) {
     return;
   }
   if (expectedType.equals(type)) {
     return;
   }
   final PsiClass resolved = PsiUtil.resolveClassInType(expectedType);
   if (resolved != null && !resolved.isPhysical()) {
     return;
   }
   if (expectedType.isAssignableFrom(operandType)) {
     // then it's redundant, and caught by the built-in exception
     return;
   }
   if (isTypeParameter(expectedType)) {
     return;
   }
   if (expectedType instanceof PsiArrayType) {
     final PsiArrayType arrayType = (PsiArrayType) expectedType;
     final PsiType componentType = arrayType.getDeepComponentType();
     if (isTypeParameter(componentType)) {
       return;
     }
   }
   if (type instanceof PsiPrimitiveType || expectedType instanceof PsiPrimitiveType) {
     return;
   }
   if (PsiPrimitiveType.getUnboxedType(type) != null
       || PsiPrimitiveType.getUnboxedType(expectedType) != null) {
     return;
   }
   if (expectedType instanceof PsiClassType) {
     final PsiClassType expectedClassType = (PsiClassType) expectedType;
     final PsiClassType expectedRawType = expectedClassType.rawType();
     if (type.equals(expectedRawType)) {
       return;
     }
     if (type instanceof PsiClassType) {
       final PsiClassType classType = (PsiClassType) type;
       final PsiClassType rawType = classType.rawType();
       if (rawType.equals(expectedRawType)) {
         return;
       }
     }
     if (type instanceof PsiArrayType) {
       return;
     }
   }
   if (ignoreInMatchingInstanceof && InstanceOfUtils.hasAgreeingInstanceof(expression)) {
     return;
   }
   final PsiTypeElement castTypeElement = expression.getCastType();
   if (castTypeElement == null) {
     return;
   }
   registerError(castTypeElement, expectedType);
 }