From d8da2fd7ec3cd0070b21beebac10b5859f930cd6 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Tue, 22 Aug 2017 15:16:03 +0700 Subject: [PATCH] Check nullability in array initializers (IDEA-174042) --- .../dataFlow/ControlFlowAnalyzer.java | 24 ++++++++++++------- ...yComponentAndMethodAnnotationConflict.java | 7 ++++-- 2 files changed, 20 insertions(+), 11 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 d4d53b10966c..c4c0f90eec9e 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 @@ -1013,16 +1013,24 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) { startElement(expression); PsiType type = expression.getType(); + PsiType componentType = type instanceof PsiArrayType ? ((PsiArrayType)type).getComponentType() : null; + processArrayInitializers(expression, componentType); + pushUnknown(); + finishElement(expression); + } + + private void processArrayInitializers(@NotNull PsiArrayInitializerExpression expression, PsiType componentType) { PsiExpression[] initializers = expression.getInitializers(); for (PsiExpression initializer : initializers) { initializer.accept(this); - if (type instanceof PsiArrayType) { - generateBoxingUnboxingInstructionFor(initializer, ((PsiArrayType)type).getComponentType()); + if (componentType != null) { + generateBoxingUnboxingInstructionFor(initializer, componentType); + if (DfaPsiUtil.getTypeNullability(componentType) == Nullness.NOT_NULL) { + addInstruction(new CheckNotNullInstruction(initializer, NullabilityProblem.assigningToNotNull)); + } } addInstruction(new PopInstruction()); } - pushUnknown(); - finishElement(expression); } @Override @@ -1517,7 +1525,8 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { pushUnknown(); - if (expression.getType() instanceof PsiArrayType) { + PsiType type = expression.getType(); + if (type instanceof PsiArrayType) { final PsiExpression[] dimensions = expression.getArrayDimensions(); for (final PsiExpression dimension : dimensions) { dimension.accept(this); @@ -1527,10 +1536,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { } final PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer(); if (arrayInitializer != null) { - for (final PsiExpression initializer : arrayInitializer.getInitializers()) { - initializer.accept(this); - addInstruction(new PopInstruction()); - } + processArrayInitializers(arrayInitializer, ((PsiArrayType)type).getComponentType()); } addConditionalRuntimeThrow(); addInstruction(new MethodCallInstruction(expression, null, Collections.emptyList())); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ArrayComponentAndMethodAnnotationConflict.java b/java/java-tests/testData/inspection/dataFlow/fixture/ArrayComponentAndMethodAnnotationConflict.java index b9314775b96b..4f081a56a7af 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/ArrayComponentAndMethodAnnotationConflict.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ArrayComponentAndMethodAnnotationConflict.java @@ -18,8 +18,11 @@ class FooImpl implements Foo { if (Math.random() > 0.5) { return null; } - else { - return new Object[]{null, new Object()}; + else if (Math.random() > 0.5) { + @NotNull Object @Nullable [] arr1 = new Object[]{null, new Object(), Math.random() > 0.5 ? new Object() : null}; + @NotNull Object @Nullable [] arr2 = {null, new Object(), Math.random() > 0.5 ? new Object() : null}; + return new Object[]{null, new Object(), Math.random() > 0.5 ? new Object() : null}; } + return new @NotNull Object @Nullable []{null, new Object(), Math.random() > 0.5 ? new Object() : null}; } } \ No newline at end of file