IDEA-42270 Good code is yellow: null passed to a @NotNull annotated varargs parameter

This commit is contained in:
peter
2012-10-29 12:57:22 +01:00
parent b2ca4d8a33
commit 03ab1d39cb
4 changed files with 44 additions and 2 deletions
@@ -187,7 +187,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
for (int i = 0; i < args.length; i++) {
final DfaValue arg = memState.pop();
final int revIdx = args.length - i - 1;
if (args.length <= parametersNotNull.length && revIdx < parametersNotNull.length) {
if (args.length <= parametersNotNull.length && revIdx < parametersNotNull.length && !(i == args.length - 1 && instruction.isVarargCall())) {
if (parametersNotNull[revIdx]) {
if (!memState.applyNotNull(arg)) {
onPassingNullParameter(runner, args[revIdx]);
@@ -42,13 +42,15 @@ public class MethodCallInstruction extends Instruction {
@NotNull private final PsiExpression myContext;
private final MethodType myMethodType;
@Nullable private DfaValue myPrecalculatedReturnValue;
public static enum MethodType {
private boolean myVarargCall;
public enum MethodType {
BOXING, UNBOXING, REGULAR_METHOD_CALL, CAST
}
public MethodCallInstruction(@NotNull PsiCallExpression callExpression, @Nullable DfaValue precalculatedReturnValue) {
this(callExpression, MethodType.REGULAR_METHOD_CALL);
myPrecalculatedReturnValue = precalculatedReturnValue;
myVarargCall = calcIsVarargCall(callExpression);
}
public MethodCallInstruction(@NotNull PsiExpression context, MethodType methodType, @Nullable PsiType resultType) {
@@ -77,6 +79,34 @@ public class MethodCallInstruction extends Instruction {
return myType;
}
public boolean isVarargCall() {
return myVarargCall;
}
private static boolean calcIsVarargCall(PsiCallExpression callExpression) {
PsiExpressionList argumentList = callExpression.getArgumentList();
if (argumentList != null) {
JavaResolveResult result = callExpression.resolveMethodGenerics();
PsiMethod method = (PsiMethod)result.getElement();
if (method != null && method.isVarArgs()) {
PsiType[] argTypes = argumentList.getExpressionTypes();
int argCount = argTypes.length;
PsiParameter[] parameters = method.getParameterList().getParameters();
int paramCount = parameters.length;
if (argCount > paramCount) {
return true;
}
PsiType lastParam = parameters[paramCount - 1].getType();
if (argCount == paramCount && !result.getSubstitutor().substitute(lastParam).isAssignableFrom(argTypes[argCount - 1])) {
return true;
}
}
}
return false;
}
@NotNull
public PsiExpression[] getArgs() {
return myArgs;
@@ -0,0 +1,10 @@
import org.jetbrains.annotations.NotNull;
class Test {
public static void test(@NotNull Object... objects) { }
public static void main(String[] args) {
Object o = null;
test(o);
}
}
@@ -99,4 +99,6 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas
public void testPreserveNullableOnUncheckedCast() throws Throwable { doTest(); }
public void testPassingNullableIntoVararg() throws Throwable { doTest(); }
}