diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/OptionalAssignedToNullInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/OptionalAssignedToNullInspection.java index 544f32b59e67..0476b53383a7 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/OptionalAssignedToNullInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/OptionalAssignedToNullInspection.java @@ -2,6 +2,7 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.PsiEquivalenceUtil; +import com.intellij.codeInspection.dataFlow.DfaUtil; import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.codeInspection.util.OptionalUtil; import com.intellij.java.JavaBundle; @@ -13,6 +14,8 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.ObjectUtils; +import com.intellij.util.containers.ContainerUtil; +import com.siyeh.ig.callMatcher.CallMatcher; import com.siyeh.ig.psiutils.*; import one.util.streamex.StreamEx; import org.jetbrains.annotations.Nls; @@ -22,6 +25,9 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; public class OptionalAssignedToNullInspection extends AbstractBaseJavaLocalInspectionTool { + private static final CallMatcher MAP_GET = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_MAP, "get").parameterTypes( + CommonClassNames.JAVA_LANG_OBJECT); + public boolean WARN_ON_COMPARISON = true; @Nullable @@ -88,7 +94,8 @@ public class OptionalAssignedToNullInspection extends AbstractBaseJavaLocalInspe PsiExpression value = ExpressionUtils.getValueComparedWithNull(binOp); if (value != null && TypeUtils.isOptional(value.getType()) && - !hasSubsequentIsPresentCall(value, binOp, JavaTokenType.EQEQ.equals(binOp.getOperationTokenType()))) { + !hasSubsequentIsPresentCall(value, binOp, JavaTokenType.EQEQ.equals(binOp.getOperationTokenType())) && + !comesFromMapGet(value)) { boolean useIsEmpty = binOp.getOperationTokenType().equals(JavaTokenType.EQEQ) && PsiUtil.isLanguageLevel11OrHigher(binOp); @@ -100,6 +107,17 @@ public class OptionalAssignedToNullInspection extends AbstractBaseJavaLocalInspe } } + private boolean comesFromMapGet(PsiExpression value) { + PsiLocalVariable local = ExpressionUtils.resolveLocalVariable(value); + if (local != null) { + PsiExpression initializer = ContainerUtil.getOnlyItem(DfaUtil.getVariableValues(local, value)); + if (initializer != null) { + value = initializer; + } + } + return MAP_GET.matches(ExpressionUtils.resolveExpression(value)); + } + private boolean hasSubsequentIsPresentCall(@NotNull PsiExpression optionalExpression, @NotNull PsiExpression previousExpression, boolean negated) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/optionalNull/afterOptionalComparison.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/optionalNull/afterOptionalComparison.java index 2e947d175e91..95c16c97d443 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/optionalNull/afterOptionalComparison.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/optionalNull/afterOptionalComparison.java @@ -1,5 +1,6 @@ // "Fix all 'Null value for Optional type' problems in file" "true" import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.OptionalInt; @@ -38,4 +39,11 @@ public class Test { } } + void test6(Map> map) { + Optional result = map.get("key"); + if (result == null) { + return; + } + System.out.println(result); + } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/optionalNull/beforeOptionalComparison.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/optionalNull/beforeOptionalComparison.java index cee49a8b41f3..f4c2680eb5f3 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/optionalNull/beforeOptionalComparison.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/optionalNull/beforeOptionalComparison.java @@ -1,5 +1,6 @@ // "Fix all 'Null value for Optional type' problems in file" "true" import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.OptionalInt; @@ -37,4 +38,11 @@ public class Test { } } + void test6(Map> map) { + Optional result = map.get("key"); + if (result == null) { + return; + } + System.out.println(result); + } } \ No newline at end of file