[kotlin-dfa] Slight adjustments and more complex tests for IDEA-363059

GitOrigin-RevId: a874b1ff7471f6bd7f8880769ebb02f81267b755
This commit is contained in:
Tagir Valeev
2024-11-28 17:43:28 +00:00
committed by intellij-monorepo-bot
parent 6048fc2e21
commit ed84affe00
2 changed files with 65 additions and 4 deletions
@@ -97,9 +97,12 @@ class K2DfaAssistProvider : DfaAssistProvider {
while(true) {
val function = current.parentOfType<KtFunction>()
if (function != null) {
val lambda = function.parent as? KtLambdaExpression
val arg = lambda?.parent as? KtLambdaArgument
val call = arg?.parent as? KtCallExpression
val realFun = function.parent as? KtLambdaExpression ?: function
val arg = realFun?.parent as? KtValueArgument
val call = when(arg) {
is KtLambdaArgument -> arg.parent
else -> arg?.parent?.parent
} as? KtCallExpression
if (call != null) {
val inline = analyze(call) {
val functionCall = call.resolveToCall()?.singleFunctionCallOrNull()
@@ -122,7 +125,6 @@ class K2DfaAssistProvider : DfaAssistProvider {
): Value? {
val qualifier = dfaVar.qualifier
val descriptor = dfaVar.descriptor
val scope = anchor.getScope()
val variables = (proxy as StackFrameProxyImpl).visibleVariables()
val inlineDepth = getInlineDepth(variables)
val inlineSuffix = KotlinDebuggerConstants.INLINE_FUN_VAR_SUFFIX.repeat(inlineDepth)
@@ -201,6 +203,7 @@ class K2DfaAssistProvider : DfaAssistProvider {
var value: Value? = null
if (variable == null) {
val psi = symbol.psi
val scope = anchor.getScope()
if (psi != null && scope != null && psi.containingFile == scope.containingFile && !scope.isAncestor(psi)) {
// Captured variable
val capturedName = AsmUtil.CAPTURED_PREFIX + name
@@ -783,6 +783,64 @@ class K2DfaAssistTest : DfaAssistTest(), ExpectedPluginModeProvider {
}
}
fun testFunCapture() {
val text = """
fun main() {
test(1)
}
fun test(i: Int) {
block2 {
block(fun() {
<caret>if (i > 0/*TRUE*/) {
print("foo")
}
})
}
}
fun block2(block: () -> Unit) {
block()
}
inline fun block(block: () -> Unit) {
block()
}
""".trimIndent()
doTest(text) { vm, frame ->
frame.addVariable("\$i", MockIntegerValue(vm, 1))
}
}
fun testLambdaArgCapture() {
val text = """
fun main() {
test(1)
}
fun test(i: Int) {
block2 {
block({
<caret>if (i > 0/*TRUE*/) {
print("foo")
}
})
}
}
fun block2(block: () -> Unit) {
block()
}
inline fun block(block: () -> Unit) {
block()
}
""".trimIndent()
doTest(text) { vm, frame ->
frame.addVariable("\$i", MockIntegerValue(vm, 1))
}
}
private fun doTest(text: String, mockValues: BiConsumer<MockVirtualMachine, MockStackFrame>) {
doTest(text, mockValues, "Test.kt")
}