public static boolean processImplementations(final PsiClass psiClass, final Processor<PsiElement> processor, SearchScope scope) { if (!FunctionalExpressionSearch.search(psiClass, scope).forEach(new Processor<PsiFunctionalExpression>() { @Override public boolean process(PsiFunctionalExpression expression) { return processor.process(expression); } })) { return false; } final boolean showInterfaces = Registry.is("ide.goto.implementation.show.interfaces"); return ClassInheritorsSearch.search(psiClass, scope, true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() { public boolean execute(@NotNull PsiClass element) { if (!showInterfaces && element.isInterface()) { return true; } return processor.process(element); } })); }
private void addExprTypesByDerivedClasses(LinkedHashSet<PsiType> set, PsiExpression expr) { PsiType type = expr.getType(); if (!(type instanceof PsiClassType)) return; PsiClass refClass = PsiUtil.resolveClassInType(type); if (refClass == null) return; PsiManager manager = PsiManager.getInstance(myProject); PsiElementProcessor.CollectElementsWithLimit<PsiClass> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiClass>(5); ClassInheritorsSearch.search(refClass, true).forEach(new PsiElementProcessorAdapter<PsiClass>(processor)); if (processor.isOverflow()) return; for (PsiClass derivedClass : processor.getCollection()) { if (derivedClass instanceof PsiAnonymousClass) continue; PsiType derivedType = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(derivedClass); set.add(derivedType); } }
private static String getOverriddenMethodTooltip(@NotNull PsiMethod method) { PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5); OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(processor)); boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); if (processor.isOverflow()){ return isAbstract ? DaemonBundle.message("method.is.implemented.too.many") : DaemonBundle.message("method.is.overridden.too.many"); } PsiMethod[] overridings = processor.toArray(PsiMethod.EMPTY_ARRAY); if (overridings.length == 0) { final PsiClass aClass = method.getContainingClass(); if (aClass != null && FunctionalExpressionSearch.search(aClass).findFirst() != null) { return "Has functional implementations"; } return null; } Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator(); Arrays.sort(overridings, comparator); String start = isAbstract ? DaemonBundle.message("method.is.implemented.header") : DaemonBundle.message("method.is.overriden.header"); @NonNls String pattern = " <a href=\"#javaClass/{1}\">{1}</a>"; return composeText(overridings, start, pattern, IdeActions.ACTION_GOTO_IMPLEMENTATION); }
private static void _findImplementingClasses(PsiClass anInterface, final Set<PsiClass> visited, final Collection<PsiClass> result) { LOG.assertTrue(anInterface.isInterface()); visited.add(anInterface); ClassInheritorsSearch.search(anInterface, false).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() { public boolean execute(@NotNull PsiClass aClass) { if (!aClass.isInterface()) { result.add(aClass); } else if (!visited.contains(aClass)){ _findImplementingClasses(aClass, visited, result); } return true; } })); }
private boolean implementersHaveOnlyPrivateConstructors(final PsiClass aClass) { final GlobalSearchScope scope = GlobalSearchScope.allScope(aClass.getProject()); final PsiElementProcessor.CollectElementsWithLimit<PsiClass> processor = new PsiElementProcessor.CollectElementsWithLimit(6); final ProgressManager progressManager = ProgressManager.getInstance(); progressManager.runProcess(new Runnable() { @Override public void run() { ClassInheritorsSearch.search(aClass, scope, true, true).forEach(new PsiElementProcessorAdapter<PsiClass>(processor)); } }, null); if (processor.isOverflow()) { return false; } final Collection<PsiClass> implementers = processor.getCollection(); for (PsiClass implementer : implementers) { if (!implementer.isInterface() && !implementer.hasModifierProperty(PsiModifier.ABSTRACT)) { if (!hasOnlyPrivateConstructors(implementer)) { return false; } } } return true; }
@Nullable @Override public String fun(PsiElement element) { PsiElement parent = element.getParent(); if (!(parent instanceof GrField)) return null; final List<GrAccessorMethod> accessors = GroovyPropertyUtils.getFieldAccessors((GrField)parent); PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5); for (GrAccessorMethod method : accessors) { OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(processor)); } if (processor.isOverflow()) { return DaemonBundle.message("method.is.overridden.too.many"); } PsiMethod[] overridings = processor.toArray(new PsiMethod[processor.getCollection().size()]); if (overridings.length == 0) return null; Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator(); Arrays.sort(overridings, comparator); String start = DaemonBundle.message("method.is.overriden.header"); @NonNls String pattern = " {1}"; return GutterIconTooltipHelper.composeText(overridings, start, pattern); }
public static boolean processImplementations(final PsiClass psiClass, final Processor<? super PsiClass> processor) { final boolean showInterfaces = Registry.is("ide.goto.implementation.show.interfaces"); return ClassInheritorsSearch.search(psiClass, ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() { @Override public SearchScope compute() { return psiClass.getUseScope(); } }), true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() { public boolean execute(@NotNull PsiClass element) { if (!showInterfaces && element.isInterface()) { return true; } return processor.process(element); } })); }
public static String getOverriddenMethodTooltip(PsiMethod method) { PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5); OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(processor)); boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); if (processor.isOverflow()){ return isAbstract ? DaemonBundle.message("method.is.implemented.too.many") : DaemonBundle.message("method.is.overridden.too.many"); } PsiMethod[] overridings = processor.toArray(new PsiMethod[processor.getCollection().size()]); if (overridings.length == 0) return null; Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator(); Arrays.sort(overridings, comparator); String start = isAbstract ? DaemonBundle.message("method.is.implemented.header") : DaemonBundle.message("method.is.overriden.header"); @NonNls String pattern = " {1}"; return GutterIconTooltipHelper.composeText(overridings, start, pattern); }
public static void navigateToOverriddenMethod(MouseEvent e, final PsiMethod method) { if (DumbService.isDumb(method.getProject())) { DumbService.getInstance(method.getProject()).showDumbModeNotification( "Navigation to overriding classes is not possible during index update"); return; } final PsiElementProcessor.CollectElementsWithLimit<PsiMethod> collectProcessor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(2, new THashSet<PsiMethod>()); if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { @Override public void run() { OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(collectProcessor)); } }, SEARCHING_FOR_OVERRIDING_METHODS, true, method.getProject(), (JComponent)e.getComponent())) { return; } PsiMethod[] overridings = collectProcessor.toArray(PsiMethod.EMPTY_ARRAY); if (overridings.length == 0) return; boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(overridings); MethodCellRenderer renderer = new MethodCellRenderer(showMethodNames); Arrays.sort(overridings, renderer.getComparator()); final OverridingMethodsUpdater methodsUpdater = new OverridingMethodsUpdater(method, renderer); PsiElementListNavigator.openTargets(e, overridings, methodsUpdater.getCaption(overridings.length), "Overriding methods of " + method.getName(), renderer, methodsUpdater); }
public static String getSubclassedClassTooltip(PsiClass aClass) { PsiElementProcessor.CollectElementsWithLimit<PsiClass> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiClass>(5, new THashSet<PsiClass>()); ClassInheritorsSearch.search(aClass, true).forEach(new PsiElementProcessorAdapter<PsiClass>(processor)); if (processor.isOverflow()) { return aClass.isInterface() ? DaemonBundle.message("interface.is.implemented.too.many") : DaemonBundle.message("class.is.subclassed.too.many"); } PsiClass[] subclasses = processor.toArray(new PsiClass[processor.getCollection().size()]); if (subclasses.length == 0) return null; Comparator<PsiClass> comparator = new PsiClassListCellRenderer().getComparator(); Arrays.sort(subclasses, comparator); String start = aClass.isInterface() ? DaemonBundle.message("interface.is.implemented.by.header") : DaemonBundle.message("class.is.subclassed.by.header"); @NonNls String pattern = " {0}"; return GutterIconTooltipHelper.composeText(subclasses, start, pattern); }
public static void navigateToSubclassedClass(MouseEvent e, final PsiClass aClass) { if (DumbService.isDumb(aClass.getProject())) { DumbService.getInstance(aClass.getProject()).showDumbModeNotification("Navigation to overriding methods is not possible during index update"); return; } final PsiElementProcessor.CollectElementsWithLimit<PsiClass> collectProcessor = new PsiElementProcessor.CollectElementsWithLimit<PsiClass>(2, new THashSet<PsiClass>()); if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { @Override public void run() { ClassInheritorsSearch.search(aClass, true).forEach(new PsiElementProcessorAdapter<PsiClass>(collectProcessor)); } }, SEARCHING_FOR_OVERRIDDEN_METHODS, true, aClass.getProject(), (JComponent)e.getComponent())) { return; } PsiClass[] inheritors = collectProcessor.toArray(PsiClass.EMPTY_ARRAY); if (inheritors.length == 0) return; final PsiClassListCellRenderer renderer = new PsiClassListCellRenderer(); final SubclassUpdater subclassUpdater = new SubclassUpdater(aClass, renderer); Arrays.sort(inheritors, renderer.getComparator()); PsiElementListNavigator.openTargets(e, inheritors, subclassUpdater.getCaption(inheritors.length), CodeInsightBundle.message("goto.implementation.findUsages.title", aClass.getName()), renderer, subclassUpdater); }
private static <Member extends PsiMember, P extends Processor<Member>> PsiElementProcessorAdapter<Member> createMembersProcessor(final List<P> processors, final AnalysisScope scope) { return new PsiElementProcessorAdapter<Member>(new PsiElementProcessor<Member>() { @Override public boolean execute(@NotNull Member member) { if (scope.contains(member)) return true; final List<P> processorsArrayed = new ArrayList<P>(processors); for (P processor : processorsArrayed) { if (!processor.process(member)) { processors.remove(processor); } } return !processors.isEmpty(); } }); }
private boolean implementersHaveOnlyPrivateConstructors(final PsiClass aClass) { final GlobalSearchScope scope = GlobalSearchScope.allScope(aClass.getProject()); final PsiElementProcessor.CollectElementsWithLimit<PsiClass> processor = new PsiElementProcessor.CollectElementsWithLimit(6); final ProgressManager progressManager = ProgressManager.getInstance(); progressManager.runProcess(new Runnable() { public void run() { ClassInheritorsSearch.search(aClass, scope, true, true).forEach(new PsiElementProcessorAdapter<PsiClass>(processor)); } }, null); if (processor.isOverflow()) { return false; } final Collection<PsiClass> implementers = processor.getCollection(); for (PsiClass implementer : implementers) { if (!implementer.isInterface() && !implementer.hasModifierProperty(PsiModifier.ABSTRACT)) { if (!hasOnlyPrivateConstructors(implementer)) { return false; } } } return true; }
public static String getSubclassedClassTooltip(@NotNull PsiClass aClass) { PsiElementProcessor.CollectElementsWithLimit<PsiClass> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiClass>(5, new THashSet<PsiClass>()); ClassInheritorsSearch.search(aClass, true).forEach(new PsiElementProcessorAdapter<PsiClass>(processor)); if (processor.isOverflow()) { return aClass.isInterface() ? DaemonBundle.message("interface.is.implemented.too.many") : DaemonBundle.message("class.is.subclassed.too.many"); } PsiClass[] subclasses = processor.toArray(PsiClass.EMPTY_ARRAY); if (subclasses.length == 0) { final PsiElementProcessor.CollectElementsWithLimit<PsiFunctionalExpression> functionalImplementations = new PsiElementProcessor.CollectElementsWithLimit<PsiFunctionalExpression>(2, new THashSet<PsiFunctionalExpression>()); FunctionalExpressionSearch.search(aClass).forEach(new PsiElementProcessorAdapter<PsiFunctionalExpression>(functionalImplementations)); if (!functionalImplementations.getCollection().isEmpty()) { return "Has functional implementations"; } return null; } Comparator<PsiClass> comparator = new PsiClassListCellRenderer().getComparator(); Arrays.sort(subclasses, comparator); String start = aClass.isInterface() ? DaemonBundle.message("interface.is.implemented.by.header") : DaemonBundle.message("class.is.subclassed.by.header"); @NonNls String pattern = " <a href=\"#javaClass/{0}\">{0}</a>"; return composeText(subclasses, start, pattern, IdeActions.ACTION_GOTO_IMPLEMENTATION); }
public static void navigateToSubclassedClass(MouseEvent e, @NotNull final PsiClass aClass) { if (DumbService.isDumb(aClass.getProject())) { DumbService.getInstance(aClass.getProject()).showDumbModeNotification("Navigation to overriding methods is not possible during index update"); return; } final PsiElementProcessor.CollectElementsWithLimit<PsiClass> collectProcessor = new PsiElementProcessor.CollectElementsWithLimit<PsiClass>(2, new THashSet<PsiClass>()); final PsiElementProcessor.CollectElementsWithLimit<PsiFunctionalExpression> collectExprProcessor = new PsiElementProcessor.CollectElementsWithLimit<PsiFunctionalExpression>(2, new THashSet<PsiFunctionalExpression>()); if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { @Override public void run() { ClassInheritorsSearch.search(aClass, true).forEach(new PsiElementProcessorAdapter<PsiClass>(collectProcessor)); if (collectProcessor.getCollection().size() < 2) { FunctionalExpressionSearch.search(aClass).forEach(new PsiElementProcessorAdapter<PsiFunctionalExpression>(collectExprProcessor)); } } }, SEARCHING_FOR_OVERRIDDEN_METHODS, true, aClass.getProject(), (JComponent)e.getComponent())) { return; } final List<NavigatablePsiElement> inheritors = new ArrayList<NavigatablePsiElement>(); inheritors.addAll(collectProcessor.getCollection()); inheritors.addAll(collectExprProcessor.getCollection()); if (inheritors.isEmpty()) return; final PsiClassOrFunctionalExpressionListCellRenderer renderer = new PsiClassOrFunctionalExpressionListCellRenderer(); final SubclassUpdater subclassUpdater = new SubclassUpdater(aClass, renderer); Collections.sort(inheritors, renderer.getComparator()); PsiElementListNavigator.openTargets(e, inheritors.toArray(new NavigatablePsiElement[inheritors.size()]), subclassUpdater.getCaption(inheritors.size()), CodeInsightBundle.message("goto.implementation.findUsages.title", aClass.getName()), renderer, subclassUpdater); }
@Nullable private static List<PsiClass> findDescendants(ExpressionContext context, Expression[] params) { if (params == null || params.length == 0) return null; PsiManager instance = PsiManager.getInstance(context.getProject()); Result result = params[0].calculateResult(context); if (result == null) return null; final String paramResult = result.toString(); if (paramResult == null) return null; final boolean isAllowAbstract = isAllowAbstract(context, params); final PsiClass myBaseClass = JavaPsiFacade.getInstance(instance.getProject()).findClass(paramResult, GlobalSearchScope.allScope(context.getProject())); if (myBaseClass != null) { final List<PsiClass> classes = new ArrayList<PsiClass>(); ClassInheritorsSearch.search(myBaseClass, true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() { @Override public boolean execute(@NotNull PsiClass element) { if (isAllowAbstract || !isAbstractOrInterface(element)) { classes.add(element); } return true; } })); return classes; } return null; }
@Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { int offset = editor.getCaretModel().getOffset(); final PsiMethod method = findMethod(file, offset); if (method == null || !method.isValid()) return false; setText(getIntentionName(method)); if (!method.getManager().isInProject(method)) return false; PsiClass containingClass = method.getContainingClass(); if (containingClass == null) return false; final boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); if (isAbstract || !method.hasModifierProperty(PsiModifier.PRIVATE) && !method.hasModifierProperty(PsiModifier.STATIC)) { if (!isAbstract && !isOnIdentifier(file, offset)) return false; MyElementProcessor processor = new MyElementProcessor(method); if (containingClass.isEnum()) { for (PsiField field : containingClass.getFields()) { if (field instanceof PsiEnumConstant) { final PsiEnumConstantInitializer initializingClass = ((PsiEnumConstant)field).getInitializingClass(); if (initializingClass == null) { processor.myHasMissingImplementations = true; } else { if (!processor.execute(initializingClass)){ break; } } } } } ClassInheritorsSearch.search(containingClass, false).forEach(new PsiElementProcessorAdapter<PsiClass>( processor)); return isAvailable(processor); } return false; }
public static boolean findAllTestClasses(final TestClassFilter testClassFilter, final Set<PsiClass> found) { final PsiManager manager = testClassFilter.getPsiManager(); final Project project = manager.getProject(); GlobalSearchScope projectScopeWithoutLibraries = GlobalSearchScope.projectScope(project); final GlobalSearchScope scope = projectScopeWithoutLibraries.intersectWith(testClassFilter.getScope()); ClassInheritorsSearch.search(testClassFilter.getBase(), scope, true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() { public boolean execute(@NotNull final PsiClass aClass) { if (testClassFilter.isAccepted(aClass)) found.add(aClass); return true; } })); // classes having suite() method final PsiMethod[] suiteMethods = ApplicationManager.getApplication().runReadAction( new Computable<PsiMethod[]>() { public PsiMethod[] compute() { return PsiShortNamesCache.getInstance(project).getMethodsByName(JUnitUtil.SUITE_METHOD_NAME, scope); } } ); for (final PsiMethod method : suiteMethods) { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { final PsiClass containingClass = method.getContainingClass(); if (containingClass == null) return; if (containingClass instanceof PsiAnonymousClass) return; if (containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) return; if (containingClass.getContainingClass() != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) return; if (JUnitUtil.isSuiteMethod(method) && testClassFilter.isAccepted(containingClass)) { found.add(containingClass); } } }); } boolean hasJunit4 = addAnnotatedMethodsAnSubclasses(manager, scope, testClassFilter, found, "org.junit.Test", true); hasJunit4 |= addAnnotatedMethodsAnSubclasses(manager, scope, testClassFilter, found, "org.junit.runner.RunWith", false); return hasJunit4; }
@Override public String fun(PsiElement element) { PsiElement parent = element.getParent(); if (!(parent instanceof GrMethod)) return null; GrMethod method = (GrMethod)parent; PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5); for (GrMethod m : PsiImplUtil.getMethodOrReflectedMethods(method)) { OverridingMethodsSearch.search(m, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(processor)); } boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); if (processor.isOverflow()){ return isAbstract ? DaemonBundle.message("method.is.implemented.too.many") : DaemonBundle.message("method.is.overridden.too.many"); } PsiMethod[] overridings = processor.toArray(new PsiMethod[processor.getCollection().size()]); if (overridings.length == 0) return null; Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator(); Arrays.sort(overridings, comparator); String start = isAbstract ? DaemonBundle.message("method.is.implemented.header") : DaemonBundle.message("method.is.overriden.header"); @NonNls String pattern = " {1}"; return GutterIconTooltipHelper.composeText(overridings, start, pattern); }
public static boolean processImplementations(final PsiClass psiClass, final Processor<PsiElement> processor, SearchScope scope) { if(!FunctionalExpressionSearch.search(psiClass, scope).forEach(expression -> { return processor.process(expression); })) { return false; } return ClassInheritorsSearch.search(psiClass, scope, true).forEach(new PsiElementProcessorAdapter<>((PsiElementProcessor<PsiClass>) element -> processor.process(element))); }
private void addExprTypesByDerivedClasses(LinkedHashSet<PsiType> set, PsiExpression expr) { PsiType type = expr.getType(); if(!(type instanceof PsiClassType)) { return; } PsiClass refClass = PsiUtil.resolveClassInType(type); if(refClass == null) { return; } PsiManager manager = PsiManager.getInstance(myProject); PsiElementProcessor.CollectElementsWithLimit<PsiClass> processor = new PsiElementProcessor.CollectElementsWithLimit<>(5); ClassInheritorsSearch.search(refClass).forEach(new PsiElementProcessorAdapter<>(processor)); if(processor.isOverflow()) { return; } for(PsiClass derivedClass : processor.getCollection()) { if(derivedClass instanceof PsiAnonymousClass) { continue; } PsiType derivedType = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(derivedClass); set.add(derivedType); } }
private static String getOverriddenMethodTooltip(@NotNull PsiMethod method) { PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<>(5); GlobalSearchScope scope = GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(method)); OverridingMethodsSearch.search(method, scope, true).forEach(new PsiElementProcessorAdapter<>(processor)); boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); if(processor.isOverflow()) { return DaemonBundle.message(isAbstract ? "method.is.implemented.too.many" : "method.is.overridden.too.many"); } PsiMethod[] overridings = processor.toArray(PsiMethod.EMPTY_ARRAY); if(overridings.length == 0) { final PsiClass aClass = method.getContainingClass(); if(aClass != null && FunctionalExpressionSearch.search(aClass).findFirst() != null) { return "Has functional implementations"; } return null; } Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator(); Arrays.sort(overridings, comparator); String start = DaemonBundle.message(isAbstract ? "method.is.implemented.header" : "method.is.overriden.header"); @NonNls String pattern = " <a href=\"#javaClass/{1}\">{1}</a>"; return composeText(overridings, start, pattern, IdeActions.ACTION_GOTO_IMPLEMENTATION); }
public static String getSubclassedClassTooltip(@NotNull PsiClass aClass) { PsiElementProcessor.CollectElementsWithLimit<PsiClass> processor = new PsiElementProcessor.CollectElementsWithLimit<>(5, new THashSet<>()); ClassInheritorsSearch.search(aClass).forEach(new PsiElementProcessorAdapter<>(processor)); if(processor.isOverflow()) { return DaemonBundle.message(aClass.isInterface() ? "interface.is.implemented.too.many" : "class.is.subclassed.too.many"); } PsiClass[] subclasses = processor.toArray(PsiClass.EMPTY_ARRAY); if(subclasses.length == 0) { final PsiElementProcessor.CollectElementsWithLimit<PsiFunctionalExpression> functionalImplementations = new PsiElementProcessor.CollectElementsWithLimit<>(2, new THashSet<>()); FunctionalExpressionSearch.search(aClass).forEach(new PsiElementProcessorAdapter<>(functionalImplementations)); if(!functionalImplementations.getCollection().isEmpty()) { return "Has functional implementations"; } return null; } Comparator<PsiClass> comparator = PsiClassListCellRenderer.INSTANCE.getComparator(); Arrays.sort(subclasses, comparator); String start = DaemonBundle.message(aClass.isInterface() ? "interface.is.implemented.by.header" : "class.is.subclassed.by.header"); @NonNls String pattern = " <a href=\"#javaClass/{0}\">{0}</a>"; return composeText(subclasses, start, pattern, IdeActions.ACTION_GOTO_IMPLEMENTATION); }
public static void navigateToSubclassedClass(MouseEvent e, @NotNull final PsiClass aClass) { if(DumbService.isDumb(aClass.getProject())) { DumbService.getInstance(aClass.getProject()).showDumbModeNotification("Navigation to overriding methods is not possible during index update"); return; } final PsiElementProcessor.FindElement<PsiClass> collectProcessor = new PsiElementProcessor.FindElement<>(); final PsiElementProcessor.FindElement<PsiFunctionalExpression> collectExprProcessor = new PsiElementProcessor.FindElement<>(); if(!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> { ClassInheritorsSearch.search(aClass).forEach(new PsiElementProcessorAdapter<>(collectProcessor)); if(collectProcessor.getFoundElement() == null) { FunctionalExpressionSearch.search(aClass).forEach(new PsiElementProcessorAdapter<>(collectExprProcessor)); } }, SEARCHING_FOR_OVERRIDDEN_METHODS, true, aClass.getProject(), (JComponent) e.getComponent())) { return; } final List<NavigatablePsiElement> inheritors = new ArrayList<>(); ContainerUtil.addIfNotNull(inheritors, collectProcessor.getFoundElement()); ContainerUtil.addIfNotNull(inheritors, collectExprProcessor.getFoundElement()); if(inheritors.isEmpty()) { return; } final PsiClassOrFunctionalExpressionListCellRenderer renderer = new PsiClassOrFunctionalExpressionListCellRenderer(); final SubclassUpdater subclassUpdater = new SubclassUpdater(aClass, renderer); Collections.sort(inheritors, renderer.getComparator()); PsiElementListNavigator.openTargets(e, inheritors.toArray(new NavigatablePsiElement[inheritors.size()]), subclassUpdater.getCaption(inheritors.size()), CodeInsightBundle.message("goto" + ".implementation.findUsages.title", aClass.getName()), renderer, subclassUpdater); }
private static void navigateToOverriddenMethod(MouseEvent e, @NotNull final PsiMethod method) { if (DumbService.isDumb(method.getProject())) { DumbService.getInstance(method.getProject()).showDumbModeNotification( "Navigation to overriding classes is not possible during index update"); return; } final PsiElementProcessor.CollectElementsWithLimit<PsiMethod> collectProcessor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(2, new THashSet<PsiMethod>()); final PsiElementProcessor.CollectElementsWithLimit<PsiFunctionalExpression> collectExprProcessor = new PsiElementProcessor.CollectElementsWithLimit<PsiFunctionalExpression>(2, new THashSet<PsiFunctionalExpression>()); final boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { @Override public void run() { OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(collectProcessor)); if (isAbstract && collectProcessor.getCollection().size() < 2) { final PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() { @Override public PsiClass compute() { return method.getContainingClass(); } }); if (aClass != null) { FunctionalExpressionSearch.search(aClass).forEach(new PsiElementProcessorAdapter<PsiFunctionalExpression>(collectExprProcessor)); } } } }, SEARCHING_FOR_OVERRIDING_METHODS, true, method.getProject(), (JComponent)e.getComponent())) { return; } final PsiMethod[] methodOverriders = collectProcessor.toArray(PsiMethod.EMPTY_ARRAY); final List<NavigatablePsiElement> overridings = new ArrayList<NavigatablePsiElement>(); overridings.addAll(collectProcessor.getCollection()); overridings.addAll(collectExprProcessor.getCollection()); if (overridings.isEmpty()) return; boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(methodOverriders); MethodOrFunctionalExpressionCellRenderer renderer = new MethodOrFunctionalExpressionCellRenderer(showMethodNames); Collections.sort(overridings, renderer.getComparator()); final OverridingMethodsUpdater methodsUpdater = new OverridingMethodsUpdater(method, renderer); PsiElementListNavigator.openTargets(e, overridings.toArray(new NavigatablePsiElement[overridings.size()]), methodsUpdater.getCaption(overridings.size()), "Overriding methods of " + method.getName(), renderer, methodsUpdater); }
public static boolean findAllTestClasses(final TestClassFilter testClassFilter, final Set<PsiClass> found) { final PsiManager manager = testClassFilter.getPsiManager(); final Project project = manager.getProject(); GlobalSearchScope projectScopeWithoutLibraries = GlobalSearchScope.projectScope(project); final GlobalSearchScope scope = projectScopeWithoutLibraries.intersectWith(testClassFilter.getScope()); ClassInheritorsSearch.search(testClassFilter.getBase(), scope, true, true, false).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() { public boolean execute(@NotNull final PsiClass aClass) { if (testClassFilter.isAccepted(aClass)) found.add(aClass); return true; } })); // classes having suite() method final PsiMethod[] suiteMethods = ApplicationManager.getApplication().runReadAction( new Computable<PsiMethod[]>() { public PsiMethod[] compute() { return PsiShortNamesCache.getInstance(project).getMethodsByName(JUnitUtil.SUITE_METHOD_NAME, scope); } } ); for (final PsiMethod method : suiteMethods) { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { final PsiClass containingClass = method.getContainingClass(); if (containingClass == null) return; if (containingClass instanceof PsiAnonymousClass) return; if (containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) return; if (containingClass.getContainingClass() != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) return; if (JUnitUtil.isSuiteMethod(method) && testClassFilter.isAccepted(containingClass)) { found.add(containingClass); } } }); } Set<PsiClass> processed = ContainerUtil.newHashSet(); boolean hasJunit4 = addAnnotatedMethodsAnSubclasses(manager, scope, testClassFilter, found, processed, "org.junit.Test", true); hasJunit4 |= addAnnotatedMethodsAnSubclasses(manager, scope, testClassFilter, found, processed, "org.junit.runner.RunWith", false); return hasJunit4; }
private static boolean addAnnotatedMethodsAnSubclasses(final PsiManager manager, final GlobalSearchScope scope, final TestClassFilter testClassFilter, final Set<PsiClass> found, final String annotation, final boolean isMethod) { final Ref<Boolean> isJUnit4 = new Ref<Boolean>(Boolean.FALSE); // annotated with @Test final PsiClass testAnnotation = ApplicationManager.getApplication().runReadAction( new Computable<PsiClass>() { @Nullable public PsiClass compute() { return JavaPsiFacade.getInstance(manager.getProject()).findClass(annotation, GlobalSearchScope.allScope(manager.getProject())); } } ); if (testAnnotation != null) { AnnotatedMembersSearch.search(testAnnotation, GlobalSearchScope.allScope(manager.getProject())).forEach(new Processor<PsiMember>() { public boolean process(final PsiMember annotated) { final PsiClass containingClass = annotated instanceof PsiClass ? (PsiClass)annotated : annotated.getContainingClass(); if (containingClass != null && annotated instanceof PsiMethod == isMethod) { if (ApplicationManager.getApplication().runReadAction( new Computable<Boolean>() { @Override public Boolean compute() { return scope.contains(PsiUtilCore.getVirtualFile(containingClass)) && testClassFilter.isAccepted(containingClass); } })) { found.add(containingClass); isJUnit4.set(Boolean.TRUE); } ClassInheritorsSearch.search(containingClass, scope, true) .forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() { public boolean execute(@NotNull final PsiClass aClass) { if (testClassFilter.isAccepted(aClass)) { found.add(aClass); isJUnit4.set(Boolean.TRUE); } return true; } })); } return true; } }); } return isJUnit4.get().booleanValue(); }
private static boolean processOverridingMethods(@NotNull PsiMethod psiMethod, @NotNull final Processor<UsageInfo> processor, @NotNull final JavaMethodFindUsagesOptions options) { return OverridingMethodsSearch.search(psiMethod, options.searchScope, options.isCheckDeepInheritance).forEach(new PsiElementProcessorAdapter<>(element -> addResult(element .getNavigationElement(), options, processor))); }
private static boolean addInheritors(@NotNull PsiClass aClass, @NotNull final JavaClassFindUsagesOptions options, @NotNull final Processor<UsageInfo> processor) { return ClassInheritorsSearch.search(aClass, options.searchScope, options.isCheckDeepInheritance).forEach(new PsiElementProcessorAdapter<>(element -> addResult(element, options, processor))); }
private static boolean addDerivedInterfaces(@NotNull PsiClass anInterface, @NotNull final JavaClassFindUsagesOptions options, @NotNull final Processor<UsageInfo> processor) { return ClassInheritorsSearch.search(anInterface, options.searchScope, options.isCheckDeepInheritance).forEach(new PsiElementProcessorAdapter<>(inheritor -> !inheritor.isInterface() || addResult(inheritor, options, processor))); }
private static boolean addImplementingClasses(@NotNull PsiClass anInterface, @NotNull final JavaClassFindUsagesOptions options, @NotNull final Processor<UsageInfo> processor) { return ClassInheritorsSearch.search(anInterface, options.searchScope, options.isCheckDeepInheritance).forEach(new PsiElementProcessorAdapter<>(inheritor -> inheritor.isInterface() || addResult(inheritor, options, processor))); }