VisitorTypes (Class<?> type) { List<Class<?>> visitClasses = new ArrayList<>(); Collection<String> visitorClasses = BasicInspectionVisitorBean.getVisitorClasses(); Class<?> superClass = type; while (superClass != null) { if (superClass == PsiElementVisitor.class) { // no `inspection.basicVisitor` defined in hierarchy return new VisitorTypes(false, ALL_ELEMENTS_VISIT_LIST, visitClasses.contains(PsiElement.class)); } if (visitorClasses.contains(superClass.getName())) { break; } for (Method declaredMethod : superClass.getDeclaredMethods()) { if (declaredMethod.getParameterCount() == 1 && declaredMethod.getName().startsWith("visit") && Modifier.isPublic(declaredMethod.getModifiers()) && !Modifier.isAbstract(declaredMethod.getModifiers()) && !Modifier.isStatic(declaredMethod.getModifiers())) { Class<?> parameterType = declaredMethod.getParameterTypes()[0]; visitClasses.add(parameterType); } } if (HintedPsiElementVisitor.class.isAssignableFrom(superClass)) { // do not inspect parent break; } superClass = superClass.getSuperclass(); } if (visitClasses.contains(PsiElement.class)) { return new VisitorTypes(true, ALL_ELEMENTS_VISIT_LIST, true); } return new VisitorTypes(true, List.copyOf(visitClasses), false); }