Skip to content

Commit

Permalink
refactor(javascript): consolidate type resolution logic into JSTypeRe…
Browse files Browse the repository at this point in the history
…solver

Moved type resolution logic from `JSAutoTestingService` and `JSRelevantUtil` into a new `JSTypeResolver` utility class. Added `JavaScriptRelatedClassesProvider` for TypeScript support and updated `JSPsiContextVariableProvider` to use the new resolver. Deleted the now redundant `JSRelevantUtil` file.
  • Loading branch information
phodal committed Dec 27, 2024
1 parent a72fea7 commit bbad1d0
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 103 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
package com.phodal.shirelang.javascript.util
package com.phodal.shirelang.javascript

import com.intellij.lang.javascript.psi.JSFunction
import com.intellij.lang.javascript.psi.ecma6.TypeScriptInterface
import com.intellij.lang.javascript.psi.ecma6.TypeScriptSingleType
import com.intellij.lang.javascript.psi.ecmal4.JSClass
import com.intellij.lang.javascript.psi.util.JSStubBasedPsiTreeUtil
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.diagnostic.logger
import com.intellij.psi.PsiElement
import com.phodal.shirecore.provider.codemodel.model.ClassStructure
import com.phodal.shirelang.javascript.codemodel.JavaScriptClassStructureProvider

