Debugger: Pass files with inline functions to backend (KT-36404)
This commit is contained in:
+2
-2
@@ -221,7 +221,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, private val sourcePositi
|
|||||||
analysisResult = analyze(codeFragment, status, debugProcess)
|
analysisResult = analyze(codeFragment, status, debugProcess)
|
||||||
}
|
}
|
||||||
|
|
||||||
val (bindingContext) = runReadAction {
|
val (bindingContext, filesToCompile) = runReadAction {
|
||||||
val resolutionFacade = getResolutionFacadeForCodeFragment(codeFragment)
|
val resolutionFacade = getResolutionFacadeForCodeFragment(codeFragment)
|
||||||
DebuggerUtils.analyzeInlinedFunctions(resolutionFacade, codeFragment, false, analysisResult.bindingContext)
|
DebuggerUtils.analyzeInlinedFunctions(resolutionFacade, codeFragment, false, analysisResult.bindingContext)
|
||||||
}
|
}
|
||||||
@@ -229,7 +229,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, private val sourcePositi
|
|||||||
val moduleDescriptor = analysisResult.moduleDescriptor
|
val moduleDescriptor = analysisResult.moduleDescriptor
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val result = CodeFragmentCompiler(context, status).compile(codeFragment, bindingContext, moduleDescriptor)
|
val result = CodeFragmentCompiler(context, status).compile(codeFragment, filesToCompile, bindingContext, moduleDescriptor)
|
||||||
return createCompiledDataDescriptor(result, sourcePosition)
|
return createCompiledDataDescriptor(result, sourcePosition)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
status.error(EvaluationError.BackendException)
|
status.error(EvaluationError.BackendException)
|
||||||
|
|||||||
+17
-5
@@ -52,12 +52,16 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext, priva
|
|||||||
val mainMethodSignature: MethodSignature
|
val mainMethodSignature: MethodSignature
|
||||||
)
|
)
|
||||||
|
|
||||||
fun compile(codeFragment: KtCodeFragment, bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor): CompilationResult {
|
fun compile(
|
||||||
return runReadAction { doCompile(codeFragment, bindingContext, moduleDescriptor) }
|
codeFragment: KtCodeFragment, filesToCompile: List<KtFile>,
|
||||||
|
bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor
|
||||||
|
): CompilationResult {
|
||||||
|
return runReadAction { doCompile(codeFragment, filesToCompile, bindingContext, moduleDescriptor) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doCompile(
|
private fun doCompile(
|
||||||
codeFragment: KtCodeFragment, bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor
|
codeFragment: KtCodeFragment, filesToCompile: List<KtFile>,
|
||||||
|
bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor
|
||||||
): CompilationResult {
|
): CompilationResult {
|
||||||
require(codeFragment is KtBlockCodeFragment || codeFragment is KtExpressionCodeFragment) {
|
require(codeFragment is KtBlockCodeFragment || codeFragment is KtExpressionCodeFragment) {
|
||||||
"Unsupported code fragment type: $codeFragment"
|
"Unsupported code fragment type: $codeFragment"
|
||||||
@@ -76,8 +80,8 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext, priva
|
|||||||
|
|
||||||
val generationState = GenerationState.Builder(
|
val generationState = GenerationState.Builder(
|
||||||
project, ClassBuilderFactories.BINARIES, moduleDescriptorWrapper,
|
project, ClassBuilderFactories.BINARIES, moduleDescriptorWrapper,
|
||||||
bindingContext, listOf(codeFragment), compilerConfiguration
|
bindingContext, filesToCompile, compilerConfiguration
|
||||||
).build()
|
).generateDeclaredClassFilter(GeneratedClassFilterForCodeFragment(codeFragment)).build()
|
||||||
|
|
||||||
val parameterInfo = CodeFragmentParameterAnalyzer(executionContext, codeFragment, bindingContext, status).analyze()
|
val parameterInfo = CodeFragmentParameterAnalyzer(executionContext, codeFragment, bindingContext, status).analyze()
|
||||||
val (classDescriptor, methodDescriptor) = createDescriptorsForCodeFragment(
|
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(
|
private fun getLocalFunctionSuffixes(
|
||||||
parameters: List<CodeFragmentParameter.Smart>,
|
parameters: List<CodeFragmentParameter.Smart>,
|
||||||
typeMapper: KotlinTypeMapper
|
typeMapper: KotlinTypeMapper
|
||||||
|
|||||||
+5
@@ -310,6 +310,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
|||||||
runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt31709.kt");
|
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")
|
@TestMetadata("kt5554OnlyIntsShouldBeCoerced.kt")
|
||||||
public void testKt5554OnlyIntsShouldBeCoerced() throws Exception {
|
public void testKt5554OnlyIntsShouldBeCoerced() throws Exception {
|
||||||
runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt5554OnlyIntsShouldBeCoerced.kt");
|
runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/kt5554OnlyIntsShouldBeCoerced.kt");
|
||||||
|
|||||||
+53
@@ -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> T runReadAction(@NotNull Fun<T> computation) {
|
||||||
|
return computation.invoke();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void runReadAction(@NotNull Runnable runnable);
|
||||||
|
|
||||||
|
<T> T runReadAction(@NotNull Fun<T> computation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: lib/Fun.java
|
||||||
|
package lib;
|
||||||
|
|
||||||
|
public interface Fun<T> {
|
||||||
|
T invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: lib/foo.kt
|
||||||
|
package lib
|
||||||
|
|
||||||
|
inline fun <R> 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;
|
||||||
+10
@@ -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
|
||||||
Reference in New Issue
Block a user