ExplicitArrayFillingInspection: suggest Arrays.fill in cases when filled value is immutable (IDEA-CR-50510)

GitOrigin-RevId: a9d5627d25572edeb2f920aff62d108dd6f183ac
This commit is contained in:
Artemiy Sartakov
2019-07-26 11:02:46 +03:00
committed by intellij-monorepo-bot
parent e05fc3d3e7
commit e728e7eda8
9 changed files with 111 additions and 4 deletions
@@ -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) {
@@ -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]);
}
}
@@ -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";
}
}
@@ -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]);
}
}
@@ -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()));
}
}
@@ -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 (<caret>int i = 0; i < arr.length; i++) {
arr[i] = new int[0];
}
}
}
@@ -0,0 +1,15 @@
// "Replace loop with 'Arrays.fill()' method call" "true"
class Test {
void test() {
final String[] arr = new String[2];
for (<caret>int i = 0; i < arr.length; i++) {
arr[i] = getString();
}
}
private static String getString() {
return "foo";
}
}
@@ -0,0 +1,12 @@
// "Replace loop with 'Arrays.fill()' method call" "true"
class Test {
private void testLambdas() {
Supplier[] arr = new Supplier[10];
for (<caret>int i = 0; i < arr.length; i++) {
arr[i] = () -> new int[10];
}
}
}
@@ -0,0 +1,12 @@
// "Replace loop with 'Arrays.setAll()' method call" "true"
class Test {
void test(boolean choice) {
Object[] arr = new Object[10];
for (<caret>int i = 0; i < arr.length; i++) {
arr[i] = (choice ? "foo" : new Object());
}
}
}