mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
dfa: prefer unknown nullity from super over scoped nullity default (IDEA-167062)
This commit is contained in:
@@ -19,7 +19,6 @@ import com.intellij.codeInsight.daemon.ImplicitUsageProvider;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiSearchHelper;
|
||||
@@ -35,13 +34,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiMember;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiParameter;
|
||||
import static com.intellij.patterns.StandardPatterns.or;
|
||||
|
||||
public class NullnessUtil {
|
||||
private static final ElementPattern<? extends PsiModifierListOwner> MEMBER_OR_METHOD_PARAMETER =
|
||||
or(psiMember(), psiParameter().withSuperParent(2, psiMember()));
|
||||
|
||||
static Boolean calcCanBeNull(DfaVariableValue value) {
|
||||
PsiModifierListOwner var = value.getPsiVariable();
|
||||
@@ -50,8 +43,7 @@ public class NullnessUtil {
|
||||
return toBoolean(nullability);
|
||||
}
|
||||
|
||||
Nullness defaultNullability =
|
||||
value.getFactory().isUnknownMembersAreNullable() && MEMBER_OR_METHOD_PARAMETER.accepts(var) ? Nullness.NULLABLE : Nullness.UNKNOWN;
|
||||
Nullness defaultNullability = value.getFactory().suggestNullabilityForNonAnnotatedMember(var);
|
||||
|
||||
if (var instanceof PsiParameter && var.getParent() instanceof PsiForeachStatement) {
|
||||
PsiExpression iteratedValue = ((PsiForeachStatement)var.getParent()).getIteratedValue();
|
||||
|
||||
+3
-2
@@ -579,8 +579,9 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
|
||||
if (type != null && !(type instanceof PsiPrimitiveType)) {
|
||||
Nullness nullability = myReturnTypeNullability.get(instruction);
|
||||
if (nullability == Nullness.UNKNOWN && factory.isUnknownMembersAreNullable()) {
|
||||
nullability = Nullness.NULLABLE;
|
||||
PsiMethod targetMethod = instruction.getTargetMethod();
|
||||
if (nullability == Nullness.UNKNOWN && targetMethod != null) {
|
||||
nullability = factory.suggestNullabilityForNonAnnotatedMember(targetMethod);
|
||||
}
|
||||
return factory.createTypeValue(type, nullability);
|
||||
}
|
||||
|
||||
+17
-2
@@ -16,10 +16,12 @@
|
||||
|
||||
package com.intellij.codeInspection.dataFlow.value;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInspection.dataFlow.*;
|
||||
import com.intellij.codeInspection.dataFlow.rangeSet.LongRangeSet;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaRelationValue.RelationType;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -31,6 +33,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiMember;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiParameter;
|
||||
import static com.intellij.patterns.StandardPatterns.or;
|
||||
|
||||
public class DfaValueFactory {
|
||||
private final List<DfaValue> myValues = ContainerUtil.newArrayList();
|
||||
private final Map<Pair<DfaPsiType, DfaPsiType>, Boolean> myAssignableCache = ContainerUtil.newHashMap();
|
||||
@@ -57,8 +63,17 @@ public class DfaValueFactory {
|
||||
return myHonorFieldInitializers;
|
||||
}
|
||||
|
||||
public boolean isUnknownMembersAreNullable() {
|
||||
return myUnknownMembersAreNullable;
|
||||
private static final ElementPattern<? extends PsiModifierListOwner> MEMBER_OR_METHOD_PARAMETER =
|
||||
or(psiMember(), psiParameter().withSuperParent(2, psiMember()));
|
||||
|
||||
|
||||
@NotNull
|
||||
public Nullness suggestNullabilityForNonAnnotatedMember(@NotNull PsiModifierListOwner member) {
|
||||
if (myUnknownMembersAreNullable && MEMBER_OR_METHOD_PARAMETER.accepts(member) && AnnotationUtil.getSuperAnnotationOwners(member).isEmpty()) {
|
||||
return Nullness.NULLABLE;
|
||||
}
|
||||
|
||||
return Nullness.UNKNOWN;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -156,7 +156,7 @@ public class AnnotationUtil {
|
||||
return result == null ? PsiAnnotation.EMPTY_ARRAY : result.toArray(new PsiAnnotation[result.size()]);
|
||||
}
|
||||
|
||||
public static <T extends PsiModifierListOwner> List<T> getSuperAnnotationOwners(final T element) {
|
||||
public static <T extends PsiModifierListOwner> List<T> getSuperAnnotationOwners(@NotNull T element) {
|
||||
return CachedValuesManager.getCachedValue(element, () -> {
|
||||
Set<PsiModifierListOwner> result = ContainerUtil.newLinkedHashSet();
|
||||
if (element instanceof PsiMethod) {
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
interface UnknownInterface {
|
||||
void foo(String s);
|
||||
}
|
||||
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
class ImplWithNotNull implements UnknownInterface {
|
||||
public void foo(String s) {
|
||||
System.out.println(s.hashCode());
|
||||
}
|
||||
}
|
||||
@@ -352,6 +352,15 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNullabilityDefaultVsMethodImplementing() {
|
||||
addJavaxDefaultNullabilityAnnotations(myFixture);
|
||||
|
||||
DataFlowInspection inspection = new DataFlowInspection();
|
||||
inspection.TREAT_UNKNOWN_MEMBERS_AS_NULLABLE = true;
|
||||
myFixture.enableInspections(inspection);
|
||||
myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
public static void addJavaxDefaultNullabilityAnnotations(final JavaCodeInsightTestFixture fixture) {
|
||||
fixture.addClass("package javax.annotation;" +
|
||||
"@javax.annotation.meta.TypeQualifierDefault(java.lang.annotation.ElementType.PARAMETER) @javax.annotation.Nonnull " +
|
||||
|
||||
Reference in New Issue
Block a user