diff --git a/annotations/com/intellij/psi/search/searches/annotations.xml b/annotations/com/intellij/psi/search/searches/annotations.xml index dd6f34beb19..5f62b69d8aa 100644 --- a/annotations/com/intellij/psi/search/searches/annotations.xml +++ b/annotations/com/intellij/psi/search/searches/annotations.xml @@ -1,4 +1,8 @@ + + + diff --git a/idea/src/org/jetbrains/jet/plugin/findUsages/handlers/KotlinFindClassUsagesHandler.kt b/idea/src/org/jetbrains/jet/plugin/findUsages/handlers/KotlinFindClassUsagesHandler.kt index 7e7126bcc27..b9410107584 100644 --- a/idea/src/org/jetbrains/jet/plugin/findUsages/handlers/KotlinFindClassUsagesHandler.kt +++ b/idea/src/org/jetbrains/jet/plugin/findUsages/handlers/KotlinFindClassUsagesHandler.kt @@ -35,12 +35,10 @@ import org.jetbrains.jet.plugin.findUsages.KotlinClassFindUsagesOptions import org.jetbrains.jet.plugin.findUsages.KotlinFindUsagesHandlerFactory import org.jetbrains.jet.plugin.findUsages.dialogs.KotlinFindClassUsagesDialog import org.jetbrains.jet.plugin.search.declarationsSearch.HierarchySearchRequest -import org.jetbrains.jet.plugin.search.declarationsSearch.KotlinClassInheritorsSearch import org.jetbrains.jet.plugin.search.usagesSearch.UsagesSearch import org.jetbrains.jet.plugin.search.usagesSearch.UsagesSearchRequest import org.jetbrains.jet.plugin.search.usagesSearch.UsagesSearchTarget import org.jetbrains.jet.plugin.search.declarationsSearch.searchInheritors -import org.jetbrains.jet.plugin.search.declarationsSearch.isTraitOrInterface import org.jetbrains.jet.plugin.findUsages.toSearchTarget import org.jetbrains.jet.plugin.findUsages.toClassHelper import org.jetbrains.jet.plugin.findUsages.toClassDeclarationsHelper @@ -66,13 +64,13 @@ public class KotlinFindClassUsagesHandler( fun processInheritors(): Boolean { val request = HierarchySearchRequest(element, options.searchScope!!, options.isCheckDeepInheritance) return request.searchInheritors().forEach( - PsiElementProcessorAdapter( - object : PsiElementProcessor { - public override fun execute(element: PsiElement): Boolean { - val traitOrInterface = element.isTraitOrInterface() + PsiElementProcessorAdapter( + object : PsiElementProcessor { + public override fun execute(element: PsiClass): Boolean { + val traitOrInterface = element.isInterface() return when { traitOrInterface && options.isDerivedInterfaces, !traitOrInterface && options.isDerivedClasses -> - KotlinFindUsagesHandler.processUsage(processor, element) + KotlinFindUsagesHandler.processUsage(processor, element.getNavigationElement()) else -> true } } diff --git a/idea/src/org/jetbrains/jet/plugin/search/declarationsSearch/classInheritorsSearch.kt b/idea/src/org/jetbrains/jet/plugin/search/declarationsSearch/classInheritorsSearch.kt index b664ae04b94..6ac6782fd27 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/declarationsSearch/classInheritorsSearch.kt +++ b/idea/src/org/jetbrains/jet/plugin/search/declarationsSearch/classInheritorsSearch.kt @@ -16,108 +16,33 @@ package org.jetbrains.jet.plugin.search.declarationsSearch -import com.intellij.psi.search.SearchScope import com.intellij.psi.PsiClass import com.intellij.util.Query -import com.intellij.util.Processor import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.PsiModifier import com.intellij.psi.PsiAnonymousClass import org.jetbrains.jet.lang.psi.JetClassOrObject -import org.jetbrains.jet.lang.psi.JetClass -import org.jetbrains.jet.lang.psi.JetPsiUtil -import org.jetbrains.jet.plugin.stubindex.JetSuperClassIndex import org.jetbrains.jet.asJava.LightClassUtil -import org.jetbrains.jet.plugin.search.usagesSearch.* -import org.jetbrains.jet.lang.resolve.DescriptorUtils -import org.jetbrains.jet.lang.descriptors.ClassDescriptor -import org.jetbrains.jet.lang.psi.psiUtil.contains import com.intellij.psi.search.searches.DirectClassInheritorsSearch -import org.jetbrains.jet.lang.psi.psiUtil.isInheritable -import com.intellij.psi.PsiNamedElement -import org.jetbrains.jet.asJava.KotlinLightClass -import com.intellij.psi.CommonClassNames -import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns -import com.intellij.psi.search.searches.AllClassesSearch import com.intellij.psi.PsiElement -import java.util.HashSet -import java.util.Stack -import com.intellij.openapi.progress.ProgressIndicatorProvider import com.intellij.psi.search.searches.ClassInheritorsSearch +import com.intellij.util.EmptyQuery -fun PsiElement.isTopmostSuperClass(): Boolean = when (this) { - is PsiClass -> getQualifiedName() == CommonClassNames.JAVA_LANG_OBJECT - is JetClass -> descriptor == KotlinBuiltIns.getInstance().getAny() - else -> false -} - -fun PsiElement.isInheritableClass(): Boolean = when (this) { - is PsiClass -> !(this is PsiAnonymousClass || hasModifierProperty(PsiModifier.FINAL)) - is JetClass -> isInheritable() - else -> false -} - -fun PsiElement.isTraitOrInterface(): Boolean = when (this) { - is PsiClass -> isInterface() - is JetClass -> isTrait() - else -> false -} - -public fun HierarchySearchRequest.searchInheritors(): Query = KotlinClassInheritorsSearch.search(this) - -public object KotlinClassInheritorsSearch: DeclarationsSearch>() { - protected override fun doSearch(request: HierarchySearchRequest, consumer: Processor) { - if (request.searchDeeply) { - doSearchAll(request, consumer) - } - else { - doSearchDirect(request, consumer) - } +public fun HierarchySearchRequest.searchInheritors(): Query { + val psiClass: PsiClass? = when (originalElement) { + is JetClassOrObject -> LightClassUtil.getPsiClass(originalElement) + is PsiClass -> originalElement + else -> null } + if (psiClass == null) return EmptyQuery.getEmptyQuery() - protected override fun isApplicable(request: HierarchySearchRequest): Boolean = - request.originalElement.isInheritableClass() - - private fun doSearchDirect(request: HierarchySearchRequest, consumer: Processor) { - fun searchByPsiClass(psiClass: PsiClass) { - DirectClassInheritorsSearch.search( - aClass = psiClass, - scope = request.searchScope, - checkInheritance = false, - includeAnonymous = true - ).iterator() - .map { inheritor -> inheritor.getNavigationElement() } - .all { currentWrapper -> consumer.process(currentWrapper) } - } - - val originalElement = request.originalElement.getNavigationElement() - - when (originalElement) { - is PsiClass -> - searchByPsiClass(originalElement) - - is JetClassOrObject -> - LightClassUtil.getPsiClass(originalElement)?.let { psiClass -> searchByPsiClass(psiClass) } - } - } - - private fun doSearchAll(request: HierarchySearchRequest, consumer: Processor) { - if (request.originalElement.isTopmostSuperClass()) { - AllClassesSearch.search(request.searchScope, request.project).all { psiClass -> consumer.process(psiClass) } - } - else { - consumer.consumeHierarchy(request, ClassHierarchyTraverser) - } - } + return ClassInheritorsSearch.search( + aClass = psiClass, + scope = searchScope, + checkDeep = searchDeeply, + checkInheritance = true, + includeAnonymous = true + ) } -object ClassHierarchyTraverser : HierarchyTraverser() { - override fun nextElements(current: PsiElement): Iterable = - HierarchySearchRequest( - originalElement = current, - searchScope = GlobalSearchScope.allScope(current.getProject()), - searchDeeply = false - ).searchInheritors() - - override fun shouldDescend(element: PsiElement): Boolean = element.isInheritableClass() -} \ No newline at end of file +fun PsiClass.isInheritable(): Boolean = !(this is PsiAnonymousClass || hasModifierProperty(PsiModifier.FINAL)) \ No newline at end of file