From 282e4ff321a0d0014e977c5602f1baee80a148f1 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Wed, 3 Jan 2018 16:33:45 +0700 Subject: [PATCH] Removed special handling of getX() != null Also fixes IDEABKL-7233 if methods are annotated as pure --- .../dataFlow/DfaMemoryStateImpl.java | 5 --- .../fixture/GettersAndPureNoFlushing.java | 3 +- .../dataFlow/fixture/XorNullity.java | 38 +++++++++++++++++++ .../DataFlowInspectionTest.java | 1 + 4 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/XorNullity.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java index e4c775a4ad53..530f18aac75f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -942,11 +942,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState { final boolean containsCalls = dfaLeft instanceof DfaVariableValue && ((DfaVariableValue)dfaLeft).containsCalls(); - // track "x" property state only inside "if (getX() != null) ..." - if (containsCalls && !isNotNull(dfaLeft) && isNull(dfaRight) && !isNegated) { - return true; - } - if (dfaLeft == dfaRight) { return containsCalls || !isNegated; } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/GettersAndPureNoFlushing.java b/java/java-tests/testData/inspection/dataFlow/fixture/GettersAndPureNoFlushing.java index 8e93f3a1289a..fb2edeb9ee97 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/GettersAndPureNoFlushing.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/GettersAndPureNoFlushing.java @@ -12,10 +12,11 @@ class Doo { boolean pureSomething() { return false;} public void main2() { + // isSomething is non-pure: flush if (getMethod() == null && !isSomething()) { return; } else { - System.out.println(getMethod().hashCode()); + System.out.println(getMethod().hashCode()); } } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/XorNullity.java b/java/java-tests/testData/inspection/dataFlow/fixture/XorNullity.java new file mode 100644 index 000000000000..b55d5123224b --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/XorNullity.java @@ -0,0 +1,38 @@ +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +// IDEABKL7233 +public class XorNullity { + void test(CreateForm createForm) { + if(createForm.getOpenIdIdentity() == null ^ createForm.getOpenIdProvider() == null) { + throw new RuntimeException("Invalid request"); + } + + if(createForm.getOpenIdIdentity() != null) { + findByOpenIdIdentity(createForm.getOpenIdProvider()); // never null + } + } + + void test2(CreateForm createForm) { + if(createForm.getOpenIdIdentity() == null ^ createForm.getOpenIdProvider() != null) { + throw new RuntimeException("Invalid request"); + } + + if(createForm.getOpenIdIdentity() != null) { + findByOpenIdIdentity(createForm.getOpenIdProvider()); // nullable + } + } + + void findByOpenIdIdentity(@NotNull Object identity) {} + + interface CreateForm { + @Nullable + @Contract(pure = true) + Object getOpenIdIdentity(); + + @Nullable + @Contract(pure = true) + Object getOpenIdProvider(); + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java index 05769b22ec0d..eac38bb0d206 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -578,4 +578,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testManyBooleans() { doTest(); } public void testPureNoArgMethodAsVariable() { doTest(); } public void testRedundantAssignment() { doTest(); } + public void testXorNullity() { doTest(); } }