Do not use visitor for counting lambda ordinal for debugger
This commit is contained in:
@@ -17,53 +17,26 @@
|
|||||||
package org.jetbrains.kotlin.idea.debugger
|
package org.jetbrains.kotlin.idea.debugger
|
||||||
|
|
||||||
import com.intellij.debugger.engine.DebugProcessImpl
|
import com.intellij.debugger.engine.DebugProcessImpl
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.sun.jdi.*
|
import com.sun.jdi.*
|
||||||
import com.sun.tools.jdi.LocalVariableImpl
|
import com.sun.tools.jdi.LocalVariableImpl
|
||||||
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.psi.KtFunctionLiteralExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
|
||||||
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
fun isInsideInlineArgument(inlineArgument: KtFunction, location: Location, debugProcess: DebugProcessImpl): Boolean {
|
fun isInsideInlineArgument(inlineArgument: KtFunction, location: Location, debugProcess: DebugProcessImpl): Boolean {
|
||||||
return isInsideInlineArgument(inlineArgument, location.visibleVariables(debugProcess))
|
val visibleVariables = location.visibleVariables(debugProcess)
|
||||||
}
|
|
||||||
|
|
||||||
fun isInsideInlineArgument(inlineArgument: KtFunction, visibleVariables: List<LocalVariable>): Boolean {
|
|
||||||
val lambdaOrdinalIndex = runReadAction { lambdaOrdinalIndex(inlineArgument) }
|
val lambdaOrdinalIndex = runReadAction { lambdaOrdinalIndex(inlineArgument) }
|
||||||
val markerLocalVariables = visibleVariables.filter { it.name().startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT) }
|
val markerLocalVariables = visibleVariables.filter { it.name().startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT) }
|
||||||
for (variable in markerLocalVariables) {
|
return markerLocalVariables.firstOrNull { lambdaOrdinal(it.name()) == lambdaOrdinalIndex } != null
|
||||||
val lambdaOrdinal = lambdaOrdinal(variable.name())
|
|
||||||
if (lambdaOrdinalIndex[inlineArgument] == lambdaOrdinal) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun lambdaOrdinalIndex(elementAt: PsiElement): HashMap<KtFunction, Int> {
|
private fun lambdaOrdinalIndex(elementAt: KtFunction): Int {
|
||||||
val parent = elementAt.parents.firstIsInstanceOrNull<KtNamedFunction>()
|
val typeMapper = JetPositionManager.createTypeMapper(elementAt.getContainingJetFile())
|
||||||
|
|
||||||
val actualLambdaOrdinals = hashMapOf<KtFunction, Int>()
|
val type = CodegenBinding.asmTypeForAnonymousClass(typeMapper.bindingContext, elementAt)
|
||||||
parent?.accept(object : KtTreeVisitorVoid() {
|
return type.className.substringAfterLast("$").toInt()
|
||||||
override fun visitNamedFunction(function: KtNamedFunction) {
|
|
||||||
if (function != parent) {
|
|
||||||
actualLambdaOrdinals[function] = actualLambdaOrdinals.size + 1
|
|
||||||
}
|
|
||||||
super.visitNamedFunction(function)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunctionLiteralExpression(expression: KtFunctionLiteralExpression) {
|
|
||||||
actualLambdaOrdinals[expression.functionLiteral] = actualLambdaOrdinals.size + 1
|
|
||||||
super.visitFunctionLiteralExpression(expression)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return actualLambdaOrdinals
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Location.visibleVariables(debugProcess: DebugProcessImpl): List<LocalVariable> {
|
private fun Location.visibleVariables(debugProcess: DebugProcessImpl): List<LocalVariable> {
|
||||||
|
|||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
package isInsideInlineLambdaInLibrary
|
||||||
|
|
||||||
|
public fun test() {
|
||||||
|
val a = A()
|
||||||
|
//Breakpoint1
|
||||||
|
a.foo(1) { 1 }
|
||||||
|
|
||||||
|
// inside other lambda
|
||||||
|
a.foo(100) {
|
||||||
|
//Breakpoint2
|
||||||
|
a.foo(2) { 1 }
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
// inside variable declaration
|
||||||
|
//Breakpoint3
|
||||||
|
val x = a.foo(3) { 1 }
|
||||||
|
|
||||||
|
// inside object declaration
|
||||||
|
val y = object {
|
||||||
|
fun foo() {
|
||||||
|
//Breakpoint4
|
||||||
|
a.foo(4) { 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y.foo()
|
||||||
|
|
||||||
|
// inside local function
|
||||||
|
fun local() {
|
||||||
|
//Breakpoint5
|
||||||
|
a.foo(5) { 1 }
|
||||||
|
}
|
||||||
|
local()
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
inline fun foo(i: Int, f: (i: Int) -> Int): A {
|
||||||
|
f(i)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
LineBreakpoint created at isInsideInlineLambdaInLibrary.kt:6 lambdaOrdinal = 0
|
||||||
|
LineBreakpoint created at isInsideInlineLambdaInLibrary.kt:11 lambdaOrdinal = 0
|
||||||
|
LineBreakpoint created at isInsideInlineLambdaInLibrary.kt:17 lambdaOrdinal = 0
|
||||||
|
LineBreakpoint created at isInsideInlineLambdaInLibrary.kt:23 lambdaOrdinal = 0
|
||||||
|
LineBreakpoint created at isInsideInlineLambdaInLibrary.kt:31 lambdaOrdinal = 0
|
||||||
|
LineBreakpoint created at isInsideInlineLambda.kt:9 lambdaOrdinal = 0
|
||||||
|
LineBreakpoint created at isInsideInlineLambda.kt:17 lambdaOrdinal = 0
|
||||||
|
LineBreakpoint created at isInsideInlineLambda.kt:25 lambdaOrdinal = 0
|
||||||
|
LineBreakpoint created at isInsideInlineLambda.kt:33 lambdaOrdinal = 0
|
||||||
|
LineBreakpoint created at isInsideInlineLambda.kt:43 lambdaOrdinal = 0
|
||||||
|
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! isInsideInlineLambda.IsInsideInlineLambdaKt
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
isInsideInlineLambda.kt:9
|
||||||
|
Compile bytecode for it + 1
|
||||||
|
isInsideInlineLambda.kt:17
|
||||||
|
Compile bytecode for it + 2
|
||||||
|
isInsideInlineLambda.kt:25
|
||||||
|
Compile bytecode for it + 3
|
||||||
|
isInsideInlineLambda.kt:33
|
||||||
|
Compile bytecode for it + 4
|
||||||
|
isInsideInlineLambda.kt:43
|
||||||
|
Compile bytecode for it + 5
|
||||||
|
isInsideInlineLambdaInLibrary.kt:6
|
||||||
|
Compile bytecode for it + 11
|
||||||
|
isInsideInlineLambdaInLibrary.kt:11
|
||||||
|
Compile bytecode for it + 12
|
||||||
|
isInsideInlineLambdaInLibrary.kt:17
|
||||||
|
Compile bytecode for it + 13
|
||||||
|
isInsideInlineLambdaInLibrary.kt:23
|
||||||
|
Compile bytecode for it + 14
|
||||||
|
isInsideInlineLambdaInLibrary.kt:31
|
||||||
|
Compile bytecode for it + 15
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -17,6 +17,7 @@ stepOverIfWithInline.kt:24
|
|||||||
stepOverIfWithInline.kt:28
|
stepOverIfWithInline.kt:28
|
||||||
stepOverIfWithInline.kt:41
|
stepOverIfWithInline.kt:41
|
||||||
stepOverIfWithInline.kt:28
|
stepOverIfWithInline.kt:28
|
||||||
|
stepOverIfWithInline.kt:28
|
||||||
stepOverIfWithInline.kt:32
|
stepOverIfWithInline.kt:32
|
||||||
stepOverIfWithInline.kt:41
|
stepOverIfWithInline.kt:41
|
||||||
stepOverIfWithInline.kt:32
|
stepOverIfWithInline.kt:32
|
||||||
|
|||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
package isInsideInlineLambda
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a = A()
|
||||||
|
|
||||||
|
// EXPRESSION: it + 1
|
||||||
|
// RESULT: 2: I
|
||||||
|
//Breakpoint! (0)
|
||||||
|
a.foo(1) { 1 }
|
||||||
|
|
||||||
|
|
||||||
|
// inside other lambda
|
||||||
|
a.foo(1) {
|
||||||
|
// EXPRESSION: it + 2
|
||||||
|
// RESULT: 3: I
|
||||||
|
//Breakpoint! (0)
|
||||||
|
a.foo(1) { 1 }
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
// inside variable declaration
|
||||||
|
// EXPRESSION: it + 3
|
||||||
|
// RESULT: 4: I
|
||||||
|
//Breakpoint! (0)
|
||||||
|
val x = a.foo(1) { 1 }
|
||||||
|
|
||||||
|
// inside object declaration
|
||||||
|
val y = object {
|
||||||
|
fun foo() {
|
||||||
|
// EXPRESSION: it + 4
|
||||||
|
// RESULT: 5: I
|
||||||
|
//Breakpoint! (0)
|
||||||
|
a.foo(1) { 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y.foo()
|
||||||
|
|
||||||
|
// inside local function
|
||||||
|
fun local() {
|
||||||
|
// EXPRESSION: it + 5
|
||||||
|
// RESULT: 6: I
|
||||||
|
//Breakpoint! (0)
|
||||||
|
a.foo(1) { 1 }
|
||||||
|
}
|
||||||
|
local()
|
||||||
|
|
||||||
|
isInsideInlineLambdaInLibrary.test()
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
inline fun foo(i: Int, f: (i: Int) -> Int): A {
|
||||||
|
f(i)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADDITIONAL_BREAKPOINT: isInsideInlineLambdaInLibrary.kt:Breakpoint1:(0)
|
||||||
|
// EXPRESSION: it + 11
|
||||||
|
// RESULT: 12: I
|
||||||
|
|
||||||
|
// ADDITIONAL_BREAKPOINT: isInsideInlineLambdaInLibrary.kt:Breakpoint2:(0)
|
||||||
|
// EXPRESSION: it + 12
|
||||||
|
// RESULT: 14: I
|
||||||
|
|
||||||
|
// ADDITIONAL_BREAKPOINT: isInsideInlineLambdaInLibrary.kt:Breakpoint3:(0)
|
||||||
|
// EXPRESSION: it + 13
|
||||||
|
// RESULT: 16: I
|
||||||
|
|
||||||
|
// ADDITIONAL_BREAKPOINT: isInsideInlineLambdaInLibrary.kt:Breakpoint4:(0)
|
||||||
|
// EXPRESSION: it + 14
|
||||||
|
// RESULT: 18: I
|
||||||
|
|
||||||
|
// ADDITIONAL_BREAKPOINT: isInsideInlineLambdaInLibrary.kt:Breakpoint5:(0)
|
||||||
|
// EXPRESSION: it + 15
|
||||||
|
// RESULT: 20: I
|
||||||
+1
-1
@@ -44,4 +44,4 @@ inline fun foo(f: () -> Int): Int {
|
|||||||
|
|
||||||
fun test(i: Int) = 1
|
fun test(i: Int) = 1
|
||||||
|
|
||||||
// STEP_OVER: 21
|
// STEP_OVER: 22
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.idea.debugger
|
package org.jetbrains.kotlin.idea.debugger
|
||||||
|
|
||||||
import com.intellij.debugger.DebuggerInvocationUtil
|
import com.intellij.debugger.DebuggerInvocationUtil
|
||||||
import com.intellij.debugger.DebuggerManagerEx
|
|
||||||
import com.intellij.debugger.SourcePosition
|
import com.intellij.debugger.SourcePosition
|
||||||
import com.intellij.debugger.actions.MethodSmartStepTarget
|
import com.intellij.debugger.actions.MethodSmartStepTarget
|
||||||
import com.intellij.debugger.actions.SmartStepTarget
|
import com.intellij.debugger.actions.SmartStepTarget
|
||||||
@@ -269,7 +268,6 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
|||||||
val document = runReadAction { PsiDocumentManager.getInstance(myProject).getDocument(file) } ?: return
|
val document = runReadAction { PsiDocumentManager.getInstance(myProject).getDocument(file) } ?: return
|
||||||
val breakpointManager = XDebuggerManager.getInstance(myProject).getBreakpointManager()
|
val breakpointManager = XDebuggerManager.getInstance(myProject).getBreakpointManager()
|
||||||
val kotlinFieldBreakpointType = findBreakpointType(KotlinFieldBreakpointType::class.java)
|
val kotlinFieldBreakpointType = findBreakpointType(KotlinFieldBreakpointType::class.java)
|
||||||
val kotlinLineBreakpointType = findBreakpointType(KotlinLineBreakpointType::class.java)
|
|
||||||
val virtualFile = file.getVirtualFile()
|
val virtualFile = file.getVirtualFile()
|
||||||
|
|
||||||
val runnable = {
|
val runnable = {
|
||||||
@@ -302,27 +300,8 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (comment.startsWith("//Breakpoint!")) {
|
else if (comment.startsWith("//Breakpoint!")) {
|
||||||
val javaBreakpoint = createBreakpointOfType(
|
val ordinal = if (comment.contains(" (")) comment.substringAfter("//Breakpoint! (").substringBefore(")").toInt() else null
|
||||||
breakpointManager,
|
createLineBreakpoint(breakpointManager, file, lineIndex, ordinal)
|
||||||
kotlinLineBreakpointType as XLineBreakpointType<XBreakpointProperties<*>>,
|
|
||||||
lineIndex,
|
|
||||||
virtualFile)
|
|
||||||
if (javaBreakpoint is LineBreakpoint<*>) {
|
|
||||||
|
|
||||||
if (comment.contains("(")) {
|
|
||||||
val ordinal = comment.substringAfter("//Breakpoint! (").substringBefore(")").toInt()
|
|
||||||
|
|
||||||
val properties = javaBreakpoint.xBreakpoint.properties as? JavaLineBreakpointProperties ?: continue
|
|
||||||
properties.lambdaOrdinal = ordinal
|
|
||||||
|
|
||||||
BreakpointManager.addBreakpoint(javaBreakpoint)
|
|
||||||
println("LineBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1} lambdaOrdinal = $ordinal", ProcessOutputTypes.SYSTEM)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BreakpointManager.addBreakpoint(javaBreakpoint)
|
|
||||||
println("LineBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1}", ProcessOutputTypes.SYSTEM)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw AssertionError("Cannot create breakpoint at line ${lineIndex + 1}")
|
throw AssertionError("Cannot create breakpoint at line ${lineIndex + 1}")
|
||||||
@@ -338,6 +317,33 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createLineBreakpoint(
|
||||||
|
breakpointManager: XBreakpointManager,
|
||||||
|
file: PsiFile,
|
||||||
|
lineIndex: Int,
|
||||||
|
lambdaOrdinal: Int?
|
||||||
|
) {
|
||||||
|
val kotlinLineBreakpointType = findBreakpointType(KotlinLineBreakpointType::class.java)
|
||||||
|
val javaBreakpoint = createBreakpointOfType(
|
||||||
|
breakpointManager,
|
||||||
|
kotlinLineBreakpointType as XLineBreakpointType<XBreakpointProperties<*>>,
|
||||||
|
lineIndex,
|
||||||
|
file.virtualFile)
|
||||||
|
if (javaBreakpoint is LineBreakpoint<*>) {
|
||||||
|
if (lambdaOrdinal != null) {
|
||||||
|
val properties = javaBreakpoint.xBreakpoint.properties as? JavaLineBreakpointProperties ?: return
|
||||||
|
properties.lambdaOrdinal = lambdaOrdinal
|
||||||
|
|
||||||
|
BreakpointManager.addBreakpoint(javaBreakpoint)
|
||||||
|
println("LineBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1} lambdaOrdinal = $lambdaOrdinal", ProcessOutputTypes.SYSTEM)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BreakpointManager.addBreakpoint(javaBreakpoint)
|
||||||
|
println("LineBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1}", ProcessOutputTypes.SYSTEM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createBreakpointOfType(
|
private fun createBreakpointOfType(
|
||||||
breakpointManager: XBreakpointManager,
|
breakpointManager: XBreakpointManager,
|
||||||
breakpointType: XLineBreakpointType<XBreakpointProperties<*>>,
|
breakpointType: XLineBreakpointType<XBreakpointProperties<*>>,
|
||||||
@@ -365,12 +371,19 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
|||||||
val breakpoints = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, "// ADDITIONAL_BREAKPOINT: ")
|
val breakpoints = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, "// ADDITIONAL_BREAKPOINT: ")
|
||||||
for (breakpoint in breakpoints) {
|
for (breakpoint in breakpoints) {
|
||||||
val position = breakpoint.split(".kt:")
|
val position = breakpoint.split(".kt:")
|
||||||
assert(position.size() == 2) { "Couldn't parse position from test directive: directive = $breakpoint" }
|
assert(position.size == 2) { "Couldn't parse position from test directive: directive = $breakpoint" }
|
||||||
createBreakpoint(position[0], position[1])
|
var lineMarker = position[1]
|
||||||
|
var ordinal: Int? = null
|
||||||
|
if (lineMarker.contains(":(") && lineMarker.endsWith(")")) {
|
||||||
|
val lineMarkerAndOrdinal = lineMarker.split(":(")
|
||||||
|
lineMarker = lineMarkerAndOrdinal[0]
|
||||||
|
ordinal = lineMarkerAndOrdinal[1].substringBefore(")").toInt()
|
||||||
|
}
|
||||||
|
createBreakpoint(position[0], lineMarker, ordinal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createBreakpoint(fileName: String, lineMarker: String) {
|
private fun createBreakpoint(fileName: String, lineMarker: String, ordinal: Int?) {
|
||||||
val project = getProject()!!
|
val project = getProject()!!
|
||||||
val sourceFiles = runReadAction {
|
val sourceFiles = runReadAction {
|
||||||
FilenameIndex.getAllFilesByExt(project, "kt").filter {
|
FilenameIndex.getAllFilesByExt(project, "kt").filter {
|
||||||
@@ -384,16 +397,13 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
|||||||
val runnable = Runnable() {
|
val runnable = Runnable() {
|
||||||
val psiSourceFile = PsiManager.getInstance(project).findFile(sourceFiles.first())!!
|
val psiSourceFile = PsiManager.getInstance(project).findFile(sourceFiles.first())!!
|
||||||
|
|
||||||
val breakpointManager = DebuggerManagerEx.getInstanceEx(project)?.getBreakpointManager()!!
|
val breakpointManager = XDebuggerManager.getInstance(myProject).getBreakpointManager()
|
||||||
val document = PsiDocumentManager.getInstance(project).getDocument(psiSourceFile)!!
|
val document = PsiDocumentManager.getInstance(project).getDocument(psiSourceFile)!!
|
||||||
|
|
||||||
val index = psiSourceFile.getText()!!.indexOf(lineMarker)
|
val index = psiSourceFile.getText()!!.indexOf(lineMarker)
|
||||||
val lineNumber = document.getLineNumber(index) + 1
|
val lineNumber = document.getLineNumber(index) + 1 // lineMarker is for previous line
|
||||||
|
|
||||||
val breakpoint = breakpointManager.addLineBreakpoint(document, lineNumber)
|
createLineBreakpoint(breakpointManager, psiSourceFile, lineNumber, ordinal)
|
||||||
if (breakpoint != null) {
|
|
||||||
println("LineBreakpoint created at " + psiSourceFile.getName() + ":" + lineNumber, ProcessOutputTypes.SYSTEM);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerInvocationUtil.invokeAndWait(project, runnable, ModalityState.defaultModalityState())
|
DebuggerInvocationUtil.invokeAndWait(project, runnable, ModalityState.defaultModalityState())
|
||||||
|
|||||||
+6
@@ -682,6 +682,12 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
|||||||
doMultipleBreakpointsTest(fileName);
|
doMultipleBreakpointsTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("isInsideInlineLambda.kt")
|
||||||
|
public void testIsInsideInlineLambda() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/isInsideInlineLambda.kt");
|
||||||
|
doMultipleBreakpointsTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("localFun.kt")
|
@TestMetadata("localFun.kt")
|
||||||
public void testLocalFun() throws Exception {
|
public void testLocalFun() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/localFun.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/localFun.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user