This change improves the debugging experience around local functions
on the IR backend. The changes include moving old
checkLocalVariablesTable (cLVT) tests to the new stepping/local variable
infrastructure in order to refine the tests and further define the
behavior of the two JVM backends, and their differences.
The primary ported test case is cLVT/localFun.kt that documents the
discrepancy in implementation strategy for local functions on the two
backends. The old backend implements local functions as lambdas
assigned to a local variable while the IR backend lifts them out as
static funtions on the surrounding class. The discrepancies and their
consequences are documented in bytecodeListing, idea-stepping,
localVariableTable and debugStepping tests.
The only _code change_ is disabling the captured variable name
mangling for captured variables on the IR backend. Captured variables
are passed as arguments to the static function, so in the debugger,
they really just are local variables. For them to show properly in the
debugger and be detectable by evaluate expression, they simply need no
mangling.
Finally, this change cleans 3 redundant cLVT tests, copyFunction.kt
and destructuringInlineLambda.kt and destructuringInFor.kt, that are
all covered in the new suite. The stepping behavior needs to be made
precise around for loops, but that is an entirely seperate issue.
Extract the logic that computes ACC_SYNTHETIC flag for deprecated
declarations, and use `DeprecationResolver` as the old backend does in
`DescriptorAsmUtil.getCommonCallableFlags`. Creating IR-based
descriptors for each function to pass it there is a bit costly though,
so as a small optimization, use `allOverridden` to check if anything in
the method hierarchy is deprecated.
Also optimize `allOverridden` for the case of linear inheritance which
is far more common.
#KT-43199 Fixed
The main change here is in `JvmInlineClassLowering.visitFunctionAccess`,
where we now store the substituted return type of the function as the
type of the call expression. Without it, the call could have a
meaningless type, e.g. some `T` which is inaccessible at that place, and
that could backfire in subsequent lowerings in codegen. For example, in
the `stringPlus.kt` test, it would prevent the code in
`FlattenStringConcatenationLowering.isStringPlusCall` from recognizing
and replacing the `String.plus` call, leading to a codegen exception.
Other changes are mostly cosmetics to make the code similar to
`visitFunctionReference`, and preventive optimizations for the case when
the substitution map is empty.
FunctionLoweringPass didn't add much value over FileLoweringPass, but
had a hidden footgun (like ClassLoweringPass) in that if your lowering
pass invoked a visitor/transformer on the function body and you forgot
to override visitFunction to stop visiting nested functions,
runOnFilePostfix would work with the complexity of the squared number of
nesting levels. It looks like this was happening with K/N's
DataClassOperatorsLowering (I haven't measured though).