diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java index c67d4c995b1f..f5d21fd70282 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java @@ -82,24 +82,20 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager { if (owner instanceof PsiMethod && PsiUtil.canBeOverriden((PsiMethod)owner)) { return true; } - if (ORG_JETBRAINS_ANNOTATIONS_CONTRACT.equals(annotationFQN) && hasHardcodedContracts(owner)) { + if (ORG_JETBRAINS_ANNOTATIONS_CONTRACT.equals(annotationFQN) && HardcodedContracts.hasHardcodedContracts(owner)) { return true; } if (AnnotationUtil.NOT_NULL.equals(annotationFQN) && owner instanceof PsiParameter && owner.getParent() != null) { if (AnnotationUtil.isAnnotated(owner, NullableNotNullManager.getInstance(owner.getProject()).getNullables(), false, false)) { return true; } - if (hasHardcodedContracts(owner.getParent().getParent())) { + if (HardcodedContracts.hasHardcodedContracts(owner)) { return true; } } return false; } - private static boolean hasHardcodedContracts(PsiElement owner) { - return owner instanceof PsiMethod && !HardcodedContracts.getHardcodedContracts((PsiMethod)owner, null).isEmpty(); - } - @Nullable private PsiAnnotation getInferredContractAnnotation(PsiMethod method) { if (method.getModifierList().findAnnotation(ORG_JETBRAINS_ANNOTATIONS_CONTRACT) != null) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java index f9e58134c860..05743b52c137 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java @@ -164,4 +164,16 @@ public class HardcodedContracts { return true; } + + public static boolean hasHardcodedContracts(@Nullable PsiElement element) { + if (element instanceof PsiMethod) { + return !getHardcodedContracts((PsiMethod)element, null).isEmpty(); + } + + if (element instanceof PsiParameter) { + return hasHardcodedContracts(element.getParent().getParent()); + } + + return false; + } } diff --git a/java/openapi/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java similarity index 80% rename from java/openapi/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java rename to java/java-impl/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java index c817c3019275..adb18e11b682 100644 --- a/java/openapi/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java @@ -15,13 +15,19 @@ */ package com.intellij.codeInsight; +import com.intellij.codeInspection.dataFlow.HardcodedContracts; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.components.StoragePathMacros; +import com.intellij.psi.PsiElement; @State( name = "NullableNotNullManager", storages = {@Storage(file = StoragePathMacros.PROJECT_FILE)} ) public class NullableNotNullManagerImpl extends NullableNotNullManager { + protected boolean hasHardcodedContracts(PsiElement element) { + return HardcodedContracts.hasHardcodedContracts(element); + } + } diff --git a/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java b/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java index 3696c4c666cc..97401bc6f725 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java @@ -53,9 +53,6 @@ public abstract class InferredAnnotationsManager { * * {@link Contract} and {@link NotNull} annotations on methods are not necessarily applicable to the overridden implementations, so they're ignored, too.

* - * In addition, package-default annotations like @ParametersAreNonnullByDefault are not honored for parameters where - * {@link NotNull} inference is ignored. - * * @return whether inference is to be suppressed the given annotation on the given method or parameter */ public abstract boolean ignoreInference(@NotNull PsiModifierListOwner owner, @Nullable String annotationFQN); diff --git a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java index ea5322cdd44f..3ade181e074b 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java @@ -36,7 +36,7 @@ import java.util.*; * User: anna * Date: 1/25/11 */ -public class NullableNotNullManager implements PersistentStateComponent { +public abstract class NullableNotNullManager implements PersistentStateComponent { private static final Logger LOG = Logger.getInstance("#" + NullableNotNullManager.class.getName()); public String myDefaultNullable = AnnotationUtil.NULLABLE; @@ -184,14 +184,16 @@ public class NullableNotNullManager implements PersistentStateComponent if (AnnotationUtil.isAnnotated(owner, nullable ? Arrays.asList(DEFAULT_NOT_NULLS) : Arrays.asList(DEFAULT_NULLABLES), checkBases, false)) { return null; } - - if (!nullable && InferredAnnotationsManager.getInstance(owner.getProject()).ignoreInference(owner, AnnotationUtil.NOT_NULL)) { + + if (!nullable && hasHardcodedContracts(owner)) { return null; } - + return findNullabilityDefaultInHierarchy(owner, nullable); } + protected abstract boolean hasHardcodedContracts(PsiElement element); + @Nullable private static PsiType getOwnerType(PsiModifierListOwner owner) { if (owner instanceof PsiVariable) return ((PsiVariable)owner).getType(); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/CustomTypeQualifierDefault.java b/java/java-tests/testData/inspection/dataFlow/fixture/CustomTypeQualifierDefault.java index e9ec6b1dbe11..47df47f35b44 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/CustomTypeQualifierDefault.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/CustomTypeQualifierDefault.java @@ -1,5 +1,6 @@ import foo.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; class Some { void foo(@NotNull String s) { @@ -18,6 +19,16 @@ class Some { @bar.MethodsAreNotNullByDefault class NotNullClass { static native Object foo(String s); + + public Object foo() { + return null; + } + + @Nullable + public Object foo2() { + return null; + } + } class NullableClass {