diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/KtFakeLightClass.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/KtFakeLightClass.kt index b5a75df1ffb..4f6a99aac03 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/KtFakeLightClass.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/KtFakeLightClass.kt @@ -18,14 +18,19 @@ package org.jetbrains.kotlin.idea.caches.resolve.lightClasses import com.intellij.psi.PsiClass import com.intellij.psi.PsiElementFactory +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiType import com.intellij.psi.impl.light.AbstractLightClass +import com.intellij.psi.impl.light.LightMethod import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.LightClassInheritanceHelper +import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -58,4 +63,28 @@ class KtFakeLightClass(override val kotlinOrigin: KtClassOrObject) : val thisDescriptor = kotlinOrigin.resolveToDescriptorIfAny() as? ClassDescriptor ?: return false return if (checkDeep) DescriptorUtils.isSubclass(thisDescriptor, baseDescriptor) else DescriptorUtils.isDirectSubclass(thisDescriptor, baseDescriptor) } +} + +class KtFakeLightMethod private constructor( + val ktDeclaration: KtNamedDeclaration, + ktClassOrObject : KtClassOrObject +) : LightMethod ( + ktDeclaration.manager, + PsiElementFactory.SERVICE.getInstance(ktDeclaration.project).createMethod(ktDeclaration.name ?: "", PsiType.VOID), + KtFakeLightClass(ktClassOrObject), + KotlinLanguage.INSTANCE +), KtLightElement { + override val kotlinOrigin get() = ktDeclaration + override val clsDelegate get() = myMethod + + override fun getNavigationElement() = ktDeclaration + override fun getIcon(flags: Int) = ktDeclaration.getIcon(flags) + override fun getUseScope() = ktDeclaration.useScope + + companion object { + fun get(ktDeclaration: KtNamedDeclaration): KtFakeLightMethod? { + val ktClassOrObject = ktDeclaration.containingClassOrObject ?: return null + return KtFakeLightMethod(ktDeclaration, ktClassOrObject) + } + } } \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/classInheritorsSearch.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/classInheritorsSearch.kt index 7c90d24b380..8d487d1868e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/classInheritorsSearch.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/classInheritorsSearch.kt @@ -23,12 +23,13 @@ import com.intellij.psi.search.searches.ClassInheritorsSearch import com.intellij.util.EmptyQuery import com.intellij.util.Query import org.jetbrains.kotlin.asJava.toLightClassWithBuiltinMapping +import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.KtFakeLightClass import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.psi.KtClassOrObject fun HierarchySearchRequest<*>.searchInheritors(): Query { val psiClass: PsiClass = when (originalElement) { - is KtClassOrObject -> runReadAction { originalElement.toLightClassWithBuiltinMapping() } + is KtClassOrObject -> runReadAction { originalElement.toLightClassWithBuiltinMapping() ?: KtFakeLightClass(originalElement) } is PsiClass -> originalElement else -> null } ?: return EmptyQuery.getEmptyQuery() diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt index dabe297e59d..31df71b7f5a 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt @@ -29,14 +29,14 @@ import com.intellij.util.EmptyQuery import com.intellij.util.MergeQuery import com.intellij.util.Processor import com.intellij.util.Query -import org.jetbrains.kotlin.asJava.classes.KtLightClass -import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.getRepresentativeLightMethod import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.isOverridable +import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.KtFakeLightClass +import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.KtFakeLightMethod import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor import org.jetbrains.kotlin.idea.core.getDeepestSuperDeclarations @@ -45,10 +45,7 @@ import org.jetbrains.kotlin.idea.search.allScope import org.jetbrains.kotlin.idea.search.excludeKotlinSources import org.jetbrains.kotlin.idea.search.restrictToKotlinSources import org.jetbrains.kotlin.idea.util.application.runReadAction -import org.jetbrains.kotlin.psi.KtCallableDeclaration -import org.jetbrains.kotlin.psi.KtClass -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.types.substitutions.getTypeSubstitutor @@ -122,6 +119,17 @@ object PsiMethodOverridingHierarchyTraverser: HierarchyTraverser { override fun shouldDescend(element: PsiMethod): Boolean = PsiUtil.canBeOverriden(element) } +fun PsiElement.toPossiblyFakeLightMethods(): List { + if (this is PsiMethod) return listOf(this) + + val element = unwrapped ?: return emptyList() + + val lightMethods = element.toLightMethods() + if (lightMethods.isNotEmpty()) return lightMethods + + return if (element is KtNamedDeclaration) listOfNotNull(KtFakeLightMethod.get(element)) else emptyList() +} + private fun forEachKotlinOverride( ktClass: KtClass, members: List, @@ -133,7 +141,7 @@ private fun forEachKotlinOverride( if (baseDescriptors.isEmpty()) return true HierarchySearchRequest(ktClass, scope.restrictToKotlinSources(), true).searchInheritors().forEach { - val inheritor = (it as? KtLightClass)?.kotlinOrigin ?: return@forEach + val inheritor = it.unwrapped as? KtClassOrObject ?: return@forEach val inheritorDescriptor = runReadAction { inheritor.unsafeResolveToDescriptor() as ClassDescriptor } val substitutor = getTypeSubstitutor(baseClassDescriptor.defaultType, inheritorDescriptor.defaultType) ?: return@forEach baseDescriptors.forEach { @@ -149,16 +157,31 @@ private fun forEachKotlinOverride( return true } +fun KtNamedDeclaration.forEachOverridingElement( + scope: SearchScope = runReadAction { useScope }, + processor: (PsiElement) -> Boolean +): Boolean { + val ktClass = runReadAction { containingClassOrObject as? KtClass } ?: return true + + toLightMethods().forEach { + if (!OverridingMethodsSearch.search(it, scope.excludeKotlinSources(), true).all(processor)) return false + } + + return forEachKotlinOverride(ktClass, listOf(this), scope) { _, overrider -> processor(overrider) } +} + fun PsiMethod.forEachOverridingMethod( scope: SearchScope = runReadAction { useScope }, processor: (PsiMethod) -> Boolean ): Boolean { - if (!OverridingMethodsSearch.search(this, scope.excludeKotlinSources(), true).forEach(processor)) return false + if (this !is KtFakeLightMethod) { + if (!OverridingMethodsSearch.search(this, scope.excludeKotlinSources(), true).forEach(processor)) return false + } - val ktMember = (this as? KtLightMethod)?.kotlinOrigin as? KtNamedDeclaration ?: return true + val ktMember = this.unwrapped as? KtNamedDeclaration ?: return true val ktClass = runReadAction { ktMember.containingClassOrObject as? KtClass } ?: return true return forEachKotlinOverride(ktClass, listOf(ktMember), scope) { _, overrider -> - val lightMethods = runReadAction { overrider.toLightMethods() } + val lightMethods = runReadAction { overrider.toPossiblyFakeLightMethods() } lightMethods.all { processor(it) } } } @@ -174,9 +197,11 @@ fun PsiMethod.forEachImplementation( fun PsiClass.forEachDeclaredMemberOverride(processor: (superMember: PsiElement, overridingMember: PsiElement) -> Boolean) { val scope = runReadAction { useScope } - AllOverridingMethodsSearch.search(this, scope.excludeKotlinSources()).all { processor(it.first, it.second) } + if (this !is KtFakeLightClass) { + AllOverridingMethodsSearch.search(this, scope.excludeKotlinSources()).all { processor(it.first, it.second) } + } - val ktClass = (this as? KtLightClass)?.kotlinOrigin as? KtClass ?: return + val ktClass = unwrapped as? KtClass ?: return val members = ktClass.declarations.filterIsInstance() + ktClass.primaryConstructorParameters.filter { it.hasValOrVar() } forEachKotlinOverride(ktClass, members, scope, processor) diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/JavaPsiUtils.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/JavaPsiUtils.kt index ba4f76a52d3..b4e514a1b69 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/JavaPsiUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/JavaPsiUtils.kt @@ -21,13 +21,11 @@ import com.intellij.psi.CommonClassNames import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiMethod -import org.jetbrains.kotlin.asJava.LightClassUtil -import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.asJava.* import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.KtFakeLightClass -import org.jetbrains.kotlin.psi.KtClass -import org.jetbrains.kotlin.psi.KtFunction -import org.jetbrains.kotlin.psi.KtNamedFunction -import org.jetbrains.kotlin.psi.KtSecondaryConstructor +import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.KtFakeLightMethod +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import java.util.* fun collectContainingClasses(methods: Collection): Set { @@ -58,7 +56,8 @@ internal fun getPsiMethod(element: PsiElement?): PsiMethod? { return when { element == null -> null element is PsiMethod -> element - parent is KtNamedFunction || parent is KtSecondaryConstructor -> LightClassUtil.getLightClassMethod(parent as KtFunction) + parent is KtNamedFunction || parent is KtSecondaryConstructor -> + LightClassUtil.getLightClassMethod(parent as KtFunction) ?: KtFakeLightMethod.get(parent) else -> null } } diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt index 27739366102..4645b21afa6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt @@ -34,7 +34,6 @@ import com.intellij.psi.PsiMethod import com.intellij.psi.PsiNameIdentifierOwner import com.intellij.psi.search.searches.ClassInheritorsSearch import org.jetbrains.kotlin.asJava.LightClassUtil -import org.jetbrains.kotlin.asJava.getAccessorLightMethods import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.MemberDescriptor @@ -42,11 +41,13 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.idea.KotlinIcons import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.KtFakeLightClass +import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.KtFakeLightMethod import org.jetbrains.kotlin.idea.core.isInheritable import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.facet.implementedDescriptor import org.jetbrains.kotlin.idea.facet.implementingDescriptors +import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* @@ -271,10 +272,7 @@ private fun collectOverriddenPropertyAccessors(properties: Collection() for (property in properties) { if (property.isOverridable()) { - val accessorsPsiMethods = property.getAccessorLightMethods() - for (psiMethod in accessorsPsiMethods) { - mappingToJava.put(psiMethod, property) - } + property.toPossiblyFakeLightMethods().forEach { mappingToJava.put(it, property) } mappingToJava[property] = property } } @@ -352,7 +350,7 @@ private fun collectOverriddenFunctions(functions: Collection, r val mappingToJava = HashMap() for (function in functions) { if (function.isOverridable()) { - val method = LightClassUtil.getLightClassMethod(function) + val method = LightClassUtil.getLightClassMethod(function) ?: KtFakeLightMethod.get(function) if (method != null) { mappingToJava.put(method, function) } diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/OverridenFunctionMarker.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/OverridenFunctionMarker.kt index 2f614b851da..6520bf301a7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/OverridenFunctionMarker.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/OverridenFunctionMarker.kt @@ -24,18 +24,20 @@ import com.intellij.ide.util.PsiElementListCellRenderer import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.DumbService -import com.intellij.psi.* +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiModifier import com.intellij.psi.search.PsiElementProcessor import com.intellij.psi.search.PsiElementProcessorAdapter import com.intellij.psi.search.searches.OverridingMethodsSearch -import com.intellij.psi.util.PsiFormatUtil import com.intellij.util.CommonProcessors import gnu.trove.THashSet import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.elements.isTraitFakeOverride -import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachDeclaredMemberOverride import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod +import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods import org.jetbrains.kotlin.idea.util.application.runReadAction import java.awt.event.MouseEvent import java.util.* @@ -50,7 +52,7 @@ internal fun getOverriddenDeclarations(mappingToJava: MutableMap ProgressManager.checkCanceled() - if (overridingMember.toLightMethods().any { !it.isMethodWithDeclarationInOtherClass() }) { + if (overridingMember.toPossiblyFakeLightMethods().any { !it.isMethodWithDeclarationInOtherClass() }) { val declaration = mappingToJava[superMember] if (declaration != null) { mappingToJava.remove(superMember) @@ -67,7 +69,7 @@ internal fun getOverriddenDeclarations(mappingToJava: MutableMap(5) - OverridingMethodsSearch.search(method, true).forEach(PsiElementProcessorAdapter(processor)) + method.forEachOverridingMethod(processor = PsiElementProcessorAdapter(processor)::process) val isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT) @@ -109,15 +111,7 @@ fun buildNavigateToOverriddenMethodPopup(e: MouseEvent?, element: PsiElement?): var overridingJavaMethods = processor.collection.filter { !it.isMethodWithDeclarationInOtherClass() } if (overridingJavaMethods.isEmpty()) return null - val renderedSignatures = overridingJavaMethods.map { - PsiFormatUtil.formatMethod(it, - PsiSubstitutor.EMPTY, - PsiFormatUtil.SHOW_PARAMETERS + PsiFormatUtil.SHOW_FQ_CLASS_NAMES, - PsiFormatUtil.SHOW_TYPE + PsiFormatUtil.SHOW_FQ_CLASS_NAMES) - } - val showMethodNames = renderedSignatures.distinct().size > 1 - - val renderer = MethodCellRenderer(showMethodNames) + val renderer = MethodCellRenderer(false) overridingJavaMethods = overridingJavaMethods.sortedWith(renderer.comparator) val methodsUpdater = OverridingMethodsUpdater(method, renderer) diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/OverridenPropertyMarker.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/OverridenPropertyMarker.kt index da52b0e108d..771b2dec511 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/OverridenPropertyMarker.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/OverridenPropertyMarker.kt @@ -33,9 +33,10 @@ import com.intellij.psi.search.searches.OverridingMethodsSearch import com.intellij.util.AdapterProcessor import com.intellij.util.CommonProcessors import com.intellij.util.Function -import org.jetbrains.kotlin.asJava.LightClassUtil import org.jetbrains.kotlin.asJava.getAccessorLightMethods import org.jetbrains.kotlin.idea.KotlinBundle +import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod +import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDefinitionsSearcher import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* @@ -50,9 +51,9 @@ fun getOverriddenPropertyTooltip(property: KtNamedDeclaration): String? { Function { method: PsiMethod? -> method?.containingClass } ) - for (method in property.getAccessorLightMethods()) { + for (method in property.toPossiblyFakeLightMethods()) { if (!overriddenInClassesProcessor.isOverflow) { - OverridingMethodsSearch.search(method, true).forEach(consumer) + method.forEachOverridingMethod(processor = consumer::process) } } @@ -85,11 +86,7 @@ fun buildNavigateToPropertyOverriddenDeclarationsPopup(e: MouseEvent?, element: return null } - val psiPropertyMethods = when(propertyOrParameter) { - is KtProperty -> LightClassUtil.getLightClassPropertyMethods(propertyOrParameter) - is KtParameter -> LightClassUtil.getLightClassPropertyMethods(propertyOrParameter) - else -> return null - } + val psiPropertyMethods = propertyOrParameter.toPossiblyFakeLightMethods() val elementProcessor = CommonProcessors.CollectUniquesProcessor() val ktPsiMethodProcessor = Runnable { KotlinDefinitionsSearcher.processPropertyImplementationsMethods( 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 7673577d28c..1c2d6c47ba0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinDefinitionsSearcher.kt +++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinDefinitionsSearcher.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.idea.search.ideaExtensions -import com.intellij.codeInsight.navigation.MethodImplementationsSearch import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiMethod @@ -28,13 +27,14 @@ 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.classes.KtLightClass import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.KtFakeLightClass import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachImplementation +import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod +import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.contains @@ -117,29 +117,21 @@ class KotlinDefinitionsSearcher : QueryExecutor): Boolean { - val psiMethod = runReadAction { LightClassUtil.getLightClassMethod(function) } - return psiMethod?.forEachImplementation(scope, consumer::process) ?: true + return runReadAction { + function.toPossiblyFakeLightMethods().firstOrNull()?.forEachImplementation(scope, consumer::process) ?: true + } } - private fun processPropertyImplementations(parameter: KtParameter, scope: SearchScope, consumer: Processor): Boolean { - val accessorsPsiMethods = runReadAction { LightClassUtil.getLightClassPropertyMethods(parameter) } - - return processPropertyImplementationsMethods(accessorsPsiMethods, scope, consumer) + private fun processPropertyImplementations(declaration: KtNamedDeclaration, scope: SearchScope, consumer: Processor): Boolean { + return runReadAction { + processPropertyImplementationsMethods(declaration.toPossiblyFakeLightMethods(), scope, consumer) + } } - private fun processPropertyImplementations(property: KtProperty, scope: SearchScope, consumer: Processor): Boolean { - val accessorsPsiMethods = 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 + fun processPropertyImplementationsMethods(accessors: Iterable, scope: SearchScope, consumer: Processor): Boolean { + return accessors.all { method -> + method.forEachOverridingMethod(scope) { implementation -> + if (isDelegated(implementation)) return@forEachOverridingMethod true val elementToProcess = runReadAction { val mirrorElement = (implementation as? KtLightMethod)?.kotlinOrigin @@ -150,12 +142,9 @@ class KotlinDefinitionsSearcher : QueryExecutorany() { super.any() } }; - open fun any() {} + open fun any() {} } diff --git a/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassCommonSide/common/common.kt b/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassCommonSide/common/common.kt index b82e20396a9..26251a07f1f 100644 --- a/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassCommonSide/common/common.kt +++ b/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassCommonSide/common/common.kt @@ -1,9 +1,21 @@ package test -open class SimpleParent +open class SimpleParent { + open fun foo(n: Int) {} + open val bar: Int get() = 1 +} -expect open class ExpectedChild : SimpleParent +expect open class ExpectedChild : SimpleParent { + override fun foo(n: Int) + override val bar: Int +} -class ExpectedChildChild : ExpectedChild() +class ExpectedChildChild : ExpectedChild() { + override fun foo(n: Int) {} + override val bar: Int get() = 1 +} -class SimpleChild : SimpleParent() \ No newline at end of file +class SimpleChild : SimpleParent() { + override fun foo(n: Int) {} + override val bar: Int get() = 1 +} \ No newline at end of file diff --git a/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassCommonSide/jvm/jvm.kt b/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassCommonSide/jvm/jvm.kt index e9fc8d3a1bc..e3c8d5ddc99 100644 --- a/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassCommonSide/jvm/jvm.kt +++ b/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassCommonSide/jvm/jvm.kt @@ -2,6 +2,12 @@ package test -actual open class ExpectedChild : SimpleParent() +actual open class ExpectedChild : SimpleParent() { + actual override fun foo(n: Int) {} + actual override val bar: Int get() = 1 +} -class ExpectedChildChildJvm : ExpectedChild() \ No newline at end of file +class ExpectedChildChildJvm : ExpectedChild() { + override fun foo(n: Int) {} + override val bar: Int get() = 1 +} \ No newline at end of file diff --git a/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassPlatformSide/common/common.kt b/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassPlatformSide/common/common.kt index 7a9af35ec48..412c6b1acf8 100644 --- a/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassPlatformSide/common/common.kt +++ b/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassPlatformSide/common/common.kt @@ -2,10 +2,22 @@ package test -open class SimpleParent +open class SimpleParent { + open fun foo(n: Int) {} + open val bar: Int get() = 1 +} -expect open class ExpectedChild : SimpleParent +expect open class ExpectedChild : SimpleParent { + override fun foo(n: Int) + override val bar: Int +} -class ExpectedChildChild : ExpectedChild() +class ExpectedChildChild : ExpectedChild() { + override fun foo(n: Int) {} + override val bar: Int get() = 1 +} -class SimpleChild : SimpleParent() \ No newline at end of file +class SimpleChild : SimpleParent() { + override fun foo(n: Int) {} + override val bar: Int get() = 1 +} \ No newline at end of file diff --git a/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassPlatformSide/jvm/jvm.kt b/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassPlatformSide/jvm/jvm.kt index a6b9eefab4f..490d72915ea 100644 --- a/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassPlatformSide/jvm/jvm.kt +++ b/idea/testData/multiModuleLineMarker/hierarchyWithExpectClassPlatformSide/jvm/jvm.kt @@ -1,5 +1,11 @@ package test -actual open class ExpectedChild : SimpleParent() +actual open class ExpectedChild : SimpleParent() { + actual override fun foo(n: Int) {} + actual override val bar: Int get() = 1 +} -class ExpectedChildChildJvm : ExpectedChild() \ No newline at end of file +class ExpectedChildChildJvm : ExpectedChild() { + override fun foo(n: Int) {} + override val bar: Int get() = 1 +} \ No newline at end of file diff --git a/idea/testData/navigation/implementations/multiModule/expectClassFun/common/common.kt b/idea/testData/navigation/implementations/multiModule/expectClassFun/common/common.kt new file mode 100644 index 00000000000..9827b454613 --- /dev/null +++ b/idea/testData/navigation/implementations/multiModule/expectClassFun/common/common.kt @@ -0,0 +1,20 @@ +package test + +open class SimpleParent { + open fun foo(n: Int) {} +} + +expect open class ExpectedChild : SimpleParent { + override fun foo(n: Int) +} + +class ExpectedChildChild : ExpectedChild() { + override fun foo(n: Int) {} +} + +class SimpleChild : SimpleParent() { + override fun foo(n: Int) {} +} + +// REF: [common] (in test.ExpectedChildChild).foo(Int) +// REF: [jvm] (in test.ExpectedChildChildJvm).foo(Int) \ No newline at end of file diff --git a/idea/testData/navigation/implementations/multiModule/expectClassFun/jvm/jvm.kt b/idea/testData/navigation/implementations/multiModule/expectClassFun/jvm/jvm.kt new file mode 100644 index 00000000000..46c2c33d237 --- /dev/null +++ b/idea/testData/navigation/implementations/multiModule/expectClassFun/jvm/jvm.kt @@ -0,0 +1,9 @@ +package test + +actual open class ExpectedChild : SimpleParent() { + actual override fun foo(n: Int) {} +} + +class ExpectedChildChildJvm : ExpectedChild() { + override fun foo(n: Int) {} +} \ No newline at end of file diff --git a/idea/testData/navigation/implementations/multiModule/expectClassProperty/common/common.kt b/idea/testData/navigation/implementations/multiModule/expectClassProperty/common/common.kt new file mode 100644 index 00000000000..32f740e589b --- /dev/null +++ b/idea/testData/navigation/implementations/multiModule/expectClassProperty/common/common.kt @@ -0,0 +1,20 @@ +package test + +open class SimpleParent { + open val bar: Int get() = 1 +} + +expect open class ExpectedChild : SimpleParent { + override val bar: Int +} + +class ExpectedChildChild : ExpectedChild() { + override val bar: Int get() = 1 +} + +class SimpleChild : SimpleParent() { + override val bar: Int get() = 1 +} + +// REF: [common] (in test.ExpectedChildChild).bar +// REF: [jvm] (in test.ExpectedChildChildJvm).bar \ No newline at end of file diff --git a/idea/testData/navigation/implementations/multiModule/expectClassProperty/jvm/jvm.kt b/idea/testData/navigation/implementations/multiModule/expectClassProperty/jvm/jvm.kt new file mode 100644 index 00000000000..26aaa799bba --- /dev/null +++ b/idea/testData/navigation/implementations/multiModule/expectClassProperty/jvm/jvm.kt @@ -0,0 +1,9 @@ +package test + +actual open class ExpectedChild : SimpleParent() { + actual override val bar: Int get() = 1 +} + +class ExpectedChildChildJvm : ExpectedChild() { + override val bar: Int get() = 1 +} \ No newline at end of file diff --git a/idea/testData/navigation/implementations/multiModule/expectClassSuperclassFun/common/common.kt b/idea/testData/navigation/implementations/multiModule/expectClassSuperclassFun/common/common.kt new file mode 100644 index 00000000000..6c5d4eca256 --- /dev/null +++ b/idea/testData/navigation/implementations/multiModule/expectClassSuperclassFun/common/common.kt @@ -0,0 +1,23 @@ +package test + +open class SimpleParent { + open fun foo(n: Int) {} +} + +expect open class ExpectedChild : SimpleParent { + override fun foo(n: Int) +} + +class ExpectedChildChild : ExpectedChild() { + override fun foo(n: Int) {} +} + +class SimpleChild : SimpleParent() { + override fun foo(n: Int) {} +} + +// REF: [common] (in test.ExpectedChild).foo(Int) +// REF: [common] (in test.ExpectedChildChild).foo(Int) +// REF: [common] (in test.SimpleChild).foo(Int) +// REF: [jvm] (in test.ExpectedChild).foo(Int) +// REF: [jvm] (in test.ExpectedChildChildJvm).foo(Int) \ No newline at end of file diff --git a/idea/testData/navigation/implementations/multiModule/expectClassSuperclassFun/jvm/jvm.kt b/idea/testData/navigation/implementations/multiModule/expectClassSuperclassFun/jvm/jvm.kt new file mode 100644 index 00000000000..46c2c33d237 --- /dev/null +++ b/idea/testData/navigation/implementations/multiModule/expectClassSuperclassFun/jvm/jvm.kt @@ -0,0 +1,9 @@ +package test + +actual open class ExpectedChild : SimpleParent() { + actual override fun foo(n: Int) {} +} + +class ExpectedChildChildJvm : ExpectedChild() { + override fun foo(n: Int) {} +} \ No newline at end of file diff --git a/idea/testData/navigation/implementations/multiModule/expectClassSuperclassProperty/common/common.kt b/idea/testData/navigation/implementations/multiModule/expectClassSuperclassProperty/common/common.kt new file mode 100644 index 00000000000..f7bce1da0eb --- /dev/null +++ b/idea/testData/navigation/implementations/multiModule/expectClassSuperclassProperty/common/common.kt @@ -0,0 +1,23 @@ +package test + +open class SimpleParent { + open val bar: Int get() = 1 +} + +expect open class ExpectedChild : SimpleParent { + override val bar: Int +} + +class ExpectedChildChild : ExpectedChild() { + override val bar: Int get() = 1 +} + +class SimpleChild : SimpleParent() { + override val bar: Int get() = 1 +} + +// REF: [common] (in test.ExpectedChild).bar +// REF: [common] (in test.ExpectedChildChild).bar +// REF: [common] (in test.SimpleChild).bar +// REF: [jvm] (in test.ExpectedChild).bar +// REF: [jvm] (in test.ExpectedChildChildJvm).bar \ No newline at end of file diff --git a/idea/testData/navigation/implementations/multiModule/expectClassSuperclassProperty/jvm/jvm.kt b/idea/testData/navigation/implementations/multiModule/expectClassSuperclassProperty/jvm/jvm.kt new file mode 100644 index 00000000000..26aaa799bba --- /dev/null +++ b/idea/testData/navigation/implementations/multiModule/expectClassSuperclassProperty/jvm/jvm.kt @@ -0,0 +1,9 @@ +package test + +actual open class ExpectedChild : SimpleParent() { + actual override val bar: Int get() = 1 +} + +class ExpectedChildChildJvm : ExpectedChild() { + override val bar: Int get() = 1 +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoImplementationMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoImplementationMultiModuleTest.kt index 47315cc2996..08f1db5304e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoImplementationMultiModuleTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoImplementationMultiModuleTest.kt @@ -72,7 +72,23 @@ class KotlinGotoImplementationMultiModuleTest : AbstractMultiModuleTest() { doMultiPlatformTest("common.kt") } + fun testExpectClassSuperclassFun() { + doMultiPlatformTest("common.kt") + } + + fun testExpectClassSuperclassProperty() { + doMultiPlatformTest("common.kt") + } + fun testExpectClass() { doMultiPlatformTest("common.kt") } + + fun testExpectClassFun() { + doMultiPlatformTest("common.kt") + } + + fun testExpectClassProperty() { + doMultiPlatformTest("common.kt") + } } \ No newline at end of file