diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
index 2fb00435eb77..be3c641c08c0 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
@@ -353,13 +353,16 @@ public final class TypeConversionUtil {
*
See JEP-397 for more details.
*/
public static boolean canConvertSealedTo(@NotNull PsiClass sealedClass, @NotNull PsiClass psiClass) {
- return canConvertSealedTo(sealedClass, psiClass, new HashSet<>());
+ return canConvertSealedTo(sealedClass, psiClass, new HashSet<>(), true);
}
- private static boolean canConvertSealedTo(@NotNull PsiClass sealedClass, @NotNull PsiClass psiClass, @NotNull Set visited) {
+ private static boolean canConvertSealedTo(@NotNull PsiClass sealedClass,
+ @NotNull PsiClass psiClass,
+ @NotNull Set visited,
+ boolean isTopLevel) {
if (visited.contains(sealedClass)) return true;
visited.add(sealedClass);
- if (!sealedClass.isInterface() && !psiClass.isInterface()) return true;
+ if (isTopLevel && !sealedClass.isInterface() && !psiClass.isInterface()) return true;
PsiReferenceList permitsList = sealedClass.getPermitsList();
List sealedSubClasses = new SmartList<>();
boolean hasClassInheritors;
@@ -372,7 +375,7 @@ public final class TypeConversionUtil {
.map(t -> t.resolve())
.anyMatch(subClass -> subClassExtendsClass(subClass, psiClass, sealedSubClasses));
}
- return hasClassInheritors || sealedSubClasses.stream().anyMatch(subClass -> canConvertSealedTo(subClass, psiClass, visited));
+ return hasClassInheritors || sealedSubClasses.stream().anyMatch(subClass -> canConvertSealedTo(subClass, psiClass, visited, false));
}
private static @NotNull Set findDirectSubClassesInFile(@NotNull PsiClass sealedClass) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingSealedTypes/SealedClassCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingSealedTypes/SealedClassCast.java
index 5c7bda5f554c..5e1e327ee862 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingSealedTypes/SealedClassCast.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlightingSealedTypes/SealedClassCast.java
@@ -37,6 +37,12 @@ interface Foo {
interface I1 {}
+ sealed interface GrandParent permits Parent {}
+ static sealed class Parent implements GrandParent permits Child {}
+ static final class Child extends Parent {}
+ static class RandomClass {}
+
+
static void testA(A a) {
if (a instanceof Foo)
System.out.println("It's a Foo");
@@ -85,4 +91,10 @@ interface Foo {
static void testRecursive1(Recursive1 r1) {
if (r1 instanceof I1) {}
}
+
+ static void testDeepSealedHierarchy(GrandParent gp) {
+ if (gp instanceof RandomClass) {
+ System.out.println("It's a RandomClass");
+ }
+ }
}
\ No newline at end of file