diff --git a/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties b/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties index 8eb34d48bcf8..19caed5c0b69 100644 --- a/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties +++ b/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties @@ -272,8 +272,6 @@ user.renderers.configurable.display.name=Java Type Renderers async.stacktraces.configurable.display.name=Async Stack Traces label.user.renderers.configurable.renderer.name=Renderer name: text.user.renderers.configurable.no.renderers=No renderers -debugger.collection.visualizer.title=Collection Presentation -debugger.collection.visualizer.title.0=Collection Presentation: {0} button.copy=Copy user.renderers.configurable.button.description.copy=Copy selected renderer label.generic.debugger.parameters.patcher.configurable.shmem=Shared &memory diff --git a/java/plugin/plugin-content.yaml b/java/plugin/plugin-content.yaml index df2d0ba30875..207ac5e91d7e 100644 --- a/java/plugin/plugin-content.yaml +++ b/java/plugin/plugin-content.yaml @@ -79,7 +79,6 @@ - name: intellij.java.performancePlugin - name: intellij.java.terminal - name: intellij.java.debugger.impl.backend - - name: intellij.debugger.collections.visualizer.jvm - name: intellij.jvm.dfa.analysis.ui - name: lib/javac2.jar modules: @@ -143,6 +142,9 @@ module: intellij.java.aetherDependencyResolver files: - name: $MAVEN_REPOSITORY$/org/apache/maven/resolver/maven-resolver-transport-http/1/maven-resolver-transport-http-1.jar +- name: lib/modules/intellij.debugger.collections.visualizer.jvm.backend.jar + contentModules: + - name: intellij.debugger.collections.visualizer.jvm.backend - name: lib/modules/intellij.java.debugger.impl.frontend.jar contentModules: - name: intellij.java.debugger.impl.frontend diff --git a/java/plugin/resources/META-INF/plugin.xml b/java/plugin/resources/META-INF/plugin.xml index fdfe05ba6a56..bb8e6e78d2d6 100644 --- a/java/plugin/resources/META-INF/plugin.xml +++ b/java/plugin/resources/META-INF/plugin.xml @@ -59,7 +59,6 @@ - diff --git a/platform/xdebugger-impl/backend/src/com/intellij/platform/debugger/impl/backend/BackendXDebuggerEvaluatorApi.kt b/platform/xdebugger-impl/backend/src/com/intellij/platform/debugger/impl/backend/BackendXDebuggerEvaluatorApi.kt index 01dd59fb9b7a..444d76ff7e60 100644 --- a/platform/xdebugger-impl/backend/src/com/intellij/platform/debugger/impl/backend/BackendXDebuggerEvaluatorApi.kt +++ b/platform/xdebugger-impl/backend/src/com/intellij/platform/debugger/impl/backend/BackendXDebuggerEvaluatorApi.kt @@ -9,29 +9,19 @@ import com.intellij.openapi.application.readAction import com.intellij.openapi.project.Project import com.intellij.openapi.util.NlsContexts import com.intellij.platform.debugger.impl.rpc.* -import com.intellij.platform.debugger.impl.rpc.XFullValueEvaluatorDto.FullValueEvaluatorLinkAttributes import com.intellij.xdebugger.XDebuggerBundle import com.intellij.xdebugger.evaluation.ExpressionInfo import com.intellij.xdebugger.evaluation.XDebuggerEvaluator import com.intellij.xdebugger.evaluation.XDebuggerEvaluator.XEvaluationCallback -import com.intellij.xdebugger.impl.evaluate.XEvaluationOrigin -import com.intellij.xdebugger.frame.XNamedValue import com.intellij.xdebugger.frame.XValue import com.intellij.xdebugger.impl.XDebugSessionImpl +import com.intellij.xdebugger.impl.evaluate.XEvaluationOrigin import com.intellij.xdebugger.impl.evaluate.quick.XDebuggerDocumentOffsetEvaluator import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType -import com.intellij.xdebugger.impl.pinned.items.PinToTopValue import com.intellij.xdebugger.impl.rpc.XStackFrameId import com.intellij.xdebugger.impl.rpc.models.* -import com.intellij.xdebugger.impl.ui.XValueTextProvider import com.intellij.xdebugger.impl.ui.tree.nodes.XEvaluationCallbackWithOrigin -import fleet.rpc.core.RpcFlow -import fleet.rpc.core.toRpc import kotlinx.coroutines.* -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.future.asDeferred import kotlinx.coroutines.future.await import org.jetbrains.concurrency.asDeferred @@ -111,36 +101,6 @@ internal class BackendXDebuggerEvaluatorApi : XDebuggerEvaluatorApi { } } -internal suspend fun BackendXValueModel.toXValueDto(): XValueDto { - val xValueModel = this - val xValue = this.xValue - val valueMarkupFlow: RpcFlow = xValueModel.marker.toRpc() - - val textProvider = (xValue as? XValueTextProvider) - ?.let { - xValueModel.presentation.map { - XValueTextProviderDto( - xValue.shouldShowTextValue(), - xValue.valueText, - ) - }.distinctUntilChanged() - } - - return XValueDto( - xValueModel.id, - xValue.xValueDescriptorAsync?.asDeferred(), - canNavigateToSource = xValue.canNavigateToSource(), - canNavigateToTypeSource = xValue.canNavigateToTypeSourceAsync().asDeferred(), - canBeModified = xValue.modifierAsync.thenApply { modifier -> modifier != null }.asDeferred(), - valueMarkupFlow, - xValueModel.presentation.toRpc(), - xValueModel.getEvaluatorDtoFlow().toRpc(), - (xValue as? XNamedValue)?.name, - textProvider?.toRpc(), - (xValue as? PinToTopValue)?.pinToTopDataFuture?.asDeferred(), - ) -} - internal fun BackendXValueGroupModel.toXValueGroupDto(): XValueGroupDto { return XValueGroupDto( id, @@ -153,22 +113,6 @@ internal fun BackendXValueGroupModel.toXValueGroupDto(): XValueGroupDto { ) } -private fun BackendXValueModel.getEvaluatorDtoFlow(): Flow { - return fullValueEvaluator.map { - if (it == null) { - return@map null - } - XFullValueEvaluatorDto( - it.linkText, - it.isEnabled, - it.isShowValuePopup, - it.linkAttributes?.let { attributes -> - FullValueEvaluatorLinkAttributes(attributes.linkIcon?.rpcId(), attributes.linkTooltipText, attributes.shortcutSupplier?.get()) - } - ) - } -} - internal fun newXValueModel( stackFrameModel: XStackFrameModel, xValue: XValue, diff --git a/platform/xdebugger-impl/backend/src/com/intellij/platform/debugger/impl/backend/BackendXValueApi.kt b/platform/xdebugger-impl/backend/src/com/intellij/platform/debugger/impl/backend/BackendXValueApi.kt index 5c028bf079c3..1c440f0b79a6 100644 --- a/platform/xdebugger-impl/backend/src/com/intellij/platform/debugger/impl/backend/BackendXValueApi.kt +++ b/platform/xdebugger-impl/backend/src/com/intellij/platform/debugger/impl/backend/BackendXValueApi.kt @@ -17,6 +17,7 @@ import com.intellij.xdebugger.impl.rpc.XValueId import com.intellij.xdebugger.impl.rpc.models.BackendXValueModel import com.intellij.xdebugger.impl.rpc.models.findValue import com.intellij.xdebugger.impl.rpc.models.getOrStoreGlobally +import com.intellij.xdebugger.impl.rpc.models.toXValueDto import fleet.rpc.core.toRpc import kotlinx.coroutines.* import kotlinx.coroutines.channels.* diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/collection/visualizer/XDebuggerNodeLinkActionProvider.kt b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/collection/visualizer/XDebuggerNodeLinkActionProvider.kt index eea851f92874..3cf7678e582c 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/collection/visualizer/XDebuggerNodeLinkActionProvider.kt +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/collection/visualizer/XDebuggerNodeLinkActionProvider.kt @@ -4,7 +4,6 @@ package com.intellij.xdebugger.impl.collection.visualizer import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.project.Project import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink -import com.intellij.xdebugger.impl.XDebuggerSuspendScopeProvider import com.intellij.xdebugger.impl.frame.XDebugView import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl import kotlinx.coroutines.CoroutineScope @@ -23,9 +22,6 @@ interface XDebuggerNodeLinkActionProvider { /** * Compute a hyperlink for the given [node]. * - * Passed [CoroutineScope] restricts the lifetime of the link action to a current debugger session state. - * Refer to [XDebuggerSuspendScopeProvider.provideSuspendScope] for more details. - * * @see [XDebuggerNodeLinkActionProvider.computeHyperlink] */ suspend fun CoroutineScope.provideHyperlink(project: Project, node: XValueNodeImpl): XDebuggerTreeNodeHyperlink? @@ -37,7 +33,8 @@ interface XDebuggerNodeLinkActionProvider { fun computeHyperlink(project: Project, node: XValueNodeImpl) { if (node.hasLinks()) return - val scope = XDebugView.getSessionProxy(node.tree)?.currentSuspendContextCoroutineScope?: return + val sessionProxy = XDebugView.getSessionProxy(node.tree) ?: return + val scope = sessionProxy.currentSuspendContextCoroutineScope ?: return scope.launch(Dispatchers.Default) { for (provider in EP_NAME.extensionList) { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/rpc/models/BackendXValueModel.kt b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/rpc/models/BackendXValueModel.kt index 1e5b34ddb2fc..b77c7c0d3b48 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/rpc/models/BackendXValueModel.kt +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/rpc/models/BackendXValueModel.kt @@ -1,11 +1,16 @@ // 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.rpcId import com.intellij.openapi.components.Service import com.intellij.openapi.components.service import com.intellij.openapi.project.Project +import com.intellij.platform.debugger.impl.rpc.XFullValueEvaluatorDto +import com.intellij.platform.debugger.impl.rpc.XFullValueEvaluatorDto.FullValueEvaluatorLinkAttributes +import com.intellij.platform.debugger.impl.rpc.XValueDto import com.intellij.platform.debugger.impl.rpc.XValueMarkerDto import com.intellij.platform.debugger.impl.rpc.XValueSerializedPresentation +import com.intellij.platform.debugger.impl.rpc.XValueTextProviderDto import com.intellij.platform.kernel.ids.BackendValueIdType import com.intellij.platform.kernel.ids.deleteValueById import com.intellij.platform.kernel.ids.findValueById @@ -13,16 +18,24 @@ import com.intellij.platform.kernel.ids.storeValueGlobally import com.intellij.util.AwaitCancellationAndInvoke import com.intellij.util.awaitCancellationAndInvoke import com.intellij.xdebugger.frame.XFullValueEvaluator +import com.intellij.xdebugger.frame.XNamedValue import com.intellij.xdebugger.frame.XValue import com.intellij.xdebugger.frame.XValuePlace import com.intellij.xdebugger.impl.XDebugSessionImpl +import com.intellij.xdebugger.impl.pinned.items.PinToTopValue import com.intellij.xdebugger.impl.rpc.XValueId +import com.intellij.xdebugger.impl.ui.XValueTextProvider import com.intellij.xdebugger.impl.ui.tree.ValueMarkup +import fleet.rpc.core.RpcFlow +import fleet.rpc.core.toRpc import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.* +import kotlinx.coroutines.future.asDeferred import org.jetbrains.annotations.ApiStatus +import org.jetbrains.concurrency.asDeferred /** * Model which holds reference to the [XValue]. @@ -112,6 +125,57 @@ class BackendXValueModel internal constructor( } } +@ApiStatus.Internal +suspend fun BackendXValueModel.toXValueDto(): XValueDto { + val xValueModel = this + val xValue = this.xValue + val valueMarkupFlow: RpcFlow = xValueModel.marker.toRpc() + + val textProvider = getTextProviderFlow(xValue, xValueModel) + + return XValueDto( + xValueModel.id, + xValue.xValueDescriptorAsync?.asDeferred(), + canNavigateToSource = xValue.canNavigateToSource(), + canNavigateToTypeSource = xValue.canNavigateToTypeSourceAsync().asDeferred(), + canBeModified = xValue.modifierAsync.thenApply { modifier -> modifier != null }.asDeferred(), + valueMarkupFlow, + xValueModel.presentation.toRpc(), + xValueModel.getEvaluatorDtoFlow().toRpc(), + (xValue as? XNamedValue)?.name, + textProvider?.toRpc(), + (xValue as? PinToTopValue)?.pinToTopDataFuture?.asDeferred(), + ) +} + +private fun BackendXValueModel.getEvaluatorDtoFlow(): Flow { + return fullValueEvaluator.map { + if (it == null) { + return@map null + } + XFullValueEvaluatorDto( + it.linkText, + it.isEnabled, + it.isShowValuePopup, + it.linkAttributes?.let { attributes -> + FullValueEvaluatorLinkAttributes(attributes.linkIcon?.rpcId(), attributes.linkTooltipText, attributes.shortcutSupplier?.get()) + } + ) + } +} + +private fun getTextProviderFlow( + xValue: XValue, + xValueModel: BackendXValueModel, +): Flow? = (xValue as? XValueTextProvider) + ?.let { + xValueModel.presentation.map { + XValueTextProviderDto( + xValue.shouldShowTextValue(), + xValue.valueText, + ) + }.distinctUntilChanged() + } @ApiStatus.Internal @Service(Service.Level.PROJECT) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java index e3619b6f251e..41a814e9f40d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java @@ -173,7 +173,7 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu public void addAdditionalHyperlink(@NotNull XDebuggerTreeNodeHyperlink link) { invokeNodeUpdate(() -> { if (!myAdditionalHyperLink.compareAndSet(null, link)) { - LOG.warn("Additional hyperlink already set; having more than one is discouraged"); + LOG.warn("Additional hyperlink already set; having more than one is not supported"); } fireNodeChanged(); });