PsiElementVisitor (@NotNull ProblemsHolder holder, boolean isOnTheFly) { if (!JavaFeature.ADVANCED_COLLECTIONS_API.isFeatureSupported(holder.getFile())) { return PsiElementVisitor.EMPTY_VISITOR; } return new JavaElementVisitor() { private static boolean isRedundantOperation(PsiExpression replacement, PsiStatement body, CountingLoop countingLoop, IndexedContainer container) { PsiLocalVariable counter = countingLoop.getCounter(); if (ExpressionUtils.isReferenceTo(container.extractIndexFromGetExpression(replacement), counter)) return true; if (!(replacement instanceof PsiReferenceExpression)) return false; PsiVariable variable = tryCast(((PsiReferenceExpression)replacement).resolve(), PsiVariable.class); if (variable == null) return false; PsiExpression initializer = variable.getInitializer(); PsiExpression index = container.extractIndexFromGetExpression(initializer); return ExpressionUtils.isReferenceTo(index, counter) && HighlightControlFlowUtil.isEffectivelyFinal(variable, body, null); } private static boolean isMultilineLambda(PsiStatement body, PsiStatement[] statements) { if (statements.length == 1) return false; if (statements.length > 3) return true; if (getVariableToInline(statements[0], body) == null) return true; return statements.length == 3 && getVariableToInline(statements[1], body) == null; } @Override public void visitForStatement(@NotNull PsiForStatement statement) { super.visitForStatement(statement); PsiStatement body = statement.getBody(); PsiStatement[] statements = ControlFlowUtils.unwrapBlock(body); PsiMethodCallExpression maybeSetCall = getLastMethodCall(statements); if (!LIST_SET.test(maybeSetCall)) return; if (dontWarnInCaseOfMultilineLambda && isMultilineLambda(body, statements)) return; PsiExpression index = PsiUtil.skipParenthesizedExprDown(maybeSetCall.getArgumentList().getExpressions()[0]); CountingLoop countingLoop = CountingLoop.from(statement); if (countingLoop == null) return; PsiLocalVariable counter = countingLoop.getCounter(); if (countingLoop.isIncluding() || countingLoop.isDescending() || !ExpressionUtils.isZero(countingLoop.getInitializer()) || !ExpressionUtils.isReferenceTo(index, counter)) { return; } IndexedContainer container = IndexedContainer.fromLengthExpression(countingLoop.getBound()); if (container == null) return; List<PsiReferenceExpression> references = VariableAccessUtils.getVariableReferences(counter, body); if (!ContainerUtil.all(references, reference -> reference == index || container.extractGetExpressionFromIndex(reference) != null)) { return; } if (isRedundantOperation(maybeSetCall.getArgumentList().getExpressions()[1], body, countingLoop, container)) return; if (!container.isQualifierEquivalent(ExpressionUtils.getEffectiveQualifier(maybeSetCall.getMethodExpression()))) return; Predicate<PsiVariable> variableAllowedPredicate = v -> PsiEquivalenceUtil.areElementsEquivalent(v, counter); if (!LambdaGenerationUtil.canBeUncheckedLambda(body, variableAllowedPredicate)) return; holder.registerProblem(statement.getFirstChild(), QuickFixBundle.message("java.8.list.replaceall.inspection.description"), new ReplaceWithReplaceAllQuickFix()); } }; }