Watches: Add Kotlin/JVM views to watches window (KT-28134, KT-28087, KT-22250)
Kotlin mode: show only Kotlin variables and captured values. The variable names are Kotlin-friendly. JVM mode: show all variables available in the current stack position, including synthetic ones.
This commit is contained in:
@@ -17,15 +17,93 @@
|
||||
package org.jetbrains.kotlin.idea.debugger
|
||||
|
||||
import com.intellij.debugger.engine.JavaStackFrame
|
||||
import com.intellij.debugger.engine.JavaValue
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
|
||||
import com.intellij.debugger.jdi.LocalVariableProxyImpl
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
||||
import com.intellij.debugger.ui.impl.watch.MethodsTracker
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl
|
||||
import com.intellij.xdebugger.frame.XValueChildrenList
|
||||
import com.sun.jdi.Value
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CONTINUATION_PARAMETER_NAME
|
||||
import org.jetbrains.kotlin.codegen.inline.INLINE_FUN_VAR_SUFFIX
|
||||
import org.jetbrains.kotlin.codegen.inline.isFakeLocalVariableForInline
|
||||
import org.jetbrains.kotlin.idea.debugger.evaluate.THIS_NAME
|
||||
|
||||
class KotlinStackFrame(frame: StackFrameProxyImpl) : JavaStackFrame(StackFrameDescriptorImpl(frame, MethodsTracker()), true) {
|
||||
override fun getVisibleVariables(): List<LocalVariableProxyImpl>? {
|
||||
return super.getStackFrameProxy().visibleVariablesSafe()
|
||||
.filter { !isFakeLocalVariableForInline(it.name()) }
|
||||
private val kotlinVariableViewService = ToggleKotlinVariablesState.getService()
|
||||
|
||||
override fun superBuildVariables(evaluationContext: EvaluationContextImpl, children: XValueChildrenList) {
|
||||
if (!kotlinVariableViewService.kotlinVariableView) {
|
||||
return super.superBuildVariables(evaluationContext, children)
|
||||
}
|
||||
|
||||
val nodeManager = evaluationContext.debugProcess.xdebugProcess!!.nodeManager
|
||||
|
||||
fun addItem(variable: LocalVariableProxyImpl) {
|
||||
val variableDescriptor = nodeManager.getLocalVariableDescriptor(null, variable)
|
||||
children.add(JavaValue.create(null, variableDescriptor, evaluationContext, nodeManager, false))
|
||||
}
|
||||
|
||||
val (thisReferences, otherVariables) = visibleVariables
|
||||
.partition { it.name() == THIS_NAME || it.name().startsWith("$THIS_NAME ") }
|
||||
|
||||
thisReferences.forEach(::addItem)
|
||||
otherVariables.forEach(::addItem)
|
||||
}
|
||||
|
||||
override fun getVisibleVariables(): List<LocalVariableProxyImpl> {
|
||||
val allVisibleVariables = super.getStackFrameProxy().safeVisibleVariables()
|
||||
|
||||
if (!kotlinVariableViewService.kotlinVariableView) {
|
||||
return allVisibleVariables.map { variable ->
|
||||
if (isFakeLocalVariableForInline(variable.name())) variable.wrapSyntheticInlineVariable() else variable
|
||||
}
|
||||
}
|
||||
|
||||
return allVisibleVariables.asSequence()
|
||||
.filter { !isHidden(it) }
|
||||
.map { remapVariableName(it) }
|
||||
.distinctBy { it.name() }
|
||||
.toList()
|
||||
.sortedBy { it.variable }
|
||||
}
|
||||
|
||||
private fun isHidden(variable: LocalVariableProxyImpl): Boolean {
|
||||
val name = variable.name()
|
||||
return isFakeLocalVariableForInline(name)
|
||||
|| name.endsWith(INLINE_FUN_VAR_SUFFIX)
|
||||
|| name == CONTINUATION_PARAMETER_NAME.asString()
|
||||
}
|
||||
|
||||
private fun remapVariableName(variable: LocalVariableProxyImpl) = with(variable) {
|
||||
when {
|
||||
isLabeledThisReference() -> {
|
||||
val label = variable.name().drop(AsmUtil.LABELED_THIS_PARAMETER.length)
|
||||
clone(withName = "$THIS_NAME (@$label)")
|
||||
}
|
||||
else -> variable
|
||||
}
|
||||
}
|
||||
|
||||
private fun LocalVariableProxyImpl.isLabeledThisReference(): Boolean {
|
||||
@Suppress("ConvertToStringTemplate")
|
||||
return name().startsWith(AsmUtil.LABELED_THIS_PARAMETER)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LocalVariableProxyImpl.clone(withName: String): LocalVariableProxyImpl {
|
||||
return object : LocalVariableProxyImpl(frame, variable) {
|
||||
override fun name() = withName
|
||||
}
|
||||
}
|
||||
|
||||
private fun LocalVariableProxyImpl.wrapSyntheticInlineVariable(): LocalVariableProxyImpl {
|
||||
val proxyWrapper = object : StackFrameProxyImpl(frame.threadProxy(), frame.stackFrame, frame.indexFromBottom) {
|
||||
override fun getValue(localVariable: LocalVariableProxyImpl): Value {
|
||||
return frame.virtualMachine.mirrorOfVoid()
|
||||
}
|
||||
}
|
||||
return LocalVariableProxyImpl(proxyWrapper, variable)
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.ToggleAction
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.xdebugger.XDebugSession
|
||||
import com.intellij.xdebugger.impl.XDebuggerUtilImpl
|
||||
import org.jetbrains.kotlin.idea.KotlinFileTypeFactory
|
||||
|
||||
class ToggleKotlinVariablesState {
|
||||
companion object {
|
||||
private const val KOTLIN_VARIABLE_VIEW = "debugger.kotlin.variable.view"
|
||||
|
||||
fun getService(): ToggleKotlinVariablesState {
|
||||
return ServiceManager.getService(ToggleKotlinVariablesState::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
var kotlinVariableView = PropertiesComponent.getInstance().getBoolean(KOTLIN_VARIABLE_VIEW, true)
|
||||
set(newValue) {
|
||||
field = newValue
|
||||
PropertiesComponent.getInstance().setValue(KOTLIN_VARIABLE_VIEW, newValue)
|
||||
}
|
||||
}
|
||||
|
||||
class ToggleKotlinVariablesView : ToggleAction() {
|
||||
private val kotlinVariableViewService = ToggleKotlinVariablesState.getService()
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
super.update(e)
|
||||
val session = XDebugSession.DATA_KEY.getData(e.dataContext)
|
||||
e.presentation.isEnabledAndVisible = session != null && session.isInKotlinFile()
|
||||
}
|
||||
|
||||
private fun XDebugSession.isInKotlinFile(): Boolean {
|
||||
val fileExtension = currentPosition?.file?.extension ?: return false
|
||||
return fileExtension in KotlinFileTypeFactory.KOTLIN_EXTENSIONS
|
||||
}
|
||||
|
||||
override fun isSelected(e: AnActionEvent) = kotlinVariableViewService.kotlinVariableView
|
||||
|
||||
override fun setSelected(e: AnActionEvent, state: Boolean) {
|
||||
kotlinVariableViewService.kotlinVariableView = state
|
||||
XDebuggerUtilImpl.rebuildAllSessionsViews(e.project)
|
||||
}
|
||||
}
|
||||
+3
-6
@@ -470,15 +470,12 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour
|
||||
val parameters = mutableListOf<Parameter>()
|
||||
val receiver = config.descriptor.receiverParameter
|
||||
if (receiver != null) {
|
||||
parameters += Parameter(THIS_NAME, receiver.getParameterType(true))
|
||||
parameters += Parameter(THIS_NAME + "@" + config.descriptor.name, receiver.getParameterType(true))
|
||||
}
|
||||
|
||||
for (param in config.descriptor.parameters) {
|
||||
val paramName = when {
|
||||
param.argumentText.contains("@") -> param.argumentText.substringBefore("@")
|
||||
param.argumentText.startsWith("::") -> param.argumentText.substring(2)
|
||||
else -> param.argumentText
|
||||
}
|
||||
val argument = param.argumentText
|
||||
val paramName = if (argument.startsWith("::")) argument.substring(2) else argument
|
||||
|
||||
val paramDescriptor = param.originalDescriptor
|
||||
if (paramDescriptor is SyntheticFieldDescriptor) {
|
||||
|
||||
@@ -61,6 +61,17 @@
|
||||
<action id="AddToProblemApiInspection" class="org.jetbrains.kotlin.idea.inspections.api.AddIncompatibleApiAction"
|
||||
text="Report as incompatible API">
|
||||
</action>
|
||||
|
||||
<group id="Kotlin.XDebugger.Actions">
|
||||
<action id="Kotlin.XDebugger.ToggleKotlinVariableView"
|
||||
class="org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesView"
|
||||
icon="/org/jetbrains/kotlin/idea/icons/kotlin.png"/>
|
||||
</group>
|
||||
|
||||
<group id="Kotlin.XDebugger.Watches.Tree.Toolbar">
|
||||
<reference ref="Kotlin.XDebugger.ToggleKotlinVariableView"/>
|
||||
<add-to-group group-id="XDebugger.Watches.Tree.Toolbar" relative-to-action="XDebugger.SwitchWatchesInVariables" anchor="after"/>
|
||||
</group>
|
||||
</actions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
@@ -77,6 +88,8 @@
|
||||
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.versions.SuppressNotificationState"/>
|
||||
|
||||
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesState"/>
|
||||
|
||||
<debugger.jvmSmartStepIntoHandler implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSmartStepIntoHandler"/>
|
||||
<debugger.positionManagerFactory implementation="org.jetbrains.kotlin.idea.debugger.KotlinPositionManagerFactory"/>
|
||||
<debugger.codeFragmentFactory implementation="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory"/>
|
||||
|
||||
@@ -61,6 +61,17 @@
|
||||
<action id="AddToProblemApiInspection" class="org.jetbrains.kotlin.idea.inspections.api.AddIncompatibleApiAction"
|
||||
text="Report as incompatible API">
|
||||
</action>
|
||||
|
||||
<group id="Kotlin.XDebugger.Actions">
|
||||
<action id="Kotlin.XDebugger.ToggleKotlinVariableView"
|
||||
class="org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesView"
|
||||
icon="/org/jetbrains/kotlin/idea/icons/kotlin.png"/>
|
||||
</group>
|
||||
|
||||
<group id="Kotlin.XDebugger.Watches.Tree.Toolbar">
|
||||
<reference ref="Kotlin.XDebugger.ToggleKotlinVariableView"/>
|
||||
<add-to-group group-id="XDebugger.Watches.Tree.Toolbar" relative-to-action="XDebugger.SwitchWatchesInVariables" anchor="after"/>
|
||||
</group>
|
||||
</actions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
@@ -77,6 +88,8 @@
|
||||
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.versions.SuppressNotificationState"/>
|
||||
|
||||
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesState"/>
|
||||
|
||||
<debugger.jvmSmartStepIntoHandler implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSmartStepIntoHandler"/>
|
||||
<debugger.positionManagerFactory implementation="org.jetbrains.kotlin.idea.debugger.KotlinPositionManagerFactory"/>
|
||||
<debugger.codeFragmentFactory implementation="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory"/>
|
||||
|
||||
+2
@@ -33,7 +33,9 @@ class A {
|
||||
local = element: int = 1 (sp = frameInlineArgument.kt, 4)
|
||||
local = this_$iv: frameInlineArgument.A = {frameInlineArgument.A@uniqueID} (sp = null)
|
||||
field = prop: int = 1 (sp = frameInlineArgument.kt, 17)
|
||||
local = $i$f$inlineFun: int = undefined (sp = null)
|
||||
local = element$iv: double = 1.0 (sp = frameInlineArgument.kt, 4)
|
||||
local = $i$a$-inlineFun-FrameInlineArgumentKt$main$1: int = undefined (sp = null)
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
|
||||
+3
@@ -47,11 +47,14 @@ fun main(args: Array<String>) {
|
||||
local = element: float = 1.0 (sp = frameInlineArgumentInsideInlineFun.kt, 13)
|
||||
local = this_$iv: frameInlineArgumentInsideInlineFun.B = {frameInlineArgumentInsideInlineFun.B@uniqueID} (sp = null)
|
||||
- Class has no fields
|
||||
local = $i$f$foo: int = undefined (sp = null)
|
||||
local = element$iv: int = 1 (sp = frameInlineArgumentInsideInlineFun.kt, 13)
|
||||
local = this_$iv$iv: frameInlineArgumentInsideInlineFun.A = {frameInlineArgumentInsideInlineFun.A@uniqueID} (sp = null)
|
||||
- Class has no fields
|
||||
local = $i$f$inlineFun: int = undefined (sp = null)
|
||||
local = element$iv$iv: double = 1.0 (sp = frameInlineArgumentInsideInlineFun.kt, 13)
|
||||
local = it$iv: int = 1 (sp = null)
|
||||
local = $i$a$-inlineFun-B$foo$1: int = undefined (sp = null)
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
|
||||
+1
@@ -37,6 +37,7 @@ class A {
|
||||
local = element: int = 1 (sp = frameInlineFun.kt, 12)
|
||||
local = this_$iv: frameInlineFun.A = {frameInlineFun.A@uniqueID} (sp = null)
|
||||
field = prop: int = 1 (sp = frameInlineFun.kt, 17)
|
||||
local = $i$f$inlineFun: int = undefined (sp = null)
|
||||
local = element$iv: double = 1.0 (sp = frameInlineFun.kt, 12)
|
||||
Disconnected from the target VM
|
||||
|
||||
|
||||
+2
@@ -60,11 +60,13 @@ fun main(args: Array<String>) {
|
||||
local = element: float = 1.0 (sp = frameInlineFunCallInsideInlineFun.kt, 5)
|
||||
local = this_$iv: frameInlineFunCallInsideInlineFun.B = {frameInlineFunCallInsideInlineFun.B@uniqueID} (sp = null)
|
||||
- Class has no fields
|
||||
local = $i$f$foo: int = undefined (sp = null)
|
||||
local = element$iv: int = 2 (sp = frameInlineFunCallInsideInlineFun.kt, 5)
|
||||
local = a$iv: frameInlineFunCallInsideInlineFun.A = {frameInlineFunCallInsideInlineFun.A@uniqueID} (sp = null)
|
||||
field = prop: int = 1 (sp = frameInlineFunCallInsideInlineFun.kt, 10)
|
||||
local = this_$iv$iv: frameInlineFunCallInsideInlineFun.A = {frameInlineFunCallInsideInlineFun.A@uniqueID} (sp = null)
|
||||
field = prop: int = 1 (sp = frameInlineFunCallInsideInlineFun.kt, 10)
|
||||
local = $i$f$inlineFun: int = undefined (sp = null)
|
||||
local = element$iv$iv: double = 1.0 (sp = frameInlineFunCallInsideInlineFun.kt, 5)
|
||||
Disconnected from the target VM
|
||||
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// SHOW_KOTLIN_VARIABLES
|
||||
|
||||
package frameInlineFunCallInsideInlineFunKotlinVariables
|
||||
|
||||
class A {
|
||||
inline fun inlineFun(s: (Int) -> Unit) {
|
||||
val element = 1.0
|
||||
//TODO breakpoint here doesn't work (not only in tests)
|
||||
s(1)
|
||||
}
|
||||
|
||||
val prop = 1
|
||||
}
|
||||
|
||||
class B {
|
||||
inline fun foo(s: (Int) -> Unit) {
|
||||
val element = 2
|
||||
val a = A()
|
||||
// STEP_INTO: 1
|
||||
// STEP_OVER: 1
|
||||
//Breakpoint!
|
||||
a.inlineFun {
|
||||
val e = element
|
||||
}
|
||||
s(1)
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
fun bar() {
|
||||
val element = 1f
|
||||
B().foo {
|
||||
val e = element
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
C().bar()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: element
|
||||
// RESULT: 1.0: D
|
||||
|
||||
// EXPRESSION: this.prop
|
||||
// RESULT: 1: I
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
LineBreakpoint created at frameInlineFunCallInsideInlineFunKotlinVariables.kt:22
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
frameInlineFunCallInsideInlineFunKotlinVariables.kt:22
|
||||
frameInlineFunCallInsideInlineFunKotlinVariables.kt:7
|
||||
frameInlineFunCallInsideInlineFunKotlinVariables.kt:9
|
||||
Compile bytecode for element
|
||||
Compile bytecode for this.prop
|
||||
// SHOW_KOTLIN_VARIABLES
|
||||
|
||||
package frameInlineFunCallInsideInlineFunKotlinVariables
|
||||
|
||||
class A {
|
||||
inline fun inlineFun(s: (Int) -> Unit) {
|
||||
val element = 1.0
|
||||
//TODO breakpoint here doesn't work (not only in tests)
|
||||
s(1)
|
||||
}
|
||||
|
||||
val prop = 1
|
||||
}
|
||||
|
||||
class B {
|
||||
inline fun foo(s: (Int) -> Unit) {
|
||||
val element = 2
|
||||
val a = A()
|
||||
// STEP_INTO: 1
|
||||
// STEP_OVER: 1
|
||||
//Breakpoint!
|
||||
a.inlineFun {
|
||||
val e = element
|
||||
}
|
||||
s(1)
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
fun bar() {
|
||||
val element = 1f
|
||||
B().foo {
|
||||
val e = element
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
C().bar()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: element
|
||||
// RESULT: 1.0: D
|
||||
|
||||
// EXPRESSION: this.prop
|
||||
// RESULT: 1: I
|
||||
|
||||
|
||||
frame = bar:9, C {frameInlineFunCallInsideInlineFunKotlinVariables}
|
||||
this = this = {frameInlineFunCallInsideInlineFunKotlinVariables.C@uniqueID}
|
||||
- Class has no fields
|
||||
local = element: float = 1.0 (sp = frameInlineFunCallInsideInlineFunKotlinVariables.kt, 7)
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
Vendored
+2
@@ -24,6 +24,8 @@ inline fun foo(f: () -> Unit) {
|
||||
frame = main:7, FrameSharedVarLocalVarKt {frameSharedVarLocalVar}
|
||||
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID} (sp = frameSharedVarLocalVar.kt, 3)
|
||||
local = var1: int = 1 (sp = frameSharedVarLocalVar.kt, 4)
|
||||
local = $i$f$foo: int = undefined (sp = null)
|
||||
local = $i$a$-foo-FrameSharedVarLocalVarKt$main$1: int = undefined (sp = null)
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package kt28087
|
||||
|
||||
fun main() {
|
||||
"a".indexed { index, c ->
|
||||
//Breakpoint!
|
||||
val a = 5
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun CharSequence.indexed(action: (index: Int, Char) -> Unit): Unit {
|
||||
var index = 0
|
||||
for (item in this) action(index++, item)
|
||||
}
|
||||
|
||||
// EXPRESSION: index
|
||||
// RESULT: 0: I
|
||||
@@ -0,0 +1,8 @@
|
||||
LineBreakpoint created at kt28087.kt:6
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
kt28087.kt:6
|
||||
Compile bytecode for index
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
+8
@@ -42,6 +42,7 @@ import org.jetbrains.eval4j.jdi.asValue
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.debugger.KotlinDebuggerTestBase
|
||||
import org.jetbrains.kotlin.idea.debugger.KotlinFrameExtraVariablesProvider
|
||||
import org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesState
|
||||
import org.jetbrains.kotlin.idea.debugger.evaluate.AbstractKotlinEvaluateExpressionTest.PrinterConfig.DescriptorViewOptions
|
||||
import org.jetbrains.kotlin.idea.debugger.invokeInManagerThread
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
@@ -57,6 +58,7 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestBase() {
|
||||
private var appender: AppenderSkeleton? = null
|
||||
|
||||
private var oldLogLevel: Level? = null
|
||||
private var oldShowKotlinVariables: Boolean = false
|
||||
private var oldShowFqTypeNames = false
|
||||
|
||||
override fun setUp() {
|
||||
@@ -66,6 +68,8 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestBase() {
|
||||
oldShowFqTypeNames = classRenderer.SHOW_FQ_TYPE_NAMES
|
||||
classRenderer.SHOW_FQ_TYPE_NAMES = true
|
||||
|
||||
oldShowKotlinVariables = ToggleKotlinVariablesState.getService().kotlinVariableView
|
||||
|
||||
oldLogLevel = logger.level
|
||||
logger.level = Level.DEBUG
|
||||
|
||||
@@ -82,6 +86,8 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestBase() {
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
ToggleKotlinVariablesState.getService().kotlinVariableView = oldShowKotlinVariables
|
||||
|
||||
logger.level = oldLogLevel
|
||||
logger.removeAppender(appender)
|
||||
|
||||
@@ -104,6 +110,8 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestBase() {
|
||||
val skipInPrintFrame = if (shouldPrintFrame) findListWithPrefixes(fileText, "// SKIP: ") else emptyList()
|
||||
val descriptorViewOptions = DescriptorViewOptions.valueOf(findStringWithPrefixes(fileText, "// DESCRIPTOR_VIEW_OPTIONS: ") ?: "FULL")
|
||||
|
||||
ToggleKotlinVariablesState.getService().kotlinVariableView = isDirectiveDefined(fileText, "// SHOW_KOTLIN_VARIABLES")
|
||||
|
||||
val expressions = loadTestDirectivesPairs(fileText, "// EXPRESSION: ", "// RESULT: ")
|
||||
|
||||
val blocks = findFilesWithBlocks(file).map { FileUtil.loadFile(it, true) }
|
||||
|
||||
Generated
+10
@@ -231,6 +231,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt22366.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt28087.kt")
|
||||
public void testKt28087() throws Exception {
|
||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt28087.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt5554OnlyIntsShouldBeCoerced.kt")
|
||||
public void testKt5554OnlyIntsShouldBeCoerced() throws Exception {
|
||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt5554OnlyIntsShouldBeCoerced.kt");
|
||||
@@ -655,6 +660,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/frameInlineFunCallInsideInlineFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("frameInlineFunCallInsideInlineFunKotlinVariables.kt")
|
||||
public void testFrameInlineFunCallInsideInlineFunKotlinVariables() throws Exception {
|
||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/frameInlineFunCallInsideInlineFunKotlinVariables.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("frameInnerClass.kt")
|
||||
public void testFrameInnerClass() throws Exception {
|
||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/frame/frameInnerClass.kt");
|
||||
|
||||
Reference in New Issue
Block a user