mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-dfa] IDEA-351380 Support @CheckForNull with @TypeQualifierNickname
GitOrigin-RevId: 7247332e3e0aba95116cb4d84696c00cfa20ba45
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a116699350
commit
02f815ca4a
@@ -16,6 +16,7 @@ import java.util.Set;
|
||||
public final class Jsr305Support implements AnnotationPackageSupport {
|
||||
public static final String JAVAX_ANNOTATION_NULLABLE = "javax.annotation.Nullable";
|
||||
public static final String JAVAX_ANNOTATION_NONNULL = "javax.annotation.Nonnull";
|
||||
public static final String JAVAX_ANNOTATION_CHECK_FOR_NULL = "javax.annotation.CheckForNull";
|
||||
public static final String TYPE_QUALIFIER_NICKNAME = "javax.annotation.meta.TypeQualifierNickname";
|
||||
|
||||
@Override
|
||||
@@ -69,10 +70,18 @@ public final class Jsr305Support implements AnnotationPackageSupport {
|
||||
* @return nicknamed nullability declared by this annotation; null if this annotation is not a nullability nickname annotation
|
||||
*/
|
||||
public static @Nullable Nullability getNickNamedNullability(@NotNull PsiClass psiClass) {
|
||||
if (AnnotationUtil.findAnnotation(psiClass, TYPE_QUALIFIER_NICKNAME) == null) return null;
|
||||
PsiModifierList modifierList = psiClass.getModifierList();
|
||||
if (modifierList == null) return null;
|
||||
if (!modifierList.hasAnnotation(TYPE_QUALIFIER_NICKNAME)) return null;
|
||||
|
||||
PsiAnnotation nonNull = AnnotationUtil.findAnnotation(psiClass, JAVAX_ANNOTATION_NONNULL);
|
||||
return nonNull != null ? extractNullityFromWhenValue(nonNull) : null;
|
||||
PsiAnnotation nonNull = modifierList.findAnnotation(JAVAX_ANNOTATION_NONNULL);
|
||||
if (nonNull != null) {
|
||||
return extractNullityFromWhenValue(nonNull);
|
||||
}
|
||||
if (modifierList.hasAnnotation(JAVAX_ANNOTATION_CHECK_FOR_NULL)) {
|
||||
return Nullability.NULLABLE;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static @Nullable Nullability extractNullityFromWhenValue(@NotNull PsiAnnotation nonNull) {
|
||||
@@ -101,7 +110,7 @@ public final class Jsr305Support implements AnnotationPackageSupport {
|
||||
public @NotNull List<String> getNullabilityAnnotations(@NotNull Nullability nullability) {
|
||||
return switch (nullability) {
|
||||
case NOT_NULL -> Collections.singletonList(JAVAX_ANNOTATION_NONNULL);
|
||||
case NULLABLE -> Arrays.asList(JAVAX_ANNOTATION_NULLABLE, "javax.annotation.CheckForNull");
|
||||
case NULLABLE -> Arrays.asList(JAVAX_ANNOTATION_NULLABLE, JAVAX_ANNOTATION_CHECK_FOR_NULL);
|
||||
case UNKNOWN -> Collections.emptyList();
|
||||
};
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import static javax.annotation.meta.When.MAYBE;
|
||||
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierNickname;
|
||||
|
||||
class Main {
|
||||
int go(Lib lib) {
|
||||
return lib.usingNonnullMaybe().<warning descr="Method invocation 'hashCode' may produce 'NullPointerException'">hashCode</warning>() + lib.usingCheckForNull().<warning descr="Method invocation 'hashCode' may produce 'NullPointerException'">hashCode</warning>();
|
||||
}
|
||||
|
||||
interface Lib {
|
||||
@UsingNonnullMaybe
|
||||
Object usingNonnullMaybe();
|
||||
|
||||
@UsingCheckForNull
|
||||
Object usingCheckForNull();
|
||||
}
|
||||
|
||||
@Nonnull(when = MAYBE)
|
||||
@TypeQualifierNickname
|
||||
@interface UsingNonnullMaybe {}
|
||||
|
||||
@CheckForNull
|
||||
@TypeQualifierNickname
|
||||
@interface UsingCheckForNull {}
|
||||
}
|
||||
+24
-10
@@ -352,6 +352,12 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
|
||||
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testJsr305CheckForNullAsQualifierNickname() {
|
||||
addJavaxNullabilityAnnotations(myFixture);
|
||||
addJavaxDefaultNullabilityAnnotations(myFixture);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNullabilityDefaultVsMethodImplementing() {
|
||||
addJavaxDefaultNullabilityAnnotations(myFixture);
|
||||
@@ -396,16 +402,24 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
|
||||
fixture.addClass("package javax.annotation.meta;" +
|
||||
"public enum When { ALWAYS, UNKNOWN, MAYBE, NEVER }");
|
||||
|
||||
fixture.addClass("package javax.annotation;" +
|
||||
"import javax.annotation.meta.*;" +
|
||||
"public @interface Nonnull {" +
|
||||
" When when() default When.ALWAYS;" +
|
||||
"}");
|
||||
fixture.addClass("package javax.annotation;" +
|
||||
"import javax.annotation.meta.*;" +
|
||||
"@TypeQualifierNickname " +
|
||||
"@Nonnull(when = When.UNKNOWN) " +
|
||||
"public @interface Nullable {}");
|
||||
fixture.addClass("""
|
||||
package javax.annotation;
|
||||
import javax.annotation.meta.*;
|
||||
public @interface Nonnull {
|
||||
When when() default When.ALWAYS;
|
||||
}""");
|
||||
fixture.addClass("""
|
||||
package javax.annotation;
|
||||
import javax.annotation.meta.*;
|
||||
@TypeQualifierNickname
|
||||
@Nonnull(when = When.MAYBE)
|
||||
public @interface CheckForNull {}""");
|
||||
fixture.addClass("""
|
||||
package javax.annotation;
|
||||
import javax.annotation.meta.*;
|
||||
@TypeQualifierNickname
|
||||
@Nonnull(when = When.UNKNOWN)
|
||||
public @interface Nullable {}""");
|
||||
}
|
||||
|
||||
public void testCustomTypeQualifierDefault() {
|
||||
|
||||
Reference in New Issue
Block a user