diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/java/JavaDfaAssistProvider.kt b/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/java/JavaDfaAssistProvider.kt index 5680eed3e56a..a5cd40294878 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/java/JavaDfaAssistProvider.kt +++ b/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/java/JavaDfaAssistProvider.kt @@ -25,21 +25,23 @@ private class JavaDfaAssistProvider : DfaAssistProvider { val method = location.method() val methodName = method.name() val methodArgumentsSize = method.argumentTypeNames().size - val context = readAction { DebuggerUtilsEx.getContainingMethod(element) } - if (context is PsiMethod) { - return readAction { - val name = if (context.isConstructor()) "" else context.getName() - name == methodName && context.getParameterList().getParametersCount() == methodArgumentsSize + val isLambda = DebuggerUtilsEx.isLambda(method) + return readAction { + when (val context = DebuggerUtilsEx.getContainingMethod(element)) { + is PsiMethod -> { + val name = if (context.isConstructor()) "" else context.getName() + name == methodName && context.getParameterList().getParametersCount() == methodArgumentsSize + } + is PsiLambdaExpression -> { + isLambda && methodArgumentsSize >= context.getParameterList().getParametersCount() + } + is PsiClassInitializer -> { + val expectedMethod = if (context.hasModifierProperty(PsiModifier.STATIC)) "" else "" + methodName == expectedMethod + } + else -> false } } - if (context is PsiLambdaExpression) { - return DebuggerUtilsEx.isLambda(method) && readAction { methodArgumentsSize >= context.getParameterList().getParametersCount() } - } - if (context is PsiClassInitializer) { - val expectedMethod = readAction { if (context.hasModifierProperty(PsiModifier.STATIC)) "" else "" } - return methodName == expectedMethod - } - return false } override fun getAnchor(element: PsiElement): PsiElement? { @@ -111,8 +113,10 @@ private class JavaDfaAssistProvider : DfaAssistProvider { return captureTraverser.traverse(proxy.thisObject()) } if (psi is PsiLocalVariable || psi is PsiParameter) { - val varName: String = readAction { psi.getName()!! } - val resolveVariable = readAction { PsiResolveHelper.getInstance(psi.getProject()).resolveReferencedVariable(varName, anchor) } + val (varName, resolveVariable) = readAction { + val name = psi.getName()!! + name to PsiResolveHelper.getInstance(psi.getProject()).resolveReferencedVariable(name, anchor) + } if (resolveVariable !== psi) { // Another variable with the same name could be tracked by DFA in different code branch but not visible at current code location return null @@ -137,18 +141,21 @@ private class JavaDfaAssistProvider : DfaAssistProvider { } } } - if (psi is PsiField && readAction { psi.hasModifierProperty(PsiModifier.STATIC) }) { - val psiClass = readAction { psi.getContainingClass() } - if (psiClass != null) { - val name = readAction { psiClass.getQualifiedName() } - if (name != null) { - val type = ContainerUtil.getOnlyItem(proxy.getVirtualMachine().classesByName(name)) - if (type != null && type.isPrepared) { - val field = DebuggerUtils.findField(type, readAction { psi.getName() }) - if (field != null && field.isStatic) { - return wrap(type.getValue(field)) - } - } + val fieldData = readAction { + if (psi !is PsiField) return@readAction null + if (!psi.hasModifierProperty(PsiModifier.STATIC)) return@readAction null + val psiClass = psi.getContainingClass() ?: return@readAction null + val name = psiClass.getQualifiedName() ?: return@readAction null + val fieldName = psi.getName() + name to fieldName + } + if (fieldData != null) { + val (className, fieldName) = fieldData + val type = ContainerUtil.getOnlyItem(proxy.getVirtualMachine().classesByName(className)) + if (type != null && type.isPrepared) { + val field = DebuggerUtils.findField(type, fieldName) + if (field != null && field.isStatic) { + return wrap(type.getValue(field)) } } } @@ -177,18 +184,16 @@ private class JavaDfaAssistProvider : DfaAssistProvider { } is ObjectReference -> { val type = qualifier.referenceType() + val typeName = type.name() for (descriptor in descriptors) { - val element = readAction { descriptor.psiElement } - if (element is PsiField) { - val psiClass = readAction { element.getContainingClass() } - if (psiClass != null && type.name() == readAction { JVMNameUtil.getClassVMName(psiClass) }) { - val field = DebuggerUtils.findField(type, readAction { element.getName() }) - if (field != null) { - map[descriptor] = wrap(qualifier.getValue(field)) - continue - } - } - } + val fieldName = readAction { + val element = descriptor.psiElement as? PsiField ?: return@readAction null + val psiClass = element.getContainingClass() ?: return@readAction null + if (typeName != JVMNameUtil.getClassVMName(psiClass)) return@readAction null + element.getName() + } ?: continue + val field = DebuggerUtils.findField(type, fieldName) ?: continue + map[descriptor] = wrap(qualifier.getValue(field)) } } } diff --git a/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/dfaassist/KotlinDfaAssistProvider.kt b/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/dfaassist/KotlinDfaAssistProvider.kt index ae7425ae83ab..08cc8247fea2 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/dfaassist/KotlinDfaAssistProvider.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/dfaassist/KotlinDfaAssistProvider.kt @@ -93,10 +93,11 @@ private class KotlinDfaAssistProvider : DfaAssistProvider { } } return null - } - else if (descriptor is KtVariableDescriptor) { - val psiVariable = readAction { descriptor.psiElement } - val name = readAction { (psiVariable as KtNamedDeclaration).name } + } else if (descriptor is KtVariableDescriptor) { + val name = readAction { + val psiVariable = descriptor.psiElement as? KtNamedDeclaration ?: return@readAction null + psiVariable.name + } val variable = proxy.visibleVariableByName(name) if (variable != null) { return postprocess(proxy.getVariableValue(variable)) @@ -115,14 +116,12 @@ private class KotlinDfaAssistProvider : DfaAssistProvider { // Avoid relying on hashCode/equals, as descriptors are known to be deduplicated here val map = IdentityHashMap() for (descriptor in descriptors) { - val psiVariable = readAction { descriptor.psiElement } - if (psiVariable is KtCallableDeclaration) { - val name = readAction { psiVariable.name } - val field = name?.let { DebuggerUtils.findField(qualifier.referenceType(), it) } - if (field != null) { - map[descriptor] = postprocess(qualifier.getValue(field)) - } - } + val name = readAction { + val psiVariable = descriptor.psiElement as? KtCallableDeclaration ?: return@readAction null + psiVariable.name + } ?: continue + val field = DebuggerUtils.findField(qualifier.referenceType(), name) ?: continue + map[descriptor] = postprocess(qualifier.getValue(field)) } return map } diff --git a/plugins/kotlin/jvm-debugger/evaluation/k2/src/org/jetbrains/kotlin/idea/k2/debugger/dfaassist/K2DfaAssistProvider.kt b/plugins/kotlin/jvm-debugger/evaluation/k2/src/org/jetbrains/kotlin/idea/k2/debugger/dfaassist/K2DfaAssistProvider.kt index b5fd916bd812..bb1a0a353abf 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/k2/src/org/jetbrains/kotlin/idea/k2/debugger/dfaassist/K2DfaAssistProvider.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/k2/src/org/jetbrains/kotlin/idea/k2/debugger/dfaassist/K2DfaAssistProvider.kt @@ -97,7 +97,11 @@ private class K2DfaAssistProvider : DfaAssistProvider { return value } - private suspend fun getJdiValueForDfaVariableInner(proxy: StackFrameProxyEx, descriptor: VariableDescriptor, anchor: KtElement): Value? { + private suspend fun getJdiValueForDfaVariableInner( + proxy: StackFrameProxyEx, + descriptor: VariableDescriptor, + anchor: KtElement + ): Value? { val variables = (proxy as StackFrameProxyImpl).visibleVariables() val inlineDepth = getInlineDepth(variables) val inlineSuffix = KotlinDebuggerConstants.INLINE_FUN_VAR_SUFFIX.repeat(inlineDepth) @@ -197,11 +201,13 @@ private class K2DfaAssistProvider : DfaAssistProvider { var variable = proxy.visibleVariableByName(result.name) var value: Value? = null if (variable == null) { - val psi = result.psi - val scope = readAction { anchor.getScope() } - if (psi != null && scope != null - && readAction { psi.containingFile == scope.containingFile && !scope.isAncestor(psi) } - ) { + val isValidScope = readAction { + val psi = result.psi ?: return@readAction false + val scope = anchor.getScope() + scope != null && psi.containingFile == scope.containingFile + && !scope.isAncestor(psi) + } + if (isValidScope) { // Captured variable val capturedName = AsmUtil.CAPTURED_PREFIX + result.name variable = proxy.visibleVariableByName(capturedName) @@ -301,6 +307,7 @@ private class K2DfaAssistProvider : DfaAssistProvider { QualifierVariableResult.InlineClassProperty -> { map[descriptor] = if (qualifier is DfaAssistProvider.InlinedValue) qualifier.value else qualifier } + is QualifierVariableResult.NamedVariable -> { val type = (qualifier as? ObjectReference)?.referenceType() if (type != null) { @@ -310,6 +317,7 @@ private class K2DfaAssistProvider : DfaAssistProvider { } } } + else -> {} } }