i18n: Add bundle for JVM debugger (coroutine)

This commit is contained in:
Yan Zhulanow
2020-02-18 21:02:16 +09:00
committed by Dmitry Gridin
parent e0d5607fcd
commit 7f80fb8b98
10 changed files with 86 additions and 27 deletions
@@ -242,13 +242,6 @@ kotlin.compiler.js.option.output.postfix.browse.title=Choose file to append to g
kotlin.compiler.js.option.output.copy.files=&Copy library runtime files kotlin.compiler.js.option.output.copy.files=&Copy library runtime files
kotlin.compiler.js.option.output.copy.dir=O&utput directory for library &runtime files: kotlin.compiler.js.option.output.copy.dir=O&utput directory for library &runtime files:
# Coroutine Debugger
debugger.session.tab.coroutine.title=Coroutines
debugger.session.tab.coroutine.message.failure=Failed to retrieve coroutine status
debugger.session.tab.coroutine.message.resume=Application resumed
debugger.session.tab.coroutine.message.error=Coroutine dump failed, see log
debugger.session.tab.xcoroutine.title=Coroutines
# Android Lint # Android Lint
android.klint.inspections.group.name=Android Lint for Kotlin android.klint.inspections.group.name=Android Lint for Kotlin
@@ -0,0 +1,25 @@
coroutine.dump.panel.title=Coroutine dump
coroutine.dump.filter.field=Filter:
coroutine.dump.filter.action=Filter
coroutine.dump.filter.description=Show only coroutines containing a specific string
coroutine.dump.merge.action=Merge Identical Stacktrace
coroutine.dump.merge.description=Group coroutines with identical stacktrace
coroutine.dump.copy.action=Copy to Clipboard
coroutine.dump.copy.description=Copy whole coroutine dump to clipboard
coroutine.dump.failed=Coroutine dump failed, see the log
coroutine.dump.copy.analyze=Analyze coroutine dump
coroutine.dump.full.title=Full coroutine dump
coroutine.dump.full.copied=Full coroutine dump was successfully copied to clipboard
coroutine.dump.creation.trace=Coroutine creation stack trace
coroutine.dump.creation.frame=Creation stack frame of {0}
coroutine.dump.threads.loading=Loading…
coroutine.view.title=Coroutines
coroutine.view.default.group=Default group
coroutine.view.fetching.error=An error occurred on fetching information
@@ -0,0 +1,24 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.debugger.coroutine
import com.intellij.CommonBundle
import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.PropertyKey
import org.jetbrains.kotlin.idea.core.util.KotlinBundleBase
import java.util.*
object KotlinDebuggerCoroutinesBundle : KotlinBundleBase() {
@NonNls
private const val BUNDLE = "org.jetbrains.kotlin.idea.debugger.coroutine.KotlinDebuggerCoroutinesBundle"
override fun createBundle(): ResourceBundle = ResourceBundle.getBundle(BUNDLE)
@JvmStatic
fun message(@NonNls @PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any?): String {
return CommonBundle.message(bundle, key, *params)
}
}
@@ -15,7 +15,7 @@ class VersionedImplementationProvider {
if (value != null) { if (value != null) {
label.text = value label.text = value
} else if (index >= 0) { } else if (index >= 0) {
label.text = "Loading..." label.text = KotlinDebuggerCoroutinesBundle.message("coroutine.dump.threads.loading")
} }
} }
} }
@@ -15,7 +15,7 @@ class VersionedImplementationProvider {
if (value != null) { if (value != null) {
label.text = value label.text = value
} else if (index >= 0) { } else if (index >= 0) {
label.text = "Loading..." label.text = KotlinDebuggerCoroutinesBundle.message("coroutine.dump.threads.loading")
} }
} }
} }
@@ -23,7 +23,7 @@ import com.intellij.openapi.util.Disposer
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.text.DateFormatUtil import com.intellij.util.text.DateFormatUtil
import com.intellij.xdebugger.impl.XDebuggerManagerImpl import com.intellij.xdebugger.impl.XDebuggerManagerImpl
import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.debugger.coroutine.KotlinDebuggerCoroutinesBundle
import org.jetbrains.kotlin.idea.debugger.coroutine.view.CoroutineDumpPanel import org.jetbrains.kotlin.idea.debugger.coroutine.view.CoroutineDumpPanel
import org.jetbrains.kotlin.idea.debugger.coroutine.coroutineDebuggerEnabled import org.jetbrains.kotlin.idea.debugger.coroutine.coroutineDebuggerEnabled
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineInfoData import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineInfoData
@@ -43,7 +43,7 @@ class CoroutineDumpAction : AnAction(), AnAction.TransparentUpdate {
val states = CoroutineDebugProbesProxy(context.suspendContext ?: return) val states = CoroutineDebugProbesProxy(context.suspendContext ?: return)
.dumpCoroutines() .dumpCoroutines()
if (states.isOk()) { if (states.isOk()) {
val message = KotlinBundle.message("debugger.session.tab.coroutine.message.error") val message = KotlinDebuggerCoroutinesBundle.message("coroutine.dump.failed")
XDebuggerManagerImpl.NOTIFICATION_GROUP.createNotification(message,MessageType.ERROR).notify(project) XDebuggerManagerImpl.NOTIFICATION_GROUP.createNotification(message,MessageType.ERROR).notify(project)
} else { } else {
val f = fun() { val f = fun() {
@@ -72,7 +72,7 @@ class CoroutineDumpAction : AnAction(), AnAction.TransparentUpdate {
val content = ui.createContent(id, panel, id, null, null).apply { val content = ui.createContent(id, panel, id, null, null).apply {
putUserData(RunnerContentUi.LIGHTWEIGHT_CONTENT_MARKER, true) putUserData(RunnerContentUi.LIGHTWEIGHT_CONTENT_MARKER, true)
isCloseable = true isCloseable = true
description = "Coroutine Dump" description = KotlinDebuggerCoroutinesBundle.message("coroutine.dump.panel.title")
} }
ui.addContent(content) ui.addContent(content)
ui.selectAndFocus(content, true, true) ui.selectAndFocus(content, true, true)
@@ -17,6 +17,7 @@ import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener import com.intellij.debugger.ui.tree.render.DescriptorLabelListener
import com.intellij.icons.AllIcons import com.intellij.icons.AllIcons
import com.sun.jdi.ObjectReference import com.sun.jdi.ObjectReference
import org.jetbrains.kotlin.idea.debugger.coroutine.KotlinDebuggerCoroutinesBundle
import javax.swing.Icon import javax.swing.Icon
@Deprecated("moved to XCoroutineView") @Deprecated("moved to XCoroutineView")
@@ -49,7 +50,7 @@ class CoroutineDescriptorImpl(val infoData: CoroutineInfoData) : NodeDescriptorI
@Deprecated("moved to XCoroutineView") @Deprecated("moved to XCoroutineView")
class CreationFramesDescriptor(val frames: List<StackTraceElement>) : class CreationFramesDescriptor(val frames: List<StackTraceElement>) :
MessageDescriptor("Coroutine creation stack trace", INFORMATION) { MessageDescriptor(KotlinDebuggerCoroutinesBundle.message("coroutine.dump.creation.trace"), INFORMATION) {
override fun isExpandable() = true override fun isExpandable() = true
} }
@@ -32,6 +32,7 @@ import com.intellij.ui.components.JBList
import com.intellij.unscramble.AnalyzeStacktraceUtil import com.intellij.unscramble.AnalyzeStacktraceUtil
import com.intellij.util.PlatformIcons import com.intellij.util.PlatformIcons
import com.intellij.util.ui.EmptyIcon import com.intellij.util.ui.EmptyIcon
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.CoroutineInfoData
import java.awt.BorderLayout import java.awt.BorderLayout
import java.awt.Color import java.awt.Color
@@ -61,7 +62,7 @@ class CoroutineDumpPanel(project: Project, consoleView: ConsoleView, toolbarActi
}) })
filterPanel.apply { filterPanel.apply {
add(JLabel("Filter:"), BorderLayout.WEST) add(JLabel(KotlinDebuggerCoroutinesBundle.message("coroutine.dump.filter.field")), BorderLayout.WEST)
add(filterField) add(filterField)
isVisible = false isVisible = false
} }
@@ -215,8 +216,8 @@ class CoroutineDumpPanel(project: Project, consoleView: ConsoleView, toolbarActi
} }
private inner class FilterAction : ToggleAction( private inner class FilterAction : ToggleAction(
"Filter", KotlinDebuggerCoroutinesBundle.message("coroutine.dump.filter.action"),
"Show only coroutines containing a specific string", KotlinDebuggerCoroutinesBundle.message("coroutine.dump.filter.description"),
AllIcons.General.Filter AllIcons.General.Filter
), DumbAware { ), DumbAware {
@@ -235,8 +236,8 @@ class CoroutineDumpPanel(project: Project, consoleView: ConsoleView, toolbarActi
} }
private inner class MergeStackTracesAction : ToggleAction( private inner class MergeStackTracesAction : ToggleAction(
"Merge Identical Stacktrace", KotlinDebuggerCoroutinesBundle.message("coroutine.dump.merge.action"),
"Group coroutines with identical stacktrace", KotlinDebuggerCoroutinesBundle.message("coroutine.dump.merge.description"),
AllIcons.Actions.Collapseall AllIcons.Actions.Collapseall
), DumbAware { ), DumbAware {
@@ -251,23 +252,30 @@ class CoroutineDumpPanel(project: Project, consoleView: ConsoleView, toolbarActi
} }
private class CopyToClipboardAction(private val myCoroutinesDump: List<CoroutineInfoData>, private val myProject: Project) : private class CopyToClipboardAction(private val myCoroutinesDump: List<CoroutineInfoData>, private val myProject: Project) :
DumbAwareAction("Copy to Clipboard", "Copy whole coroutine dump to clipboard", PlatformIcons.COPY_ICON) { DumbAwareAction(
KotlinDebuggerCoroutinesBundle.message("coroutine.dump.copy.action"),
KotlinDebuggerCoroutinesBundle.message("coroutine.dump.copy.description"),
PlatformIcons.COPY_ICON
) {
override fun actionPerformed(e: AnActionEvent) { override fun actionPerformed(e: AnActionEvent) {
val buf = StringBuilder() val buf = StringBuilder()
buf.append("Full coroutine dump").append("\n\n") buf.append(KotlinDebuggerCoroutinesBundle.message("coroutine.dump.full.title")).append("\n\n")
for (state in myCoroutinesDump) { for (state in myCoroutinesDump) {
buf.append(state.stringStackTrace).append("\n\n") buf.append(state.stringStackTrace).append("\n\n")
} }
CopyPasteManager.getInstance().setContents(StringSelection(buf.toString())) CopyPasteManager.getInstance().setContents(StringSelection(buf.toString()))
group.createNotification( group.createNotification(
"Full coroutine dump was successfully copied to clipboard", KotlinDebuggerCoroutinesBundle.message("coroutine.dump.full.copied"),
MessageType.INFO MessageType.INFO
).notify(myProject) ).notify(myProject)
} }
private val group = NotificationGroup.toolWindowGroup("Analyze coroutine dump", ToolWindowId.RUN, false) private val group = NotificationGroup.toolWindowGroup(
KotlinDebuggerCoroutinesBundle.message("coroutine.dump.copy.analyze"),
ToolWindowId.RUN, false
)
} }
private class MyToFileExporter( private class MyToFileExporter(
@@ -24,6 +24,7 @@ import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants
import com.intellij.xdebugger.ui.DebuggerColors import com.intellij.xdebugger.ui.DebuggerColors
import com.sun.jdi.Location import com.sun.jdi.Location
import com.sun.jdi.ReferenceType import com.sun.jdi.ReferenceType
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.CoroutineInfoData
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
import java.awt.Color import java.awt.Color
@@ -177,7 +178,10 @@ class SimpleColoredTextIconPresentationRenderer {
} }
fun renderCreationNode(infoData: CoroutineInfoData) = fun renderCreationNode(infoData: CoroutineInfoData) =
SimpleColoredTextIcon(AllIcons.Debugger.ThreadSuspended, true, "Creation stack frame of ${infoData.name}") SimpleColoredTextIcon(
AllIcons.Debugger.ThreadSuspended, true,
KotlinDebuggerCoroutinesBundle.message("coroutine.dump.creation.frame", infoData.name)
)
fun renderErrorNode(error: String) = fun renderErrorNode(error: String) =
SimpleColoredTextIcon(AllIcons.Actions.Lightning,false, error) SimpleColoredTextIcon(AllIcons.Actions.Lightning,false, error)
@@ -40,9 +40,9 @@ import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl
import com.sun.jdi.request.EventRequest import com.sun.jdi.request.EventRequest
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineDebuggerContentInfo import org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineDebuggerContentInfo
import org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineDebuggerContentInfo.Companion.XCOROUTINE_POPUP_ACTION_GROUP import org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineDebuggerContentInfo.Companion.XCOROUTINE_POPUP_ACTION_GROUP
import org.jetbrains.kotlin.idea.debugger.coroutine.KotlinDebuggerCoroutinesBundle
import org.jetbrains.kotlin.idea.debugger.coroutine.VersionedImplementationProvider import org.jetbrains.kotlin.idea.debugger.coroutine.VersionedImplementationProvider
import org.jetbrains.kotlin.idea.debugger.coroutine.data.* import org.jetbrains.kotlin.idea.debugger.coroutine.data.*
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.ApplicationThreadExecutor import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.ApplicationThreadExecutor
@@ -150,7 +150,7 @@ class XCoroutineView(val project: Project, val session: XDebugSession) :
CreateContentParams( CreateContentParams(
CoroutineDebuggerContentInfo.XCOROUTINE_THREADS_CONTENT, CoroutineDebuggerContentInfo.XCOROUTINE_THREADS_CONTENT,
mainPanel, mainPanel,
KotlinBundle.message("debugger.session.tab.xcoroutine.title"), KotlinDebuggerCoroutinesBundle.message("coroutine.view.title"),
null, null,
panel.tree panel.tree
) )
@@ -158,7 +158,10 @@ class XCoroutineView(val project: Project, val session: XDebugSession) :
inner class EmptyNode : XValueContainerNode<XValueContainer>(panel.tree, null, true, object : XValueContainer() {}) inner class EmptyNode : XValueContainerNode<XValueContainer>(panel.tree, null, true, object : XValueContainer() {})
inner class XCoroutinesRootNode(suspendContext: XSuspendContext) : inner class XCoroutinesRootNode(suspendContext: XSuspendContext) :
XValueContainerNode<CoroutineGroupContainer>(panel.tree, null, false, CoroutineGroupContainer(suspendContext, "Default group")) XValueContainerNode<CoroutineGroupContainer>(
panel.tree, null, false,
CoroutineGroupContainer(suspendContext, KotlinDebuggerCoroutinesBundle.message("coroutine.view.default.group"))
)
inner class CoroutineGroupContainer(val suspendContext: XSuspendContext, val groupName: String) : XValueContainer() { inner class CoroutineGroupContainer(val suspendContext: XSuspendContext, val groupName: String) : XValueContainer() {
override fun computeChildren(node: XCompositeNode) { override fun computeChildren(node: XCompositeNode) {
@@ -191,7 +194,8 @@ class XCoroutineView(val project: Project, val session: XDebugSession) :
} }
node.addChildren(children, true) node.addChildren(children, true)
} else { } else {
node.addChildren(XValueChildrenList.singleton(ErrorNode("Error occurs while fetching information")), true) val errorNode = ErrorNode(KotlinDebuggerCoroutinesBundle.message("coroutine.view.fetching.error"))
node.addChildren(XValueChildrenList.singleton(errorNode), true)
} }
} }
} }