object JSRelevantUtil {
fun lookupRelevantClass(element: PsiElement): List<ClassStructure> {
return ReadAction.compute<List<ClassStructure>, Throwable> {
val elements = mutableListOf<ClassStructure>()
object JSTypeResolver {
fun resolveByElement(element: PsiElement): List<JSClass> =
ReadAction.compute<List<JSClass>, Throwable> {
val elements = mutableListOf<JSClass>()
when (element) {
is JSClass -> {
element.functions.map {
Expand All @@ -31,10 +28,9 @@ object JSRelevantUtil {

return@compute elements
}
}

private fun resolveByFunction(jsFunction: JSFunction): Map<String, ClassStructure> {
val result = mutableMapOf<String, ClassStructure>()
private fun resolveByFunction(jsFunction: JSFunction): Map<String, JSClass> {
val result = mutableMapOf<String, JSClass>()
jsFunction.parameterList?.parameters?.map {
it.typeElement?.let { typeElement ->
result += resolveByType(typeElement, it.typeElement!!.text)
Expand All @@ -51,31 +47,16 @@ object JSRelevantUtil {
private fun resolveByType(
returnType: PsiElement?,
typeName: String,
): MutableMap<String, ClassStructure> {
val result = mutableMapOf<String, ClassStructure>()
): MutableMap<String, JSClass> {
val result = mutableMapOf<String, JSClass>()
when (returnType) {
is TypeScriptSingleType -> {
val resolveReferenceLocally = JSStubBasedPsiTreeUtil.resolveLocally(
typeName,
returnType
)

when (resolveReferenceLocally) {
when (val referenceLocally = JSStubBasedPsiTreeUtil.resolveLocally(typeName, returnType)) {
is TypeScriptInterface -> {
JavaScriptClassStructureProvider().build(resolveReferenceLocally, false)?.let {
result += mapOf(typeName to it)
}
}

else -> {
logger<JSRelevantUtil>().warn("resolveReferenceLocally is not TypeScriptInterface: $resolveReferenceLocally")
result += mapOf(typeName to referenceLocally)
}
}
}

else -> {
logger<JSRelevantUtil>().warn("returnType is not TypeScriptSingleType: $returnType")
}
}

return result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ package com.phodal.shirelang.javascript.codeedit
import com.intellij.execution.configurations.RunProfile
import com.intellij.lang.javascript.buildTools.npm.rc.NpmRunConfiguration
import com.intellij.lang.javascript.psi.JSFile
import com.intellij.lang.javascript.psi.JSFunction
import com.intellij.lang.javascript.psi.ecma6.TypeScriptInterface
import com.intellij.lang.javascript.psi.ecma6.TypeScriptSingleType
import com.intellij.lang.javascript.psi.ecmal4.JSClass
import com.intellij.lang.javascript.psi.ecmal4.JSImportStatement
import com.intellij.lang.javascript.psi.util.JSStubBasedPsiTreeUtil
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.command.WriteCommandAction
Expand All @@ -21,9 +16,10 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.psi.util.PsiTreeUtil
import com.phodal.shirecore.provider.codemodel.model.ClassStructure
import com.phodal.shirecore.provider.TestingService
import com.phodal.shirecore.provider.codemodel.model.ClassStructure
import com.phodal.shirecore.variable.toolchain.unittest.AutoTestingPromptContext
import com.phodal.shirelang.javascript.JSTypeResolver
import com.phodal.shirelang.javascript.codemodel.JavaScriptClassStructureProvider
import com.phodal.shirelang.javascript.codemodel.JavaScriptMethodStructureProvider
import com.phodal.shirelang.javascript.util.JSPsiUtil
Expand Down Expand Up @@ -103,71 +99,8 @@ class JSAutoTestingService : TestingService() {
}

override fun lookupRelevantClass(project: Project, element: PsiElement): List<ClassStructure> {
return ReadAction.compute<List<ClassStructure>, Throwable> {
val elements = mutableListOf<ClassStructure>()
when (element) {
is JSClass -> {
element.functions.map {
elements += resolveByFunction(it).values
}
}

is JSFunction -> {
elements += resolveByFunction(element).values
}

else -> {}
}

return@compute elements
return JSTypeResolver.resolveByElement(element).mapNotNull {
JavaScriptClassStructureProvider().build(it, false)
}
}

private fun resolveByFunction(jsFunction: JSFunction): Map<String, ClassStructure> {
val result = mutableMapOf<String, ClassStructure>()
jsFunction.parameterList?.parameters?.map {
it.typeElement?.let { typeElement ->
result += resolveByType(typeElement, it.typeElement!!.text)
}
}

result += jsFunction.returnTypeElement?.let {
resolveByType(it, jsFunction.returnType!!.resolvedTypeText)
} ?: emptyMap()

return result
}

private fun resolveByType(
returnType: PsiElement?,
typeName: String,
): MutableMap<String, ClassStructure> {
val result = mutableMapOf<String, ClassStructure>()
when (returnType) {
is TypeScriptSingleType -> {
val resolveReferenceLocally = JSStubBasedPsiTreeUtil.resolveLocally(
typeName,
returnType
)

when (resolveReferenceLocally) {
is TypeScriptInterface -> {
JavaScriptClassStructureProvider().build(resolveReferenceLocally, false)?.let {
result += mapOf(typeName to it)
}
}

else -> {
log.warn("resolveReferenceLocally is not TypeScriptInterface: $resolveReferenceLocally")
}
}
}

else -> {
log.warn("returnType is not TypeScriptSingleType: $returnType")
}
}

return result
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.phodal.shirelang.javascript.provider

import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.phodal.shirecore.provider.psi.RelatedClassesProvider
import com.phodal.shirelang.javascript.JSTypeResolver

class JavaScriptRelatedClassesProvider : RelatedClassesProvider {
override fun lookup(element: PsiElement): List<PsiElement> {
return JSTypeResolver.resolveByElement(element)
}

override fun lookup(element: PsiFile): List<PsiElement> {
return JSTypeResolver.resolveByElement(element)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import com.phodal.shirecore.psi.CodeSmellCollector
import com.phodal.shirecore.provider.variable.model.PsiContextVariable
import com.phodal.shirecore.provider.variable.model.PsiContextVariable.*
import com.phodal.shirecore.search.similar.SimilarChunksSearch
import com.phodal.shirelang.javascript.JSTypeResolver
import com.phodal.shirelang.javascript.codemodel.JavaScriptClassStructureProvider
import com.phodal.shirelang.javascript.codemodel.JavaScriptMethodStructureProvider
import com.phodal.shirelang.javascript.util.JSPsiUtil
import com.phodal.shirelang.javascript.util.JSRelevantUtil

class JSPsiContextVariableProvider : PsiContextVariableProvider {
override fun resolve(variable: PsiContextVariable, project: Project, editor: Editor, psiElement: PsiElement?): Any {
Expand Down Expand Up @@ -66,7 +66,7 @@ class JSPsiContextVariableProvider : PsiContextVariableProvider {
}
}

RELATED_CLASSES -> JSRelevantUtil.lookupRelevantClass(underTestElement)
RELATED_CLASSES -> JSTypeResolver.resolveByElement(underTestElement)
SIMILAR_TEST_CASE -> ""
IMPORTS -> {
return PsiTreeUtil.findChildrenOfAnyType(sourceFile,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,8 @@
language="JavaScript"
implementationClass="com.phodal.shirelang.javascript.variable.JSPsiContextVariableProvider"/>

<shireRelatedClass language="TypeScript"
implementationClass="com.phodal.shirelang.javascript.provider.JavaScriptRelatedClassesProvider"/>

</extensions>
</idea-plugin>

0 comments on commit bbad1d0

Please sign in to comment.