diff --git a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinDefinitionsSearcher.kt b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinDefinitionsSearcher.kt index 58b3191a116..b33f1064f7a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinDefinitionsSearcher.kt +++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinDefinitionsSearcher.kt @@ -14,166 +14,136 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.search.ideaExtensions; +package org.jetbrains.kotlin.idea.search.ideaExtensions -import com.intellij.codeInsight.navigation.MethodImplementationsSearch; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.util.Computable; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.search.SearchScope; -import com.intellij.psi.search.searches.ClassInheritorsSearch; -import com.intellij.psi.search.searches.DefinitionsScopedSearch; -import com.intellij.util.Processor; -import com.intellij.util.QueryExecutor; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.asJava.LightClassUtil; -import org.jetbrains.kotlin.asJava.elements.KtLightMethod; -import org.jetbrains.kotlin.psi.*; +import com.intellij.codeInsight.navigation.MethodImplementationsSearch +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.util.Computable +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import com.intellij.psi.search.SearchScope +import com.intellij.psi.search.searches.ClassInheritorsSearch +import com.intellij.psi.search.searches.DefinitionsScopedSearch +import com.intellij.util.Processor +import com.intellij.util.QueryExecutor +import com.intellij.util.containers.ContainerUtil +import org.jetbrains.kotlin.asJava.LightClassUtil +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.psi.* -import java.util.ArrayList; -import java.util.List; +import java.util.ArrayList -import static org.jetbrains.kotlin.asJava.LightClassUtilsKt.toLightClass; +import org.jetbrains.kotlin.asJava.toLightClass -public class KotlinDefinitionsSearcher implements QueryExecutor { - @Override - public boolean execute(@NotNull DefinitionsScopedSearch.SearchParameters queryParameters, @NotNull Processor consumer) { - PsiElement element = queryParameters.getElement(); - SearchScope scope = queryParameters.getScope(); - consumer = skipDelegatedMethodsConsumer(consumer); +class KotlinDefinitionsSearcher : QueryExecutor { + override fun execute(queryParameters: DefinitionsScopedSearch.SearchParameters, consumer: Processor): Boolean { + var consumer = consumer + val element = queryParameters.element + val scope = queryParameters.scope + consumer = skipDelegatedMethodsConsumer(consumer) - if (element instanceof KtClass) { - return processClassImplementations((KtClass) element, consumer); + if (element is KtClass) { + return processClassImplementations(element, consumer) } - if (element instanceof KtNamedFunction || element instanceof KtSecondaryConstructor) { - return processFunctionImplementations((KtFunction) element, scope, consumer); + if (element is KtNamedFunction || element is KtSecondaryConstructor) { + return processFunctionImplementations(element as KtFunction, scope, consumer) } - if (element instanceof KtProperty) { - return processPropertyImplementations((KtProperty) element, scope, consumer); + if (element is KtProperty) { + return processPropertyImplementations(element, scope, consumer) } - if (element instanceof KtParameter) { - KtParameter parameter = (KtParameter) element; + if (element is KtParameter) { - if (isFieldParameter(parameter)) { - return processPropertyImplementations((KtParameter) element, scope, consumer); + if (isFieldParameter(element)) { + return processPropertyImplementations(element, scope, consumer) } } - return true; - } + return true + } - @NotNull - private static Processor skipDelegatedMethodsConsumer(@NotNull final Processor baseConsumer) { - return new Processor() { - @Override - public boolean process(PsiElement element) { + companion object { + + private fun skipDelegatedMethodsConsumer(baseConsumer: Processor): Processor { + return Processor { element -> if (isDelegated(element)) { - return true; - } - return baseConsumer.process(element); - } - }; - } - - private static boolean isDelegated(@NotNull PsiElement element) { - return element instanceof KtLightMethod && ((KtLightMethod) element).isDelegated(); - } - - private static boolean isFieldParameter(final KtParameter parameter) { - return ApplicationManager.getApplication().runReadAction( - new Computable() { - @Override - public Boolean compute() { - return KtPsiUtil.getClassIfParameterIsProperty(parameter) != null; - } - }); - } - - private static boolean processClassImplementations(@NotNull final KtClass klass, Processor consumer) { - PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiClass compute() { - return toLightClass(klass); - } - }); - if (psiClass != null) { - return ContainerUtil.process(ClassInheritorsSearch.search(psiClass, true), consumer); - } - return true; - } - - private static boolean processFunctionImplementations(final KtFunction function, SearchScope scope, Processor consumer) { - PsiMethod psiMethod = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiMethod compute() { - return LightClassUtil.INSTANCE.getLightClassMethod(function); - } - }); - - if (psiMethod != null) { - MethodImplementationsSearch.processImplementations(psiMethod, consumer, scope); - } - - return true; - } - - private static boolean processPropertyImplementations(@NotNull final KtParameter parameter, @NotNull SearchScope scope, @NotNull Processor consumer) { - LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = ApplicationManager.getApplication().runReadAction( - new Computable() { - @Override - public LightClassUtil.PropertyAccessorsPsiMethods compute() { - return LightClassUtil.INSTANCE.getLightClassPropertyMethods(parameter); - } - }); - - return processPropertyImplementationsMethods(accessorsPsiMethods, scope, consumer); - } - - private static boolean processPropertyImplementations(@NotNull final KtProperty property, @NotNull SearchScope scope, @NotNull Processor consumer) { - LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = ApplicationManager.getApplication().runReadAction( - new Computable() { - @Override - public LightClassUtil.PropertyAccessorsPsiMethods compute() { - return LightClassUtil.INSTANCE.getLightClassPropertyMethods(property); - } - }); - - return processPropertyImplementationsMethods(accessorsPsiMethods, scope, consumer); - } - - public static boolean processPropertyImplementationsMethods(LightClassUtil.PropertyAccessorsPsiMethods accessors, @NotNull SearchScope scope, @NotNull Processor consumer) { - for (PsiMethod method : accessors) { - List implementations = new ArrayList(); - MethodImplementationsSearch.getOverridingMethods(method, implementations, scope); - - for (PsiMethod implementation : implementations) { - if (isDelegated(implementation)) continue; - - PsiElement mirrorElement = implementation instanceof KtLightMethod - ? ((KtLightMethod) implementation).getKotlinOrigin() : null; - if (mirrorElement instanceof KtProperty || mirrorElement instanceof KtParameter) { - if (!consumer.process(mirrorElement)) { - return false; - } - } - else if (mirrorElement instanceof KtPropertyAccessor && mirrorElement.getParent() instanceof KtProperty) { - if (!consumer.process(mirrorElement.getParent())) { - return false; - } - } - else { - if (!consumer.process(implementation)) { - return false; - } + return@Processor true } + baseConsumer.process(element) } } - return true; + + private fun isDelegated(element: PsiElement): Boolean { + return element is KtLightMethod && element.isDelegated + } + + private fun isFieldParameter(parameter: KtParameter): Boolean { + return ApplicationManager.getApplication().runReadAction( + Computable { KtPsiUtil.getClassIfParameterIsProperty(parameter) != null }) + } + + private fun processClassImplementations(klass: KtClass, consumer: Processor): Boolean { + val psiClass = ApplicationManager.getApplication().runReadAction(Computable { klass.toLightClass() }) + if (psiClass != null) { + return ContainerUtil.process(ClassInheritorsSearch.search(psiClass, true), consumer) + } + return true + } + + private fun processFunctionImplementations(function: KtFunction, scope: SearchScope, consumer: Processor): Boolean { + val psiMethod = ApplicationManager.getApplication().runReadAction(Computable { LightClassUtil.getLightClassMethod(function) }) + + if (psiMethod != null) { + MethodImplementationsSearch.processImplementations(psiMethod, consumer, scope) + } + + return true + } + + private fun processPropertyImplementations(parameter: KtParameter, scope: SearchScope, consumer: Processor): Boolean { + val accessorsPsiMethods = ApplicationManager.getApplication().runReadAction { LightClassUtil.getLightClassPropertyMethods(parameter) } + + return processPropertyImplementationsMethods(accessorsPsiMethods, scope, consumer) + } + + private fun processPropertyImplementations(property: KtProperty, scope: SearchScope, consumer: Processor): Boolean { + val accessorsPsiMethods = ApplicationManager.getApplication().runReadAction { LightClassUtil.getLightClassPropertyMethods(property) } + + return processPropertyImplementationsMethods(accessorsPsiMethods, scope, consumer) + } + + fun processPropertyImplementationsMethods(accessors: LightClassUtil.PropertyAccessorsPsiMethods, scope: SearchScope, consumer: Processor): Boolean { + for (method in accessors) { + val implementations = ArrayList() + MethodImplementationsSearch.getOverridingMethods(method, implementations, scope) + + for (implementation in implementations) { + if (isDelegated(implementation)) continue + + val mirrorElement = if (implementation is KtLightMethod) + implementation.kotlinOrigin + else + null + if (mirrorElement is KtProperty || mirrorElement is KtParameter) { + if (!consumer.process(mirrorElement)) { + return false + } + } + else if (mirrorElement is KtPropertyAccessor && mirrorElement.parent is KtProperty) { + if (!consumer.process(mirrorElement.parent)) { + return false + } + } + else { + if (!consumer.process(implementation)) { + return false + } + } + } + } + return true + } } }