Skip to content

Commit eacc191

Browse files
committed
feat(javascript): add callee lookup for JS functions #308
Implement `lookupCallee` and `findCallees` methods in `JavaScriptRelatedClassProvider` to find called functions within a JS function. Added corresponding test case in `JavaScriptRelatedClassProviderTest`.
1 parent 7fd9580 commit eacc191

File tree

3 files changed

+74
-1
lines changed

3 files changed

+74
-1
lines changed

javascript/src/main/kotlin/cc/unitmesh/ide/javascript/provider/JavaScriptRelatedClassProvider.kt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,45 @@ package cc.unitmesh.ide.javascript.provider
22

33
import cc.unitmesh.devti.provider.RelatedClassesProvider
44
import cc.unitmesh.ide.javascript.util.JSTypeResolver
5+
import com.intellij.lang.javascript.psi.JSCallExpression
6+
import com.intellij.lang.javascript.psi.JSFunction
7+
import com.intellij.lang.javascript.psi.JSRecursiveWalkingElementVisitor
8+
import com.intellij.openapi.project.Project
59
import com.intellij.psi.PsiElement
610
import com.intellij.psi.PsiFile
711

812
class JavaScriptRelatedClassProvider : RelatedClassesProvider {
913
override fun lookupIO(element: PsiElement): List<PsiElement> = JSTypeResolver.resolveByElement(element)
1014
override fun lookupIO(element: PsiFile): List<PsiElement> = JSTypeResolver.resolveByElement(element)
15+
16+
override fun lookupCallee(
17+
project: Project,
18+
element: PsiElement
19+
): List<PsiElement> {
20+
return when (element) {
21+
is JSFunction -> findCallees(project, element)
22+
else -> emptyList()
23+
}
24+
}
25+
26+
fun findCallees(project: Project, method: JSFunction): List<JSFunction> {
27+
val calledMethods = mutableSetOf<JSFunction>()
28+
method.accept(object : JSRecursiveWalkingElementVisitor() {
29+
override fun visitJSCallExpression(node: JSCallExpression) {
30+
// if (node.isRequireCall) {
31+
// val path = CommonJSUtil.getModulePathIfRequireCall(node)
32+
// if (!path.isNullOrEmpty() && !JSFileReferencesUtil.isRelative(path)) {
33+
// //
34+
// }
35+
// }
36+
val psiRef = node.stubSafeMethodExpression?.reference ?: return
37+
val resolve = psiRef?.resolve() ?: return
38+
if (resolve is JSFunction) {
39+
calledMethods.add(resolve)
40+
}
41+
}
42+
})
43+
44+
return calledMethods.toList()
45+
}
1146
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package cc.unitmesh.ide.javascript.provider
2+
3+
import com.intellij.lang.javascript.psi.JSFunction
4+
import com.intellij.psi.PsiFileFactory
5+
import com.intellij.testFramework.LightPlatformTestCase
6+
import org.intellij.lang.annotations.Language
7+
8+
class JavaScriptRelatedClassProviderTest : LightPlatformTestCase() {
9+
@Language("JavaScript")
10+
val code = """
11+
function bar() {
12+
console.log('bar');
13+
}
14+
15+
function baz() {
16+
console.log('baz');
17+
}
18+
19+
function foo() {
20+
bar();
21+
baz();
22+
}
23+
""".trimIndent()
24+
25+
fun testShouldReturnCorrectCallees() {
26+
// given
27+
val file = PsiFileFactory.getInstance(project).createFileFromText("test.js", code)
28+
val lastFunction = file.children.last()
29+
30+
// when
31+
val provider = JavaScriptRelatedClassProvider()
32+
val result = provider.findCallees(project, lastFunction as JSFunction)
33+
34+
// then
35+
assertEquals(2, result.size)
36+
}
37+
}

javascript/src/test/kotlin/cc/unitmesh/ide/javascript/provider/testing/JSWriteTestServiceTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ import com.intellij.psi.PsiFileFactory
99
import com.intellij.psi.util.PsiTreeUtil
1010
import com.intellij.testFramework.LightPlatformTestCase
1111
import junit.framework.TestCase
12+
import org.intellij.lang.annotations.Language
1213
import java.io.File
1314

1415
class JSWriteTestServiceTest : LightPlatformTestCase() {
1516
fun testShouldReturnNullWhenFilePathEmpty() {
16-
// given
17+
@Language("JavaScript")
1718
val code = """
1819
export class Foo {
1920
constructor() {

0 commit comments

Comments
 (0)