[java-inspections] OptionalAssignedToNull: avoid warning when Optional is received from Map.get (IDEA-292883)

GitOrigin-RevId: f41b21fa9d6588247aff0b3b4c8335ddfe74e7e9
This commit is contained in:
Tagir Valeev
2022-04-25 22:42:06 +00:00
committed by intellij-monorepo-bot
parent ee388a1595
commit 60a8572183
3 changed files with 35 additions and 1 deletions
@@ -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) {
@@ -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<String, Optional<String>> map) {
Optional<String> result = map.get("key");
if (result == null) {
return;
}
System.out.println(result);
}
}
@@ -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<String, Optional<String>> map) {
Optional<String> result = map.get("key");
if (result == null) {
return;
}
System.out.println(result);
}
}