RecordCandidate (@NotNull PsiClass psiClass, boolean suggestAccessorsRenaming, @NotNull List<String> ignoredAnnotations) { boolean isNotAppropriatePsiClass = psiClass.isEnum() || psiClass.isAnnotationType() || psiClass instanceof PsiAnonymousClass || psiClass.isInterface() || psiClass.isRecord(); if (isNotAppropriatePsiClass) return null; PsiModifierList psiClassModifiers = psiClass.getModifierList(); if (psiClassModifiers == null || psiClassModifiers.hasModifierProperty(ABSTRACT) || psiClassModifiers.hasModifierProperty(SEALED)) { return null; } // todo support local classes later if (PsiUtil.isLocalClass(psiClass)) return null; if (psiClass.getContainingClass() != null && !psiClass.hasModifierProperty(STATIC)) return null; PsiClass superClass = psiClass.getSuperClass(); if (superClass == null || !JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) return null; if (ContainerUtil.exists(psiClass.getInitializers(), initializer -> !initializer.hasModifierProperty(STATIC))) return null; if (AnnotationUtil.checkAnnotatedUsingPatterns(psiClass, ignoredAnnotations)) return null; RecordCandidate result = new RecordCandidate(psiClass, suggestAccessorsRenaming); if (!result.isValid()) return null; return ClassInheritorsSearch.search(psiClass, false).findFirst() == null ? result : null; }