IDEA-136603 IDEA does not warn if annotated with @Nullable local variable is used...
authorpeter <peter@jetbrains.com>
Tue, 17 Feb 2015 14:37:44 +0000 (15:37 +0100)
committerpeter <peter@jetbrains.com>
Tue, 17 Feb 2015 14:55:07 +0000 (15:55 +0100)
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java
java/java-tests/testData/inspection/dataFlow/fixture/ExplicitlyNullableLocalVar.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java

index 38d4857c7514479a05ecfbbf13eaf77bbd8a24b5..3cde802544c84496b40bc31a1fc809c60838768d 100644 (file)
@@ -1330,11 +1330,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
 
   @Override public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
     startElement(expression);
-    PsiElement[] children = expression.getChildren();
-    for (PsiElement child : children) {
-      child.accept(this);
-    }
-    pushUnknown();
+    addInstruction(new PushInstruction(myFactory.createTypeValue(expression.getType(), Nullness.NOT_NULL), expression));
     finishElement(expression);
   }
 
index 4d8df8da219a443c5a6f1d505afe300a7e18b909..390b0451e0827a8082ef6e33c216d20745313906 100644 (file)
@@ -80,6 +80,11 @@ public class StandardInstructionVisitor extends InstructionVisitor {
       if (!(psi instanceof PsiField) || !psi.hasModifierProperty(PsiModifier.VOLATILE)) {
         memState.setVarValue(var, dfaSource);
       }
+      if (var.getInherentNullability() == Nullness.NULLABLE && !memState.isNotNull(dfaSource) && instruction.isVariableInitializer()) {
+        DfaMemoryStateImpl stateImpl = (DfaMemoryStateImpl)memState;
+        stateImpl.setVariableState(var, stateImpl.getVariableState(var).withNullability(Nullness.NULLABLE));
+      }
+
     } else if (dfaDest instanceof DfaTypeValue && ((DfaTypeValue)dfaDest).isNotNull()) {
       checkNotNullable(memState, dfaSource, NullabilityProblem.assigningToNotNull, instruction.getRExpression());
     }
index a320e5ccf495f3e0199ae6f0afb2797351782f46..90b3796a43fa06acdd7c414ca088c506bb9a3724 100644 (file)
@@ -30,6 +30,7 @@ import com.intellij.codeInspection.dataFlow.DfaMemoryState;
 import com.intellij.codeInspection.dataFlow.InstructionVisitor;
 import com.intellij.codeInspection.dataFlow.value.DfaValue;
 import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiVariable;
 import org.jetbrains.annotations.Nullable;
 
 public class AssignInstruction extends Instruction {
@@ -46,10 +47,15 @@ public class AssignInstruction extends Instruction {
     return visitor.visitAssign(this, runner, stateBefore);
   }
 
+  @Nullable
   public PsiExpression getRExpression() {
     return myRExpression;
   }
 
+  public boolean isVariableInitializer() {
+    return myRExpression != null && myRExpression.getParent() instanceof PsiVariable;
+  }
+
   @Nullable
   public DfaValue getAssignedValue() {
     return myAssignedValue;
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ExplicitlyNullableLocalVar.java b/java/java-tests/testData/inspection/dataFlow/fixture/ExplicitlyNullableLocalVar.java
new file mode 100644 (file)
index 0000000..f7a0b48
--- /dev/null
@@ -0,0 +1,15 @@
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+abstract class IDEATest {
+  abstract Object someMethod(@NotNull Object someParam);
+  abstract Object someObject();
+
+  public void testIDEA() {
+    @Nullable Object obj2 = someObject();
+    someMethod(<warning descr="Argument 'obj2' might be null">obj2</warning>);
+  }
+}
\ No newline at end of file
index 2d44dcbd70b901223924ef423044f51d896bcfab..acc64ef5f9a0aeb0c47b21f2d2b5f44479ef223c 100644 (file)
@@ -198,6 +198,8 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
   public void testNullCheckDoesntAffectUncheckedCast() { doTest(); }
   public void testThrowNull() { doTest(); }
 
+  public void testExplicitlyNullableLocalVar() { doTest(); }
+
   public void testTryWithResourcesNullability() { doTest(); }
   public void testTryWithResourcesInstanceOf() { doTest(); }
   public void testOmnipresentExceptions() { doTest(); }