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 b1c12da627a7..f74238bb1d19 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java @@ -23,7 +23,7 @@ import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizableStringList; import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiModifierListOwner; +import com.intellij.psi.*; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -126,11 +126,38 @@ public class NullableNotNullManager implements PersistentStateComponent } public boolean isNullable(PsiModifierListOwner owner, boolean checkBases) { - return AnnotationUtil.isAnnotated(owner, getNullables(), checkBases, false); + if (AnnotationUtil.isAnnotated(owner, getNullables(), checkBases, false)) { + return true; + } + + return owner instanceof PsiParameter && isContainerAnnotated(owner, "javax.annotation.ParametersAreNullableByDefault"); } public boolean isNotNull(PsiModifierListOwner owner, boolean checkBases) { - return AnnotationUtil.isAnnotated(owner, getNotNulls(), checkBases, false); + if (AnnotationUtil.isAnnotated(owner, getNotNulls(), checkBases, false)) { + return true; + } + + return owner instanceof PsiParameter && isContainerAnnotated(owner, "javax.annotation.ParametersAreNonnullByDefault"); + } + + private static boolean isContainerAnnotated(PsiModifierListOwner owner, String annotationFQN) { + PsiElement element = owner.getParent(); + while (element != null) { + if (element instanceof PsiModifierListOwner && + AnnotationUtil.isAnnotated((PsiModifierListOwner)element, annotationFQN, false, false)) { + return true; + } + + if (element instanceof PsiClassOwner) { + String packageName = ((PsiClassOwner)element).getPackageName(); + PsiPackage psiPackage = JavaPsiFacade.getInstance(element.getProject()).findPackage(packageName); + return psiPackage != null && AnnotationUtil.isAnnotated(psiPackage, annotationFQN, false, false); + } + + element = element.getContext(); + } + return false; } public List getNullables() { diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ParametersAreNonnullByDefault.java b/java/java-tests/testData/inspection/dataFlow/fixture/ParametersAreNonnullByDefault.java new file mode 100644 index 000000000000..7dc2e51effe4 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ParametersAreNonnullByDefault.java @@ -0,0 +1,25 @@ +import foo.*; + +class Some { + void foo() { + NotNullClass.foo(null); + NotNullClass.foo("a"); + + NullableClass.foo(null); + NullableClass.foo("a"); + + AnotherPackageNotNull.foo(null); + AnotherPackageNotNull.foo("a"); + } + +} + +@javax.annotation.ParametersAreNonnullByDefault +class NotNullClass { + static void foo(String s) {} + +} +@javax.annotation.ParametersAreNullableByDefault +class NullableClass { + static void foo(String s) {} +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java index 3abc49aaddba..69c31a6b270b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java @@ -303,6 +303,16 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase { public void testNotEqualsTypo() { doTest(); } public void testAndEquals() { doTest(); } + + public void testParametersAreNonnullByDefault() { + myFixture.addClass("package javax.annotation; public @interface ParametersAreNonnullByDefault {}"); + myFixture.addClass("package javax.annotation; public @interface ParametersAreNullableByDefault {}"); + + myFixture.addClass("package foo; public class AnotherPackageNotNull { public static void foo(String s) {}}"); + myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;"); + + doTest(); + } public void _testNullCheckBeforeInstanceof() { doTest(); } // http://youtrack.jetbrains.com/issue/IDEA-113220 } diff --git a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index 5098070dec16..697e78de64d1 100644 --- a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -305,6 +305,7 @@ nominvalue nomonitoring nonatomic noninfingement +nonnull nonschema noorder noparallel