IDEA-209618 NotNull annotated method might result in null inspection disappears with pure Contract annotation set.

This commit is contained in:
Tagir Valeev
2019-04-02 10:43:27 +07:00
parent be87aa1df8
commit 90cfb46930
2 changed files with 31 additions and 2 deletions
@@ -494,8 +494,18 @@ public class StandardInstructionVisitor extends InstructionVisitor {
}
@NotNull
private static PsiMethod findSpecificMethod(@NotNull PsiMethod method, @NotNull DfaMemoryState state, @Nullable DfaValue qualifier) {
private static PsiMethod findSpecificMethod(PsiElement context,
@NotNull PsiMethod method,
@NotNull DfaMemoryState state,
@Nullable DfaValue qualifier) {
if (qualifier == null || !PsiUtil.canBeOverridden(method)) return method;
PsiExpression qualifierExpression = null;
if (context instanceof PsiMethodCallExpression) {
qualifierExpression = ((PsiMethodCallExpression)context).getMethodExpression().getQualifierExpression();
} else if (context instanceof PsiMethodReferenceExpression) {
qualifierExpression = ((PsiMethodReferenceExpression)context).getQualifierExpression();
}
if (qualifierExpression instanceof PsiSuperExpression) return method; // non-virtual call
TypeConstraint constraint = state.getValueFact(qualifier, DfaFactType.TYPE_CONSTRAINT);
PsiType type = constraint == null ? null : constraint.getPsiType();
return MethodUtils.findSpecificMethod(method, type);
@@ -526,7 +536,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
Mutability mutable = Mutability.UNKNOWN;
if (targetMethod != null) {
mutable = Mutability.getMutability(targetMethod);
PsiMethod realMethod = findSpecificMethod(targetMethod, state, qualifierValue);
PsiMethod realMethod = findSpecificMethod(instruction.getContext(), targetMethod, state, qualifierValue);
if (realMethod != targetMethod) {
nullability = DfaPsiUtil.getElementNullability(type, realMethod);
mutable = Mutability.getMutability(realMethod);
@@ -1,4 +1,5 @@
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
class NullableReturn {
@@ -7,4 +8,22 @@ class NullableReturn {
// no nullable return from notnull method here
return x == null ? o3 : x;
}
interface Context {}
static class Foo {
@Nullable
protected Boolean executeImpl(@Nullable Context context) {
return null;
}
}
static class Bar extends Foo {
@NotNull
@Contract(pure = true)
@Override
protected Boolean executeImpl(@Nullable Context context) {
return <warning descr="Expression 'super.executeImpl(context)' might evaluate to null but is returned by the method declared as @NotNull">super.executeImpl(context)</warning>;
}
}
}