Commit 9ff31b80 authored by Tagir Valeev's avatar Tagir Valeev
Browse files

IDEA-181645 Suspicious method calls false positive for null-containing collection

parent 5c25b28e
Branches unavailable Tags unavailable
No related merge requests found
Showing with 36 additions and 0 deletions
+36 -0
......@@ -21,13 +21,23 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.IntArrayList;
import com.siyeh.ig.callMatcher.CallMatcher;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class SuspiciousMethodCallUtil {
// List.of/Set.of are unnecessary here as they don't accept nulls
private static final CallMatcher.Simple SINGLETON_COLLECTION =
CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "singletonList", "singleton").parameterCount(1);
static void setupPatternMethods(PsiManager manager,
GlobalSearchScope searchScope,
List<PsiMethod> patternMethods,
......@@ -199,6 +209,10 @@ public class SuspiciousMethodCallUtil {
final PsiType itemType = JavaGenericsUtil.getCollectionItemType(argType, calleeMethod.getResolveScope());
final PsiType qualifierItemType = JavaGenericsUtil.getCollectionItemType(qualifierType, calleeMethod.getResolveScope());
if (qualifierItemType != null && itemType != null && !qualifierItemType.isAssignableFrom(itemType)) {
if (TypeUtils.isJavaLangObject(itemType) && hasNullCollectionArg(methodExpression)) {
// removeAll(Collections.singleton(null)) is a valid way to remove all nulls from collection
return null;
}
return InspectionsBundle.message("inspection.suspicious.collections.method.calls.problem.descriptor",
PsiFormatUtil.formatType(qualifierType, 0, PsiSubstitutor.EMPTY),
PsiFormatUtil.formatType(itemType, 0, PsiSubstitutor.EMPTY));
......@@ -235,4 +249,18 @@ public class SuspiciousMethodCallUtil {
}
return null;
}
private static boolean hasNullCollectionArg(PsiReferenceExpression methodExpression) {
PsiMethodCallExpression call = ObjectUtils.tryCast(methodExpression.getParent(), PsiMethodCallExpression.class);
if (call != null) {
PsiExpression arg =
ExpressionUtils.resolveExpression(ArrayUtil.getFirstElement(call.getArgumentList().getExpressions()));
PsiMethodCallExpression argCall =
ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(arg), PsiMethodCallExpression.class);
if (SINGLETON_COLLECTION.test(argCall) && ExpressionUtils.isNullLiteral(argCall.getArgumentList().getExpressions()[0])) {
return true;
}
}
return false;
}
}
......@@ -13,4 +13,12 @@ class Simple {
setO.removeAll(someData.keySet());
}
void testNull(List<String> list) {
list.removeAll(Collections.singleton(null));
}
void testNotNull(List<String> list) {
list.removeAll(<warning descr="'List<String>' may not contain objects of type 'Integer'">Collections.singleton(1)</warning>);
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment