mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-341719 [java-analysis] Nullability annotation on type param doesn't apply to uses of type param
GitOrigin-RevId: 6a15d9e40e8d132e01c6a1b0b08a30ac3d33189d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d0cfe3767b
commit
4b457ac3e7
+4
-2
@@ -42,8 +42,10 @@ final class CheckerFrameworkSupport implements AnnotationPackageSupport {
|
||||
// DefaultQualifier is not applicable to type parameter declarations
|
||||
if (context instanceof PsiTypeParameter) return false;
|
||||
// DefaultQualifier is not applicable to type parameter uses
|
||||
return !(PsiUtil.getTypeByPsiElement(context) instanceof PsiClassType classType) ||
|
||||
!(classType.resolve() instanceof PsiTypeParameter);
|
||||
return !(PsiUtil.getTypeByPsiElement(context) instanceof PsiClassType classType &&
|
||||
classType.resolve() instanceof PsiTypeParameter ||
|
||||
context instanceof PsiJavaCodeReferenceElement ref &&
|
||||
ref.resolve() instanceof PsiTypeParameter);
|
||||
});
|
||||
}
|
||||
return ContextNullabilityInfo.EMPTY;
|
||||
|
||||
@@ -200,7 +200,7 @@ public abstract class NullableNotNullManager {
|
||||
for (PsiParameter parameter: superParameters) {
|
||||
NullabilityAnnotationInfo plain = findPlainAnnotation(parameter, false, annotations);
|
||||
// Plain not null annotation is not inherited
|
||||
if (plain != null) return null;
|
||||
if (plain != null && !plain.isContainer()) return null;
|
||||
NullabilityAnnotationInfo defaultInfo = findContainerAnnotation(parameter);
|
||||
if (defaultInfo != null) {
|
||||
return defaultInfo.getNullability() == Nullability.NOT_NULL ? defaultInfo.withInheritedFrom(parameter) : null;
|
||||
@@ -259,6 +259,11 @@ public abstract class NullableNotNullManager {
|
||||
Nullability origNullability = holder.getNullability(annotation);
|
||||
return nullabilities.contains(origNullability) ? origNullability : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWantedNullability(@NotNull Nullability nullability) {
|
||||
return nullabilities.contains(nullability);
|
||||
}
|
||||
};
|
||||
NullabilityAnnotationInfo result = findPlainAnnotation(owner, false, filtered);
|
||||
return result == null || !nullabilities.contains(result.getNullability()) ? null : result;
|
||||
@@ -296,7 +301,7 @@ public abstract class NullableNotNullManager {
|
||||
}
|
||||
if (type == null || type instanceof PsiPrimitiveType) return null;
|
||||
NullabilityAnnotationInfo info = type.getNullability().toNullabilityAnnotationInfo();
|
||||
return info != null && annotations.getNullability(info.getAnnotation().getQualifiedName()) != null ? info : null;
|
||||
return info != null && annotations.isWantedNullability(info.getNullability()) ? info : null;
|
||||
}
|
||||
|
||||
protected @NotNull Nullability correctNullability(@NotNull Nullability nullability, @NotNull PsiAnnotation annotation) {
|
||||
@@ -479,6 +484,10 @@ public abstract class NullableNotNullManager {
|
||||
* @return nullability
|
||||
*/
|
||||
@Nullable Nullability getNullability(String annotation);
|
||||
|
||||
default boolean isWantedNullability(@NotNull Nullability nullability) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param map from annotation qualified name to nullability
|
||||
|
||||
@@ -82,7 +82,12 @@ public final class JavaTypeNullabilityUtil {
|
||||
PsiElement context = classType.getPsiContext();
|
||||
return context instanceof PsiJavaCodeReferenceElement &&
|
||||
context.getParent() instanceof PsiTypeElement &&
|
||||
context.getParent().getParent() instanceof PsiLocalVariable;
|
||||
isLocalVariable(context.getParent().getParent());
|
||||
}
|
||||
|
||||
private static boolean isLocalVariable(PsiElement element) {
|
||||
return element instanceof PsiLocalVariable ||
|
||||
element instanceof PsiParameter && !(element.getParent() instanceof PsiParameterList);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.NotNullByDefault;
|
||||
|
||||
interface Test<T> {
|
||||
@NotNull
|
||||
T test();
|
||||
}
|
||||
@NotNullByDefault
|
||||
class TestImpl<T> implements Test<T> {
|
||||
|
||||
final T value;
|
||||
|
||||
public TestImpl(final T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T test() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ public class CheckerNullityTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
import org.checkerframework.framework.qual.*;
|
||||
|
||||
@DefaultQualifier(NonNull.class)
|
||||
interface Test<X> {
|
||||
interface Test<X extends @Nullable Object> {
|
||||
String test(X x);
|
||||
X test(String x);
|
||||
}""");
|
||||
|
||||
+4
@@ -520,4 +520,8 @@ public class NullableStuffInspectionTest extends LightJavaCodeInsightFixtureTest
|
||||
addJSpecifyNullMarked(myFixture);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDefaultNotNullTypeParameterOverrides() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user