Set<PsiClass> (@NotNull PsiType selectorType, @NotNull List<? extends PsiCaseLabelElement> elements) { LinkedHashMap<PsiClass, PsiPattern> patternClasses = findPatternClasses(elements); List<PsiPrimaryPattern> unconditionalPatterns = ContainerUtil.mapNotNull(elements, element -> JavaPsiPatternUtil.findUnconditionalPattern(element)); List<PsiTypeTestPattern> typeTestPatterns = ContainerUtil.filterIsInstance(unconditionalPatterns, PsiTypeTestPattern.class); PsiClass selectorClass = PsiUtil.resolveClassInClassTypeOnly(TypeConversionUtil.erasure(selectorType)); if (selectorClass == null) return Collections.emptySet(); Queue<PsiClass> nonVisited = new ArrayDeque<>(); nonVisited.add(selectorClass); Set<PsiClass> visited = new SmartHashSet<>(); Set<PsiClass> missingClasses = new LinkedHashSet<>(); while (!nonVisited.isEmpty()) { PsiClass psiClass = nonVisited.peek(); if (psiClass.hasModifierProperty(SEALED) && (psiClass.hasModifierProperty(ABSTRACT) || psiClass.equals(selectorClass))) { for (PsiClass permittedClass : SwitchBlockHighlightingModel.PatternsInSwitchBlockHighlightingModel.getPermittedClasses(psiClass)) { if (!visited.add(permittedClass)) continue; PsiPattern pattern = patternClasses.get(permittedClass); PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(selectorClass, permittedClass, PsiSubstitutor.EMPTY); PsiType permittedType = JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, substitutor); if (pattern == null && (PsiUtil.getLanguageLevel(permittedClass).isLessThan(LanguageLevel.JDK_18) || TypeConversionUtil.areTypesConvertible(selectorType, permittedType)) || pattern != null && !JavaPsiPatternUtil.isUnconditionalForType(pattern, TypeUtils.getType(permittedClass), true)) { nonVisited.add(permittedClass); } } } else { visited.add(psiClass); if (!ContainerUtil.exists(typeTestPatterns, pattern -> JavaPsiPatternUtil.isUnconditionalForType(pattern, TypeUtils.getType(psiClass), true))) { missingClasses.add(psiClass); } } nonVisited.poll(); } if (!selectorClass.hasModifierProperty(ABSTRACT)) { missingClasses.add(selectorClass); } return missingClasses; }