diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/JavaEvaluationContextWrapper.kt b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/JavaEvaluationContextWrapper.kt index 9503d66b53c8..4f9fa9418023 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/JavaEvaluationContextWrapper.kt +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/JavaEvaluationContextWrapper.kt @@ -20,7 +20,7 @@ internal class JavaEvaluationContextWrapper : EvaluationContextWrapper { override fun wrapContext(project: Project, context: PsiElement?, additionalElements: List): PsiElement? { if (additionalElements.isEmpty()) return context val elementsByName = additionalElements.groupBy { it.name }.mapValues { (_, v) -> v[0] } - val text = additionalElements.joinToString("\n") { (name, jvmTypeName, _) -> + val text = additionalElements.joinToString("\n") { (name, _, jvmTypeName, _) -> val suitableTypeName = convertTypeName(jvmTypeName) "$suitableTypeName $name;" } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/MarkedObjectAdditionalContextProvider.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/MarkedObjectAdditionalContextProvider.java index ec5e1cc474b7..4032ad8e0486 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/MarkedObjectAdditionalContextProvider.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/MarkedObjectAdditionalContextProvider.java @@ -1,6 +1,9 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.debugger.engine.evaluation; +import com.intellij.debugger.engine.JavaDebugProcess; +import com.intellij.debugger.impl.DebuggerUtilsImpl; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; @@ -11,6 +14,7 @@ import com.intellij.xdebugger.impl.frame.XValueMarkers; import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import com.sun.jdi.ObjectCollectedException; import com.sun.jdi.ObjectReference; +import com.sun.jdi.Type; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -23,9 +27,18 @@ class MarkedObjectAdditionalContextProvider implements AdditionalContextProvider @Override public @NotNull List getAdditionalContextElements(@NotNull Project project, @Nullable PsiElement context) { XDebugSession xSession = XDebuggerManager.getInstance(project).getCurrentSession(); - if (!(xSession instanceof XDebugSessionImpl session)) return Collections.emptyList(); - XValueMarkers xValueMarkers = session.getValueMarkers(); + XValueMarkers xValueMarkers = null; + if (xSession instanceof XDebugSessionImpl session) { + xValueMarkers = session.getValueMarkers(); + } + else if (ApplicationManager.getApplication().isUnitTestMode()) { + JavaDebugProcess javaDebugProcess = XDebuggerManager.getInstance(project) + .getDebugProcesses(JavaDebugProcess.class).stream().findFirst().orElse(null); + if (javaDebugProcess != null) { + xValueMarkers = DebuggerUtilsImpl.getValueMarkers(javaDebugProcess.getDebuggerSession().getProcess()); + } + } if (xValueMarkers == null) return Collections.emptyList(); Map markers = xValueMarkers.getAllMarkers(); if (markers.isEmpty()) return Collections.emptyList(); @@ -43,7 +56,8 @@ class MarkedObjectAdditionalContextProvider implements AdditionalContextProvider } try { labelName += CodeFragmentFactoryContextWrapper.DEBUG_LABEL_SUFFIX; - result.add(new AdditionalContextElement(labelName, objectRef.type().name(), () -> objectRef)); + Type type = objectRef.type(); + result.add(new AdditionalContextElement(labelName, type.signature(), type.name(), () -> objectRef)); } catch (ObjectCollectedException e) { //it.remove(); diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContextWrapper.kt b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContextWrapper.kt index 75878761872d..9a65a41ba1b3 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContextWrapper.kt +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/evaluation/EvaluationContextWrapper.kt @@ -37,4 +37,4 @@ interface AdditionalContextProvider { } @ApiStatus.Internal -data class AdditionalContextElement(val name: String, val jvmTypeName: String, val value: () -> Value) +data class AdditionalContextElement(val name: String, val jvmSignature: String, val jvmTypeName: String, val value: () -> Value) diff --git a/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/K1KotlinCodeFragmentCompiler.kt b/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/K1KotlinCodeFragmentCompiler.kt index d3f2a994ab08..461342d16fbf 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/K1KotlinCodeFragmentCompiler.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/K1KotlinCodeFragmentCompiler.kt @@ -79,7 +79,7 @@ class K1KotlinCodeFragmentCompiler : KotlinCodeFragmentCompiler { val resolutionFacade = getResolutionFacadeForCodeFragment(codeFragment) - DebugLabelPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugLabels() + DebugForeignPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugForeignProperties() val analysisResult = resolutionFacade.analyzeWithAllCompilerChecks(codeFragment) diff --git a/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinK1CodeFragmentFactory.kt b/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinK1CodeFragmentFactory.kt index 87c58ae7e20d..509f3740c926 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinK1CodeFragmentFactory.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinK1CodeFragmentFactory.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.idea.core.syncNonBlockingReadAction import org.jetbrains.kotlin.idea.core.util.CodeFragmentUtils import org.jetbrains.kotlin.idea.debugger.base.util.hopelessAware import org.jetbrains.kotlin.idea.debugger.core.CodeFragmentContextTuner -import org.jetbrains.kotlin.idea.debugger.evaluate.compilation.DebugLabelPropertyDescriptorProvider +import org.jetbrains.kotlin.idea.debugger.evaluate.compilation.DebugForeignPropertyDescriptorProvider import org.jetbrains.kotlin.j2k.OldJ2kPostProcessor import org.jetbrains.kotlin.idea.j2k.convertToKotlin import org.jetbrains.kotlin.idea.j2k.j2kText @@ -45,8 +45,6 @@ class KotlinK1CodeFragmentFactory : CodeFragmentFactory() { val codeFragment = KtBlockCodeFragment(project, "fragment.kt", item.text, initImports(item.imports), contextElement) - supplyDebugInformation(codeFragment, context) - codeFragment.putCopyableUserData(CodeFragmentUtils.RUNTIME_TYPE_EVALUATOR) { expression: KtExpression -> val debuggerContext = DebuggerManagerEx.getInstanceEx(project).context val debuggerSession = debuggerContext.debuggerSession @@ -127,6 +125,8 @@ class KotlinK1CodeFragmentFactory : CodeFragmentFactory() { } } + supplyDebugInformation(codeFragment, context) + return codeFragment } @@ -137,7 +137,7 @@ class KotlinK1CodeFragmentFactory : CodeFragmentFactory() { private fun supplyDebugInformation(codeFragment: KtCodeFragment, context: PsiElement?) { val project = codeFragment.project val debugProcess = DebugContextProvider.getDebuggerContext(project, context)?.debugProcess ?: return - DebugLabelPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugLabels() + DebugForeignPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugForeignProperties() } private fun getFrameInfo(project: Project, contextElement: PsiElement?, debuggerContext: DebuggerContextImpl): FrameInfo? { diff --git a/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameterAnalyzer.kt b/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameterAnalyzer.kt index 9d0334389bd4..284ca94fb9d9 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameterAnalyzer.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameterAnalyzer.kt @@ -146,7 +146,7 @@ class CodeFragmentParameterAnalyzer( } private fun processDescriptor(descriptor: DeclarationDescriptor, expression: KtSimpleNameExpression): SmartCodeFragmentParameter? { - return processDebugLabel(descriptor) + return processForeignProperty(descriptor) ?: processCoroutineContextCall(descriptor) ?: processSimpleNameExpression(descriptor, expression) } @@ -366,14 +366,11 @@ class CodeFragmentParameterAnalyzer( return null } - private fun processDebugLabel(target: DeclarationDescriptor): SmartCodeFragmentParameter? { - val debugLabelPropertyDescriptor = target as? DebugLabelPropertyDescriptor ?: return null - val labelName = debugLabelPropertyDescriptor.labelName - val debugString = debugLabelPropertyDescriptor.name.asString() + private fun processForeignProperty(target: DeclarationDescriptor): SmartCodeFragmentParameter? { + val descriptor = target as? ForeignPropertyDescriptor ?: return null return parameters.getOrPut(target) { - val type = debugLabelPropertyDescriptor.type - SmartCodeFragmentParameter(Dumb(Kind.DEBUG_LABEL, labelName, debugString), type, debugLabelPropertyDescriptor) + SmartCodeFragmentParameter(Dumb(Kind.FOREIGN_VALUE, descriptor.propertyName), descriptor.type, descriptor) } } diff --git a/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/DebugLabelPropertyDescriptorProvider.kt b/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/DebugForeignPropertyDescriptorProvider.kt similarity index 61% rename from plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/DebugLabelPropertyDescriptorProvider.kt rename to plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/DebugForeignPropertyDescriptorProvider.kt index 3bffba64e9bb..a16c7a2ba5f0 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/DebugLabelPropertyDescriptorProvider.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/k1/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/DebugForeignPropertyDescriptorProvider.kt @@ -2,8 +2,8 @@ package org.jetbrains.kotlin.idea.debugger.evaluate.compilation import com.intellij.debugger.engine.DebugProcessImpl +import com.intellij.debugger.engine.evaluation.AdditionalContextProvider import com.intellij.psi.search.GlobalSearchScope -import com.sun.jdi.* import org.jetbrains.kotlin.backend.common.SimpleMemberScope import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns @@ -24,42 +24,40 @@ import org.jetbrains.kotlin.psi.KtCodeFragment import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.Variance -import com.sun.jdi.Type as JdiType -import org.jetbrains.org.objectweb.asm.Type as AsmType +import org.jetbrains.org.objectweb.asm.Type -class DebugLabelPropertyDescriptorProvider(val codeFragment: KtCodeFragment, val debugProcess: DebugProcessImpl) { +class DebugForeignPropertyDescriptorProvider(val codeFragment: KtCodeFragment, val debugProcess: DebugProcessImpl) { - private val moduleDescriptor = DebugLabelModuleDescriptor + private val moduleDescriptor = DebugForeignPropertyModuleDescriptor - fun supplyDebugLabels() { + fun supplyDebugForeignProperties() { val packageFragment = object : PackageFragmentDescriptorImpl(moduleDescriptor, FqName.ROOT) { - val properties = createDebugLabelDescriptors(this) + val properties = createForeignPropertyDescriptors(this) override fun getMemberScope() = SimpleMemberScope(properties) } codeFragment.externalDescriptors = packageFragment.properties } - private fun createDebugLabelDescriptors(containingDeclaration: PackageFragmentDescriptor): List { - val markupMap = MarkupUtils.getMarkupMap(debugProcess) + private fun createForeignPropertyDescriptors(containingDeclaration: PackageFragmentDescriptor): List { + val result = mutableListOf() + val additionalContextElements = AdditionalContextProvider + .getAllAdditionalContextElements(codeFragment.project, codeFragment.context) - val result = ArrayList(markupMap.size) - - nextValue@ for ((value, markup) in markupMap) { - val labelName = markup.text - val kotlinType = value?.type()?.let { convertType(it) } ?: moduleDescriptor.builtIns.nullableAnyType - result += createDebugLabelDescriptor(labelName, kotlinType, containingDeclaration) + for ((name, signature, _, _) in additionalContextElements) { + val kotlinType = convertType(signature) + result += createForeignPropertyDescriptor(name, kotlinType, containingDeclaration) } return result } - private fun createDebugLabelDescriptor( - labelName: String, + private fun createForeignPropertyDescriptor( + name: String, type: KotlinType, containingDeclaration: PackageFragmentDescriptor ): PropertyDescriptor { - val propertyDescriptor = DebugLabelPropertyDescriptor(containingDeclaration, labelName) + val propertyDescriptor = ForeignPropertyDescriptor(containingDeclaration, name) propertyDescriptor.setType(type, emptyList(), null, null, emptyList()) val getterDescriptor = PropertyGetterDescriptorImpl( @@ -79,42 +77,41 @@ class DebugLabelPropertyDescriptorProvider(val codeFragment: KtCodeFragment, val return propertyDescriptor } - private fun convertType(type: JdiType): KotlinType { - val builtIns = moduleDescriptor.builtIns + private fun convertType(signature: String): KotlinType = convertType(Type.getType(signature)) - return when (type) { - is VoidType -> builtIns.unitType - is LongType -> builtIns.longType - is DoubleType -> builtIns.doubleType - is CharType -> builtIns.charType - is FloatType -> builtIns.floatType - is ByteType -> builtIns.byteType - is IntegerType -> builtIns.intType - is BooleanType -> builtIns.booleanType - is ShortType -> builtIns.shortType - is ArrayType -> { - when (val componentType = type.componentType()) { - is VoidType -> builtIns.getArrayType(Variance.INVARIANT, builtIns.unitType) - is LongType -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.LONG) - is DoubleType -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.DOUBLE) - is CharType -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.CHAR) - is FloatType -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.FLOAT) - is ByteType -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.BYTE) - is IntegerType -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.INT) - is BooleanType -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.BOOLEAN) - is ShortType -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.SHORT) - else -> builtIns.getArrayType(Variance.INVARIANT, convertReferenceType(componentType)) + private fun convertType(asmType: Type): KotlinType { + val builtIns = moduleDescriptor.builtIns + return when (asmType.sort) { + Type.VOID -> builtIns.unitType + Type.LONG -> builtIns.longType + Type.DOUBLE -> builtIns.doubleType + Type.CHAR -> builtIns.charType + Type.FLOAT -> builtIns.floatType + Type.BYTE -> builtIns.byteType + Type.INT -> builtIns.intType + Type.BOOLEAN -> builtIns.booleanType + Type.SHORT -> builtIns.shortType + Type.ARRAY -> { + when (asmType.elementType.sort) { + Type.VOID -> builtIns.getArrayType(Variance.INVARIANT, builtIns.unitType) + Type.LONG -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.LONG) + Type.DOUBLE -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.DOUBLE) + Type.CHAR -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.CHAR) + Type.FLOAT -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.FLOAT) + Type.BYTE -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.BYTE) + Type.INT -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.INT) + Type.BOOLEAN -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.BOOLEAN) + Type.SHORT -> builtIns.getPrimitiveArrayKotlinType(PrimitiveType.SHORT) + else -> builtIns.getArrayType(Variance.INVARIANT, convertReferenceType(asmType.elementType)) } } - is ReferenceType -> convertReferenceType(type) + Type.OBJECT -> convertReferenceType(asmType) else -> builtIns.anyType } } - private fun convertReferenceType(type: JdiType): KotlinType { - require(type is ClassType || type is InterfaceType) - - val asmType = AsmType.getType(type.signature()) + private fun convertReferenceType(asmType: Type): KotlinType { + require(asmType.sort == Type.OBJECT) val project = codeFragment.project val classDescriptor = asmType.getClassDescriptor(GlobalSearchScope.allScope(project), mapBuiltIns = false) ?: return moduleDescriptor.builtIns.nullableAnyType @@ -122,8 +119,8 @@ class DebugLabelPropertyDescriptorProvider(val codeFragment: KtCodeFragment, val } } -private object DebugLabelModuleDescriptor : DeclarationDescriptorImpl(Annotations.EMPTY, Name.identifier("DebugLabelExtensions")), - ModuleDescriptor { +private object DebugForeignPropertyModuleDescriptor : DeclarationDescriptorImpl(Annotations.EMPTY, Name.identifier("DebugLabelExtensions")), + ModuleDescriptor { override val builtIns: KotlinBuiltIns get() = DefaultBuiltIns.Instance @@ -143,7 +140,7 @@ private object DebugLabelModuleDescriptor : DeclarationDescriptorImpl(Annotation get() = MemberScope.Empty override val module: ModuleDescriptor - get() = this@DebugLabelModuleDescriptor + get() = this@DebugForeignPropertyModuleDescriptor override val fragments: List get() = emptyList() @@ -178,9 +175,9 @@ private object DebugLabelModuleDescriptor : DeclarationDescriptorImpl(Annotation override fun assertValid() {} } -internal class DebugLabelPropertyDescriptor( +internal class ForeignPropertyDescriptor( containingDeclaration: DeclarationDescriptor, - val labelName: String + val propertyName: String ) : PropertyDescriptorImpl( containingDeclaration, null, @@ -188,7 +185,7 @@ internal class DebugLabelPropertyDescriptor( Modality.FINAL, DescriptorVisibilities.PUBLIC, /*isVar = */false, - Name.identifier(labelName + "_DebugLabel"), + Name.identifier(propertyName), CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, /*lateInit = */false, diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/IdeForeignValueProviderService.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/IdeForeignValueProviderService.kt index 5945ed4b5a98..55d7a421045c 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/IdeForeignValueProviderService.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/IdeForeignValueProviderService.kt @@ -1,9 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.debugger.evaluate -import com.intellij.debugger.engine.evaluation.CodeFragmentFactoryContextWrapper -import com.intellij.debugger.impl.DebuggerUtilsImpl -import com.sun.jdi.Value +import com.intellij.debugger.engine.evaluation.AdditionalContextProvider import org.jetbrains.kotlin.analysis.api.platform.declarations.KotlinForeignValueProviderService import org.jetbrains.kotlin.psi.KtCodeFragment @@ -11,17 +9,7 @@ internal class IdeForeignValueProviderService : KotlinForeignValueProviderServic override fun getForeignValues(codeFragment: KtCodeFragment): Map { val project = codeFragment.project val context = codeFragment.context - val debugProcess = DebugContextProvider.getDebuggerContext(project, context)?.debugProcess ?: return emptyMap() - val valueMarkers = DebuggerUtilsImpl.getValueMarkers(debugProcess)?.allMarkers ?: return emptyMap() - - return buildMap { - for ((value, markup) in valueMarkers) { - if (value is Value) { - val valueName = markup.text + CodeFragmentFactoryContextWrapper.DEBUG_LABEL_SUFFIX - val typeDescriptor = value.type().signature() - put(valueName, typeDescriptor) - } - } - } + val additionalContextElements = AdditionalContextProvider.getAllAdditionalContextElements(project, context) + return additionalContextElements.associate { it.name to it.jvmSignature } } } \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentCompiler.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentCompiler.kt index 82f1065b60af..d11a035e1da2 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentCompiler.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentCompiler.kt @@ -1,7 +1,6 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.debugger.evaluate -import com.intellij.debugger.engine.evaluation.CodeFragmentFactoryContextWrapper import com.intellij.debugger.engine.evaluation.EvaluateException import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil import com.intellij.openapi.components.service @@ -151,9 +150,7 @@ class K2KotlinCodeFragmentCompiler : KotlinCodeFragmentCompiler { CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.CONTEXT_RECEIVER, name, displayText) } is CodeFragmentCapturedValue.ForeignValue -> { - assert(name.endsWith(CodeFragmentFactoryContextWrapper.DEBUG_LABEL_SUFFIX)) - val valueName = name.substringBeforeLast(CodeFragmentFactoryContextWrapper.DEBUG_LABEL_SUFFIX) - CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.DEBUG_LABEL, valueName, name) + CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.FOREIGN_VALUE, name) } is CodeFragmentCapturedValue.BackingField -> CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.FIELD_VAR, name, displayText) diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt index fbb9f9d153c2..b7c5389d913b 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt @@ -328,7 +328,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, private val sourcePositi val args = valueParameters.zip(asmValueParameters) return args.map { (parameter, asmType) -> - val result = variableFinder.find(parameter, asmType) + val result = variableFinder.find(parameter, asmType, codeFragment) if (result == null) { val name = parameter.debugString diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameter.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameter.kt index 135976d5ea52..95513b6d0fff 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameter.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameter.kt @@ -10,7 +10,7 @@ interface CodeFragmentParameter { enum class Kind { ORDINARY, DELEGATED, EXTENSION_RECEIVER, DISPATCH_RECEIVER, CONTEXT_RECEIVER, COROUTINE_CONTEXT, LOCAL_FUNCTION, - FAKE_JAVA_OUTER_CLASS, FIELD_VAR, DEBUG_LABEL + FAKE_JAVA_OUTER_CLASS, FIELD_VAR, FOREIGN_VALUE } data class Dumb( diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/MarkupUtils.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/MarkupUtils.kt deleted file mode 100644 index e93bcffbab96..000000000000 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/MarkupUtils.kt +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.idea.debugger.evaluate.compilation - -import com.intellij.debugger.engine.DebugProcessImpl -import com.intellij.debugger.impl.DebuggerUtilsImpl -import com.intellij.xdebugger.impl.XDebugSessionImpl -import com.intellij.xdebugger.impl.ui.tree.ValueMarkup -import com.sun.jdi.ObjectReference -import com.sun.jdi.Value -import org.jetbrains.kotlin.idea.util.application.isUnitTestMode - -object MarkupUtils { - fun getMarkupMap(debugProcess: DebugProcessImpl) = doGetMarkupMap(debugProcess) ?: emptyMap() - - private fun doGetMarkupMap(debugProcess: DebugProcessImpl): Map? { - if (isUnitTestMode()) { - return DebuggerUtilsImpl.getValueMarkers(debugProcess)?.allMarkers as Map? - } - - val debugSession = debugProcess.session.xDebugSession as? XDebugSessionImpl - - @Suppress("UNCHECKED_CAST") - return debugSession?.valueMarkers?.allMarkers?.filterKeys { it is Value? } as Map? - } -} \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/variables/VariableFinder.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/variables/VariableFinder.kt index 9525270049f9..9c337d1629f3 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/variables/VariableFinder.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/variables/VariableFinder.kt @@ -3,6 +3,7 @@ package org.jetbrains.kotlin.idea.debugger.evaluate.variables import com.intellij.debugger.engine.JavaValue +import com.intellij.debugger.engine.evaluation.AdditionalContextProvider import com.intellij.debugger.engine.evaluation.EvaluationContextImpl import com.intellij.debugger.jdi.LocalVariableProxyImpl import com.intellij.debugger.jdi.StackFrameProxyImpl @@ -30,10 +31,10 @@ import org.jetbrains.kotlin.idea.debugger.core.stackFrame.InlineStackFrameProxyI import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.CoroutineStackFrameProxyImpl import org.jetbrains.kotlin.idea.debugger.evaluate.compilation.CodeFragmentParameter import org.jetbrains.kotlin.idea.debugger.evaluate.compilation.CodeFragmentParameter.Kind -import org.jetbrains.kotlin.idea.debugger.evaluate.compilation.MarkupUtils import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.NameUtils.CONTEXT_RECEIVER_PREFIX import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.psi.KtCodeFragment import kotlin.coroutines.Continuation import com.sun.jdi.Type as JdiType import org.jetbrains.org.objectweb.asm.Type as AsmType @@ -138,7 +139,7 @@ class VariableFinder(val context: ExecutionContext) { } } - fun find(parameter: CodeFragmentParameter, asmType: AsmType): Result? { + fun find(parameter: CodeFragmentParameter, asmType: AsmType, codeFragment: KtCodeFragment): Result? { return when (parameter.kind) { Kind.ORDINARY -> findOrdinary(VariableKind.Ordinary(parameter.name, asmType, isDelegated = false)) Kind.DELEGATED -> findOrdinary(VariableKind.Ordinary(parameter.name, asmType, isDelegated = true)) @@ -149,7 +150,7 @@ class VariableFinder(val context: ExecutionContext) { Kind.DISPATCH_RECEIVER -> findDispatchThis(VariableKind.OuterClassThis(asmType)) Kind.COROUTINE_CONTEXT -> findCoroutineContext() Kind.FIELD_VAR -> findFieldVariable(VariableKind.FieldVar(parameter.name, asmType)) - Kind.DEBUG_LABEL -> findDebugLabel(parameter.name) + Kind.FOREIGN_VALUE -> findForeignValue(parameter.name, codeFragment) } } @@ -289,16 +290,11 @@ class VariableFinder(val context: ExecutionContext) { return null } - private fun findDebugLabel(name: String): Result? { - val markupMap = MarkupUtils.getMarkupMap(context.debugProcess) - - for ((value, markup) in markupMap) { - if (markup.text == name) { - return Result(value) - } - } - - return null + private fun findForeignValue(foreignValueName: String, codeFragment: KtCodeFragment): Result? { + val contextElements = AdditionalContextProvider + .getAllAdditionalContextElements(codeFragment.project, codeFragment.context) + val element = contextElements.firstOrNull { it.name == foreignValueName } ?: return null + return Result(element.value()) } private fun findUnlabeledThis(kind: VariableKind.UnlabeledThis): Result? {