diff --git a/idea/jvm-debugger/jvm-debugger-evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt b/idea/jvm-debugger/jvm-debugger-evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt index 19b6add72ea..9586b50637e 100644 --- a/idea/jvm-debugger/jvm-debugger-evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt +++ b/idea/jvm-debugger/jvm-debugger-evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt @@ -221,7 +221,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, private val sourcePositi analysisResult = analyze(codeFragment, status, debugProcess) } - val (bindingContext) = runReadAction { + val (bindingContext, filesToCompile) = runReadAction { val resolutionFacade = getResolutionFacadeForCodeFragment(codeFragment) DebuggerUtils.analyzeInlinedFunctions(resolutionFacade, codeFragment, false, analysisResult.bindingContext) } @@ -229,7 +229,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, private val sourcePositi val moduleDescriptor = analysisResult.moduleDescriptor try { - val result = CodeFragmentCompiler(context, status).compile(codeFragment, bindingContext, moduleDescriptor) + val result = CodeFragmentCompiler(context, status).compile(codeFragment, filesToCompile, bindingContext, moduleDescriptor) return createCompiledDataDescriptor(result, sourcePosition) } catch (e: Throwable) { status.error(EvaluationError.BackendException) diff --git a/idea/jvm-debugger/jvm-debugger-evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompiler.kt b/idea/jvm-debugger/jvm-debugger-evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompiler.kt index e4204d675e4..656709c2ae8 100644 --- a/idea/jvm-debugger/jvm-debugger-evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompiler.kt +++ b/idea/jvm-debugger/jvm-debugger-evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompiler.kt @@ -52,12 +52,16 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext, priva val mainMethodSignature: MethodSignature ) - fun compile(codeFragment: KtCodeFragment, bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor): CompilationResult { - return runReadAction { doCompile(codeFragment, bindingContext, moduleDescriptor) } + fun compile( + codeFragment: KtCodeFragment, filesToCompile: List, + bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor + ): CompilationResult { + return runReadAction { doCompile(codeFragment, filesToCompile, bindingContext, moduleDescriptor) } } private fun doCompile( - codeFragment: KtCodeFragment, bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor + codeFragment: KtCodeFragment, filesToCompile: List, + bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor ): CompilationResult { require(codeFragment is KtBlockCodeFragment || codeFragment is KtExpressionCodeFragment) { "Unsupported code fragment type: $codeFragment" @@ -76,8 +80,8 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext, priva val generationState = GenerationState.Builder( project, ClassBuilderFactories.BINARIES, moduleDescriptorWrapper, - bindingContext, listOf(codeFragment), compilerConfiguration - ).build() + bindingContext, filesToCompile, compilerConfiguration + ).generateDeclaredClassFilter(GeneratedClassFilterForCodeFragment(codeFragment)).build() val parameterInfo = CodeFragmentParameterAnalyzer(executionContext, codeFragment, bindingContext, status).analyze() val (classDescriptor, methodDescriptor) = createDescriptorsForCodeFragment( @@ -105,6 +109,14 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext, priva } } + private class GeneratedClassFilterForCodeFragment(private val codeFragment: KtCodeFragment) : GenerationState.GenerateClassFilter() { + override fun shouldGeneratePackagePart(@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") file: KtFile) = file == codeFragment + override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject) = true + override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject) = processingClassOrObject.containingFile == codeFragment + override fun shouldGenerateCodeFragment(codeFragment: KtCodeFragment) = codeFragment == this.codeFragment + override fun shouldGenerateScript(script: KtScript) = false + } + private fun getLocalFunctionSuffixes( parameters: List, typeMapper: KotlinTypeMapper diff --git a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java index 9eccc53170f..075e1da6b92 100644 --- a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java +++ b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java @@ -310,6 +310,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt31709.kt"); } + @TestMetadata("kt36404.kt") + public void testKt36404() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt36404.kt"); + } + @TestMetadata("kt5554OnlyIntsShouldBeCoerced.kt") public void testKt5554OnlyIntsShouldBeCoerced() throws Exception { runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt5554OnlyIntsShouldBeCoerced.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt36404.kt b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt36404.kt new file mode 100644 index 00000000000..d8e352f895d --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt36404.kt @@ -0,0 +1,53 @@ +// FILE: lib/Application.java +package lib; + +import org.jetbrains.annotations.NotNull; +import java.util.function.Supplier; + +public interface Application { + static Application getInstance() { + return new Application() { + @Override + public void runReadAction(@NotNull Runnable runnable) { + runnable.run(); + } + + @Override + public T runReadAction(@NotNull Fun computation) { + return computation.invoke(); + } + }; + } + + void runReadAction(@NotNull Runnable runnable); + + T runReadAction(@NotNull Fun computation); +} + +// FILE: lib/Fun.java +package lib; + +public interface Fun { + T invoke(); +} + +// FILE: lib/foo.kt +package lib + +inline fun runReadAction(crossinline runnable: () -> R): R { + return Application.getInstance().runReadAction(Fun { runnable() }) +} + + +// FILE: test.kt +package test + +import lib.* + +fun main() { + //Breakpoint! + println(runReadAction { "hello" }) +} + +// EXPRESSION: runReadAction { "hello" } +// RESULT: "hello": Ljava/lang/String; \ No newline at end of file diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt36404.out b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt36404.out new file mode 100644 index 00000000000..1e6d4b2be4b --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt36404.out @@ -0,0 +1,10 @@ +LineBreakpoint created at test.kt:8 +Run Java +Connected to the target VM +test.kt:8 +Compile bytecode for runReadAction { "hello" } +test.kt:8 +Disconnected from the target VM + +Process finished with exit code 0 +hello