Skip to content

Commit 70e86e7

Browse files
committed
feat(devti): implement caller lookup functionality #358
- Add lookupCaller function to RelatedClassesProvider interface - Implement caller lookup for Java and Kotlin - Update UsageInsCommand to use lookupCaller instead of lookupCallee - Improve output formatting for UsageInsCommand
1 parent 5eecf11 commit 70e86e7

File tree

4 files changed

+60
-4
lines changed

4 files changed

+60
-4
lines changed

core/src/main/kotlin/cc/unitmesh/devti/provider/RelatedClassesProvider.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ package cc.unitmesh.devti.provider
22

33
import com.intellij.lang.Language
44
import com.intellij.lang.LanguageExtension
5+
import com.intellij.openapi.progress.ProgressManager
6+
import com.intellij.openapi.progress.util.ProgressIndicatorBase
57
import com.intellij.openapi.project.Project
68
import com.intellij.psi.PsiElement
79
import com.intellij.psi.PsiFile
10+
import com.intellij.psi.PsiMethod
811
import com.intellij.psi.PsiNamedElement
12+
import com.intellij.psi.search.searches.MethodReferencesSearch
13+
import com.intellij.psi.util.PsiTreeUtil
914

1015
/**
1116
* The `RelatedClassesProvider` interface is used to provide related classes for a given element.
@@ -33,6 +38,8 @@ interface RelatedClassesProvider {
3338

3439
fun lookupCallee(project: Project, element: PsiElement): List<PsiNamedElement> = emptyList()
3540

41+
fun lookupCaller(project: Project, element: PsiElement): List<PsiNamedElement> = emptyList()
42+
3643
companion object {
3744
private val languageExtension: LanguageExtension<RelatedClassesProvider> =
3845
LanguageExtension("cc.unitmesh.relatedClassProvider")

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/exec/UsageInsCommand.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ class UsageInsCommand(val myProject: Project, private val symbol: String) : InsC
1919
if (elements.isEmpty()) return "$DEVINS_ERROR: No symbol found for $symbol"
2020

2121
val psiElements = elements.mapNotNull {
22-
RelatedClassesProvider.provide(it.language)?.lookupCallee(myProject, it)
22+
RelatedClassesProvider.provide(it.language)?.lookupCaller(myProject, it)
2323
}.flatten()
2424

2525
if (psiElements.isEmpty()) return "$DEVINS_ERROR: No usage found for $symbol"
2626

27-
return psiElements.joinToString("\n") { it.text }
27+
return "Here is related to $symbol usage" + psiElements.joinToString("\n\n") {
28+
runReadAction { it.text }
29+
}
2830
}
2931
}

java/src/main/kotlin/cc/unitmesh/idea/provider/JavaRelatedClassesProvider.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package cc.unitmesh.idea.provider
33
import cc.unitmesh.devti.provider.RelatedClassesProvider
44
import cc.unitmesh.idea.context.JavaContextCollection
55
import cc.unitmesh.idea.service.JavaTypeUtil.resolveByType
6-
import cc.unitmesh.idea.util.JavaCallHelper.findCallees
6+
import cc.unitmesh.idea.util.JavaCallHelper
77
import com.intellij.openapi.application.ApplicationManager
88
import com.intellij.openapi.application.runReadAction
99
import com.intellij.openapi.project.Project
@@ -32,7 +32,17 @@ class JavaRelatedClassesProvider : RelatedClassesProvider {
3232

3333
override fun lookupCallee(project: Project, element: PsiElement): List<PsiNamedElement> {
3434
return when (element) {
35-
is PsiMethod -> runReadAction { findCallees(project, element) }
35+
is PsiMethod -> runReadAction { JavaCallHelper.findCallees(project, element) }
36+
else -> emptyList()
37+
}
38+
}
39+
40+
override fun lookupCaller(
41+
project: Project,
42+
element: PsiElement
43+
): List<PsiNamedElement> {
44+
return when (element) {
45+
is PsiMethod -> runReadAction { JavaCallHelper.findCallers(project, element) }
3646
else -> emptyList()
3747
}
3848
}

kotlin/src/main/kotlin/cc/unitmesh/kotlin/provider/KotlinRelatedClassesProvider.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.intellij.openapi.project.Project
66
import com.intellij.psi.PsiElement
77
import com.intellij.psi.PsiFile
88
import com.intellij.psi.PsiNamedElement
9+
import com.intellij.psi.search.searches.ReferencesSearch
910
import org.jetbrains.kotlin.idea.structuralsearch.visitor.KotlinRecursiveElementWalkingVisitor
1011
import org.jetbrains.kotlin.psi.KtCallExpression
1112
import org.jetbrains.kotlin.psi.KtNamedFunction
@@ -26,6 +27,16 @@ class KotlinRelatedClassProvider : RelatedClassesProvider {
2627
}
2728
}
2829

30+
override fun lookupCaller(
31+
project: Project,
32+
element: PsiElement
33+
): List<PsiNamedElement> {
34+
return when (element) {
35+
is KtNamedFunction -> findCallers(project, element)
36+
else -> emptyList()
37+
}
38+
}
39+
2940
fun findCallees(project: Project, method: KtNamedFunction): List<KtNamedFunction> {
3041
val calledMethods = mutableSetOf<KtNamedFunction>()
3142
method.accept(object : KotlinRecursiveElementWalkingVisitor() {
@@ -39,4 +50,30 @@ class KotlinRelatedClassProvider : RelatedClassesProvider {
3950

4051
return calledMethods.toList()
4152
}
53+
54+
fun findCallers(project: Project, method: KtNamedFunction): List<KtNamedFunction> {
55+
val callers = mutableSetOf<KtNamedFunction>()
56+
val references = ReferencesSearch.search(method).findAll()
57+
58+
for (reference in references) {
59+
val element = reference.element
60+
61+
var parentFunction: KtNamedFunction? = null
62+
var parent = element.parent
63+
64+
while (parent != null) {
65+
if (parent is KtNamedFunction) {
66+
parentFunction = parent
67+
break
68+
}
69+
parent = parent.parent
70+
}
71+
72+
if (parentFunction != null && parentFunction != method) {
73+
callers.add(parentFunction)
74+
}
75+
}
76+
77+
return callers.toList()
78+
}
4279
}

0 commit comments

Comments
 (0)