mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Sealed classes: fixed type conversion check for deep sealed hierarchy
GitOrigin-RevId: b70a5ddf84cada4dc8efd29c8ed4090d42672b55
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3042bfaaba
commit
d691432ee6
@@ -353,13 +353,16 @@ public final class TypeConversionUtil {
|
||||
* <p>See JEP-397 for more details.</p>
|
||||
*/
|
||||
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<PsiClass> visited) {
|
||||
private static boolean canConvertSealedTo(@NotNull PsiClass sealedClass,
|
||||
@NotNull PsiClass psiClass,
|
||||
@NotNull Set<PsiClass> 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<PsiClass> 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<PsiClass> findDirectSubClassesInFile(@NotNull PsiClass sealedClass) {
|
||||
|
||||
+12
@@ -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 (<error descr="Inconvertible types; cannot cast 'Foo.A' to 'Foo'">a instanceof Foo</error>)
|
||||
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 (<error descr="Inconvertible types; cannot cast 'Foo.GrandParent' to 'Foo.RandomClass'">gp instanceof RandomClass</error>) {
|
||||
System.out.println("It's a RandomClass");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user