summaryrefslogtreecommitdiff
path: root/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java')
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java41
1 files changed, 29 insertions, 12 deletions
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
index 7037fac8cfea..f919ac5f8796 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
@@ -31,6 +31,7 @@ import com.siyeh.ig.psiutils.SideEffectChecker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -59,12 +60,27 @@ public class ContractInference {
class ContractInferenceInterpreter {
private final PsiMethod myMethod;
+ private final ValueConstraint[] myEmptyConstraints;
public ContractInferenceInterpreter(PsiMethod method) {
myMethod = method;
+ myEmptyConstraints = MethodContract.createConstraintArray(myMethod.getParameterList().getParametersCount());
}
List<MethodContract> inferContracts() {
+ final boolean notNull = NullableNotNullManager.isNotNull(myMethod);
+ return ContainerUtil.filter(doInferContracts(), new Condition<MethodContract>() {
+ @Override
+ public boolean value(MethodContract contract) {
+ if (notNull && contract.returnValue == NOT_NULL_VALUE && Arrays.equals(contract.arguments, myEmptyConstraints)) {
+ return false;
+ }
+ return true;
+ }
+ });
+ }
+
+ private List<MethodContract> doInferContracts() {
PsiCodeBlock body = myMethod.getBody();
PsiStatement[] statements = body == null ? PsiStatement.EMPTY_ARRAY : body.getStatements();
if (statements.length == 0) return Collections.emptyList();
@@ -101,8 +117,7 @@ class ContractInferenceInterpreter {
}
}
- ValueConstraint[] emptyState = MethodContract.createConstraintArray(myMethod.getParameterList().getParametersCount());
- return visitStatements(Collections.singletonList(emptyState), statements);
+ return visitStatements(Collections.singletonList(myEmptyConstraints), statements);
}
@Nullable
@@ -130,12 +145,12 @@ class ContractInferenceInterpreter {
return RecursionManager.doPreventingRecursion(myMethod, true, new Computable<List<MethodContract>>() {
@Override
public List<MethodContract> compute() {
- List<MethodContract> delegateContracts = ControlFlowAnalyzer.getMethodContracts(targetMethod);
- return ContainerUtil.mapNotNull(delegateContracts, new NullableFunction<MethodContract, MethodContract>() {
+ final boolean notNull = NullableNotNullManager.isNotNull(targetMethod);
+ List<MethodContract> fromDelegate = ContainerUtil.mapNotNull(ControlFlowAnalyzer.getMethodContracts(targetMethod), new NullableFunction<MethodContract, MethodContract>() {
@Nullable
@Override
public MethodContract fun(MethodContract delegateContract) {
- ValueConstraint[] answer = MethodContract.createConstraintArray(myMethod.getParameterList().getParametersCount());
+ ValueConstraint[] answer = myEmptyConstraints;
for (int i = 0; i < delegateContract.arguments.length; i++) {
if (i >= arguments.length) return null;
@@ -155,9 +170,17 @@ class ContractInferenceInterpreter {
}
}
}
- return answer == null ? null : new MethodContract(answer, negated ? negateConstraint(delegateContract.returnValue) : delegateContract.returnValue);
+ ValueConstraint returnValue = negated ? negateConstraint(delegateContract.returnValue) : delegateContract.returnValue;
+ if (notNull && returnValue != THROW_EXCEPTION) {
+ returnValue = NOT_NULL_VALUE;
+ }
+ return answer == null ? null : new MethodContract(answer, returnValue);
}
});
+ if (notNull) {
+ return ContainerUtil.concat(fromDelegate, Arrays.asList(new MethodContract(myEmptyConstraints, NOT_NULL_VALUE)));
+ }
+ return fromDelegate;
}
});
}
@@ -370,12 +393,6 @@ class ContractInferenceInterpreter {
else if (statement instanceof PsiDoWhileStatement) {
result.addAll(visitStatements(states, ((PsiDoWhileStatement)statement).getBody()));
}
- else if (statement instanceof PsiTryStatement) {
- PsiCodeBlock block = ((PsiTryStatement)statement).getTryBlock();
- if (block != null) {
- result.addAll(visitStatements(states, block.getStatements()));
- }
- }
break; // visit only the first statement unless it's 'if' whose 'then' always returns and the next statement is effectively 'else'
}