From ec8b2435cb73ab20dcde88d4281c2436262f4a7d Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 18 Dec 2013 10:40:41 +0100 Subject: [PATCH] IDEA-117297 @Contract doesn't play nice with @NotNull/@Nullable --- .../dataFlow/ControlFlowAnalyzer.java | 15 +++++++++-- .../fixture/ContractWithNullable.java | 27 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index 0fb794a3c743..a3d85d0c301f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -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 getCallContracts(PsiMethodCallExpression expression) { PsiMethod resolved = expression.resolveMethod(); if (resolved != null) { diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNullable.java b/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNullable.java index 99cee251aa00..47ce7fcddd03 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNullable.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNullable.java @@ -12,5 +12,32 @@ public class Foo { @Nullable Object foo(Object a) { return a; } + @NotNull + Object notNull() { + return nullable(false); + } + + @NotNull + Object notNull2() { + return nullable2(false); + } + + @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; + } + }