mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[java] IDEA-359811 Support experimentally container annotation @NotNullByDefault
GitOrigin-RevId: 0f02149f8f9313357bab47e7d62d6f1ccfea6f9b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
70b05eb272
commit
087825794e
@@ -3,12 +3,36 @@ package com.intellij.codeInsight.annoPackages;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.Nullability;
|
||||
import com.intellij.codeInsight.NullabilityAnnotationInfo;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
final class JetBrainsAnnotationSupport implements AnnotationPackageSupport {
|
||||
@Override
|
||||
public @Nullable NullabilityAnnotationInfo getNullabilityByContainerAnnotation(@NotNull PsiAnnotation anno,
|
||||
@NotNull PsiElement context,
|
||||
PsiAnnotation.TargetType @NotNull [] types,
|
||||
boolean superPackage) {
|
||||
if (superPackage) return null;
|
||||
if (ArrayUtil.contains(PsiAnnotation.TargetType.LOCAL_VARIABLE, types) ||
|
||||
ArrayUtil.contains(PsiAnnotation.TargetType.TYPE_PARAMETER, types)) {
|
||||
return null;
|
||||
}
|
||||
if (!anno.hasQualifiedName(AnnotationUtil.NOT_NULL_BY_DEFAULT)) return null;
|
||||
PsiType targetType = context instanceof PsiMethod method ? method.getReturnType() :
|
||||
context instanceof PsiVariable variable ? variable.getType() :
|
||||
context instanceof PsiJavaCodeReferenceElement && context.getParent() instanceof PsiTypeElement typeElement ? typeElement.getType() :
|
||||
null;
|
||||
if (PsiUtil.resolveClassInClassTypeOnly(targetType) instanceof PsiTypeParameter) return null;
|
||||
return new NullabilityAnnotationInfo(anno, Nullability.NOT_NULL, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<String> getNullabilityAnnotations(@NotNull Nullability nullability) {
|
||||
return switch (nullability) {
|
||||
|
||||
@@ -24,6 +24,7 @@ public class AnnotationUtil {
|
||||
public static final String NULLABLE = "org.jetbrains.annotations.Nullable";
|
||||
public static final String UNKNOWN_NULLABILITY = "org.jetbrains.annotations.UnknownNullability";
|
||||
public static final String NOT_NULL = "org.jetbrains.annotations.NotNull";
|
||||
public static final String NOT_NULL_BY_DEFAULT = "org.jetbrains.annotations.NotNullByDefault";
|
||||
|
||||
public static final String NON_NLS = "org.jetbrains.annotations.NonNls";
|
||||
public static final String NLS = "org.jetbrains.annotations.Nls";
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import org.jetbrains.annotations.*;
|
||||
import java.util.List;
|
||||
|
||||
@NotNullByDefault
|
||||
public class JetBrainsNotNullByDefault {
|
||||
String field;
|
||||
|
||||
String test(String param) {
|
||||
if (<warning descr="Condition 'param == null' is always 'false'">param == null</warning>) {}
|
||||
if (<warning descr="Condition 'field == null' is always 'false'">field == null</warning>) {}
|
||||
String local = System.getProperty("a");
|
||||
if (local == null) {}
|
||||
return <warning descr="'null' is returned by the method declared as @NotNullByDefault">null</warning>;
|
||||
}
|
||||
|
||||
<T> T generic(T param) {
|
||||
if (param == null) {
|
||||
return <warning descr="'null' is returned by the method which is not declared as @Nullable">param</warning>;
|
||||
}
|
||||
return <warning descr="'null' is returned by the method which is not declared as @Nullable">null</warning>;
|
||||
}
|
||||
|
||||
<T> List<T> genericList(List<T> param) {
|
||||
for (T t : param) {
|
||||
if (t == null) {
|
||||
return <warning descr="'null' is returned by the method declared as @NotNullByDefault">null</warning>;
|
||||
}
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
||||
void use2(String s) {
|
||||
// T is inferred as String from "hello" type
|
||||
if (generic("hello") == null) {}
|
||||
// T is inferred as @NotNull String from the `s` type
|
||||
if (<warning descr="Condition 'generic(s) == null' is always 'false'">generic(s) == null</warning>) {}
|
||||
}
|
||||
|
||||
void use(List<String> list) {
|
||||
// T is inferred as @NotNull String from the `list` type
|
||||
for (String s : genericList(list)) {
|
||||
if (<warning descr="Condition 's == null' is always 'false'">s == null</warning>) {}
|
||||
}
|
||||
}
|
||||
|
||||
static class StaticInner implements NullableMember {
|
||||
public String myGet() {
|
||||
return <warning descr="'null' is returned by the method declared as @NotNullByDefault">null</warning>;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface NullableMember {
|
||||
@Nullable String get();
|
||||
}
|
||||
@@ -53,11 +53,11 @@ public class DataFlowInspection21Test extends DataFlowInspectionTestCase {
|
||||
public void testPatterns() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
public void testDeconstructionNullability() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
public void testUnnamedPatterns() {
|
||||
doTest();
|
||||
}
|
||||
@@ -77,7 +77,7 @@ public class DataFlowInspection21Test extends DataFlowInspectionTestCase {
|
||||
public void testNewStringWrongEquals() { doTest(); }
|
||||
|
||||
public void testSwitchWhenReturnBoolean() { doTest(); }
|
||||
|
||||
|
||||
public void testSkipSwitchExpressionWithThrow() { doTest(); }
|
||||
|
||||
public void testStringTemplates() {
|
||||
@@ -131,8 +131,19 @@ public class DataFlowInspection21Test extends DataFlowInspectionTestCase {
|
||||
|
||||
public void testArrayElementWrappedInPureMethod() { doTest(); }
|
||||
public void testArrayAddedIntoCollection() { doTest(); }
|
||||
|
||||
|
||||
public void testInstanceOfPatternAffectNullity() { doTest(); }
|
||||
|
||||
|
||||
public void testNullabilityInEnumSwitch() { doTest(); }
|
||||
|
||||
public void testJetBrainsNotNullByDefault() {
|
||||
myFixture.addClass("""
|
||||
package org.jetbrains.annotations;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.TYPE, ElementType.PACKAGE})\s
|
||||
public @interface NotNullByDefault {}""");
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user