From 2eae3c8876cc2f6b008bd9296869860e547e08e8 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 22 Jul 2014 12:27:43 +0200 Subject: [PATCH] contract inference: take explicit parameter notnull into account (IDEA-127667) --- .../codeInspection/dataFlow/ContractInference.java | 11 +++++++++-- .../ContractInferenceFromSourceTest.groovy | 10 ++++++++++ 2 files changed, 19 insertions(+), 2 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 5d8c351f5cf2..a1c908837ad0 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 @@ -15,6 +15,7 @@ */ package com.intellij.codeInspection.dataFlow; +import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInspection.dataFlow.MethodContract.ValueConstraint; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; @@ -218,7 +219,7 @@ class ContractInferenceInterpreter { } @Nullable - private static MethodContract contractWithConstraint(ValueConstraint[] state, + private MethodContract contractWithConstraint(ValueConstraint[] state, int parameter, ValueConstraint paramConstraint, ValueConstraint returnValue) { ValueConstraint[] newState = withConstraint(state, parameter, paramConstraint); @@ -390,12 +391,18 @@ class ContractInferenceInterpreter { } @Nullable - private static ValueConstraint[] withConstraint(ValueConstraint[] constraints, int index, ValueConstraint constraint) { + private ValueConstraint[] withConstraint(ValueConstraint[] constraints, int index, ValueConstraint constraint) { + if (constraints[index] == constraint) return constraints; + ValueConstraint negated = negateConstraint(constraint); if (negated != constraint && constraints[index] == negated) { return null; } + if (constraint == NULL_VALUE && NullableNotNullManager.isNotNull(myMethod.getParameterList().getParameters()[index])) { + return null; + } + ValueConstraint[] copy = constraints.clone(); copy[index] = constraint; return copy; diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy b/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy index 8656101155a3..23eac589e2db 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy @@ -272,6 +272,16 @@ class ContractInferenceFromSourceTest extends LightCodeInsightFixtureTestCase { assert c == ['null, _ -> false', '!null, _ -> true'] } + public void "test take explicit parameter notnull into account"() { + def c = inferContracts(""" + final Object foo(@org.jetbrains.annotations.NotNull Object bar) { + if (!(bar instanceof CharSequence)) return null; + return new String("abc"); + } + """) + assert c == [] + } + private String inferContract(String method) { return assertOneElement(inferContracts(method)) }