debugging Android Studio 4.2.2 -为什么debbuger不评估内部函数中的参数?

j5fpnvbx  于 2022-11-14  发布在  Android
关注(0)|答案(1)|浏览(143)
  • Android Studio 4.2.2* 会对局部和全局变量求值,但当位于内部函数中时,不会对参数函数求值。

直到以前的版本,这工作得很完美。

fun a(p:param) {
fun b(){
var v = p+1 // Here
}
}

假设有人试图用Alt F8来计算带有注解// Here的行中的参数p
评估窗口中的消息为

Cannot find the local variable 'p' with type

这会造成很大的伤害,因为它会迫使您将参数复制为每个例程中的局部变量,以便在调试器中可见。
变量p = p
有人注意到了吗?有什么解决办法吗?
请注意,Variables 窗口显示带有$前缀的参数,但它在 evaluate 窗口中也不起作用。
我在JetBrains上看过这期。

ttcibm8c

ttcibm8c1#

首先要做的是:
是否有解决方法?
是,将参数p绑定到b内部的局部变量:

fun a(p: Param) {
  fun b() {
    val p = p
    var v = p + 1
  }
}

并且它将按预期工作。
根本原因稍微复杂一些。
Kotlin是在一个与Kotlin的IntelliJ语言插件紧密相连的语言工具链上成长起来的,最初的JVM编译器是一个代码生成器,它使用IntelliJ语言插件所使用的语义信息的数据结构来进行诊断、快速修复等。
这种体系结构非常适合为IDE提供语言支持,但不太适合构建快速批处理编译器。
在Kotlin1.5中,“IR后端”被启用为JVM的默认代码生成器。它使用更传统的编译方法,在输出JVM字节代码之前,逐渐将抽象语法树(AST)转换为更简单的中间语言。
随着这一变化,许多新的编译策略被实现。特别是,在旧的策略中,局部函数被视为绑定到局部变量的lambda。它们的自由变量被记录在声明位置的分配的Function对象的状态中。当局部函数被调用时,它被转换为对该函数对象的invoke的调用。故事结束。
在新的方法中,局部函数被提升到与外部函数相同的类上的私有静态函数中。局部函数中的自由变量被提升后的函数的参数关闭,并且它们不是在lambda对象的声明位置记录,而是作为参数传递到调用位置。
在您的示例中,p在内部函数b中是空闲的,因此将额外的参数$p添加到b
虽然这适用于“release build”,但周围的工具直到最近才跟上。“Evaluate Expression...”机制受到的冲击特别大,因为它对生成的JVM字节代码的布局和形状非常敏感。
在这个特定的例子中,需要调整调试器中的机制,将片段的自由变量Map到断点处的局部变量。对于针对2022.3的this change,您应该不会再注意到这个特定的bug,并且随着新的和修订的求值机制版本的发布,还会有许多其他的改进。

相关问题