mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 02:09:59 +07:00
[debugger] show icon tooltip for thread dump items, IDEA-367627
GitOrigin-RevId: 98a49d442375e4fbff82aa825085c95199851afc
This commit is contained in:
committed by
intellij-monorepo-bot
parent
de6bff2db3
commit
24ad155a3b
@@ -71,12 +71,17 @@ private fun truncateIfNeeded(allDumpItems: List<DumpItem>, maxItems: Int): Pair<
|
||||
|
||||
private fun dumpItemDtos(allDumpItems: List<DumpItem>, maxItems: Int): ThreadDumpWithAwaitingDependencies {
|
||||
val (dumpItems, truncatedSize) = truncateIfNeeded(allDumpItems, maxItems)
|
||||
val attributes = dumpItems.map { it.attributes }.distinct()
|
||||
val attributesToIndex = attributes.withIndex().associate { it.value to it.index.toByte() }
|
||||
val icons = dumpItems.map { it.icon }.distinct()
|
||||
val iconToIndex = icons.withIndex().associate { it.value to it.index.toByte() }
|
||||
val stateDescriptions = dumpItems.map { it.stateDesc }.distinct()
|
||||
val stateDescriptionsToIndex = stateDescriptions.withIndex().associate { it.value to it.index }
|
||||
|
||||
fun <T> prepareIndex(selector: (DumpItem) -> T): Pair<List<T>, Map<T, Int>> {
|
||||
val values = dumpItems.map(selector).distinct()
|
||||
val valueToIndex = values.withIndex().associate { it.value to it.index }
|
||||
return Pair(values, valueToIndex)
|
||||
}
|
||||
|
||||
val (attributes, attributesToIndex) = prepareIndex { it.attributes }
|
||||
val (icons, iconToIndex) = prepareIndex { it.icon }
|
||||
val (stateDescriptions, stateDescriptionToIndex) = prepareIndex { it.stateDesc }
|
||||
val (iconToolTips, iconToolTipToIndex) = prepareIndex { it.iconToolTip }
|
||||
|
||||
val awaiting = hashMapOf<Int, IntArray>()
|
||||
val itemToIndex = dumpItems.withIndex().associate { it.value to it.index }
|
||||
@@ -110,12 +115,13 @@ private fun dumpItemDtos(allDumpItems: List<DumpItem>, maxItems: Int): ThreadDum
|
||||
val items = dumpItems.map {
|
||||
val (firstLine, stackTraceIndex) = itemToStackTrace[it]!!
|
||||
JavaThreadDumpItemDto(name = it.name,
|
||||
stateDescriptionIndex = stateDescriptionsToIndex[it.stateDesc]!!,
|
||||
stateDescriptionIndex = stateDescriptionToIndex[it.stateDesc]!!,
|
||||
interestLevel = it.interestLevel,
|
||||
iconIndex = iconToIndex[it.icon]!!,
|
||||
attributesIndex = attributesToIndex[it.attributes]!!,
|
||||
iconIndex = iconToIndex[it.icon]!!.toByte(),
|
||||
attributesIndex = attributesToIndex[it.attributes]!!.toByte(),
|
||||
isDeadLocked = it.isDeadLocked,
|
||||
stackTraceIndex = stackTraceIndex,
|
||||
iconToolTipIndex = iconToolTipToIndex[it.iconToolTip]!!.toByte(),
|
||||
firstLine = firstLine)
|
||||
}
|
||||
|
||||
@@ -125,6 +131,7 @@ private fun dumpItemDtos(allDumpItems: List<DumpItem>, maxItems: Int): ThreadDum
|
||||
stackTraces = stackTraces,
|
||||
awaitingDependencies = awaiting,
|
||||
stateDescriptions = stateDescriptions,
|
||||
iconToolTips = iconToolTips,
|
||||
truncatedItemsNumber = truncatedSize)
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.Nls
|
||||
import java.awt.event.InputEvent
|
||||
import javax.swing.Icon
|
||||
|
||||
@@ -114,7 +115,7 @@ private fun ThreadDumpWithAwaitingDependencies.toDumpItems(): List<DumpItem> {
|
||||
val iconsCache = icons.map { it.icon() }
|
||||
val attributesCache = attributes.map { it.toSimpleTextAttributes() }
|
||||
|
||||
val feDumpItems = items.map { FrontendDumpItem(it, iconsCache, attributesCache, stackTraces, stateDescriptions) }
|
||||
val feDumpItems = items.map { FrontendDumpItem(it, iconsCache, attributesCache, stackTraces, stateDescriptions, iconToolTips) }
|
||||
for ((index, awaitingIndices) in awaitingDependencies) {
|
||||
val awaitingItems = awaitingIndices.map { feDumpItems[it] }.toHashSet()
|
||||
feDumpItems[index].setAwaitingItems(awaitingItems)
|
||||
@@ -128,12 +129,14 @@ private class FrontendDumpItem(
|
||||
private val attributesCache: List<SimpleTextAttributes>,
|
||||
private val stackTracesCache: List<@NlsSafe String>,
|
||||
private val stateDescriptionsCache: List<@NlsSafe String>,
|
||||
private val iconToolTipsCache: List<@Nls String?>,
|
||||
) : DumpItem {
|
||||
private var internalAwaitingItems: Set<DumpItem> = emptySet()
|
||||
|
||||
override val name: @NlsSafe String get() = itemDto.name
|
||||
override val stateDesc: @NlsSafe String get() = stateDescriptionsCache[itemDto.stateDescriptionIndex]
|
||||
override val stackTrace: @NlsSafe String get() = "${itemDto.firstLine}\n${stackTracesCache[itemDto.stackTraceIndex]}"
|
||||
override val iconToolTip: @Nls String? get() = iconToolTipsCache[itemDto.iconToolTipIndex.toUInt().toInt()]
|
||||
override val interestLevel: Int get() = itemDto.interestLevel
|
||||
override val icon: Icon get() = iconsCache[itemDto.iconIndex.toUInt().toInt()]
|
||||
override val attributes: SimpleTextAttributes get() = attributesCache[itemDto.attributesIndex.toInt().toUInt().toInt()]
|
||||
|
||||
@@ -15,6 +15,7 @@ import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.Nls
|
||||
|
||||
@ApiStatus.Internal
|
||||
@Rpc
|
||||
@@ -54,6 +55,7 @@ data class ThreadDumpWithAwaitingDependencies(
|
||||
val attributes: List<SerializableSimpleTextAttributes>,
|
||||
val stackTraces: List<@NlsSafe String>,
|
||||
val stateDescriptions: List<@NlsSafe String>,
|
||||
val iconToolTips: List<@Nls String?>,
|
||||
val awaitingDependencies: Map<Int, IntArray>,
|
||||
val truncatedItemsNumber: Int,
|
||||
)
|
||||
@@ -65,6 +67,7 @@ data class JavaThreadDumpItemDto(
|
||||
val firstLine: @NlsSafe String,
|
||||
val stateDescriptionIndex: Int,
|
||||
val stackTraceIndex: Int,
|
||||
val iconToolTipIndex: Byte,
|
||||
val interestLevel: Int,
|
||||
val iconIndex: Byte,
|
||||
val attributesIndex: Byte,
|
||||
|
||||
@@ -102,3 +102,6 @@ listbox.import.static=Static
|
||||
listbox.import.with.subpackages=With Subpackages
|
||||
do.not.import.inner.classes.for=Exclude inner classes by short name:
|
||||
do.not.import.inner.classes.no.classes=No inner classes defined
|
||||
|
||||
dump.item.java.thread.icon.tooltip.virtual=Virtual Thread
|
||||
dump.item.java.thread.icon.tooltip.daemon=Daemon Thread
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
package com.intellij.unscramble
|
||||
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.java.frontback.impl.JavaFrontbackBundle
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.threadDumpParser.ThreadOperation
|
||||
import com.intellij.threadDumpParser.ThreadState
|
||||
import com.intellij.ui.SimpleTextAttributes
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.Nls
|
||||
import java.awt.Color
|
||||
import java.util.*
|
||||
import javax.swing.Icon
|
||||
@@ -23,6 +25,8 @@ interface DumpItem {
|
||||
|
||||
val icon: Icon
|
||||
|
||||
val iconToolTip: @Nls String?
|
||||
|
||||
val attributes: SimpleTextAttributes
|
||||
|
||||
val isDeadLocked: Boolean
|
||||
@@ -175,6 +179,13 @@ private class JavaThreadDumpItem(private val threadState: ThreadState) : Mergeab
|
||||
}
|
||||
}
|
||||
|
||||
override val iconToolTip: @Nls String?
|
||||
get() = when {
|
||||
threadState.isVirtual -> JavaFrontbackBundle.message("dump.item.java.thread.icon.tooltip.virtual")
|
||||
threadState.isDaemon -> JavaFrontbackBundle.message("dump.item.java.thread.icon.tooltip.daemon")
|
||||
else -> null
|
||||
}
|
||||
|
||||
override val attributes: SimpleTextAttributes = when {
|
||||
threadState.isSleeping -> DumpItem.SLEEPING_ATTRIBUTES
|
||||
threadState.isEmptyStackTrace || this.isServiceThread || threadState.isKnownJDKThread() -> DumpItem.UNINTERESTING_ATTRIBUTES
|
||||
|
||||
@@ -243,9 +243,12 @@ public final class ThreadDumpPanel extends JPanel implements NoStackTraceFolding
|
||||
}
|
||||
|
||||
private static class ThreadListCellRenderer extends ColoredListCellRenderer<DumpItem> {
|
||||
private String iconToolTip;
|
||||
|
||||
@Override
|
||||
protected void customizeCellRenderer(@NotNull JList<? extends DumpItem> list, DumpItem threadState, int index, boolean selected, boolean hasFocus) {
|
||||
setIcon(threadState.getIcon());
|
||||
iconToolTip = threadState.getIconToolTip();
|
||||
if (!selected) {
|
||||
DumpItem selectedThread = list.getSelectedValue();
|
||||
setBackground(getBackgroundColor(threadState, selectedThread));
|
||||
@@ -255,6 +258,11 @@ public final class ThreadDumpPanel extends JPanel implements NoStackTraceFolding
|
||||
append(threadState.getStateDesc(), attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getIconToolTipText() {
|
||||
return iconToolTip;
|
||||
}
|
||||
|
||||
private static @NotNull Color getBackgroundColor(DumpItem threadState, DumpItem selectedThread) {
|
||||
if (threadState.isDeadLocked()) {
|
||||
return LightColors.RED;
|
||||
|
||||
@@ -356,6 +356,11 @@ a:com.intellij.ui.ColoredTreeCellRenderer
|
||||
- f:setup(javax.swing.JScrollPane,java.util.Set,javax.swing.JComponent):V
|
||||
- bs:setup$default(com.intellij.ui.ScrollableContentBorder$Companion,javax.swing.JScrollPane,com.intellij.ui.Side,javax.swing.JComponent,I,java.lang.Object):V
|
||||
- bs:setup$default(com.intellij.ui.ScrollableContentBorder$Companion,javax.swing.JScrollPane,java.util.Set,javax.swing.JComponent,I,java.lang.Object):V
|
||||
c:com.intellij.ui.SimpleColoredComponent
|
||||
- javax.swing.JComponent
|
||||
- com.intellij.ui.ColoredTextContainer
|
||||
- javax.accessibility.Accessible
|
||||
- *p:getIconToolTipText():java.lang.String
|
||||
*c:com.intellij.ui.components.JBHtmlPane
|
||||
- com.intellij.openapi.Disposable
|
||||
- javax.swing.JEditorPane
|
||||
|
||||
@@ -1174,10 +1174,22 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string to be used as the tooltip at the icon fragment (if there is an icon).
|
||||
* By default this returns {@link IconWithToolTip#getToolTip(boolean)} if icon is an instance of {@link IconWithToolTip},
|
||||
* otherwise {@code null}.
|
||||
*
|
||||
* @return a string containing the icon tooltip
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
protected @Nls @Nullable String getIconToolTipText() {
|
||||
return myIcon instanceof IconWithToolTip i ? i.getToolTip(false) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToolTipText(MouseEvent event) {
|
||||
if (myIcon instanceof IconWithToolTip && findFragmentAt(event.getX()) == FRAGMENT_ICON) {
|
||||
String iconToolTip = ((IconWithToolTip)myIcon).getToolTip(false);
|
||||
if (myIcon != null && findFragmentAt(event.getX()) == FRAGMENT_ICON) {
|
||||
String iconToolTip = getIconToolTipText();
|
||||
if (iconToolTip != null) {
|
||||
return StringUtil.capitalize(iconToolTip);
|
||||
}
|
||||
|
||||
@@ -29,3 +29,5 @@ coroutine.view.fetching.not_found=No coroutine information found
|
||||
optimised.variable.message={0} was optimised out
|
||||
|
||||
to.enable.information.breakpoint.suspend.policy.should.be.set.to.all.threads=To enable information breakpoint suspend policy should be set to 'All' threads.
|
||||
|
||||
dump.item.coroutine.tooltip=Coroutine
|
||||
@@ -15,6 +15,7 @@ import com.intellij.unscramble.IconsCache
|
||||
import com.intellij.unscramble.MergeableDumpItem
|
||||
import com.intellij.unscramble.MergeableToken
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.KotlinDebuggerCoroutinesBundle
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineInfoData
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.State
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.CoroutineDebugProbesProxy
|
||||
@@ -52,6 +53,9 @@ private class CoroutineDumpItem(info: CoroutineInfoData) : MergeableDumpItem {
|
||||
|
||||
override val stateDesc: String = " (${info.state.name.lowercase()})"
|
||||
|
||||
override val iconToolTip: String
|
||||
get() = KotlinDebuggerCoroutinesBundle.message("dump.item.coroutine.tooltip")
|
||||
|
||||
private val dispatcher = info.dispatcher
|
||||
|
||||
override val stackTrace: String =
|
||||
|
||||
Reference in New Issue
Block a user