[debugger] IDEA-357571 Reuse Java mark object provider in Kotlin

Merge-request: IJ-MR-143713
Merged-by: Maksim Zuev <Maksim.Zuev@jetbrains.com>

GitOrigin-RevId: 8e12de6d84f602f430f85ff8e3dc322464a81024
This commit is contained in:
Maksim Zuev
2024-09-09 16:52:33 +00:00
committed by intellij-monorepo-bot
parent 87e11dc6e4
commit bac29e8431
13 changed files with 93 additions and 129 deletions

View File

@@ -20,7 +20,7 @@ internal class JavaEvaluationContextWrapper : EvaluationContextWrapper {
override fun wrapContext(project: Project, context: PsiElement?, additionalElements: List<AdditionalContextElement>): 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;"
}

View File

@@ -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<AdditionalContextElement> 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<?, ValueMarkup> 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();

View File

@@ -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)

View File

@@ -79,7 +79,7 @@ class K1KotlinCodeFragmentCompiler : KotlinCodeFragmentCompiler {
val resolutionFacade = getResolutionFacadeForCodeFragment(codeFragment)
DebugLabelPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugLabels()
DebugForeignPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugForeignProperties()
val analysisResult = resolutionFacade.analyzeWithAllCompilerChecks(codeFragment)

View File

@@ -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? {

View File

@@ -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)
}
}

View File

@@ -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<PropertyDescriptor> {
val markupMap = MarkupUtils.getMarkupMap(debugProcess)
private fun createForeignPropertyDescriptors(containingDeclaration: PackageFragmentDescriptor): List<PropertyDescriptor> {
val result = mutableListOf<PropertyDescriptor>()
val additionalContextElements = AdditionalContextProvider
.getAllAdditionalContextElements(codeFragment.project, codeFragment.context)
val result = ArrayList<PropertyDescriptor>(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<PackageFragmentDescriptor>
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,

View File

@@ -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<String, String> {
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 }
}
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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(

View File

@@ -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<out Value?, ValueMarkup>? {
if (isUnitTestMode()) {
return DebuggerUtilsImpl.getValueMarkers(debugProcess)?.allMarkers as Map<ObjectReference, ValueMarkup>?
}
val debugSession = debugProcess.session.xDebugSession as? XDebugSessionImpl
@Suppress("UNCHECKED_CAST")
return debugSession?.valueMarkers?.allMarkers?.filterKeys { it is Value? } as Map<out Value?, ValueMarkup>?
}
}

View File

@@ -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? {