diff --git a/java/java-impl/src/com/intellij/codeInspection/ExplicitArrayFillingInspection.java b/java/java-impl/src/com/intellij/codeInspection/ExplicitArrayFillingInspection.java index 6219e6f4cd30..875257a43a46 100644 --- a/java/java-impl/src/com/intellij/codeInspection/ExplicitArrayFillingInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/ExplicitArrayFillingInspection.java @@ -13,7 +13,6 @@ import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; import com.intellij.util.ObjectUtils; import com.siyeh.ig.psiutils.*; @@ -73,9 +72,13 @@ public class ExplicitArrayFillingInspection extends AbstractBaseJavaLocalInspect } private boolean isChangedInLoop(@NotNull CountingLoop loop, @NotNull PsiExpression rValue) { - return VariableAccessUtils.collectUsedVariables(rValue).contains(loop.getCounter()) || - SideEffectChecker.mayHaveSideEffects(rValue) || - PsiTreeUtil.findChildOfType(rValue, PsiNewExpression.class, false) != null; + if (VariableAccessUtils.collectUsedVariables(rValue).contains(loop.getCounter()) || + SideEffectChecker.mayHaveSideEffects(rValue)) { + return true; + } + return ExpressionUtils.nonStructuralChildren(rValue) + .filter(c -> c instanceof PsiCallExpression) + .anyMatch(call -> !ClassUtils.isImmutable(call.getType()) && !ConstructionUtils.isEmptyArrayInitializer(call)); } private void registerProblem(@NotNull PsiForStatement statement, boolean isSetAll) { diff --git a/java/java-tests/testData/inspection/explicitArrayFilling/afterEmptyArrayCreation.java b/java/java-tests/testData/inspection/explicitArrayFilling/afterEmptyArrayCreation.java new file mode 100644 index 000000000000..6bbae5c85c70 --- /dev/null +++ b/java/java-tests/testData/inspection/explicitArrayFilling/afterEmptyArrayCreation.java @@ -0,0 +1,13 @@ +// "Replace loop with 'Arrays.fill()' method call" "true" + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +class Test { + private void test2() { + int[][] arr = new int[10][]; + Arrays.fill(arr, new int[0]); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/explicitArrayFilling/afterImmutableObjectFromMethod.java b/java/java-tests/testData/inspection/explicitArrayFilling/afterImmutableObjectFromMethod.java new file mode 100644 index 000000000000..97f9d8f853a5 --- /dev/null +++ b/java/java-tests/testData/inspection/explicitArrayFilling/afterImmutableObjectFromMethod.java @@ -0,0 +1,15 @@ +// "Replace loop with 'Arrays.fill()' method call" "true" + +import java.util.Arrays; + +class Test { + + void test() { + final String[] arr = new String[2]; + Arrays.fill(arr, getString()); + } + + private static String getString() { + return "foo"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/explicitArrayFilling/afterSuppliersArray.java b/java/java-tests/testData/inspection/explicitArrayFilling/afterSuppliersArray.java new file mode 100644 index 000000000000..f8e4eed47900 --- /dev/null +++ b/java/java-tests/testData/inspection/explicitArrayFilling/afterSuppliersArray.java @@ -0,0 +1,12 @@ +// "Replace loop with 'Arrays.fill()' method call" "true" + +import java.util.Arrays; + +class Test { + + private void testLambdas() { + Supplier[] arr = new Supplier[10]; + Arrays.fill(arr, () -> new int[10]); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/explicitArrayFilling/afterTernaryWithMutable.java b/java/java-tests/testData/inspection/explicitArrayFilling/afterTernaryWithMutable.java new file mode 100644 index 000000000000..db63db5b1a1a --- /dev/null +++ b/java/java-tests/testData/inspection/explicitArrayFilling/afterTernaryWithMutable.java @@ -0,0 +1,12 @@ +// "Replace loop with 'Arrays.setAll()' method call" "true" + +import java.util.Arrays; + +class Test { + + void test(boolean choice) { + Object[] arr = new Object[10]; + Arrays.setAll(arr, i -> (choice ? "foo" : new Object())); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/explicitArrayFilling/beforeEmptyArrayCreation.java b/java/java-tests/testData/inspection/explicitArrayFilling/beforeEmptyArrayCreation.java new file mode 100644 index 000000000000..f333557740b4 --- /dev/null +++ b/java/java-tests/testData/inspection/explicitArrayFilling/beforeEmptyArrayCreation.java @@ -0,0 +1,13 @@ +// "Replace loop with 'Arrays.fill()' method call" "true" + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +class Test { + private void test2() { + int[][] arr = new int[10][]; + for (int i = 0; i < arr.length; i++) { + arr[i] = new int[0]; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/explicitArrayFilling/beforeImmutableObjectFromMethod.java b/java/java-tests/testData/inspection/explicitArrayFilling/beforeImmutableObjectFromMethod.java new file mode 100644 index 000000000000..5eefdecf10d5 --- /dev/null +++ b/java/java-tests/testData/inspection/explicitArrayFilling/beforeImmutableObjectFromMethod.java @@ -0,0 +1,15 @@ +// "Replace loop with 'Arrays.fill()' method call" "true" + +class Test { + + void test() { + final String[] arr = new String[2]; + for (int i = 0; i < arr.length; i++) { + arr[i] = getString(); + } + } + + private static String getString() { + return "foo"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/explicitArrayFilling/beforeSuppliersArray.java b/java/java-tests/testData/inspection/explicitArrayFilling/beforeSuppliersArray.java new file mode 100644 index 000000000000..d81017059781 --- /dev/null +++ b/java/java-tests/testData/inspection/explicitArrayFilling/beforeSuppliersArray.java @@ -0,0 +1,12 @@ +// "Replace loop with 'Arrays.fill()' method call" "true" + +class Test { + + private void testLambdas() { + Supplier[] arr = new Supplier[10]; + for (int i = 0; i < arr.length; i++) { + arr[i] = () -> new int[10]; + } + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/explicitArrayFilling/beforeTernaryWithMutable.java b/java/java-tests/testData/inspection/explicitArrayFilling/beforeTernaryWithMutable.java new file mode 100644 index 000000000000..0f1162897a46 --- /dev/null +++ b/java/java-tests/testData/inspection/explicitArrayFilling/beforeTernaryWithMutable.java @@ -0,0 +1,12 @@ +// "Replace loop with 'Arrays.setAll()' method call" "true" + +class Test { + + void test(boolean choice) { + Object[] arr = new Object[10]; + for (int i = 0; i < arr.length; i++) { + arr[i] = (choice ? "foo" : new Object()); + } + } + +} \ No newline at end of file