Make breakpoints work inside nameless function bodies in inline calls
This commit is contained in:
@@ -181,15 +181,27 @@ class DebuggerClassNameProvider(val myDebugProcess: DebugProcess, val scopes: Li
|
||||
private fun inlineCallClassPatterns(typeMapper: KotlinTypeMapper, element: KtElement): List<String> {
|
||||
val context = typeMapper.bindingContext
|
||||
|
||||
val (inlineCall, functionLiteral) = runReadAction {
|
||||
element.parents.filterIsInstance<KtFunctionLiteral>().map {
|
||||
val lambdaExpression = it.parent as? KtLambdaExpression ?: return@map null
|
||||
val ktCallExpression =
|
||||
lambdaExpression.typedParent<KtValueArgument>()?.typedParent<KtValueArgumentList>()?.typedParent<KtCallExpression>() ?:
|
||||
lambdaExpression.typedParent<KtLambdaArgument>()?.typedParent<KtCallExpression>() ?:
|
||||
return@map null
|
||||
val (inlineCall, ktAnonymousClassElementProducer) = runReadAction {
|
||||
element.parents.map {
|
||||
val ktCallExpression: KtCallExpression = when(it) {
|
||||
is KtFunctionLiteral -> {
|
||||
val lambdaExpression = it.parent as? KtLambdaExpression
|
||||
// call(param, { <it> })
|
||||
lambdaExpression?.typedParent<KtValueArgument>()?.typedParent<KtValueArgumentList>()?.typedParent<KtCallExpression>() ?:
|
||||
|
||||
ktCallExpression to it
|
||||
// call { <it> }
|
||||
lambdaExpression?.typedParent<KtLambdaArgument>()?.typedParent<KtCallExpression>()
|
||||
}
|
||||
|
||||
is KtNamedFunction -> {
|
||||
// call(fun () {})
|
||||
it.typedParent<KtValueArgument>()?.typedParent<KtValueArgumentList>()?.typedParent<KtCallExpression>()
|
||||
}
|
||||
|
||||
else -> null
|
||||
} ?: return@map null
|
||||
|
||||
ktCallExpression to (it as KtElement)
|
||||
}.lastOrNull {
|
||||
it != null && isInlineCall(context, it.component1())
|
||||
}
|
||||
@@ -200,7 +212,9 @@ class DebuggerClassNameProvider(val myDebugProcess: DebugProcess, val scopes: Li
|
||||
val resolvedCall = runReadAction { inlineCall.getResolvedCall(context) } ?: return emptyList()
|
||||
val inlineFunctionName = resolvedCall.resultingDescriptor.name
|
||||
|
||||
val originalInternalClassName = CodegenBinding.asmTypeForAnonymousClass(typeMapper.bindingContext, functionLiteral).internalName
|
||||
val originalInternalClassName = CodegenBinding.asmTypeForAnonymousClass(
|
||||
typeMapper.bindingContext, ktAnonymousClassElementProducer).internalName
|
||||
|
||||
val ownerDescriptorName = lexicalScope.ownerDescriptor.name
|
||||
|
||||
val mangledInternalClassName = originalInternalClassName.funPrefix() + (if (ownerDescriptorName.isSpecial) "\$\$special\$" else "$") +
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
LineBreakpoint created at stopInNamelessFunInInlineCall.kt:9
|
||||
!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! stopInNamelessFunInInlineCall.StopInNamelessFunInInlineCallKt
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
stopInNamelessFunInInlineCall.kt:9
|
||||
stopInNamelessFunInInlineCall.kt:10
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package stopInNamelessFunInInlineCall
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val a = 1
|
||||
|
||||
inlineFun(fun (): Unit {
|
||||
{
|
||||
//Breakpoint!
|
||||
foo(a)
|
||||
foo(a)
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
inline fun inlineFun(f: () -> Any) {
|
||||
f()
|
||||
}
|
||||
|
||||
fun foo(a: Any) {}
|
||||
@@ -764,6 +764,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
doStepOverTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stopInNamelessFunInInlineCall.kt")
|
||||
public void testStopInNamelessFunInInlineCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stopInNamelessFunInInlineCall.kt");
|
||||
doStepOverTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stopInNonInlinedLambdaInInlineCallWithClosure.kt")
|
||||
public void testStopInNonInlinedLambdaInInlineCallWithClosure() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stopInNonInlinedLambdaInInlineCallWithClosure.kt");
|
||||
|
||||
Reference in New Issue
Block a user