mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-221863 SOE in type inlay hint: fix endless recreation of DFA for single method
GitOrigin-RevId: 3eca8237078e4524bed5593ccd5704ce006f95ba
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7f3c23f58e
commit
fbd7bc8a46
+39
-2
@@ -8,6 +8,8 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.parentOfType
|
||||
import org.jetbrains.plugins.groovy.intentions.style.inference.MethodParameterAugmenter.Companion.VisitState.NOT_VISITED
|
||||
import org.jetbrains.plugins.groovy.intentions.style.inference.MethodParameterAugmenter.Companion.VisitState.VISITED_MANY
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
|
||||
@@ -19,6 +21,9 @@ class MethodParameterAugmenter : TypeAugmenter() {
|
||||
|
||||
const val GROOVY_COLLECT_METHOD_CALLS_FOR_INFERENCE = "groovy.collect.method.calls.for.inference"
|
||||
|
||||
private val methodRegistry: ThreadLocal<MutableMap<GrMethod, VisitState>> =
|
||||
ThreadLocal.withInitial { mutableMapOf<GrMethod, VisitState>() }
|
||||
|
||||
internal fun createInferenceResult(method: GrMethod): InferenceResult? {
|
||||
if (!Registry.`is`(GROOVY_COLLECT_METHOD_CALLS_FOR_INFERENCE, false)) {
|
||||
return null
|
||||
@@ -27,13 +32,45 @@ class MethodParameterAugmenter : TypeAugmenter() {
|
||||
val scope = with(originalMethod.containingFile?.virtualFile) {
|
||||
if (this == null) return null else GlobalSearchScope.fileScope(originalMethod.project, this)
|
||||
}
|
||||
return CachedValuesManager.getCachedValue(method) {
|
||||
val involvedMethods = methodRegistry.get()
|
||||
if (involvedMethods.getOrDefault(method, NOT_VISITED) == VISITED_MANY) {
|
||||
return InferenceResult(method, PsiSubstitutor.EMPTY)
|
||||
}
|
||||
else {
|
||||
involvedMethods[method] = involvedMethods.getOrDefault(method, NOT_VISITED).nextState()
|
||||
try {
|
||||
return computeInferredMethod(method, scope)
|
||||
}
|
||||
finally {
|
||||
involvedMethods[method] = involvedMethods[method]!!.prevState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeInferredMethod(method: GrMethod, scope: GlobalSearchScope): InferenceResult =
|
||||
CachedValuesManager.getCachedValue(method) {
|
||||
val typedMethod = runInferenceProcess(method, scope)
|
||||
val typeParameterSubstitutor = createVirtualToActualSubstitutor(typedMethod, method)
|
||||
CachedValueProvider.Result(InferenceResult(typedMethod, typeParameterSubstitutor), method)
|
||||
}
|
||||
}
|
||||
|
||||
private enum class VisitState {
|
||||
NOT_VISITED {
|
||||
override fun nextState(): VisitState = VISITED_ONCE
|
||||
override fun prevState(): VisitState = NOT_VISITED
|
||||
},
|
||||
VISITED_ONCE {
|
||||
override fun nextState(): VisitState = VISITED_MANY
|
||||
override fun prevState(): VisitState = NOT_VISITED
|
||||
},
|
||||
VISITED_MANY {
|
||||
override fun nextState(): VisitState = VISITED_MANY
|
||||
override fun prevState(): VisitState = VISITED_ONCE
|
||||
};
|
||||
|
||||
abstract fun nextState(): VisitState
|
||||
abstract fun prevState(): VisitState
|
||||
}
|
||||
}
|
||||
|
||||
data class InferenceResult(val virtualMethod: GrMethod?, val typeParameterSubstitutor: PsiSubstitutor)
|
||||
|
||||
Reference in New Issue
Block a user