From 68c6e9e2d6f43b9fcf9b629f0391718a3864bad6 Mon Sep 17 00:00:00 2001 From: Vladimir Ilmov Date: Sun, 19 Apr 2020 15:17:32 +0200 Subject: [PATCH] (CoroutineDebugger) kotlinx-coroutines-core:1.3.5 support --- .../jvm-debugger-coroutine/build.gradle.kts | 1 + .../debugger/coroutine/DebuggerConnection.kt | 41 +++++++++++++++---- .../XCoroutinesStackTraceTestGenerated.java | 5 +++ .../xcoroutines/coroutineSuspendFun135.kt | 29 +++++++++++++ 4 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 idea/jvm-debugger/jvm-debugger-test/testData/xcoroutines/coroutineSuspendFun135.kt diff --git a/idea/jvm-debugger/jvm-debugger-coroutine/build.gradle.kts b/idea/jvm-debugger/jvm-debugger-coroutine/build.gradle.kts index c4ded1cde71..e5482a06df3 100644 --- a/idea/jvm-debugger/jvm-debugger-coroutine/build.gradle.kts +++ b/idea/jvm-debugger/jvm-debugger-coroutine/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { implementation(project(":idea:jvm-debugger:jvm-debugger-core")) + implementation("org.apache.maven:maven-artifact:3.6.3") compileOnly(toolsJarApi()) compileOnly(intellijDep()) diff --git a/idea/jvm-debugger/jvm-debugger-coroutine/src/org/jetbrains/kotlin/idea/debugger/coroutine/DebuggerConnection.kt b/idea/jvm-debugger/jvm-debugger-coroutine/src/org/jetbrains/kotlin/idea/debugger/coroutine/DebuggerConnection.kt index 5eab83595fd..6b64bfe5b85 100644 --- a/idea/jvm-debugger/jvm-debugger-coroutine/src/org/jetbrains/kotlin/idea/debugger/coroutine/DebuggerConnection.kt +++ b/idea/jvm-debugger/jvm-debugger-coroutine/src/org/jetbrains/kotlin/idea/debugger/coroutine/DebuggerConnection.kt @@ -26,6 +26,7 @@ import com.intellij.xdebugger.XDebugSession import com.intellij.xdebugger.XDebuggerManager import com.intellij.xdebugger.XDebuggerManagerListener import com.intellij.xdebugger.impl.XDebugSessionImpl +import org.apache.maven.artifact.versioning.DefaultArtifactVersion import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.ManagerThreadExecutor import org.jetbrains.kotlin.idea.debugger.coroutine.util.CreateContentParamsProvider import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger @@ -44,19 +45,39 @@ class DebuggerConnection( init { if (params is JavaParameters) { // gradle related logic in KotlinGradleCoroutineDebugProjectResolver - val kotlinxCoroutinesClassPathLib = - params.classPath?.pathList?.firstOrNull { it.contains("kotlinx-coroutines-debug") } - if (kotlinxCoroutinesClassPathLib is String) - initializeCoroutineAgent(params, kotlinxCoroutinesClassPathLib) - else - log.warn("'kotlinx-coroutines-debug' not found in classpath.") + val kotlinxCoroutinesCore = params.classPath?.pathList?.firstOrNull { it.contains("kotlinx-coroutines-core") } + val kotlinxCoroutinesDebug = params.classPath?.pathList?.firstOrNull { it.contains("kotlinx-coroutines-debug") } + + val mode = if (kotlinxCoroutinesDebug != null) { + CoroutineDebuggerMode.VERSION_UP_TO_1_3_4 + } else if (kotlinxCoroutinesCore != null) { + determineCoreVersionMode(kotlinxCoroutinesCore) + } else + CoroutineDebuggerMode.DISABLED + + when (mode) { + CoroutineDebuggerMode.VERSION_1_3_5_AND_UP -> initializeCoroutineAgent(params, kotlinxCoroutinesCore) + CoroutineDebuggerMode.VERSION_UP_TO_1_3_4 -> initializeCoroutineAgent(params, kotlinxCoroutinesDebug) + else -> log.debug("CoroutineDebugger disabled.") + } } connect() } + private fun determineCoreVersionMode(kotlinxCoroutinesCore: String): CoroutineDebuggerMode { + val regex = Regex(""".+\Wkotlinx\-coroutines\-core\-(.+)?\.jar""") + val matchResult = regex.matchEntire(kotlinxCoroutinesCore) + + val coroutinesCoreVersion = DefaultArtifactVersion(matchResult?.groupValues?.get(1)) ?: return CoroutineDebuggerMode.DISABLED + val versionToCompareTo = DefaultArtifactVersion("1.3.5") + return if (versionToCompareTo.compareTo(coroutinesCoreVersion) < 0) + CoroutineDebuggerMode.VERSION_1_3_5_AND_UP + else + CoroutineDebuggerMode.DISABLED + } + private fun initializeCoroutineAgent(params: JavaParameters, it: String?) { params.vmParametersList?.add("-javaagent:$it") - params.vmParametersList?.add("-ea") } private fun connect() { @@ -100,3 +121,9 @@ class DebuggerConnection( return ui.createContent(param.id, param.component, param.displayName, param.icon, param.parentComponent) } } + +enum class CoroutineDebuggerMode { + DISABLED, + VERSION_UP_TO_1_3_4, + VERSION_1_3_5_AND_UP +} \ No newline at end of file diff --git a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/XCoroutinesStackTraceTestGenerated.java b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/XCoroutinesStackTraceTestGenerated.java index 216ec8e0e5a..83fb0624211 100644 --- a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/XCoroutinesStackTraceTestGenerated.java +++ b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/XCoroutinesStackTraceTestGenerated.java @@ -32,4 +32,9 @@ public class XCoroutinesStackTraceTestGenerated extends AbstractXCoroutinesStack public void testCoroutineSuspendFun() throws Exception { runTest("idea/jvm-debugger/jvm-debugger-test/testData/xcoroutines/coroutineSuspendFun.kt"); } + + @TestMetadata("coroutineSuspendFun135.kt") + public void testCoroutineSuspendFun135() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/xcoroutines/coroutineSuspendFun135.kt"); + } } diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/xcoroutines/coroutineSuspendFun135.kt b/idea/jvm-debugger/jvm-debugger-test/testData/xcoroutines/coroutineSuspendFun135.kt new file mode 100644 index 00000000000..e355828a724 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/xcoroutines/coroutineSuspendFun135.kt @@ -0,0 +1,29 @@ +package continuation +// ATTACH_LIBRARY: maven(org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5-SNAPSHOT)-javaagent + +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.yield + +fun main() { + val main = "main" + runBlocking { + a() + } +} + +suspend fun a() { + val a = "a" + b(a) + val aLate = "a" // to prevent stackFrame to collapse +} + +suspend fun b(paramA: String) { + yield() + val b = "b" + c(b) +} + +suspend fun c(paramB: String) { + val c = "c" + //Breakpoint! +} \ No newline at end of file