diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9NonAccessibleTypeExposedInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9NonAccessibleTypeExposedInspection.java
index 44d0476d689d..ab4cdfb2ed10 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9NonAccessibleTypeExposedInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9NonAccessibleTypeExposedInspection.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
@@ -109,16 +110,19 @@ public class Java9NonAccessibleTypeExposedInspection extends BaseJavaLocalInspec
PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
if (referenceElement != null) {
PsiElement resolved = referenceElement.resolve();
- if (resolved instanceof PsiClass && !isModulePublicApi((PsiClass)resolved)) {
- PsiAnnotationOwner owner = annotation.getOwner();
- if (isModulePublicApi(owner)) {
- myHolder.registerProblem(referenceElement, CLASS_IS_NOT_EXPORTED);
- }
- if (owner instanceof PsiParameter) {
- PsiElement parent = ((PsiParameter)owner).getParent();
- if (parent instanceof PsiMember && isModulePublicApi((PsiMember)parent)) {
+ if (resolved instanceof PsiClass) {
+ PsiClass annotationClass = (PsiClass)resolved;
+ if (isInModuleSource(annotationClass) && !isModulePublicApi(annotationClass)) {
+ PsiAnnotationOwner owner = annotation.getOwner();
+ if (isModulePublicApi(owner)) {
myHolder.registerProblem(referenceElement, CLASS_IS_NOT_EXPORTED);
}
+ if (owner instanceof PsiParameter) {
+ PsiElement parent = ((PsiParameter)owner).getParent();
+ if (parent instanceof PsiMember && isModulePublicApi((PsiMember)parent)) {
+ myHolder.registerProblem(referenceElement, CLASS_IS_NOT_EXPORTED);
+ }
+ }
}
}
}
@@ -132,7 +136,7 @@ public class Java9NonAccessibleTypeExposedInspection extends BaseJavaLocalInspec
}
private void checkType(PsiClass psiClass, @NotNull PsiElement typeElement) {
- if (psiClass != null && isInModuleSource(psiClass) && !isModulePublicApi(psiClass)) {
+ if (psiClass != null && !(psiClass instanceof PsiTypeParameter) && isInModuleSource(psiClass) && !isModulePublicApi(psiClass)) {
myHolder.registerProblem(typeElement, CLASS_IS_NOT_EXPORTED);
}
}
@@ -171,6 +175,19 @@ public class Java9NonAccessibleTypeExposedInspection extends BaseJavaLocalInspec
if (parent instanceof PsiMember) {
return isModulePublicApi((PsiMember)parent);
}
+ if (parent instanceof PsiReferenceParameterList) {
+ PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
+ return isModulePublicApi(method);
+ }
+ }
+ else if (owner instanceof PsiTypeParameter) {
+ PsiElement parent = ((PsiTypeParameter)owner).getParent();
+ if (parent instanceof PsiTypeParameterList) {
+ PsiElement grandParent = parent.getParent();
+ if (grandParent instanceof PsiMember) {
+ return isModulePublicApi((PsiMember)grandParent);
+ }
+ }
}
return false;
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/Java9NonAccessibleTypeExposedTest.kt b/java/java-tests/testSrc/com/intellij/codeInspection/Java9NonAccessibleTypeExposedTest.kt
index 0caaef127bdf..21d34e9e27de 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/Java9NonAccessibleTypeExposedTest.kt
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/Java9NonAccessibleTypeExposedTest.kt
@@ -217,6 +217,7 @@ public class Highlighted {
fun testPublicAnnotation() {
add("apiPkg", "MyAnnotation", "public @interface MyAnnotation {}")
highlight("""package apiPkg;
+@MyAnnotation
public class Highlighted {
@MyAnnotation public PublicApi field;
@MyAnnotation public Highlighted() {}
@@ -231,6 +232,7 @@ public class Highlighted {
fun testPackageLocalAnnotation() {
add("apiPkg", "MyAnnotation", "@interface MyAnnotation {}")
highlight("""package apiPkg;
+@MyAnnotation
public class Highlighted {
@MyAnnotation public PublicApi field;
@MyAnnotation public Highlighted() {}
@@ -246,6 +248,7 @@ public class Highlighted {
add("implPkg", "MyAnnotation", "public @interface MyAnnotation {}")
highlight("""package apiPkg;
import implPkg.MyAnnotation;
+@MyAnnotation
public class Highlighted {
@MyAnnotation public PublicApi field;
@MyAnnotation public Highlighted() {}
@@ -257,6 +260,32 @@ public class Highlighted {
""")
}
+ fun testTypeParameterAndUseAnnotation() {
+ highlight("""package apiPkg;
+import java.lang.annotation.*;
+import java.util.*;
+@Highlighted.PublicAnnotation
+@Highlighted.PackageLocalAnnotation
+public class Highlighted {
+ @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) public @interface PublicAnnotation {}
+ @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) @interface PackageLocalAnnotation {}
+
+ public class C1<@PublicAnnotation T> {
+ public void foo(Set<@PublicAnnotation String> s) {}
+ protected <@PublicAnnotation X> void bar(X x) {}
+ protected List<@PublicAnnotation T> baz() { return new ArrayList<@PublicAnnotation T>();}
+ }
+ public class C2<@PackageLocalAnnotation T> {
+ public void foo(Set<@PackageLocalAnnotation String> s) {}
+ protected <@PackageLocalAnnotation X> void bar(X x) {}
+ protected List<@PackageLocalAnnotation T> baz() {
+ return new ArrayList<@PackageLocalAnnotation T>();
+ }
+ }
+}
+""")
+ }
+
private fun highlight(@Language("JAVA") @NotNull @NonNls text: String) {
val file = addFile("apiPkg/Highlighted.java", text, MAIN)
myFixture.configureFromExistingVirtualFile(file)