boolean (@NotNull PsiTypeCastExpression cast, @NotNull PsiType targetType, @NotNull PsiReferenceExpression reference) { PsiElement parent = PsiUtil.skipParenthesizedExprUp(reference.getParent()); if (PsiUtil.isAccessedForWriting(reference)) { PsiAssignmentExpression assignmentExpression = tryCast(parent, PsiAssignmentExpression.class); if (assignmentExpression == null) return false; PsiExpression rValue = assignmentExpression.getRExpression(); if (rValue == null) return false; PsiType rValueType = rValue.getType(); return rValueType != null && targetType.isAssignableFrom(rValueType); } while (parent instanceof PsiConditionalExpression) { parent = PsiUtil.skipParenthesizedExprUp(parent.getParent()); } if (parent instanceof PsiInstanceOfExpression) { PsiTypeElement checkTypeElement = ((PsiInstanceOfExpression)parent).getCheckType(); if (checkTypeElement == null) return false; PsiType checkType = checkTypeElement.getType(); // Could be always false instanceof which will become compilation error after fix return TypeConversionUtil.areTypesConvertible(targetType, checkType); } if (parent instanceof PsiTypeCastExpression && parent != cast) { PsiTypeElement castTypeElement = ((PsiTypeCastExpression)parent).getCastType(); if (castTypeElement == null) return false; PsiType castType = castTypeElement.getType(); // Another cast could become invalid due to this change return TypeConversionUtil.areTypesConvertible(targetType, castType); } // Some method call can be mis-resolved after update, check this if (parent instanceof PsiExpressionList && parent.getParent() instanceof PsiCallExpression) { PsiCallExpression call = (PsiCallExpression)parent.getParent(); PsiMethod method = call.resolveMethod(); if (method == null) return false; Object mark = new Object(); PsiTreeUtil.mark(reference, mark); PsiCallExpression callCopy = (PsiCallExpression)call.copy(); PsiTreeUtil.releaseMark(reference, mark); PsiElement refCopy = PsiTreeUtil.releaseMark(callCopy, mark); if (refCopy == null) return false; refCopy.replace(cast); return callCopy.resolveMethod() == method; } if (parent instanceof PsiReferenceExpression && parent.getParent() instanceof PsiMethodCallExpression) { PsiMethodCallExpression call = (PsiMethodCallExpression)parent.getParent(); PsiMethod method = call.resolveMethod(); if (method == null) return false; if (method.hasModifierProperty(PsiModifier.PRIVATE)) { // private method cannot be called on a subtype qualifier return false; } } return true; }