private static Couple<Integer> collectInheritorsInfo(final PsiClass aClass, final Set<InheritorsCountData> collector, final Set<String> disabledNames, final Set<String> processedElements, final Set<String> allNotAnonymousInheritors) { final String className = aClass.getName(); if (!processedElements.add(className)) return Couple.of(0, 0); final MyInheritorsInfoProcessor processor = new MyInheritorsInfoProcessor(collector, disabledNames, processedElements); DirectClassInheritorsSearch.search(aClass).forEach(processor); allNotAnonymousInheritors.addAll(processor.getAllNotAnonymousInheritors()); final int allInheritorsCount = processor.getAllNotAnonymousInheritors().size() + processor.getAnonymousInheritorsCount(); if (!aClass.isInterface() && allInheritorsCount != 0 && !disabledNames.contains(className)) { collector.add(new InheritorsCountData(aClass, allInheritorsCount)); } return Couple.of(allNotAnonymousInheritors.size(), processor.getAnonymousInheritorsCount()); }
@Nullable private static PsiClass getVisibleInheritor(@NotNull PsiClass superClass, PsiClass upperBound, PsiElement context) { final Query<PsiClass> search = DirectClassInheritorsSearch.search(superClass, context.getResolveScope()); final Project project = superClass.getProject(); for (PsiClass aClass : search) { if (aClass.isInheritor(superClass, true) && upperBound.isInheritor(aClass, true)) { if (PsiUtil.isAccessible(project, aClass, context, null)) { return aClass; } else { return getVisibleInheritor(aClass, upperBound, context); } } } return null; }
@Override public boolean execute(@NotNull final DirectClassInheritorsSearch.SearchParameters queryParameters, @NotNull final Processor<PsiClass> consumer) { final PsiClass clazz = queryParameters.getClassToProcess(); final SearchScope scope = queryParameters.getScope(); if (scope instanceof GlobalSearchScope) { final List<PsiClass> candidates = ApplicationManager.getApplication().runReadAction(new Computable<List<PsiClass>>() { @Override public List<PsiClass> compute() { if (!clazz.isValid()) return Collections.emptyList(); return getDerivingClassCandidates(clazz, (GlobalSearchScope)scope, queryParameters.includeAnonymous()); } }); for (final PsiClass candidate : candidates) { if (!queryParameters.isCheckInheritance() || isInheritor(clazz, candidate)) { if (!consumer.process(candidate)) { return false; } } } return true; } return true; }
private static Pair<Integer, Integer> collectInheritorsInfo(final PsiClass aClass, final Set<InheritorsCountData> collector, final Set<String> disabledNames, final Set<String> processedElements, final Set<String> allNotAnonymousInheritors) { final String className = aClass.getName(); if (!processedElements.add(className)) return Pair.create(0, 0); final MyInheritorsInfoProcessor processor = new MyInheritorsInfoProcessor(collector, disabledNames, processedElements); DirectClassInheritorsSearch.search(aClass).forEach(processor); allNotAnonymousInheritors.addAll(processor.getAllNotAnonymousInheritors()); final int allInheritorsCount = processor.getAllNotAnonymousInheritors().size() + processor.getAnonymousInheritorsCount(); if (!aClass.isInterface() && allInheritorsCount != 0 && !disabledNames.contains(className)) { collector.add(new InheritorsCountData(aClass, allInheritorsCount)); } return Pair.create(allNotAnonymousInheritors.size(), processor.getAnonymousInheritorsCount()); }
private static GlobalSearchScope getAllAnnotationFilesScope(Project project) { return CachedValuesManager.getManager(project).getCachedValue(project, () -> { GlobalSearchScope scope = GlobalSearchScope.allScope(project); Set<VirtualFile> allAnnotationFiles = new HashSet<>(); for(PsiClass javaLangAnnotation : JavaPsiFacade.getInstance(project).findClasses(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION, scope)) { DirectClassInheritorsSearch.search(javaLangAnnotation, scope, false).forEach(annotationClass -> { ContainerUtil.addIfNotNull(allAnnotationFiles, PsiUtilCore.getVirtualFile(annotationClass)); return true; }); } scope = GlobalSearchScope.filesWithLibrariesScope(project, allAnnotationFiles); return CachedValueProvider.Result.createSingleDependency(scope, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); }); }
private static GlobalSearchScope getAllAnnotationFilesScope(Project project) { return CachedValuesManager.getManager(project).getCachedValue(project, () -> { GlobalSearchScope scope = GlobalSearchScope.allScope(project); Set<VirtualFile> allAnnotationFiles = new HashSet<>(); for(PsiClass javaLangAnnotation : JavaPsiFacade.getInstance(project).findClasses(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION, scope)) { DirectClassInheritorsSearch.search(javaLangAnnotation, scope, false).forEach(annotationClass -> { ContainerUtil.addIfNotNull(allAnnotationFiles, PsiUtilCore.getVirtualFile(annotationClass)); return true; }); } return CachedValueProvider.Result.createSingleDependency(GlobalSearchScope.filesWithLibrariesScope(project, allAnnotationFiles), PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); }); }
private static boolean checkInheritance(final DirectClassInheritorsSearch.SearchParameters p, final PsiClass aClass, final PsiClass candidate, Project project) { return MethodUsagesSearcher.resolveInReadAction(project, new Computable<Boolean>() { @Override public Boolean compute() { return !p.isCheckInheritance() || candidate.isInheritor(aClass, false); } }); }
@Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { if (!(file instanceof PsiJavaFile)) return false; final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); if (element instanceof PsiIdentifier) { final PsiElement parent = element.getParent(); if (parent instanceof PsiClass) { return isEmptyClass(project, (PsiClass)parent) && DirectClassInheritorsSearch.search((PsiClass)parent).findFirst() != null; } } final PsiReference psiReference = TargetElementUtil.findReference(editor); if (psiReference == null) return false; final PsiReferenceList referenceList = PsiTreeUtil.getParentOfType(psiReference.getElement(), PsiReferenceList.class); if (referenceList == null) return false; final PsiClass psiClass = PsiTreeUtil.getParentOfType(referenceList, PsiClass.class); if (psiClass == null) return false; if (psiClass.getExtendsList() != referenceList && psiClass.getImplementsList() != referenceList) return false; final PsiElement target = psiReference.resolve(); if (target == null || !(target instanceof PsiClass)) return false; return isEmptyClass(project, (PsiClass)target); }
public void inlineElement(final Project project, final Editor editor, final PsiElement element) { PsiClass superClass = (PsiClass) element; Collection<PsiClass> inheritors = DirectClassInheritorsSearch.search((PsiClass)element).findAll(); if (!superClass.getManager().isInProject(superClass)) { CommonRefactoringUtil.showErrorHint(project, editor, "Cannot inline non-project class", REFACTORING_NAME, null); return; } for (PsiClass inheritor : inheritors) { if (PsiTreeUtil.isAncestor(superClass, inheritor, false)) { CommonRefactoringUtil.showErrorHint(project, editor, "Cannot inline into the inner class. Move \'" + inheritor.getName() + "\' to upper level", REFACTORING_NAME, null); return; } if (inheritor instanceof PsiAnonymousClass) { CommonRefactoringUtil.showErrorHint(project, editor, "Cannot inline into anonymous class.", REFACTORING_NAME, null); return; } } PsiClass chosen = null; PsiReference reference = editor != null ? TargetElementUtil.findReference(editor, editor.getCaretModel().getOffset()) : null; if (reference != null) { final PsiElement resolve = reference.resolve(); if (resolve == superClass) { final PsiElement referenceElement = reference.getElement(); if (referenceElement != null) { final PsiElement parent = referenceElement.getParent(); if (parent instanceof PsiReferenceList) { final PsiElement gParent = parent.getParent(); if (gParent instanceof PsiClass && inheritors.contains(gParent)) { chosen = (PsiClass)gParent; } } } } } new InlineSuperClassRefactoringDialog(project, superClass, chosen, inheritors.toArray(new PsiClass[inheritors.size()])).show(); }
private static boolean checkInheritance(final DirectClassInheritorsSearch.SearchParameters p, final PsiClass aClass, final PsiClass candidate) { return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() { @Override public Boolean compute() { return !p.isCheckInheritance() || candidate.isInheritor(aClass, false); } }); }
@Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { if (!(file instanceof PsiJavaFile)) return false; final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); if (element instanceof PsiIdentifier) { final PsiElement parent = element.getParent(); if (parent instanceof PsiClass) { return isEmptyClass(project, (PsiClass)parent) && DirectClassInheritorsSearch.search((PsiClass)parent).findFirst() != null; } } final PsiReference psiReference = TargetElementUtilBase.findReference(editor); if (psiReference == null) return false; final PsiReferenceList referenceList = PsiTreeUtil.getParentOfType(psiReference.getElement(), PsiReferenceList.class); if (referenceList == null) return false; final PsiClass psiClass = PsiTreeUtil.getParentOfType(referenceList, PsiClass.class); if (psiClass == null) return false; if (psiClass.getExtendsList() != referenceList && psiClass.getImplementsList() != referenceList) return false; final PsiElement target = psiReference.resolve(); if (target == null || !(target instanceof PsiClass)) return false; return isEmptyClass(project, (PsiClass)target); }
private static List<LookupElement> searchForLookups(final String targetClassQName, final Set<String> contextRelevantTypes, final ChainCompletionContext completionContext) { final MethodChainsSearchService searchService = new MethodChainsSearchService(completionContext.getProject()); final List<MethodsChain> searchResult = searchChains(targetClassQName, contextRelevantTypes, MAX_SEARCH_RESULT_SIZE, MAX_CHAIN_SIZE, completionContext, searchService); if (searchResult.size() < MAX_SEARCH_RESULT_SIZE) { final PsiClass aClass = JavaPsiFacade.getInstance(completionContext.getProject()) .findClass(targetClassQName, GlobalSearchScope.allScope(completionContext.getProject())); if (aClass != null) { DirectClassInheritorsSearch.search(aClass).forEach(new Processor<PsiClass>() { @Override public boolean process(final PsiClass psiClass) { final String inheritorQName = psiClass.getQualifiedName(); if (!StringUtil.isEmpty(inheritorQName)) { final List<MethodsChain> inheritorFilteredSearchResult = new SmartList<MethodsChain>(); //noinspection ConstantConditions for (final MethodsChain chain : searchChains(inheritorQName, contextRelevantTypes, MAX_SEARCH_RESULT_SIZE, MAX_CHAIN_SIZE, completionContext, searchService)) { boolean insert = true; for (final MethodsChain baseChain : searchResult) { if (baseChain.weakContains(chain)) { insert = false; break; } } if (insert) { inheritorFilteredSearchResult.add(chain); } } searchResult.addAll(inheritorFilteredSearchResult); } return true; } }); } } return MethodsChainLookupRangingHelper.chainsToWeightableLookupElements(filterTailAndGetSumLastMethodOccurrence(searchResult), completionContext); }
public void inlineElement(final Project project, final Editor editor, final PsiElement element) { PsiClass superClass = (PsiClass) element; Collection<PsiClass> inheritors = DirectClassInheritorsSearch.search((PsiClass)element).findAll(); if (!superClass.getManager().isInProject(superClass)) { CommonRefactoringUtil.showErrorHint(project, editor, "Cannot inline non-project class", REFACTORING_NAME, null); return; } for (PsiClass inheritor : inheritors) { if (PsiTreeUtil.isAncestor(superClass, inheritor, false)) { CommonRefactoringUtil.showErrorHint(project, editor, "Cannot inline into the inner class. Move \'" + inheritor.getName() + "\' to upper level", REFACTORING_NAME, null); return; } if (inheritor instanceof PsiAnonymousClass) { CommonRefactoringUtil.showErrorHint(project, editor, "Cannot inline into anonymous class.", REFACTORING_NAME, null); return; } } PsiClass chosen = null; PsiReference reference = editor != null ? TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset()) : null; if (reference != null) { final PsiElement resolve = reference.resolve(); if (resolve == superClass) { final PsiElement referenceElement = reference.getElement(); if (referenceElement != null) { final PsiElement parent = referenceElement.getParent(); if (parent instanceof PsiReferenceList) { final PsiElement gParent = parent.getParent(); if (gParent instanceof PsiClass && inheritors.contains(gParent)) { chosen = (PsiClass)gParent; } } } } } new InlineSuperClassRefactoringDialog(project, superClass, chosen, inheritors.toArray(new PsiClass[inheritors.size()])).show(); }
@Nullable private static PsiClass getVisibleInheritor(PsiClass superClass, PsiElement context) { final Query<PsiClass> search = DirectClassInheritorsSearch.search(superClass, context.getResolveScope()); for (PsiClass aClass : search) { if (superClass.isInheritor(aClass, true)) { if (PsiUtil.isAccessible(aClass, context, null)) { return aClass; } else { return getVisibleInheritor(aClass, context); } } } return null; }
public boolean execute(@NotNull DirectClassInheritorsSearch.SearchParameters queryParameters, @NotNull final Processor<PsiClass> consumer) { final PsiClass clazz = queryParameters.getClassToProcess(); final SearchScope scope = queryParameters.getScope(); if (scope instanceof GlobalSearchScope) { final PsiClass[] candidates = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() { public PsiClass[] compute() { if (!clazz.isValid()) return PsiClass.EMPTY_ARRAY; return getDeriverCandidates(clazz, (GlobalSearchScope)scope); } }); for (final PsiClass candidate : candidates) { final boolean isInheritor; AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock(); try { isInheritor = candidate.isValid() && candidate.isInheritor(clazz, false); } finally { accessToken.finish(); } if (isInheritor) { if (!consumer.process(candidate)) { return false; } } } return true; } return true; }
@NotNull private static MultiMap<String, PsiClass> getAllAnnotationClasses(PsiElement context, PrefixMatcher matcher) { MultiMap<String, PsiClass> map = new MultiMap<>(); GlobalSearchScope scope = context.getResolveScope(); PsiClass annotation = JavaPsiFacade.getInstance(context.getProject()).findClass(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION, scope); if(annotation != null) { DirectClassInheritorsSearch.search(annotation, scope, false).forEach(psiClass -> { if(!psiClass.isAnnotationType() || psiClass.getQualifiedName() == null) { return true; } String name = ObjectUtils.assertNotNull(psiClass.getName()); if(!matcher.prefixMatches(name)) { name = getClassNameWithContainers(psiClass); if(!matcher.prefixMatches(name)) { return true; } } map.putValue(name, psiClass); return true; }); } return map; }
private static void processInheritors(@NotNull final Processor<PsiClass> consumer, @NotNull final PsiClass baseClass, @NotNull final SearchScope searchScope, @NotNull final ClassInheritorsSearch.SearchParameters parameters) { if (baseClass instanceof PsiAnonymousClass || isFinal(baseClass)) return; Project project = PsiUtilCore.getProjectInReadAction(baseClass); if (isJavaLangObject(baseClass)) { AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(new Processor<PsiClass>() { @Override public boolean process(final PsiClass aClass) { ProgressManager.checkCanceled(); return isJavaLangObject(aClass) || consumer.process(aClass); } }); return; } final Ref<PsiClass> currentBase = Ref.create(null); final Stack<PsiAnchor> stack = new Stack<PsiAnchor>(); final Set<PsiAnchor> processed = ContainerUtil.newTroveSet(); final Processor<PsiClass> processor = new ReadActionProcessor<PsiClass>() { @Override public boolean processInReadAction(PsiClass candidate) { ProgressManager.checkCanceled(); if (parameters.isCheckInheritance() || parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass)) { if (!candidate.isInheritor(currentBase.get(), false)) { return true; } } if (PsiSearchScopeUtil.isInScope(searchScope, candidate)) { if (candidate instanceof PsiAnonymousClass) { return consumer.process(candidate); } final String name = candidate.getName(); if (name != null && parameters.getNameCondition().value(name) && !consumer.process(candidate)) { return false; } } if (parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass) && !isFinal(candidate)) { stack.push(PsiAnchor.create(candidate)); } return true; } }; ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { stack.push(PsiAnchor.create(baseClass)); } }); final GlobalSearchScope projectScope = GlobalSearchScope.allScope(project); while (!stack.isEmpty()) { ProgressManager.checkCanceled(); final PsiAnchor anchor = stack.pop(); if (!processed.add(anchor)) continue; PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() { @Override public PsiClass compute() { return (PsiClass)anchor.retrieve(); } }); if (psiClass == null) continue; currentBase.set(psiClass); if (!DirectClassInheritorsSearch.search(psiClass, projectScope, parameters.isIncludeAnonymous(), false).forEach(processor)) return; } }
public boolean canInlineElement(PsiElement element) { if (!(element instanceof PsiClass)) return false; if (element.getLanguage() != StdLanguages.JAVA) return false; Collection<PsiClass> inheritors = DirectClassInheritorsSearch.search((PsiClass)element).findAll(); return inheritors.size() > 0; }
private static List<LookupElement> searchForLookups(final TargetType target, final Set<String> contextRelevantTypes, final ChainCompletionContext completionContext) { final Project project = completionContext.getProject(); final MethodsUsageIndexReader methodsUsageIndexReader = MethodsUsageIndexReader.getInstance(project); final List<MethodsChain> searchResult = searchChains(target, contextRelevantTypes, MAX_SEARCH_RESULT_SIZE, MAX_CHAIN_SIZE, completionContext, methodsUsageIndexReader); if (searchResult.size() < MAX_SEARCH_RESULT_SIZE) { if (!target.isArray()) { final List<MethodsChain> inheritorFilteredSearchResult = new SmartList<MethodsChain>(); final Processor<TargetType> consumer = new Processor<TargetType>() { @Override public boolean process(final TargetType targetType) { for (final MethodsChain chain : searchChains(targetType, contextRelevantTypes, MAX_SEARCH_RESULT_SIZE, MAX_CHAIN_SIZE, completionContext, methodsUsageIndexReader)) { boolean insert = true; for (final MethodsChain baseChain : searchResult) { final MethodsChain.CompareResult r = MethodsChain.compare(baseChain, chain, completionContext.getPsiManager()); if (r != MethodsChain.CompareResult.NOT_EQUAL) { insert = false; break; } } if (insert) { inheritorFilteredSearchResult.add(chain); } } searchResult.addAll(inheritorFilteredSearchResult); return searchResult.size() < MAX_SEARCH_RESULT_SIZE; } }; DirectClassInheritorsSearch.search(((PsiClassType)target.getPsiType()).resolve()).forEach(new Processor<PsiClass>() { @Override public boolean process(final PsiClass psiClass) { final String inheritorQName = psiClass.getQualifiedName(); if (inheritorQName == null) { return true; } return consumer.process(new TargetType(inheritorQName, false, new PsiImmediateClassType(psiClass, PsiSubstitutor.EMPTY))); } }); } } final List<MethodsChain> chains = searchResult.size() > MAX_CHAIN_SIZE ? chooseHead(searchResult) : searchResult; return MethodsChainLookupRangingHelper .chainsToWeightableLookupElements(filterTailAndGetSumLastMethodOccurrence(chains), completionContext); }
static void processConstructorUsages(final PsiMethod constructor, final SearchScope searchScope, final Processor<PsiReference> consumer, final SearchRequestCollector collector, final boolean includeOverloads) { if (!constructor.isConstructor()) return; final PsiClass clazz = constructor.getContainingClass(); if (clazz == null) return; SearchScope onlyGroovy = GroovyScopeUtil.restrictScopeToGroovyFiles(searchScope, GroovyScopeUtil.getEffectiveScope(constructor)); Set<PsiClass> processed = collector.getSearchSession().getUserData(LITERALLY_CONSTRUCTED_CLASSES); if (processed == null) { collector.getSearchSession().putUserData(LITERALLY_CONSTRUCTED_CLASSES, processed = ContainerUtil.newConcurrentSet()); } if (!processed.add(clazz)) return; if (clazz.isEnum() && clazz instanceof GroovyPsiElement) { for (PsiField field : clazz.getFields()) { if (field instanceof GrEnumConstant) { final PsiReference ref = field.getReference(); if (ref != null && ref.isReferenceTo(constructor)) { if (!consumer.process(ref)) return; } } } } final LiteralConstructorSearcher literalProcessor = new LiteralConstructorSearcher(constructor, consumer, includeOverloads); final Processor<GrNewExpression> newExpressionProcessor = new Processor<GrNewExpression>() { @Override public boolean process(GrNewExpression grNewExpression) { final PsiMethod resolvedConstructor = grNewExpression.resolveMethod(); if (includeOverloads || constructor.getManager().areElementsEquivalent(resolvedConstructor, constructor)) { return consumer.process(grNewExpression.getReferenceElement()); } return true; } }; processGroovyClassUsages(clazz, searchScope, collector, newExpressionProcessor, literalProcessor); //this() if (clazz instanceof GrTypeDefinition) { if (!processConstructors(constructor, consumer, clazz, true)) { return; } } //super() DirectClassInheritorsSearch.search(clazz, onlyGroovy).forEach(new ReadActionProcessor<PsiClass>() { @Override public boolean processInReadAction(PsiClass inheritor) { if (inheritor instanceof GrTypeDefinition) { if (!processConstructors(constructor, consumer, inheritor, false)) return false; } return true; } }); }
static void processConstructorUsages(final PsiMethod constructor, final SearchScope searchScope, final Processor<PsiReference> consumer, final SearchRequestCollector collector, final boolean searchGppCalls, final boolean includeOverloads) { if (!constructor.isConstructor()) return; final PsiClass clazz = constructor.getContainingClass(); if (clazz == null) return; SearchScope onlyGroovy = GroovyScopeUtil.restrictScopeToGroovyFiles(searchScope, GroovyScopeUtil.getEffectiveScope(constructor)); Set<PsiClass> processed = collector.getSearchSession().getUserData(LITERALLY_CONSTRUCTED_CLASSES); if (processed == null) { collector.getSearchSession().putUserData(LITERALLY_CONSTRUCTED_CLASSES, processed = new ConcurrentHashSet<PsiClass>()); } if (!processed.add(clazz)) return; if (clazz.isEnum() && clazz instanceof GroovyPsiElement) { for (PsiField field : clazz.getFields()) { if (field instanceof GrEnumConstant) { final PsiReference ref = field.getReference(); if (ref != null && ref.isReferenceTo(constructor)) { if (!consumer.process(ref)) return; } } } } final LiteralConstructorSearcher literalProcessor = new LiteralConstructorSearcher(constructor, consumer, includeOverloads); final Processor<GrNewExpression> newExpressionProcessor = new Processor<GrNewExpression>() { @Override public boolean process(GrNewExpression grNewExpression) { final PsiMethod resolvedConstructor = grNewExpression.resolveMethod(); if (includeOverloads || constructor.getManager().areElementsEquivalent(resolvedConstructor, constructor)) { return consumer.process(grNewExpression.getReferenceElement()); } return true; } }; processGroovyClassUsages(clazz, searchScope, collector, searchGppCalls, newExpressionProcessor, literalProcessor); //this() if (clazz instanceof GrTypeDefinition) { if (!processConstructors(constructor, consumer, clazz, true)) { return; } } //super() DirectClassInheritorsSearch.search(clazz, onlyGroovy).forEach(new ReadActionProcessor<PsiClass>() { @Override public boolean processInReadAction(PsiClass inheritor) { if (inheritor instanceof GrTypeDefinition) { if (!processConstructors(constructor, consumer, inheritor, false)) return false; } return true; } }); }
protected List<LineMarkerInfo> collectInheritingClasses(@NotNull PsiClass aClass) { if(aClass.hasModifierProperty(PsiModifier.FINAL)) { return Collections.emptyList(); } if(CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) { return Collections.emptyList(); // It's useless to have overridden markers for object. } PsiClass subClass = DirectClassInheritorsSearch.search(aClass).findFirst(); if(subClass != null || FunctionalExpressionSearch.search(aClass).findFirst() != null) { final Icon icon; if(aClass.isInterface()) { if(!myImplementedOption.isEnabled()) { return Collections.emptyList(); } icon = AllIcons.Gutter.ImplementedMethod; } else { if(!myOverriddenOption.isEnabled()) { return Collections.emptyList(); } icon = AllIcons.Gutter.OverridenMethod; } PsiElement range = aClass.getNameIdentifier(); if(range == null) { range = aClass; } MarkerType type = MarkerType.SUBCLASSED_CLASS; LineMarkerInfo info = new LineMarkerInfo<>(range, range.getTextRange(), icon, Pass.LINE_MARKERS, type.getTooltip(), type.getNavigationHandler(), GutterIconRenderer.Alignment.RIGHT); NavigateAction.setNavigateAction(info, aClass.isInterface() ? "Go to implementation(s)" : "Go to subclass(es)", IdeActions.ACTION_GOTO_IMPLEMENTATION); return Collections.singletonList(info); } return Collections.emptyList(); }
public boolean canInlineElement(PsiElement element) { if (!(element instanceof PsiClass)) return false; if (element.getLanguage() != JavaLanguage.INSTANCE) return false; Collection<PsiClass> inheritors = DirectClassInheritorsSearch.search((PsiClass)element).findAll(); return inheritors.size() > 0; }