IterableUsedAsVararg: fixes according to review IDEA-CR-45949

This commit is contained in:
Tagir Valeev
2019-04-10 14:49:18 +07:00
parent 4e4c6ed950
commit cb2e86701d
4 changed files with 67 additions and 9 deletions
@@ -55,9 +55,13 @@ public class IterableUsedAsVarargInspection extends AbstractBaseJavaLocalInspect
String replacement = "new " + className + "[0]";
argCopy.replace(factory.createExpressionFromText(replacement, argCopy));
JavaResolveResult copyResult = callCopy.getMethodExpression().advancedResolve(false);
if (copyResult.getElement() != method) return;
PsiType substitutionWithArray = copyResult.getSubstitutor().substitute(componentType);
if (substitutionWithArray == null || TypeUtils.isJavaLangObject(substitutionWithArray)) return;
if (copyResult.getElement() == method) {
PsiType substitutionWithArray = copyResult.getSubstitutor().substitute(componentType);
if (substitutionWithArray == null || TypeUtils.isJavaLangObject(substitutionWithArray)) return;
} else {
PsiMethod newMethod = (PsiMethod)copyResult.getElement();
if (newMethod == null || !newMethod.isVarArgs() || newMethod.getParameterList().getParametersCount() != argCount) return;
}
LocalQuickFix fix = null;
if (InheritanceUtil.isInheritor(varArgExpression.getType(), CommonClassNames.JAVA_UTIL_COLLECTION)) {
fix = new AddToArrayFix(className);
@@ -86,7 +90,7 @@ public class IterableUsedAsVarargInspection extends AbstractBaseJavaLocalInspect
if (!InheritanceUtil.isInheritor(expression.getType(), CommonClassNames.JAVA_UTIL_COLLECTION)) return;
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
String fullReplacementText =
ParenthesesUtils.getText(expression, ParenthesesUtils.METHOD_CALL_PRECEDENCE) + ".toArray(new " + myClassName + "[0])";
ParenthesesUtils.getText(expression, ParenthesesUtils.METHOD_CALL_PRECEDENCE + 1) + ".toArray(new " + myClassName + "[0])";
expression.replace(factory.createExpressionFromText(fullReplacementText, expression));
}
}
@@ -1,10 +1,12 @@
<html>
<body>
Reports suspicious usages of collection or iterables in vararg method calls. E.g. given method
<code>&lt;T&gt; boolean contains(T needle, T... haystack)</code> the call like
<code>if(contains("item", listOfStrings)) {...}</code> looks suspicious as the list will be
wrapped into single element array. Such code can be correctly compiled and likely run without
exceptions, but it's unlikely intended.
Reports suspicious usages of <b>Collection</b> or an <b>Iterable</b> in vararg method calls. E.g. given method
<pre>&lt;T&gt; boolean contains(T needle, T... haystack) {...}</pre>
<p>a call like</p>
<pre>if(contains("item", listOfStrings)) {...}</pre>
<p>looks suspicious as the list will be wrapped into a single element array.
Such code can be successfully compiled and likely run without
exceptions, but it's unlikely intended.</p>
<!-- tooltip end -->
<p><small>New in 2019.2</small></p>
</body>
@@ -0,0 +1,26 @@
// "Call 'toArray(new String[0])'" "true"
import java.util.List;
import java.util.Objects;
class Test {
static <T> boolean contains(T needle, T... haystack) {
for (final T t : haystack) {
if (Objects.equals(t, needle)) {
return true;
}
}
return false;
}
static <T> boolean contains(String needle, String... haystack) {
return contains((Object)needle, (Object[])haystack);
}
void use(String s) {
if (contains(s, getList().toArray(new String[0]))) {
}
}
native List<String> getList();
}
@@ -0,0 +1,26 @@
// "Call 'toArray(new String[0])'" "true"
import java.util.List;
import java.util.Objects;
class Test {
static <T> boolean contains(T needle, T... haystack) {
for (final T t : haystack) {
if (Objects.equals(t, needle)) {
return true;
}
}
return false;
}
static <T> boolean contains(String needle, String... haystack) {
return contains((Object)needle, (Object[])haystack);
}
void use(String s) {
if (contains(s, <caret>getList())) {
}
}
native List<String> getList();
}