Skip to content

Commit 7fd9580

Browse files
committed
feat(javascript): add JavaScript type resolver and related class provider #308
Introduce JSTypeResolver utility to resolve JavaScript/TypeScript types and related classes. Add JavaScriptRelatedClassProvider to integrate with the existing class context system. Refactor JSAutoTestService to use the new resolver for cleaner code.
1 parent 93756d3 commit 7fd9580

File tree

5 files changed

+84
-70
lines changed

5 files changed

+84
-70
lines changed

core/src/main/kotlin/cc/unitmesh/devti/context/ClassContextProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import com.intellij.lang.LanguageExtension
77
import com.intellij.openapi.diagnostic.logger
88
import com.intellij.psi.PsiElement
99

10-
class ClassContextProvider(private val gatherUsages: Boolean) : LLMCodeContextProvider<PsiElement> {
10+
class ClassContextProvider(private val gatherUsages: Boolean = false) : LLMCodeContextProvider<PsiElement> {
1111
private val languageExtension = LanguageExtension<ClassContextBuilder>("cc.unitmesh.classContextBuilder")
1212
private val providers: List<ClassContextBuilder>
1313

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package cc.unitmesh.ide.javascript.provider
2+
3+
import cc.unitmesh.devti.provider.RelatedClassesProvider
4+
import cc.unitmesh.ide.javascript.util.JSTypeResolver
5+
import com.intellij.psi.PsiElement
6+
import com.intellij.psi.PsiFile
7+
8+
class JavaScriptRelatedClassProvider : RelatedClassesProvider {
9+
override fun lookupIO(element: PsiElement): List<PsiElement> = JSTypeResolver.resolveByElement(element)
10+
override fun lookupIO(element: PsiFile): List<PsiElement> = JSTypeResolver.resolveByElement(element)
11+
}

javascript/src/main/kotlin/cc/unitmesh/ide/javascript/provider/testing/JSAutoTestService.kt

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
package cc.unitmesh.ide.javascript.provider.testing
22

33
import cc.unitmesh.devti.context.ClassContext
4+
import cc.unitmesh.devti.context.ClassContextProvider
45
import cc.unitmesh.devti.provider.AutoTestService
56
import cc.unitmesh.devti.provider.context.TestFileContext
67
import cc.unitmesh.ide.javascript.context.JavaScriptClassContextBuilder
78
import cc.unitmesh.ide.javascript.context.JavaScriptMethodContextBuilder
89
import cc.unitmesh.ide.javascript.util.JSPsiUtil
10+
import cc.unitmesh.ide.javascript.util.JSTypeResolver
911
import cc.unitmesh.ide.javascript.util.LanguageApplicableUtil
1012
import com.intellij.execution.configurations.RunProfile
1113
import com.intellij.lang.javascript.buildTools.npm.rc.NpmRunConfiguration
1214
import com.intellij.lang.javascript.psi.JSFile
1315
import com.intellij.lang.javascript.psi.JSFunction
1416
import com.intellij.lang.javascript.psi.JSVarStatement
15-
import com.intellij.lang.javascript.psi.ecma6.TypeScriptInterface
16-
import com.intellij.lang.javascript.psi.ecma6.TypeScriptSingleType
1717
import com.intellij.lang.javascript.psi.ecmal4.JSClass
1818
import com.intellij.lang.javascript.psi.ecmal4.JSImportStatement
19-
import com.intellij.lang.javascript.psi.util.JSStubBasedPsiTreeUtil
2019
import com.intellij.openapi.application.ReadAction
2120
import com.intellij.openapi.application.runReadAction
2221
import com.intellij.openapi.command.WriteCommandAction
@@ -103,72 +102,7 @@ class JSAutoTestService : AutoTestService() {
103102
}
104103

105104
override fun lookupRelevantClass(project: Project, element: PsiElement): List<ClassContext> {
106-
return ReadAction.compute<List<ClassContext>, Throwable> {
107-
val elements = mutableListOf<ClassContext>()
108-
when (element) {
109-
is JSClass -> {
110-
element.functions.map {
111-
elements += resolveByFunction(it).values
112-
}
113-
}
114-
115-
is JSFunction -> {
116-
elements += resolveByFunction(element).values
117-
}
118-
119-
else -> {}
120-
}
121-
122-
return@compute elements
123-
}
124-
}
125-
126-
private fun resolveByFunction(jsFunction: JSFunction): Map<String, ClassContext> {
127-
val result = mutableMapOf<String, ClassContext>()
128-
jsFunction.parameterList?.parameters?.map {
129-
it.typeElement?.let { typeElement ->
130-
result += resolveByType(typeElement, it.typeElement!!.text)
131-
}
132-
}
133-
134-
result += jsFunction.returnTypeElement?.let {
135-
resolveByType(it, jsFunction.returnType!!.resolvedTypeText)
136-
} ?: emptyMap()
137-
138-
return result
139-
}
140-
141-
private fun resolveByType(
142-
returnType: PsiElement?,
143-
typeName: String
144-
): MutableMap<String, ClassContext> {
145-
val result = mutableMapOf<String, ClassContext>()
146-
when (returnType) {
147-
is TypeScriptSingleType -> {
148-
val resolveReferenceLocally = JSStubBasedPsiTreeUtil.resolveLocally(
149-
typeName,
150-
returnType
151-
)
152-
153-
when (resolveReferenceLocally) {
154-
is TypeScriptInterface -> {
155-
JavaScriptClassContextBuilder().getClassContext(resolveReferenceLocally, false)?.let {
156-
result += mapOf(typeName to it)
157-
}
158-
}
159-
160-
else -> {
161-
log.warn("resolveReferenceLocally is not TypeScriptInterface: $resolveReferenceLocally")
162-
}
163-
}
164-
}
165-
166-
else -> {
167-
log.warn("returnType is not TypeScriptSingleType: $returnType")
168-
}
169-
}
170-
171-
return result
105+
return JSTypeResolver.resolveByElement(element).map(ClassContextProvider(false)::from)
172106
}
173107

174108
object Util {
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package cc.unitmesh.ide.javascript.util
2+
3+
import com.intellij.lang.javascript.psi.JSFunction
4+
import com.intellij.lang.javascript.psi.ecma6.TypeScriptInterface
5+
import com.intellij.lang.javascript.psi.ecma6.TypeScriptSingleType
6+
import com.intellij.lang.javascript.psi.ecmal4.JSClass
7+
import com.intellij.lang.javascript.psi.util.JSStubBasedPsiTreeUtil
8+
import com.intellij.openapi.application.ReadAction
9+
import com.intellij.psi.PsiElement
10+
11+
object JSTypeResolver {
12+
fun resolveByElement(element: PsiElement): List<JSClass> =
13+
ReadAction.compute<List<JSClass>, Throwable> {
14+
val elements = mutableListOf<JSClass>()
15+
when (element) {
16+
is JSClass -> {
17+
element.functions.map {
18+
elements += resolveByFunction(it).values
19+
}
20+
}
21+
22+
is JSFunction -> {
23+
elements += resolveByFunction(element).values
24+
}
25+
26+
else -> {}
27+
}
28+
29+
return@compute elements
30+
}
31+
32+
private fun resolveByFunction(jsFunction: JSFunction): Map<String, JSClass> {
33+
val result = mutableMapOf<String, JSClass>()
34+
jsFunction.parameterList?.parameters?.map {
35+
it.typeElement?.let { typeElement ->
36+
result += resolveByType(typeElement, it.typeElement!!.text)
37+
}
38+
}
39+
40+
result += jsFunction.returnTypeElement?.let {
41+
resolveByType(it, jsFunction.returnType!!.resolvedTypeText)
42+
} ?: emptyMap()
43+
44+
return result
45+
}
46+
47+
private fun resolveByType(
48+
returnType: PsiElement?,
49+
typeName: String,
50+
): MutableMap<String, JSClass> {
51+
val result = mutableMapOf<String, JSClass>()
52+
when (returnType) {
53+
is TypeScriptSingleType -> {
54+
when (val referenceLocally = JSStubBasedPsiTreeUtil.resolveLocally(typeName, returnType)) {
55+
is TypeScriptInterface -> {
56+
result += mapOf(typeName to referenceLocally)
57+
}
58+
}
59+
}
60+
}
61+
62+
return result
63+
}
64+
}

javascript/src/main/resources/cc.unitmesh.javascript.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,10 @@
4747

4848
<componentProvider implementation="cc.unitmesh.ide.javascript.bridge.ReactComponentViewProvider"/>
4949
<toolchainFunctionProvider implementation="cc.unitmesh.ide.javascript.bridge.StylingViewFunctionProvider"/>
50+
51+
<relatedClassProvider language="JavaScript"
52+
implementationClass="cc.unitmesh.ide.javascript.provider.JavaScriptRelatedClassProvider"/>
53+
<relatedClassProvider language="TypeScript"
54+
implementationClass="cc.unitmesh.ide.javascript.provider.JavaScriptRelatedClassProvider"/>
5055
</extensions>
5156
</idea-plugin>

0 commit comments

Comments
 (0)