Skip to content

fix: should wrap runReadAction when read PsiElment fields #154 #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cc.unitmesh.idea.context

import cc.unitmesh.devti.context.ClassContext
import cc.unitmesh.devti.context.builder.ClassContextBuilder
import com.intellij.openapi.application.runReadAction
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
Expand All @@ -10,9 +11,9 @@ class JavaClassContextBuilder : ClassContextBuilder {
override fun getClassContext(psiElement: PsiElement, gatherUsages: Boolean): ClassContext? {
if (psiElement !is PsiClass) return null

val supers = psiElement.extendsList?.referenceElements?.mapNotNull {
val supers = runReadAction { psiElement.extendsList?.referenceElements?.mapNotNull {
it.text
}
}}

val fields = psiElement.fields.toList()
val methods = psiElement.methods.toList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cc.unitmesh.devti.context.MethodContext
import cc.unitmesh.devti.context.builder.ClassContextBuilder
import cc.unitmesh.devti.context.builder.MethodContextBuilder
import cc.unitmesh.idea.service.JavaTypeUtil
import com.intellij.openapi.application.runReadAction
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiNameIdentifierOwner
Expand All @@ -29,7 +30,7 @@ class JavaMethodContextBuilder : MethodContextBuilder {

val ios: List<PsiElement> = JavaTypeUtil.resolveByMethod(psiElement).values.mapNotNull { it }

return MethodContext(
return runReadAction { MethodContext(
psiElement,
text = psiElement.text,
name = psiElement.name,
Expand All @@ -41,7 +42,7 @@ class JavaMethodContextBuilder : MethodContextBuilder {
includeClassContext,
usagesList,
ios
)
)}
}

private fun processReturnTypeText(returnType: String?): String? {
Expand All @@ -50,8 +51,8 @@ class JavaMethodContextBuilder : MethodContextBuilder {
}

fun getSignatureString(method: PsiMethod): String {
val bodyStart = method.body?.startOffsetInParent ?: method.textLength
val text = method.text
val bodyStart = runReadAction { method.body?.startOffsetInParent ?: method.textLength }
val text = runReadAction { method.text }
val substring = text.substring(0, bodyStart)
val trimmed = substring.replace('\n', ' ').trim()
return trimmed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cc.unitmesh.idea.context
import cc.unitmesh.devti.context.VariableContext
import cc.unitmesh.devti.context.builder.ClassContextBuilder
import cc.unitmesh.devti.context.builder.VariableContextBuilder
import com.intellij.openapi.application.runReadAction
import com.intellij.psi.*

class JavaVariableContextBuilder : VariableContextBuilder {
Expand All @@ -14,13 +15,13 @@ class JavaVariableContextBuilder : VariableContextBuilder {
): VariableContext? {
if (psiElement !is PsiVariable) return null

val containingMethod = psiElement.getContainingMethod()
val containingClass = psiElement.getContainingClass()
val containingMethod = runReadAction {psiElement.getContainingMethod() }
val containingClass = runReadAction { psiElement.getContainingClass()}

val references =
if (gatherUsages) ClassContextBuilder.findUsages(psiElement as PsiNameIdentifierOwner) else emptyList()

return VariableContext(
return runReadAction { VariableContext(
psiElement,
psiElement.text ?: "",
psiElement.name,
Expand All @@ -29,7 +30,7 @@ class JavaVariableContextBuilder : VariableContextBuilder {
references,
withMethodContext,
withClassContext
)
)}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class JavaAutoTestService : AutoTestService() {
if (psiElement is PsiClass) {
currentClass = classContextProvider.from(psiElement)
} else if (psiElement is PsiMethod) {
currentClass = psiElement.containingClass?.let { classContextProvider.from(it) }
currentClass = runReadAction { psiElement.containingClass?.let { classContextProvider.from(it) }}
}

return currentClass?.format();
Expand Down
46 changes: 25 additions & 21 deletions java/src/main/kotlin/cc/unitmesh/idea/service/JavaTypeUtil.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cc.unitmesh.idea.service

import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.psi.*
import com.intellij.psi.impl.source.PsiClassReferenceType
Expand Down Expand Up @@ -45,29 +46,31 @@ object JavaTypeUtil {
*/
fun resolveByMethod(element: PsiElement): Map<String, PsiClass> {
val resolvedClasses = mutableMapOf<String, PsiClass>()
if (element is PsiMethod) {
element.parameterList.parameters.filter {
it.type is PsiClassReferenceType
}.map {
val type = it.type as PsiClassReferenceType
val resolve: PsiClass = type.resolve() ?: return@map null
val typeParametersTypeList: List<PsiType> = getTypeParametersType(type)
runReadAction {
if (element is PsiMethod) {
element.parameterList.parameters.filter {
it.type is PsiClassReferenceType
}.map {
val type = it.type as PsiClassReferenceType
val resolve: PsiClass = type.resolve() ?: return@map null
val typeParametersTypeList: List<PsiType> = getTypeParametersType(type)

val relatedClass = mutableListOf(it.type)
relatedClass.addAll(typeParametersTypeList)
val relatedClass = mutableListOf(it.type)
relatedClass.addAll(typeParametersTypeList)

relatedClass
.filter { isProjectContent((it as PsiClassReferenceType).resolve() ?: return@filter false) }
.forEach { resolvedClasses.putAll(resolveByType(it)) }
relatedClass
.filter { isProjectContent((it as PsiClassReferenceType).resolve() ?: return@filter false) }
.forEach { resolvedClasses.putAll(resolveByType(it)) }

resolvedClasses[it.name] = resolve
}
resolvedClasses[it.name] = resolve
}

val outputType = element.returnTypeElement?.type
resolvedClasses.putAll(resolveByType(outputType))
val outputType = element.returnTypeElement?.type
resolvedClasses.putAll(resolveByType(outputType))
}
}

return resolvedClasses.filter { isProjectContent(it.value) }.toMap()
return runReadAction {resolvedClasses.filter { isProjectContent(it.value) }.toMap()}
}

private fun getTypeParametersType(
Expand All @@ -76,16 +79,17 @@ object JavaTypeUtil {
val result = psiType.resolveGenerics()
val psiClass = result.element;
if (psiClass != null) {
val substitutor = result.substitutor
return psiClass.typeParameters.map {
val substitutor = runReadAction { result.substitutor }
return runReadAction { psiClass.typeParameters.map {
substitutor.substitute(it)
}.filterNotNull()
}.filterNotNull()}
}
return emptyList()
}
}

fun isProjectContent(element: PsiElement): Boolean {
val virtualFile = PsiUtil.getVirtualFile(element)
return virtualFile == null || ProjectFileIndex.getInstance(element.project).isInContent(virtualFile)
val project = runReadAction { element.project }
return virtualFile == null || ProjectFileIndex.getInstance(project).isInContent(virtualFile)
}
3 changes: 2 additions & 1 deletion src/main/kotlin/cc/unitmesh/devti/context/VariableContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cc.unitmesh.devti.context

import cc.unitmesh.devti.context.base.NamedElementContext
import com.google.gson.Gson
import com.intellij.openapi.application.runReadAction
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference

Expand Down Expand Up @@ -33,7 +34,7 @@ class VariableContext(
}
}

fun shortFormat(): String = root.text ?: ""
fun shortFormat(): String = runReadAction { root.text ?: ""}

/**
* Returns a formatted string representation of the method.
Expand Down