Take java 9 modules into account in coroutines debug metadata
reading #KT-28237
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
|
||||
package kotlin.coroutines.jvm.internal
|
||||
|
||||
import java.lang.reflect.Method
|
||||
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@SinceKotlin("1.3")
|
||||
internal annotation class DebugMetadata(
|
||||
@@ -41,7 +43,48 @@ internal fun BaseContinuationImpl.getStackTraceElementImpl(): StackTraceElement?
|
||||
checkDebugMetadataVersion(COROUTINES_DEBUG_METADATA_VERSION, debugMetadata.version)
|
||||
val label = getLabel()
|
||||
val lineNumber = if (label < 0) -1 else debugMetadata.lineNumbers[label]
|
||||
return StackTraceElement(debugMetadata.className, debugMetadata.methodName, debugMetadata.sourceFile, lineNumber)
|
||||
val moduleName = ModuleNameRetriever.getModuleName(this)
|
||||
val moduleAndClass = if (moduleName == null) debugMetadata.className else "$moduleName/${debugMetadata.className}"
|
||||
return StackTraceElement(moduleAndClass, debugMetadata.methodName, debugMetadata.sourceFile, lineNumber)
|
||||
}
|
||||
|
||||
private object ModuleNameRetriever {
|
||||
private class Cache(
|
||||
@JvmField
|
||||
val getModuleMethod: Method?,
|
||||
@JvmField
|
||||
val getDescriptorMethod: Method?,
|
||||
@JvmField
|
||||
val nameMethod: Method?
|
||||
)
|
||||
|
||||
private val notOnJava9 = Cache(null, null, null)
|
||||
|
||||
@JvmField
|
||||
var cache: Cache? = null
|
||||
|
||||
fun getModuleName(continuation: BaseContinuationImpl): String? {
|
||||
val cache = this.cache ?: buildCache(continuation)
|
||||
if (cache === notOnJava9) {
|
||||
return null
|
||||
}
|
||||
val module = cache.getModuleMethod?.invoke(continuation.javaClass) ?: return null
|
||||
val descriptor = cache.getDescriptorMethod?.invoke(module) ?: return null
|
||||
return cache.nameMethod?.invoke(descriptor) as? String
|
||||
}
|
||||
|
||||
private fun buildCache(continuation: BaseContinuationImpl): Cache {
|
||||
try {
|
||||
val getModuleMethod = Class::class.java.getDeclaredMethod("getModule")
|
||||
val methodClass = continuation.javaClass.classLoader.loadClass("java.lang.Module")
|
||||
val getDescriptorMethod = methodClass.getDeclaredMethod("getDescriptor")
|
||||
val moduleDescriptorClass = continuation.javaClass.classLoader.loadClass("java.lang.module.ModuleDescriptor")
|
||||
val nameMethod = moduleDescriptorClass.getDeclaredMethod("name")
|
||||
return Cache(getModuleMethod, getDescriptorMethod, nameMethod).also { cache = it }
|
||||
} catch (ignored: Exception) {
|
||||
return notOnJava9.also { cache = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun BaseContinuationImpl.getDebugMetadataAnnotation(): DebugMetadata? =
|
||||
|
||||
Reference in New Issue
Block a user