IDEA-117297 @Contract doesn't play nice with @NotNull/@Nullable

This commit is contained in:
peter
2013-12-18 10:42:49 +01:00
parent 8bca4a68df
commit ec8b2435cb
2 changed files with 40 additions and 2 deletions
@@ -1417,7 +1417,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
for (MethodContract contract : contracts) {
handleContract(expression, contract);
}
pushUnknown(); // goto here if all contracts are false
pushUnknownReturnValue(expression); // goto here if all contracts are false
return true;
}
@@ -1451,7 +1451,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
// if contract is true
switch (contract.returnValue) {
case ANY_VALUE:
pushUnknown();
pushUnknownReturnValue(expression);
addInstruction(new GotoInstruction(exitPoint));
break;
case NULL_VALUE:
@@ -1482,6 +1482,17 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
}
private void pushUnknownReturnValue(PsiMethodCallExpression expression) {
PsiMethod method = expression.resolveMethod();
if (method != null) {
PsiType type = expression.getType();
addInstruction(new PushInstruction(myFactory.createTypeValue(type, DfaPsiUtil.getElementNullability(type, method)), null));
}
else {
pushUnknown();
}
}
private static List<MethodContract> getCallContracts(PsiMethodCallExpression expression) {
PsiMethod resolved = expression.resolveMethod();
if (resolved != null) {
@@ -12,5 +12,32 @@ public class Foo {
@Nullable
Object foo(Object a) { return a; }
@NotNull
Object notNull() {
return <warning descr="Expression 'nullable(false)' might evaluate to null but is returned by the method declared as @NotNull">nullable(false)</warning>;
}
@NotNull
Object notNull2() {
return <warning descr="Expression 'nullable2(false)' might evaluate to null but is returned by the method declared as @NotNull">nullable2(false)</warning>;
}
@Nullable
@Contract("true -> !null")
Object nullable(boolean notNull) {
return notNull ? "" : anotherNullable();
}
@Nullable
@Contract("true -> !null; _->_")
Object nullable2(boolean notNull) {
return notNull ? "" : anotherNullable();
}
@Nullable
Object anotherNullable() {
return null;
}
}