33import com .intellij .codeInspection .*;
44import com .intellij .openapi .project .Project ;
55import com .intellij .psi .*;
6+ import com .intellij .psi .util .PsiUtil ;
67import org .jetbrains .annotations .NotNull ;
78
89public final class VarCanBeUsedInspection extends AbstractBaseJavaLocalInspectionTool {
910
10- //TODO: add inspection for the for each
1111
1212 @ Override
1313 public @ NotNull PsiElementVisitor buildVisitor (final @ NotNull ProblemsHolder holder , final boolean isOnTheFly ) {
@@ -19,16 +19,12 @@ public void visitLocalVariable(final @NotNull PsiLocalVariable variable) {
1919 var initializer = variable .getInitializer ();
2020
2121 if (initializer == null ) return ;
22- if ("var" .equals (typeElement .getText ())) return ;
23-
24- //lombok feature (final + var = val)
25- if ("val" .equals (typeElement .getText ())) return ;
26-
22+ if ("var" .equals (typeElement .getText ()) || "val" .equals (typeElement .getText ())) return ;
2723 if (type .equalsToText ("var" )) return ;
2824
29- if (!(initializer .getType () instanceof PsiClassType )) return ;
30-
3125 var initType = initializer .getType ();
26+ if (initType == null ) return ;
27+ if (!(initType instanceof PsiClassType ) && !(initType instanceof PsiArrayType )) return ;
3228
3329 if (initType .equals (type )) {
3430 holder .registerProblem (
@@ -40,10 +36,43 @@ public void visitLocalVariable(final @NotNull PsiLocalVariable variable) {
4036 }
4137
4238 }
43- };
4439
40+ @ Override
41+ public void visitForeachStatement (@ NotNull PsiForeachStatement statement ) {
42+ var iteratedValue = statement .getIteratedValue ();
43+ var parameter = statement .getIterationParameter ();
44+
45+ var typeElement = parameter .getTypeElement ();
46+ if (typeElement == null ) return ;
47+ if ("var" .equals (typeElement .getText ()) || "val" .equals (typeElement .getText ())) return ;
48+
49+ var iteratedType = iteratedValue != null ? iteratedValue .getType () : null ;
50+ if (iteratedType == null ) return ;
51+
52+ var parameterType = parameter .getType ();
53+
54+ PsiType elementType = null ;
55+ if (iteratedType instanceof PsiClassType classType ) {
56+ elementType = PsiUtil .extractIterableTypeParameter (classType , false );
57+ } else if (iteratedType instanceof PsiArrayType arrayType ) {
58+ elementType = arrayType .getComponentType ();
59+ }
60+
61+ if (elementType == null ) return ;
62+
63+ if (elementType .equals (parameterType )) {
64+ holder .registerProblem (
65+ typeElement ,
66+ "Explicit type in 'for-each' can be replaced with 'var'" ,
67+ ProblemHighlightType .WEAK_WARNING ,
68+ new ReplaceWithVarQuickFix ()
69+ );
70+ }
71+ }
72+ };
4573 }
4674
75+
4776 private final static class ReplaceWithVarQuickFix implements LocalQuickFix {
4877 @ Override
4978 public void applyFix (final @ NotNull Project project , final @ NotNull ProblemDescriptor problemDescriptor ) {
0 commit comments