PsiElementVisitor (@NotNull ProblemsHolder holder, boolean isOnTheFly) { if (!JavaFeature.ADVANCED_COLLECTIONS_API.isFeatureSupported(holder.getFile())) { return PsiElementVisitor.EMPTY_VISITOR; } return new JavaElementVisitor() { @Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression call) { if (!ITERABLE_FOREACH.test(call)) return; PsiMethodCallExpression qualifierCall = MethodCallUtils.getQualifierMethodCall(call); if (!MAP_ENTRY_SET.test(qualifierCall)) return; PsiLambdaExpression lambda = ObjectUtils.tryCast(call.getArgumentList().getExpressions()[0], PsiLambdaExpression.class); if (lambda == null) return; PsiParameter[] lambdaParameters = lambda.getParameterList().getParameters(); if (lambdaParameters.length != 1) return; PsiParameter entry = lambdaParameters[0]; if (!allUsagesAllowed(entry)) return; PsiElement nameElement = Objects.requireNonNull(call.getMethodExpression().getReferenceNameElement()); holder.registerProblem(nameElement, JavaAnalysisBundle.message("inspection.can.be.replaced.with.message", "Map.forEach()"), new ReplaceWithMapForEachFix()); } private static boolean allUsagesAllowed(@NotNull PsiParameter entry) { return ReferencesSearch.search(entry).allMatch(entryRef -> { PsiMethodCallExpression entryCall = ExpressionUtils.getCallForQualifier(ObjectUtils.tryCast(entryRef.getElement(), PsiExpression.class)); return ENTRY_GETTER.test(entryCall) && !ExpressionUtils.isVoidContext(entryCall); }); } @Override public void visitForeachStatement(@NotNull PsiForeachStatement loop) { if (DO_NOT_HIGHLIGHT_LOOP && !isOnTheFly) return; PsiMethodCallExpression call = ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(loop.getIteratedValue()), PsiMethodCallExpression.class); PsiParameter parameter = loop.getIterationParameter(); if (MAP_ENTRY_SET.test(call) && LambdaGenerationUtil.canBeUncheckedLambda(loop.getBody()) && allUsagesAllowed(parameter)) { ProblemHighlightType type = DO_NOT_HIGHLIGHT_LOOP ? ProblemHighlightType.INFORMATION : ProblemHighlightType.GENERIC_ERROR_OR_WARNING; boolean wholeStatement = isOnTheFly && (DO_NOT_HIGHLIGHT_LOOP || InspectionProjectProfileManager.isInformationLevel(getShortName(), loop)); TextRange range; PsiJavaToken rParenth = loop.getRParenth(); PsiElement firstChild = loop.getFirstChild(); PsiElement toHighlight; if (wholeStatement && rParenth != null) { toHighlight = loop; range = new TextRange(firstChild.getStartOffsetInParent(), rParenth.getStartOffsetInParent() + 1); } else { toHighlight = firstChild; range = new TextRange(0, firstChild.getTextLength()); } holder.registerProblem(toHighlight, JavaAnalysisBundle.message("inspection.can.be.replaced.with.message", "Map.forEach()"), type, range, new ReplaceWithMapForEachFix()); } } }; }