[debugger dfa] IDEA-373993 Move locationMatches computation to BGT

GitOrigin-RevId: 208f19e5d471a6b077d8debbf5203cc0ceba38ed
This commit is contained in:
Maksim Zuev
2025-06-13 16:50:41 +00:00
committed by intellij-monorepo-bot
parent ad35b8a70b
commit 3f2444f6d9
7 changed files with 45 additions and 30 deletions
@@ -45,7 +45,7 @@ private suspend fun hatch(proxy: StackFrameProxyEx, pointer: SmartPsiElementPoin
} ?: return null
try {
val match = syncReadAction { provider.locationMatches(e, proxy.location()) }
val match = provider.locationMatches(e, proxy.location())
if (!match) return null
}
catch (iea: IllegalArgumentException) {
@@ -8,10 +8,12 @@ import com.intellij.debugger.jdi.StackFrameProxyEx
import com.intellij.lang.LanguageExtension
import com.intellij.psi.PsiElement
import com.sun.jdi.*
import org.jetbrains.annotations.ApiStatus
/**
* Language specific helpers to implement DFAAssist (for JVM languages only)
*/
@ApiStatus.Internal
interface DfaAssistProvider {
/**
* Represents a 'virtual' boxed value which in fact does not exist in the VM memory.
@@ -38,7 +40,7 @@ interface DfaAssistProvider {
* @return true if debugger location likely matches to the editor location;
* false if definitely doesn't match (in this case, DFA Assist will be turned off)
*/
fun locationMatches(element: PsiElement, location: Location): Boolean
suspend fun locationMatches(element: PsiElement, location: Location): Boolean
/**
* @param element psi element the debugger state points at
@@ -15,26 +15,30 @@ import com.intellij.debugger.engine.evaluation.EvaluateException
import com.intellij.debugger.engine.evaluation.expression.CaptureTraverser
import com.intellij.debugger.impl.DebuggerUtilsEx
import com.intellij.debugger.jdi.StackFrameProxyEx
import com.intellij.openapi.application.readAction
import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.containers.ContainerUtil
import com.sun.jdi.*
class JavaDfaAssistProvider : DfaAssistProvider {
override fun locationMatches(element: PsiElement, location: Location): Boolean {
private class JavaDfaAssistProvider : DfaAssistProvider {
override suspend fun locationMatches(element: PsiElement, location: Location): Boolean {
val method = location.method()
val context = DebuggerUtilsEx.getContainingMethod(element)
val methodName = method.name()
val methodArgumentsSize = method.argumentTypeNames().size
val context = readAction { DebuggerUtilsEx.getContainingMethod(element) }
if (context is PsiMethod) {
val name = if (context.isConstructor()) "<init>" else context.getName()
return name == method.name() && context.getParameterList().getParametersCount() == method.argumentTypeNames().size
return readAction {
val name = if (context.isConstructor()) "<init>" else context.getName()
name == methodName && context.getParameterList().getParametersCount() == methodArgumentsSize
}
}
if (context is PsiLambdaExpression) {
return DebuggerUtilsEx.isLambda(method) &&
method.argumentTypeNames().size >= context.getParameterList().getParametersCount()
return DebuggerUtilsEx.isLambda(method) && readAction { methodArgumentsSize >= context.getParameterList().getParametersCount() }
}
if (context is PsiClassInitializer) {
val expectedMethod = if (context.hasModifierProperty(PsiModifier.STATIC)) "<clinit>" else "<init>"
return method.name() == expectedMethod
val expectedMethod = readAction { if (context.hasModifierProperty(PsiModifier.STATIC)) "<clinit>" else "<init>" }
return methodName == expectedMethod
}
return false
}
@@ -5,6 +5,7 @@ import com.intellij.debugger.mockJDI.MockLocalVariable;
import com.intellij.debugger.mockJDI.MockMirror;
import com.intellij.debugger.mockJDI.MockVirtualMachine;
import com.intellij.debugger.mockJDI.types.MockType;
import com.intellij.openapi.application.ReadAction;
import com.intellij.psi.LambdaUtil;
import com.intellij.psi.PsiLambdaExpression;
import com.intellij.psi.PsiMethod;
@@ -41,15 +42,16 @@ public class MockPsiLambda extends MockMirror implements Method {
@Override
public @Unmodifiable List<String> argumentTypeNames() {
// Captured values are not yet supported in mock
return ContainerUtil.map(myPsiLambdaExpression.getParameterList().getParameters(), parameter -> parameter.getType().getCanonicalText());
return ReadAction.compute(() -> ContainerUtil.map(myPsiLambdaExpression.getParameterList().getParameters(),
parameter -> parameter.getType().getCanonicalText()));
}
@Override
public @Unmodifiable List<Type> argumentTypes() {
return ContainerUtil.map(
return ReadAction.compute(() -> ContainerUtil.map(
myPsiLambdaExpression.getParameterList().getParameters(),
parameter -> MockType.createType(myVirtualMachine, parameter.getType())
);
));
}
@Override
@@ -144,7 +146,7 @@ public class MockPsiLambda extends MockMirror implements Method {
@Override
public String name() {
return "lambda$" + myDeclaringMethod.getName() + "$mock";
return "lambda$" + ReadAction.compute(() -> myDeclaringMethod.getName()) + "$mock";
}
@Override
@@ -36,15 +36,16 @@ public class MockPsiMethod extends MockMirror implements Method {
@Override
public @Unmodifiable List<String> argumentTypeNames() {
return ContainerUtil.map(myPsiMethod.getParameterList().getParameters(), parameter -> parameter.getType().getCanonicalText());
return ReadAction.compute(() -> ContainerUtil.map(myPsiMethod.getParameterList().getParameters(),
parameter -> parameter.getType().getCanonicalText()));
}
@Override
public @Unmodifiable List<Type> argumentTypes() {
return ContainerUtil.map(
return ReadAction.compute(() -> ContainerUtil.map(
myPsiMethod.getParameterList().getParameters(),
parameter -> MockType.createType(myVirtualMachine, parameter.getType())
);
));
}
@Override
@@ -139,7 +140,7 @@ public class MockPsiMethod extends MockMirror implements Method {
@Override
public String name() {
return myPsiMethod.getName();
return ReadAction.compute(() -> myPsiMethod.getName());
}
@Override
@@ -13,6 +13,7 @@ import com.intellij.debugger.engine.DebuggerUtils
import com.intellij.debugger.engine.dfaassist.DebuggerDfaListener
import com.intellij.debugger.engine.dfaassist.DfaAssistProvider
import com.intellij.debugger.jdi.StackFrameProxyEx
import com.intellij.openapi.application.readAction
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
@@ -36,13 +37,15 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.org.objectweb.asm.Type as AsmType
class KotlinDfaAssistProvider : DfaAssistProvider {
override fun locationMatches(element: PsiElement, location: Location): Boolean {
private class KotlinDfaAssistProvider : DfaAssistProvider {
override suspend fun locationMatches(element: PsiElement, location: Location): Boolean {
val jdiClassName = location.method().declaringType().name()
val file = element.containingFile
if (file !is KtFile) return false
val classNames = ClassNameCalculator.getClassNames(file)
return element.parentsWithSelf.any { e -> classNames[e] == jdiClassName }
return readAction {
val file = element.containingFile
if (file !is KtFile) return@readAction false
val classNames = ClassNameCalculator.getClassNames(file)
element.parentsWithSelf.any { e -> classNames[e] == jdiClassName }
}
}
override fun getAnchor(element: PsiElement): KtExpression? {
@@ -18,6 +18,7 @@ import com.intellij.debugger.engine.dfaassist.DfaAssistProvider
import com.intellij.debugger.jdi.StackFrameProxyEx
import com.intellij.debugger.jdi.StackFrameProxyImpl
import com.intellij.lang.jvm.types.JvmPrimitiveTypeKind
import com.intellij.openapi.application.readAction
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
@@ -51,12 +52,14 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.org.objectweb.asm.Type as AsmType
private class K2DfaAssistProvider : DfaAssistProvider {
override fun locationMatches(element: PsiElement, location: Location): Boolean {
override suspend fun locationMatches(element: PsiElement, location: Location): Boolean {
val jdiClassName = location.method().declaringType().name()
val file = element.containingFile
if (file !is KtFile) return false
val classNames = ClassNameCalculator.getClassNames(file)
return element.parentsWithSelf.any { e -> classNames[e] == jdiClassName }
return readAction {
val file = element.containingFile
if (file !is KtFile) return@readAction false
val classNames = ClassNameCalculator.getClassNames(file)
element.parentsWithSelf.any { e -> classNames[e] == jdiClassName }
}
}
override fun getAnchor(element: PsiElement): PsiElement? {