diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java index ca08d4138bfa..3f4568a3f0fc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -74,6 +74,7 @@ import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.intellij.xdebugger.impl.pinned.items.PinToTopMemberValue; import com.intellij.xdebugger.impl.pinned.items.PinToTopParentValue; import com.intellij.xdebugger.impl.ui.XValueTextProvider; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeEx; import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import com.intellij.xdebugger.impl.ui.visualizedtext.VisualizedTextPopupUtil; import com.sun.jdi.AbsentInformationException; @@ -240,7 +241,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV : DebuggerTreeRenderer.getValueIcon(myValueDescriptor, myParent != null ? myParent.getDescriptor() : null); Icon inlayIcon = myValueDescriptor.getInlayIcon(); - if (inlayIcon != null && node instanceof XValueNodeImpl xValueNode) { + if (node instanceof XValueNodeEx xValueNode) { xValueNode.setInlayIcon(inlayIcon); } XValuePresentation presentation = createPresentation(myValueDescriptor); diff --git a/platform/xdebugger-impl/frontend/src/com/intellij/platform/debugger/impl/frontend/evaluate/quick/FrontendXValue.kt b/platform/xdebugger-impl/frontend/src/com/intellij/platform/debugger/impl/frontend/evaluate/quick/FrontendXValue.kt index a2fc93519de9..805110faa69c 100644 --- a/platform/xdebugger-impl/frontend/src/com/intellij/platform/debugger/impl/frontend/evaluate/quick/FrontendXValue.kt +++ b/platform/xdebugger-impl/frontend/src/com/intellij/platform/debugger/impl/frontend/evaluate/quick/FrontendXValue.kt @@ -242,6 +242,9 @@ class FrontendXValue private constructor( } private fun XValueNode.setPresentation(presentation: XValueSerializedPresentation) { + if (this is XValueNodeEx) { + setInlayIcon(presentation.inlayIcon()) + } when (presentation) { is XValueSerializedPresentation.SimplePresentation -> { setPresentation(presentation.icon?.icon(), presentation.presentationType, presentation.value, presentation.hasChildren) @@ -442,6 +445,12 @@ private fun XValueSerializedPresentation.rawText(): String = when (this) { is XValueSerializedPresentation.SimplePresentation -> value } +private fun XValueSerializedPresentation.inlayIcon() = when (this) { + is XValueSerializedPresentation.AdvancedPresentation -> inlayIcon?.icon() + is XValueSerializedPresentation.ExtendedPresentation -> presentation.inlayIcon?.icon() + is XValueSerializedPresentation.SimplePresentation -> inlayIcon?.icon() +} + private class FrontendXNamedValue( val delegate: FrontendXValue, name: String, diff --git a/platform/xdebugger-impl/rpc/src/com/intellij/platform/debugger/impl/rpc/XValueSerializedPresentation.kt b/platform/xdebugger-impl/rpc/src/com/intellij/platform/debugger/impl/rpc/XValueSerializedPresentation.kt index 6bf7c1d81f91..c1f0fdaf1aa6 100644 --- a/platform/xdebugger-impl/rpc/src/com/intellij/platform/debugger/impl/rpc/XValueSerializedPresentation.kt +++ b/platform/xdebugger-impl/rpc/src/com/intellij/platform/debugger/impl/rpc/XValueSerializedPresentation.kt @@ -14,6 +14,7 @@ sealed interface XValueSerializedPresentation { @Serializable data class SimplePresentation( val icon: IconId?, + val inlayIcon: IconId?, val presentationType: String?, val value: String, val hasChildren: Boolean, @@ -23,6 +24,7 @@ sealed interface XValueSerializedPresentation { @Serializable data class AdvancedPresentation( val icon: IconId?, + val inlayIcon: IconId?, val hasChildren: Boolean, val separator: String, val isShownName: Boolean, @@ -84,4 +86,4 @@ sealed interface XValueAdvancedPresentationPart { @ApiStatus.Internal @Serializable data class Error(override val text: String) : XValueAdvancedPresentationPart -} \ No newline at end of file +} diff --git a/platform/xdebugger-impl/shared/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeEx.kt b/platform/xdebugger-impl/shared/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeEx.kt index 9dd36851f139..0d9b19898821 100644 --- a/platform/xdebugger-impl/shared/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeEx.kt +++ b/platform/xdebugger-impl/shared/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeEx.kt @@ -5,6 +5,7 @@ import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink import com.intellij.xdebugger.frame.XValue import com.intellij.xdebugger.frame.XValueNode import org.jetbrains.annotations.ApiStatus +import javax.swing.Icon // TODO: split into separate interfaces may be? @ApiStatus.Internal @@ -19,6 +20,8 @@ interface XValueNodeEx : XValueNode { */ fun clearFullValueEvaluator() + fun setInlayIcon(icon: Icon?) + /** * Adds a hyperlink to be shown for this node, aside from the full value evaluator. * Only a single additional hyperlink is supported. @@ -29,4 +32,4 @@ interface XValueNodeEx : XValueNode { * Clears previously added additional hyperlinks, if any. */ fun clearAdditionalHyperlinks() -} \ No newline at end of file +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/rpc/models/XValuePresentationBridge.kt b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/rpc/models/XValuePresentationBridge.kt index b416d5d3c595..73c1720484e5 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/rpc/models/XValuePresentationBridge.kt +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/rpc/models/XValuePresentationBridge.kt @@ -1,6 +1,7 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.xdebugger.impl.rpc.models +import com.intellij.ide.ui.icons.IconId import com.intellij.ide.ui.icons.rpcId import com.intellij.openapi.application.EDT import com.intellij.openapi.diagnostic.fileLogger @@ -36,12 +37,17 @@ internal fun XValue.computePresentation( var isObsolete = false val valueNode = object : XValueNodeEx { + private var _inlayIcon: Icon? = null + private var lastPresentation: XValueSerializedPresentation? = null + override fun isObsolete(): Boolean { return isObsolete } override fun setPresentation(icon: Icon?, type: @NonNls String?, value: @NonNls String, hasChildren: Boolean) { - presentationHandler(XValueSerializedPresentation.SimplePresentation(icon?.rpcId(), type, value, hasChildren)) + val presentation = XValueSerializedPresentation.SimplePresentation(icon?.rpcId(), _inlayIcon?.rpcId(), type, value, hasChildren) + lastPresentation = presentation + presentationHandler(presentation) } override fun setPresentation(icon: Icon?, presentation: XValuePresentation, hasChildren: Boolean) { @@ -54,7 +60,7 @@ internal fun XValue.computePresentation( } val advancedPresentation = XValueSerializedPresentation.AdvancedPresentation( - icon?.rpcId(), hasChildren, + icon?.rpcId(), _inlayIcon?.rpcId(), hasChildren, presentation.separator, presentation.isShowName, presentation.type, presentation.isAsync, partsCollector.parts ) @@ -64,6 +70,7 @@ internal fun XValue.computePresentation( else { advancedPresentation } + lastPresentation = serializedPresentation presentationHandler(serializedPresentation) } @@ -71,6 +78,14 @@ internal fun XValue.computePresentation( fullValueEvaluatorHandler(fullValueEvaluator) } + override fun setInlayIcon(icon: Icon?) { + if (icon === _inlayIcon) return + _inlayIcon = icon + val previousPresentation = lastPresentation ?: return + val presentation = previousPresentation.withInlayIcon(icon?.rpcId()) + lastPresentation = presentation + presentationHandler(presentation) + } override fun getXValue(): XValue { return xValue @@ -103,6 +118,13 @@ internal fun XValue.computePresentation( } } +private fun XValueSerializedPresentation.withInlayIcon(icon: IconId?): XValueSerializedPresentation = + when (this) { + is XValueSerializedPresentation.AdvancedPresentation -> copy(inlayIcon = icon) + is XValueSerializedPresentation.ExtendedPresentation -> copy(presentation = presentation.copy(inlayIcon = icon)) + is XValueSerializedPresentation.SimplePresentation -> copy(inlayIcon = icon) + } + private class XValueTextRendererPartsCollector : XValueTextRenderer { private val _parts = mutableListOf() @@ -145,4 +167,4 @@ private class XValueTextRendererPartsCollector : XValueTextRenderer { override fun renderError(error: @NlsSafe String) { _parts.add(XValueAdvancedPresentationPart.Error(error)) } -} \ No newline at end of file +} diff --git a/platform/xdebugger-impl/ui/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/ui/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java index 052f0220e74f..261daa0eadcc 100644 --- a/platform/xdebugger-impl/ui/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java +++ b/platform/xdebugger-impl/ui/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java @@ -124,6 +124,7 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu return myChanged; } + @Override public void setInlayIcon(@Nullable Icon icon) { myInlayIcon = icon; } diff --git a/platform/xdebugger-impl/ui/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java b/platform/xdebugger-impl/ui/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java index 4221a7ffbcd5..ffd4cf4e741f 100644 --- a/platform/xdebugger-impl/ui/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java +++ b/platform/xdebugger-impl/ui/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java @@ -55,6 +55,10 @@ public final class XValueNodePresentationConfigurator { @Override public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) { } + + @Override + public void setInlayIcon(@Nullable Icon icon) { + } } public static void setPresentation(@Nullable Icon icon, @NotNull XValuePresentation presentation, boolean hasChildren, @@ -129,4 +133,4 @@ public final class XValueNodePresentationConfigurator { renderer.renderValue(valuePresenter.apply(myValue)); } } -} \ No newline at end of file +}