Skip to content

Commit 16a4eed

Browse files
committed
Add inspection for 'for-each' statements to suggest using 'var'
1 parent 1bd8483 commit 16a4eed

1 file changed

Lines changed: 38 additions & 9 deletions

File tree

src/main/java/dev/kalbarczyk/canbevar/VarCanBeUsedInspection.java

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
import com.intellij.codeInspection.*;
44
import com.intellij.openapi.project.Project;
55
import com.intellij.psi.*;
6+
import com.intellij.psi.util.PsiUtil;
67
import org.jetbrains.annotations.NotNull;
78

89
public 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

Comments
 (0)