ExpressionUtils#isArrayCreationExpression; used in SideEffectChecker

Fixes IDEA-194652 IDEA found side effect in primitive array creation
This commit is contained in:
Tagir Valeev
2018-06-28 17:53:29 +07:00
parent 60b72a73ad
commit 5f86f8cb46
10 changed files with 53 additions and 24 deletions
@@ -28,6 +28,7 @@ import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.psiutils.ExpressionUtils;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
@@ -645,13 +646,8 @@ public class GenericsHighlightUtil {
final PsiType retErasure2 = TypeConversionUtil.erasure(superMethod.getReturnType());
boolean differentReturnTypeErasure = !Comparing.equal(retErasure1, retErasure2);
if (checkEqualsSuper && atLeast17) {
if (retErasure1 != null && retErasure2 != null) {
differentReturnTypeErasure = !TypeConversionUtil.isAssignable(retErasure1, retErasure2);
}
else {
differentReturnTypeErasure = !(retErasure1 == null && retErasure2 == null);
}
if (checkEqualsSuper && atLeast17 && retErasure1 != null && retErasure2 != null) {
differentReturnTypeErasure = !TypeConversionUtil.isAssignable(retErasure1, retErasure2);
}
if (differentReturnTypeErasure &&
@@ -838,8 +834,7 @@ public class GenericsHighlightUtil {
@Nullable
static HighlightInfo checkEnumInstantiation(@NotNull PsiElement expression, @Nullable PsiClass aClass) {
if (aClass != null && aClass.isEnum() &&
(!(expression instanceof PsiNewExpression) ||
((PsiNewExpression)expression).getArrayDimensions().length == 0 && ((PsiNewExpression)expression).getArrayInitializer() == null)) {
!(expression instanceof PsiNewExpression && ExpressionUtils.isArrayCreationExpression((PsiNewExpression)expression))) {
String description = JavaErrorMessages.message("enum.types.cannot.be.instantiated");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create();
}
@@ -1011,7 +1006,7 @@ public class GenericsHighlightUtil {
return highlightInfo;
}
PsiClass superClass = superMethod.getMethod().getContainingClass();
if (languageLevel.equals(LanguageLevel.JDK_1_5) &&
if (languageLevel == LanguageLevel.JDK_1_5 &&
superClass != null &&
superClass.isInterface()) {
String description = JavaErrorMessages.message("override.not.allowed.in.interfaces");
@@ -17,6 +17,7 @@ import com.intellij.util.BitUtil;
import com.intellij.util.Processor;
import com.intellij.util.ThreeState;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.psiutils.ExpressionUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -211,9 +212,8 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem
@Nullable
public Collection<PsiElement> getTargetCandidates(@NotNull PsiReference reference) {
PsiElement parent = reference.getElement().getParent();
if (parent instanceof PsiMethodCallExpression || parent instanceof PsiNewExpression &&
((PsiNewExpression)parent).getArrayDimensions().length == 0 &&
((PsiNewExpression)parent).getArrayInitializer() == null) {
if (parent instanceof PsiMethodCallExpression ||
parent instanceof PsiNewExpression && !ExpressionUtils.isArrayCreationExpression((PsiNewExpression)parent)) {
PsiCallExpression callExpr = (PsiCallExpression)parent;
boolean allowStatics = false;
PsiExpression qualifier = callExpr instanceof PsiMethodCallExpression ? ((PsiMethodCallExpression)callExpr).getMethodExpression().getQualifierExpression()
@@ -33,6 +33,7 @@ import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.MultiMap;
import com.siyeh.ig.psiutils.ExpressionUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -267,7 +268,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
private void replaceNewOrType(final PsiNewExpression psiNewExpression, final PsiClassType superType) {
try {
if (psiNewExpression.getArrayDimensions().length == 0 && psiNewExpression.getArrayInitializer() == null) {
if (!ExpressionUtils.isArrayCreationExpression(psiNewExpression)) {
new InlineToAnonymousConstructorProcessor(myClass, psiNewExpression, superType).run();
}
else {
@@ -22,6 +22,7 @@ import com.intellij.psi.impl.PsiSuperMethodImplUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.usages.PsiElementUsageTarget;
import com.intellij.usages.UsageTarget;
import com.siyeh.ig.psiutils.ExpressionUtils;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -233,7 +234,7 @@ public class JavaUsageTypeProvider implements UsageTypeProviderEx {
if (isAnonymousClassOf(psiNewExpression.getAnonymousClass(), targets)) {
return UsageType.CLASS_ANONYMOUS_NEW_OPERATOR;
}
if (isNewArrayCreation(psiNewExpression)) {
if (ExpressionUtils.isArrayCreationExpression(psiNewExpression)) {
return UsageType.CLASS_NEW_ARRAY;
}
return UsageType.CLASS_NEW_OPERATOR;
@@ -243,10 +244,6 @@ public class JavaUsageTypeProvider implements UsageTypeProviderEx {
return null;
}
private static boolean isNewArrayCreation(@NotNull PsiNewExpression expression){
return expression.getArrayDimensions().length > 0 || expression.getArrayInitializer() != null;
}
private static boolean isAnonymousClassOf(@Nullable PsiAnonymousClass anonymousClass, @NotNull UsageTarget[] targets) {
if (anonymousClass == null) {
return false;
@@ -0,0 +1,11 @@
// "Remove redundant null-check" "true"
import java.util.Objects;
public class Test {
void test() {
foo();
}
native int foo();
}
@@ -0,0 +1,11 @@
// "Remove redundant null-check" "true"
import java.util.Objects;
public class Test {
void test() {
Objects.requireNonNull(new int<caret>[foo()]);
}
native int foo();
}
@@ -20,6 +20,7 @@ import com.intellij.util.containers.OrderedSet;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ExpressionUtils;
import org.jetbrains.annotations.NotNull;
public class ResultOfObjectAllocationIgnoredInspectionBase extends BaseInspection {
@@ -53,8 +54,7 @@ public class ResultOfObjectAllocationIgnoredInspectionBase extends BaseInspectio
return;
}
final PsiNewExpression newExpression = (PsiNewExpression)expression;
final PsiExpression[] arrayDimensions = newExpression.getArrayDimensions();
if (arrayDimensions.length != 0 || newExpression.getArrayInitializer() != null) {
if (ExpressionUtils.isArrayCreationExpression(newExpression)) {
return;
}
final PsiJavaCodeReferenceElement reference = newExpression.getClassOrAnonymousClassReference();
@@ -22,6 +22,7 @@ import com.intellij.psi.util.PsiUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.LibraryUtil;
import com.siyeh.ig.psiutils.MethodCallUtils;
import com.siyeh.ig.psiutils.MethodUtils;
@@ -99,7 +100,7 @@ public class RawUseOfParameterizedTypeInspection extends BaseInspection {
if (ignoreObjectConstruction) {
return;
}
if (ignoreUncompilable && (expression.getArrayInitializer() != null || expression.getArrayDimensions().length > 0)) {
if (ignoreUncompilable && ExpressionUtils.isArrayCreationExpression(expression)) {
//array creation can (almost) never be generic
return;
}
@@ -15,7 +15,10 @@
*/
package com.siyeh.ig.psiutils;
import com.intellij.codeInsight.*;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInsight.PsiEquivalenceUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
@@ -1338,4 +1341,14 @@ public class ExpressionUtils {
}
return null;
}
/**
* Returns true if given new-expression creates an array rather than an object.
*
* @param expression expression to check
* @return true if given new-expression creates an array
*/
public static boolean isArrayCreationExpression(@NotNull PsiNewExpression expression) {
return expression.getArrayInitializer() != null || expression.getArrayDimensions().length > 0;
}
}
@@ -174,7 +174,7 @@ public class SideEffectChecker {
@Override
public void visitNewExpression(@NotNull PsiNewExpression expression) {
if(!isSideEffectFreeConstructor(expression)) {
if (!ExpressionUtils.isArrayCreationExpression(expression) && !isSideEffectFreeConstructor(expression)) {
if (addSideEffect(expression)) return;
}
super.visitNewExpression(expression);