mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-195558 [debugger] Collection visualizer as a split bundled plugin
GitOrigin-RevId: 0ee6b4828ac757727c155c8f3eca0e57d14be3b4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a1566e6956
commit
67f992941a
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
<module name="intellij.java.langInjection"/>
|
||||
<module name="intellij.java.langInjection.jps"/>
|
||||
|
||||
<module name="intellij.debugger.collections.visualizer.jvm"/>
|
||||
<module name="intellij.profiler.ultimate"/>
|
||||
<module name="intellij.jvm.dfa.analysis.ui"/>
|
||||
</content>
|
||||
|
||||
+1
-57
@@ -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<XValueMarkerDto?> = 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<XFullValueEvaluatorDto?> {
|
||||
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,
|
||||
|
||||
+1
@@ -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.*
|
||||
|
||||
+2
-5
@@ -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) {
|
||||
|
||||
+64
@@ -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<XValueMarkerDto?> = 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<XFullValueEvaluatorDto?> {
|
||||
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<XValueTextProviderDto>? = (xValue as? XValueTextProvider)
|
||||
?.let {
|
||||
xValueModel.presentation.map {
|
||||
XValueTextProviderDto(
|
||||
xValue.shouldShowTextValue(),
|
||||
xValue.valueText,
|
||||
)
|
||||
}.distinctUntilChanged()
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
@Service(Service.Level.PROJECT)
|
||||
|
||||
+1
-1
@@ -173,7 +173,7 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> 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();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user