PsiElementVisitor (@NotNull ProblemsHolder holder, boolean isOnTheFly) { return new JavaElementVisitor() { @Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression call) { PsiExpression container = null; if (ARRAY_METHODS.test(call)) { container = ArrayUtil.getFirstElement(call.getArgumentList().getExpressions()); } else if (COLLECTION_METHODS.test(call) || MAP_METHODS.test(call)) { container = call.getMethodExpression().getQualifierExpression(); if ("iterator".equals(call.getMethodExpression().getReferenceName()) && COLLECTIONS_EMPTY.matches(container)) { return; } } container = PsiUtil.skipParenthesizedExprDown(container); if (container != null) { String msg = getProblemMessage(container); if (msg == null) return; ModCommandAction fix = null; if (ExpressionUtils.isVoidContext(call)) { fix = new DeleteElementFix(call, InspectionGadgetsBundle.message("remove.call.fix.family.name")); } holder.problem(container, msg).maybeFix(fix).fix(getFindCauseFix(container)).register(); } } @Override public void visitForeachStatement(@NotNull PsiForeachStatement statement) { PsiExpression value = PsiUtil.skipParenthesizedExprDown(statement.getIteratedValue()); if (value == null) return; String msg = getProblemMessage(value); if (msg == null) return; holder.problem(value, msg).fix(new DeleteElementFix(statement, InspectionGadgetsBundle.message("remove.loop.fix.family.name"))).fix(getFindCauseFix(value)).register(); } private static @NotNull LocalQuickFix getFindCauseFix(@NotNull PsiExpression value) { PsiType type = value.getType(); SpecialField field; if (type instanceof PsiArrayType) { field = SpecialField.ARRAY_LENGTH; } else { field = SpecialField.COLLECTION_SIZE; } return new FindDfaProblemCauseFix(false, value, new TrackingRunner.ZeroSizeDfaProblemType(field)); } @Nullable public @InspectionMessage String getProblemMessage(PsiExpression value) { SpecialField lengthField; PsiType type = value.getType(); String message; if (type instanceof PsiArrayType) { lengthField = SpecialField.ARRAY_LENGTH; message = JavaBundle.message("inspection.redundant.operation.on.empty.array.message"); } else if (InheritanceUtil.isInheritor(type, JAVA_UTIL_COLLECTION)) { lengthField = SpecialField.COLLECTION_SIZE; message = JavaBundle.message("inspection.redundant.operation.on.empty.collection.message"); } else if (InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) { lengthField = SpecialField.COLLECTION_SIZE; message = JavaBundle.message("inspection.redundant.operation.on.empty.map.message"); } else { return null; } DfType dfType = CommonDataflow.getDfType(value); DfType length = lengthField.getFromQualifier(dfType); // TODO: remove 0L when refactoring is complete if (length.isConst(0) || length.isConst(0L)) { return message; } return null; } }; }