diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentFactory.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentFactory.kt index c433acfebe3..0a824a0ac91 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentFactory.kt @@ -16,34 +16,51 @@ package org.jetbrains.kotlin.idea.debugger.evaluate -import com.intellij.debugger.engine.evaluation.CodeFragmentFactory -import com.intellij.debugger.engine.evaluation.TextWithImports -import com.intellij.psi.PsiElement -import com.intellij.openapi.project.Project -import com.intellij.psi.JavaCodeFragment -import org.jetbrains.kotlin.idea.JetFileType -import org.jetbrains.kotlin.psi.JetExpressionCodeFragment -import com.intellij.psi.PsiCodeBlock -import com.intellij.debugger.engine.evaluation.CodeFragmentKind -import org.jetbrains.kotlin.idea.debugger.KotlinEditorTextProvider -import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.psi.JetExpression -import org.jetbrains.kotlin.psi.JetBlockCodeFragment -import org.jetbrains.kotlin.asJava.KotlinLightClass import com.intellij.debugger.DebuggerManagerEx -import org.jetbrains.kotlin.psi.JetCodeFragment -import org.jetbrains.kotlin.types.JetType -import com.intellij.util.concurrency.Semaphore -import java.util.concurrent.atomic.AtomicReference +import com.intellij.debugger.engine.evaluation.CodeFragmentFactory +import com.intellij.debugger.engine.evaluation.CodeFragmentKind +import com.intellij.debugger.engine.evaluation.TextWithImports import com.intellij.openapi.progress.ProgressManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Key +import com.intellij.psi.JavaCodeFragment +import com.intellij.psi.PsiCodeBlock +import com.intellij.psi.PsiElement +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.util.concurrency.Semaphore +import com.intellij.xdebugger.XDebuggerManager +import com.intellij.xdebugger.impl.XDebugSessionImpl +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup +import com.sun.jdi.ObjectReference +import com.sun.jdi.Value +import org.jetbrains.kotlin.asJava.KotlinLightClass +import org.jetbrains.kotlin.idea.JetFileType +import org.jetbrains.kotlin.idea.debugger.KotlinEditorTextProvider +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.types.JetType +import java.util.HashMap +import java.util.concurrent.atomic.AtomicReference class KotlinCodeFragmentFactory: CodeFragmentFactory() { override fun createCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment { val codeFragment = if (item.getKind() == CodeFragmentKind.EXPRESSION) { - JetExpressionCodeFragment(project, "fragment.kt", item.getText(), item.getImports(), getContextElement(context)) + JetExpressionCodeFragment( + project, + "fragment.kt", + item.getText(), + item.getImports(), + getWrappedContextElement(project, context) + ) } else { - JetBlockCodeFragment(project, "fragment.kt", item.getText(), item.getImports(), getContextElement(context)) + JetBlockCodeFragment( + project, + "fragment.kt", + item.getText(), + item.getImports(), + getWrappedContextElement(project, context) + ) } codeFragment.putCopyableUserData(JetCodeFragment.RUNTIME_TYPE_EVALUATOR, { @@ -79,6 +96,9 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() { return codeFragment } + private fun getWrappedContextElement(project: Project, context: PsiElement?) + = wrapContextIfNeeded(project, getContextElement(context)) + override fun createPresentationCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment { return createCodeFragment(item, context, project) } @@ -96,6 +116,9 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() { override fun getEvaluatorBuilder() = KotlinEvaluationBuilder companion object { + public val LABEL_VARIABLE_VALUE_KEY: Key = Key.create("_label_variable_value_key_") + public val DEBUG_LABEL_SUFFIX: String = "_DebugLabel" + fun getContextElement(elementAt: PsiElement?): PsiElement? { if (elementAt == null) return null @@ -107,16 +130,65 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() { return getContextElement(elementAt.getOrigin()) } - // If label for some variable is set - if (elementAt.getParent() is JetCodeFragment) { - return elementAt.getParent().getContext() - } - val expressionAtOffset = PsiTreeUtil.findElementOfClassAtOffset(elementAt.getContainingFile()!!, elementAt.getTextOffset(), javaClass(), false) if (expressionAtOffset != null) { return expressionAtOffset } return KotlinEditorTextProvider.findExpressionInner(elementAt, true) } + + //internal for tests + fun createCodeFragmentForLabeledObjects(markupMap: Map<*, ValueMarkup>): Pair> { + val sb = StringBuilder() + val labeledObjects = HashMap() + for ((value, markup) in markupMap.entrySet()) { + val labelName = markup.getText() + if (!Name.isValidIdentifier(labelName)) continue + + val objectRef = value as ObjectReference + + val typeName = value.type().name() + val labelNameWithSuffix = labelName + DEBUG_LABEL_SUFFIX + sb.append("val ").append(labelNameWithSuffix).append(": ").append(typeName).append("? = null\n") + + labeledObjects.put(labelNameWithSuffix, objectRef) + } + sb.append("val _debug_context_val = 1") + return sb.toString() to labeledObjects + } } -} + + private fun wrapContextIfNeeded(project: Project, originalContext: PsiElement?): PsiElement? { + val session = XDebuggerManager.getInstance(project).getCurrentSession() as? XDebugSessionImpl + ?: return originalContext + + val markupMap = session.getValueMarkers()?.getAllMarkers() + if (markupMap == null || markupMap.isEmpty()) return originalContext + + val (text, labels) = createCodeFragmentForLabeledObjects(markupMap) + if (text.isEmpty()) return originalContext + + return createWrappingContext(text, labels, originalContext, project) + } + + // internal for test + fun createWrappingContext( + newFragmentText: String, + labels: Map, + originalContext: PsiElement?, + project: Project + ): PsiElement? { + val codeFragment = JetPsiFactory(project).createBlockCodeFragment(newFragmentText, originalContext) + + codeFragment.accept(object : JetTreeVisitorVoid() { + override fun visitProperty(property: JetProperty) { + val reference = labels.get(property.getName()) + if (reference != null) { + property.putUserData(LABEL_VARIABLE_VALUE_KEY, reference) + } + } + }) + + return getContextElement(codeFragment.findElementAt(codeFragment.getText().length() - 1)) + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt index 17391dbb4cc..8fa7b50fb19 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt @@ -44,6 +44,7 @@ import com.sun.jdi.request.EventRequest import org.jetbrains.eval4j.* import org.jetbrains.eval4j.jdi.JDIEval import org.jetbrains.eval4j.jdi.asJdiValue +import org.jetbrains.eval4j.jdi.asValue import org.jetbrains.eval4j.jdi.makeInitialFrame import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.binding.CodegenBinding @@ -80,7 +81,7 @@ import org.jetbrains.kotlin.types.Flexibility import org.jetbrains.org.objectweb.asm.* import org.jetbrains.org.objectweb.asm.Opcodes.ASM5 import org.jetbrains.org.objectweb.asm.tree.MethodNode -import java.util.Collections +import java.util.* private val RECEIVER_NAME = "\$receiver" private val THIS_NAME = "this" @@ -176,7 +177,7 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment, if (extractionResult == null) { throw IllegalStateException("Code fragment cannot be extracted to function") } - val parametersDescriptor = extractionResult.getParametersForDebugger() + val parametersDescriptor = extractionResult.getParametersForDebugger(codeFragment) val extractedFunction = extractionResult.declaration as JetNamedFunction val classFileFactory = createClassFileFactory(codeFragment, extractedFunction, context, parametersDescriptor) @@ -287,8 +288,22 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment, return jdiValue.asJdiValue(vm, jdiValue.asmType) } - private fun ExtractionResult.getParametersForDebugger(): ParametersDescriptor { + private fun ExtractionResult.getParametersForDebugger(fragment: JetCodeFragment): ParametersDescriptor { return runReadAction { + val valuesForLabels = HashMap() + + val contextElementFile = fragment.getContext()?.getContainingFile() + if (contextElementFile is JetCodeFragment) { + contextElementFile.accept(object: JetTreeVisitorVoid() { + override fun visitProperty(property: JetProperty) { + val value = property.getUserData(KotlinCodeFragmentFactory.LABEL_VARIABLE_VALUE_KEY) + if (value != null) { + valuesForLabels.put(property.getName(), value.asValue()) + } + } + }) + } + val parameters = ParametersDescriptor() val receiver = config.descriptor.receiverParameter if (receiver != null) { @@ -301,7 +316,7 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment, param.argumentText.startsWith("::") -> param.argumentText.substring(2) else -> param.argumentText } - parameters.add(paramName, param.getParameterType(true)) + parameters.add(paramName, param.getParameterType(true), valuesForLabels[paramName]) } parameters } @@ -310,7 +325,12 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment, private fun EvaluationContextImpl.getArgumentsForEval4j(parameters: ParametersDescriptor, parameterTypes: Array): List { val frameVisitor = FrameVisitor(this) return parameters.zip(parameterTypes).map { - frameVisitor.findValue(it.first.callText, it.second, checkType = false, failIfNotFound = true)!! + if (it.first.value != null) { + it.first.value!! + } + else { + frameVisitor.findValue(it.first.callText, it.second, checkType = false, failIfNotFound = true)!! + } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt index b761a5694d9..931f1117a58 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt @@ -153,6 +153,11 @@ private fun getExpressionToAddDebugExpressionBefore(tmpFile: JetFile, contextEle return CodeInsightUtils.getTopmostElementAtOffset(elementAtOffset, lineStart) ?: elementAtOffset } + val containingFile = contextElement.getContainingFile() + if (containingFile is JetCodeFragment) { + return getExpressionToAddDebugExpressionBefore(tmpFile, containingFile.getContext(), line) + } + fun shouldStop(el: PsiElement?, p: PsiElement?) = p is JetBlockExpression || el is JetDeclaration var elementAt = tmpFile.getElementInCopy(contextElement) @@ -239,28 +244,25 @@ private fun addDebugExpressionBeforeContextElement(codeFragment: JetCodeFragment parent.addBefore(psiFactory.createNewLine(), elementBefore) - val debugExpression = codeFragment.getContentElement() ?: return emptyList() - - val expressions = ArrayList() - - fun insertExpression(expr: JetExpression) { - val newDebugExpression = parent.addBefore(expr, elementBefore) ?: return - - expressions.add(newDebugExpression as JetExpression) - - parent.addBefore(psiFactory.createNewLine(), elementBefore) - } - - when (debugExpression) { - is JetBlockExpression -> { - for (statement in debugExpression.getStatements()) { - insertExpression(statement) + fun insertExpression(expr: JetElement?): List { + when (expr) { + is JetBlockExpression -> return expr.getStatements().flatMap { insertExpression(it) } + is JetExpression -> { + val newDebugExpression = parent.addBefore(expr, elementBefore) ?: return emptyList() + parent.addBefore(psiFactory.createNewLine(), elementBefore) + return listOf(newDebugExpression as JetExpression) } } - is JetExpression -> insertExpression(debugExpression) + return emptyList() } - return expressions + val containingFile = codeFragment.getContext()?.getContainingFile() + if (containingFile is JetCodeFragment) { + insertExpression(containingFile.getContentElement() as? JetExpression) + } + + val debugExpression = codeFragment.getContentElement() ?: return emptyList() + return insertExpression(debugExpression) } private fun replaceByRunFunction(expression: JetExpression): JetCallExpression { diff --git a/idea/testData/debugger/tinyApp/outs/allFilesPresentInLabels.out b/idea/testData/debugger/tinyApp/outs/allFilesPresentInLabels.out new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/debugger/tinyApp/outs/lCallOnLabeledObj.out b/idea/testData/debugger/tinyApp/outs/lCallOnLabeledObj.out new file mode 100644 index 00000000000..8da3076a73e --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/lCallOnLabeledObj.out @@ -0,0 +1,8 @@ +LineBreakpoint created at lCallOnLabeledObj.kt:6 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! lCallOnLabeledObj.LCallOnLabeledObjPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +lCallOnLabeledObj.kt:6 +Compile bytecode for myClass_DebugLabel.foo() +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/lSeveralLabels.out b/idea/testData/debugger/tinyApp/outs/lSeveralLabels.out new file mode 100644 index 00000000000..91b13793640 --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/lSeveralLabels.out @@ -0,0 +1,10 @@ +LineBreakpoint created at lSeveralLabels.kt:8 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! lSeveralLabels.LSeveralLabelsPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +lSeveralLabels.kt:8 +Compile bytecode for a_DebugLabel +Compile bytecode for b_DebugLabel +Compile bytecode for c_DebugLabel +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/lSimple.out b/idea/testData/debugger/tinyApp/outs/lSimple.out new file mode 100644 index 00000000000..0787991ff56 --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/lSimple.out @@ -0,0 +1,9 @@ +LineBreakpoint created at lSimple.kt:6 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! lSimple.LSimplePackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +lSimple.kt:6 +Compile bytecode for a +Compile bytecode for aLabel_DebugLabel +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lCallOnLabeledObj.kt b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lCallOnLabeledObj.kt new file mode 100644 index 00000000000..1bc1275e6e8 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lCallOnLabeledObj.kt @@ -0,0 +1,16 @@ +package lCallOnLabeledObj + +fun main(args: Array) { + val myClass = MyClass() + //Breakpoint! + val a = 1 +} + +class MyClass { + fun foo() = 1 +} + +// DEBUG_LABEL: myClass = myClass + +// EXPRESSION: myClass_DebugLabel.foo() +// RESULT: 1: I \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lSeveralLabels.kt b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lSeveralLabels.kt new file mode 100644 index 00000000000..5a6e3021f44 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lSeveralLabels.kt @@ -0,0 +1,22 @@ +package lSeveralLabels + +fun main(args: Array) { + val a = "str1" + val b = "str2" + val c = "str3" + //Breakpoint! + val d = 1 +} + +// DEBUG_LABEL: a = a +// DEBUG_LABEL: b = b +// DEBUG_LABEL: c = c + +// EXPRESSION: a_DebugLabel +// RESULT: "str1": Ljava/lang/String; + +// EXPRESSION: b_DebugLabel +// RESULT: "str2": Ljava/lang/String; + +// EXPRESSION: c_DebugLabel +// RESULT: "str3": Ljava/lang/String; \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lSimple.kt b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lSimple.kt new file mode 100644 index 00000000000..f19c9f2d732 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lSimple.kt @@ -0,0 +1,15 @@ +package lSimple + +fun main(args: Array) { + val a = "str" + //Breakpoint! + val b = 1 +} + +// DEBUG_LABEL: a = aLabel + +// EXPRESSION: a +// RESULT: "str": Ljava/lang/String; + +// EXPRESSION: aLabel_DebugLabel +// RESULT: "str": Ljava/lang/String; \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractKotlinEvaluateExpressionTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractKotlinEvaluateExpressionTest.kt index 96f9d9f8407..bc35fd78481 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractKotlinEvaluateExpressionTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractKotlinEvaluateExpressionTest.kt @@ -16,8 +16,6 @@ package org.jetbrains.kotlin.idea.debugger.evaluate -import com.intellij.debugger.DebuggerInvocationUtil -import com.intellij.debugger.DebuggerManagerEx import com.intellij.debugger.SourcePosition import com.intellij.debugger.engine.ContextUtil import com.intellij.debugger.engine.SourcePositionProvider @@ -35,13 +33,11 @@ import com.intellij.debugger.ui.tree.LocalVariableDescriptor import com.intellij.debugger.ui.tree.StackFrameDescriptor import com.intellij.debugger.ui.tree.StaticDescriptor import com.intellij.execution.process.ProcessOutputTypes -import com.intellij.openapi.application.ModalityState import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.io.FileUtil -import com.intellij.psi.PsiDocumentManager -import com.intellij.psi.PsiManager -import com.intellij.psi.search.FilenameIndex +import com.intellij.psi.PsiElement import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup import com.sun.jdi.ObjectReference import org.apache.log4j.AppenderSkeleton import org.apache.log4j.Level @@ -58,6 +54,7 @@ import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.junit.Assert import java.io.File import java.util.Collections +import kotlin.test.fail public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestBase() { private val logger = Logger.getLogger(javaClass())!! @@ -278,12 +275,39 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestB return mainFile.getParentFile()?.listFiles()?.filter { it.name.startsWith(mainFileName) && it.name != mainFileName } ?: Collections.emptyList() } + private fun createContextElement(context: SuspendContextImpl): PsiElement { + val contextElement = ContextUtil.getContextElement(debuggerContext) + Assert.assertTrue("KotlinCodeFragmentFactory should be accepted for context element otherwise default evaluator will be called. ContextElement = ${contextElement.getText()}", + KotlinCodeFragmentFactory().isContextAccepted(contextElement)) + + if (contextElement != null) { + val labelsAsText = InTextDirectivesUtils.findLinesWithPrefixesRemoved(contextElement.getContainingFile().getText(), "// DEBUG_LABEL: ") + if (labelsAsText.isEmpty()) return contextElement + + val markupMap = hashMapOf() + for (labelAsText in labelsAsText) { + val labelParts = labelAsText.splitBy("=") + assert(labelParts.size() == 2) { "Wrong format for DEBUG_LABEL directive: // DEBUG_LABEL: {localVariableName} = {labelText}"} + val localVariableName = labelParts[0].trim() + val labelName = labelParts[1].trim() + val localVariable = context.getFrameProxy().visibleVariableByName(localVariableName) + assert(localVariable != null) { "Couldn't find localVariable for label: name = $localVariableName" } + val localVariableValue = context.getFrameProxy().getValue(localVariable) as? ObjectReference + assert(localVariableValue != null) { "Local variable $localVariableName should be an ObjectReference" } + markupMap.put(localVariableValue, ValueMarkup(labelName, null, labelName)) + } + + val (text, labels) = KotlinCodeFragmentFactory.createCodeFragmentForLabeledObjects(markupMap) + return KotlinCodeFragmentFactory().createWrappingContext(text, labels, KotlinCodeFragmentFactory.getContextElement(contextElement), getProject())!! + } + + return contextElement!! + } + private fun SuspendContextImpl.evaluate(text: String, codeFragmentKind: CodeFragmentKind, expectedResult: String) { runReadAction { val sourcePosition = ContextUtil.getSourcePosition(this) - val contextElement = ContextUtil.getContextElement(sourcePosition)!! - Assert.assertTrue("KotlinCodeFragmentFactory should be accepted for context element otherwise default evaluator will be called. ContextElement = ${contextElement.getText()}", - KotlinCodeFragmentFactory().isContextAccepted(contextElement)) + val contextElement = createContextElement(this) try { diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java index 2bb8bb685db..0aad181bb24 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java @@ -526,6 +526,33 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat } } + @TestMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Labels extends AbstractKotlinEvaluateExpressionTest { + public void testAllFilesPresentInLabels() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("lCallOnLabeledObj.kt") + public void testLCallOnLabeledObj() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lCallOnLabeledObj.kt"); + doSingleBreakpointTest(fileName); + } + + @TestMetadata("lSeveralLabels.kt") + public void testLSeveralLabels() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lSeveralLabels.kt"); + doSingleBreakpointTest(fileName); + } + + @TestMetadata("lSimple.kt") + public void testLSimple() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/labels/lSimple.kt"); + doSingleBreakpointTest(fileName); + } + } + @TestMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/lambdas") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)