Navigation: add actual declarations as implementations (KT-16892)

This commit is contained in:
Mikhail Glukhikh
2018-03-07 16:58:10 +03:00
parent 3530d9b4c7
commit 849f9fc5c1
4 changed files with 28 additions and 8 deletions
@@ -32,6 +32,8 @@ import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightClass import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightClass
import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected
import org.jetbrains.kotlin.idea.highlighter.markers.isExpectedOrExpectedClassMember
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachImplementation import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachImplementation
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod
import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods
@@ -47,8 +49,9 @@ class KotlinDefinitionsSearcher : QueryExecutor<PsiElement, DefinitionsScopedSea
val scope = queryParameters.scope val scope = queryParameters.scope
return when (element) { return when (element) {
is KtClass -> is KtClass -> {
processClassImplementations(element, consumer) processClassImplementations(element, consumer) && processActualDeclarations(element, consumer)
}
is KtLightClass -> { is KtLightClass -> {
val useScope = runReadAction { element.useScope } val useScope = runReadAction { element.useScope }
@@ -58,14 +61,21 @@ class KotlinDefinitionsSearcher : QueryExecutor<PsiElement, DefinitionsScopedSea
true true
} }
is KtNamedFunction, is KtSecondaryConstructor -> is KtNamedFunction, is KtSecondaryConstructor -> {
processFunctionImplementations(element as KtFunction, scope, consumer) processFunctionImplementations(element as KtFunction, scope, consumer) && processActualDeclarations(element, consumer)
}
is KtProperty -> is KtProperty -> {
processPropertyImplementations(element, scope, consumer) processPropertyImplementations(element, scope, consumer) && processActualDeclarations(element, consumer)
}
is KtParameter -> is KtParameter -> {
if (isFieldParameter(element)) processPropertyImplementations(element, scope, consumer) else true if (isFieldParameter(element)) {
processPropertyImplementations(element, scope, consumer) && processActualDeclarations(element, consumer)
} else {
true
}
}
else -> true else -> true
} }
@@ -128,6 +138,13 @@ class KotlinDefinitionsSearcher : QueryExecutor<PsiElement, DefinitionsScopedSea
} }
} }
private fun processActualDeclarations(declaration: KtDeclaration, consumer: Processor<PsiElement>): Boolean {
return runReadAction {
if (!declaration.isExpectedOrExpectedClassMember()) true
else declaration.actualsForExpected().all(consumer::process)
}
}
fun processPropertyImplementationsMethods(accessors: Iterable<PsiMethod>, scope: SearchScope, consumer: Processor<PsiElement>): Boolean { fun processPropertyImplementationsMethods(accessors: Iterable<PsiMethod>, scope: SearchScope, consumer: Processor<PsiElement>): Boolean {
return accessors.all { method -> return accessors.all { method ->
method.forEachOverridingMethod(scope) { implementation -> method.forEachOverridingMethod(scope) { implementation ->
@@ -9,4 +9,5 @@ class ExpectedChildChild : ExpectedChild()
class SimpleChild : SimpleParent() class SimpleChild : SimpleParent()
// REF: [common] (test).ExpectedChildChild // REF: [common] (test).ExpectedChildChild
// REF: [jvm] (test).ExpectedChild
// REF: [jvm] (test).ExpectedChildChildJvm // REF: [jvm] (test).ExpectedChildChildJvm
@@ -17,4 +17,5 @@ class SimpleChild : SimpleParent() {
} }
// REF: [common] (in test.ExpectedChildChild).foo(Int) // REF: [common] (in test.ExpectedChildChild).foo(Int)
// REF: [jvm] (in test.ExpectedChild).foo(Int)
// REF: [jvm] (in test.ExpectedChildChildJvm).foo(Int) // REF: [jvm] (in test.ExpectedChildChildJvm).foo(Int)
@@ -17,4 +17,5 @@ class SimpleChild : SimpleParent() {
} }
// REF: [common] (in test.ExpectedChildChild).bar // REF: [common] (in test.ExpectedChildChild).bar
// REF: [jvm] (in test.ExpectedChild).bar
// REF: [jvm] (in test.ExpectedChildChildJvm).bar // REF: [jvm] (in test.ExpectedChildChildJvm).bar