boolean (@NotNull PsiModifierListOwner listOwner, @NotNull Set<String> runtimeAnnotationsToIgnore) { PsiModifierList modifierList = listOwner.getModifierList(); if (modifierList == null) return false; PsiAnnotation[] annotations = modifierList.getAnnotations(); for (PsiAnnotation annotation : annotations) { PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement(); String fqn; if (ref != null && ref.resolve() instanceof PsiClass annotationClass && ((fqn = annotationClass.getQualifiedName()) == null || !runtimeAnnotationsToIgnore.contains(fqn))) { final PsiAnnotation retentionAnno = AnnotationUtil.findAnnotation(annotationClass, Retention.class.getName()); // Default retention is CLASS: keep it if (retentionAnno == null) return true; if (retentionAnno.findAttributeValue("value") instanceof PsiReferenceExpression retentionValue && retentionValue.resolve() instanceof PsiField retentionField && (RetentionPolicy.RUNTIME.name().equals(retentionField.getName()) || RetentionPolicy.CLASS.name().equals(retentionField.getName()))) { final PsiClass containingClass = retentionField.getContainingClass(); if (containingClass != null && RetentionPolicy.class.getName().equals(containingClass.getQualifiedName())) { return true; } } } } return false; }