boolean (final ConfigurationContext context, final Runnable performRunnable, final PsiMethod psiMethod, final PsiClass containingClass, final Condition<? super PsiClass> acceptAbstractCondition) { if (containingClass != null && acceptAbstractCondition.value(containingClass)) { final Location location = context.getLocation(); if (location instanceof MethodLocation loc) { final PsiClass aClass = loc.getContainingClass(); if (!aClass.hasModifierProperty(PsiModifier.ABSTRACT)) { return false; } } else if (location instanceof PsiMemberParameterizedLocation) { return false; } final List<PsiClass> classes = new ArrayList<>(); if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> { collectClasses(containingClass, classes, new HashSet<>()); }, ExecutionBundle.message("search.for.0.inheritors", containingClass.getQualifiedName()), true, containingClass.getProject())) { return true; } if (classes.size() == 1) { runForClass(classes.get(0), psiMethod, context, performRunnable); return true; } if (classes.isEmpty()) return false; final FileEditor fileEditor = PlatformCoreDataKeys.FILE_EDITOR.getData(context.getDataContext()); if (fileEditor instanceof TextEditor) { final Document document = ((TextEditor)fileEditor).getEditor().getDocument(); final PsiFile containingFile = PsiDocumentManager.getInstance(context.getProject()).getPsiFile(document); if (containingFile instanceof PsiClassOwner) { final List<PsiClass> psiClasses = new ArrayList<>(Arrays.asList(((PsiClassOwner)containingFile).getClasses())); psiClasses.retainAll(classes); if (psiClasses.size() == 1) { runForClass(psiClasses.get(0), psiMethod, context, performRunnable); return true; } } } final int numberOfInheritors = classes.size(); final PsiClassListCellRenderer renderer = new PsiClassListCellRenderer() { @Override protected boolean customizeNonPsiElementLeftRenderer(ColoredListCellRenderer renderer, JList list, Object value, int index, boolean selected, boolean hasFocus) { if (value == null) { renderer.append(JavaCompilerBundle.message("all.inheritors", numberOfInheritors)); return true; } return super.customizeNonPsiElementLeftRenderer(renderer, list, value, index, selected, hasFocus); } }; classes.sort(renderer.getComparator()); //suggest to run all inherited tests classes.add(0, null); String locationName = psiMethod != null ? psiMethod.getName() : containingClass.getName(); JBPopupFactory.getInstance() .createPopupChooserBuilder(classes) .setRenderer(renderer) .setTitle(ExecutionBundle.message("test.cases.choosing.popup.title", locationName)) .setAutoselectOnMouseMove(false) .setNamerForFiltering(it -> it == null ? "" : it.getName()) .setMovable(true) .setResizable(false) .setRequestFocus(true) .setMinSize(JBUI.size(270, 55)) .setItemsChosenCallback((values) -> { if (values.isEmpty()) return; chooseAndPerform(values.toArray(), psiMethod, context, performRunnable, classes); }) .createPopup() .show(getBestPopupPosition(context.getDataContext())); return true; } if (containingClass != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) { PsiClass gContainingClass = containingClass.getContainingClass(); if (gContainingClass != null && !containingClass.isInheritor(gContainingClass, true)) { return runMethodInAbstractClass(context, performRunnable, psiMethod, gContainingClass, acceptAbstractCondition); } } return false; }