[java-analysis] Report nullability annotations on enum constants and on locals (for JSpecify)

GitOrigin-RevId: 48f21b639a1eaf3ca9c2d75e1cf846bddd726260
This commit is contained in:
Tagir Valeev
2021-02-11 12:51:11 +07:00
committed by intellij-monorepo-bot
parent 7d8727bf62
commit a6bc8802f1
7 changed files with 40 additions and 2 deletions

View File

@@ -274,7 +274,9 @@ inspection.nullable.problems.primitive.type.annotation=Primitive type members ca
inspection.nullable.problems.receiver.annotation=Receiver parameter is inherently not-null
inspection.nullable.problems.outer.type=Outer type is inherently not-null
inspection.nullable.problems.at.constructor=Nullability annotation is not applicable to constructors
inspection.nullable.problems.at.enum.constant=Nullability annotation is not applicable to enum constants
inspection.nullable.problems.at.wildcard=Nullability annotation is not applicable to wildcard type
inspection.nullable.problems.at.local.variable=Nullability annotation is not applicable to local variables
inspection.nullable.problems.at.type.parameter=Nullability annotation is not applicable to type parameters
inspection.nullable.problems.at.reference.list=Nullability annotation is not applicable to extends/implements lists
inspection.objects.equals.can.be.simplified.display.name=Objects.equals() can be replaced with equals()

View File

@@ -157,7 +157,8 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection
if (parent instanceof PsiReferenceList) {
PsiElement firstChild = parent.getFirstChild();
if ((PsiUtil.isJavaToken(firstChild, JavaTokenType.EXTENDS_KEYWORD) ||
PsiUtil.isJavaToken(firstChild, JavaTokenType.IMPLEMENTS_KEYWORD)) && !(parent.getParent() instanceof PsiTypeParameter)) {
PsiUtil.isJavaToken(firstChild, JavaTokenType.IMPLEMENTS_KEYWORD)) &&
!(parent.getParent() instanceof PsiTypeParameter)) {
reportIncorrectLocation(holder, annotation, listOwner, "inspection.nullable.problems.at.reference.list");
}
}
@@ -166,6 +167,14 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection
if (listOwner instanceof PsiMethod && ((PsiMethod)listOwner).isConstructor()) {
reportIncorrectLocation(holder, annotation, listOwner, "inspection.nullable.problems.at.constructor");
}
if (listOwner instanceof PsiEnumConstant) {
reportIncorrectLocation(holder, annotation, listOwner, "inspection.nullable.problems.at.enum.constant");
}
if ((listOwner instanceof PsiLocalVariable ||
listOwner instanceof PsiParameter && ((PsiParameter)listOwner).getDeclarationScope() instanceof PsiCatchSection)
&& !manager.canAnnotateLocals(qualifiedName)) {
reportIncorrectLocation(holder, annotation, listOwner, "inspection.nullable.problems.at.local.variable");
}
if (type instanceof PsiWildcardType && manager.isTypeUseAnnotationLocationRestricted(qualifiedName)) {
reportIncorrectLocation(holder, annotation, listOwner, "inspection.nullable.problems.at.wildcard");
}

View File

@@ -155,6 +155,17 @@ public class NullableNotNullManagerImpl extends NullableNotNullManager implement
@Override
public boolean isTypeUseAnnotationLocationRestricted(String name) {
AnnotationPackageSupport support = findAnnotationSupport(name);
return support != null && support.isTypeUseAnnotationLocationRestricted();
}
@Override
public boolean canAnnotateLocals(String name) {
AnnotationPackageSupport support = findAnnotationSupport(name);
return support == null || support.canAnnotateLocals();
}
private @Nullable AnnotationPackageSupport findAnnotationSupport(String name) {
AnnotationPackageSupport support = myDefaultUnknowns.get(name);
if (support == null) {
support = myDefaultNotNulls.get(name);
@@ -162,7 +173,7 @@ public class NullableNotNullManagerImpl extends NullableNotNullManager implement
support = myDefaultNullables.get(name);
}
}
return support != null && support.isTypeUseAnnotationLocationRestricted();
return support;
}
@Override

View File

@@ -45,4 +45,11 @@ public interface AnnotationPackageSupport {
default boolean isTypeUseAnnotationLocationRestricted() {
return false;
}
/**
* @return true if the annotations defined by this support can be used to annotate local variables
*/
default boolean canAnnotateLocals() {
return true;
}
}

View File

@@ -68,4 +68,9 @@ public class JSpecifyAnnotationSupport implements AnnotationPackageSupport {
public boolean isTypeUseAnnotationLocationRestricted() {
return true;
}
@Override
public boolean canAnnotateLocals() {
return false;
}
}

View File

@@ -46,6 +46,8 @@ public abstract class NullableNotNullManager {
public abstract @NotNull Optional<Nullability> getAnnotationNullability(String name);
public abstract boolean isTypeUseAnnotationLocationRestricted(String name);
public abstract boolean canAnnotateLocals(String name);
public static NullableNotNullManager getInstance(Project project) {
return ServiceManager.getService(project, NullableNotNullManager.class);

View File

@@ -170,10 +170,12 @@ public class JSpecifyAnnotationTest extends LightJavaCodeInsightFixtureTestCase
case "inspection.nullable.problems.outer.type":
case "inspection.nullable.problems.at.reference.list":
case "inspection.nullable.problems.at.constructor":
case "inspection.nullable.problems.at.enum.constant":
warnings.put(anchor, "jspecify_nullness_intrinsically_not_nullable");
break;
case "inspection.nullable.problems.at.wildcard":
case "inspection.nullable.problems.at.type.parameter":
case "inspection.nullable.problems.at.local.variable":
warnings.put(anchor, "jspecify_unrecognized_location");
break;
}