From fe3c1aff8b8906a6589fecaac692f7281621edd3 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Mon, 10 Apr 2017 22:29:02 +0300 Subject: [PATCH] Debugger: Classes for callable references should be treated as synthetic --- .../KotlinSyntheticTypeComponentProvider.kt | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/filter/KotlinSyntheticTypeComponentProvider.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/filter/KotlinSyntheticTypeComponentProvider.kt index e3422c8d527..fa127ee8d62 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/filter/KotlinSyntheticTypeComponentProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/filter/KotlinSyntheticTypeComponentProvider.kt @@ -17,21 +17,25 @@ package org.jetbrains.kotlin.idea.debugger.filter import com.intellij.debugger.engine.SyntheticTypeComponentProvider -import com.sun.jdi.AbsentInformationException -import com.sun.jdi.ClassType -import com.sun.jdi.Method -import com.sun.jdi.TypeComponent +import com.sun.jdi.* import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.org.objectweb.asm.Opcodes +import kotlin.jvm.internal.FunctionReference +import kotlin.jvm.internal.PropertyReference class KotlinSyntheticTypeComponentProvider: SyntheticTypeComponentProvider { override fun isSynthetic(typeComponent: TypeComponent?): Boolean { if (typeComponent !is Method) return false - val typeName = typeComponent.declaringType().name() + val containingType = typeComponent.declaringType() + val typeName = containingType.name() if (!FqNameUnsafe.isValid(typeName)) return false + if (containingType.isCallableReferenceSyntheticClass()) { + return true + } + try { if (typeComponent.isDelegateToDefaultInterfaceImpl()) return true @@ -51,6 +55,21 @@ class KotlinSyntheticTypeComponentProvider: SyntheticTypeComponentProvider { } } + private tailrec fun ReferenceType?.isCallableReferenceSyntheticClass(): Boolean { + if (this !is ClassType) return false + val superClass = this.superclass() ?: return false + val superClassName = superClass.name() + if (superClassName == PropertyReference::class.java.name || superClassName == FunctionReference::class.java.name) { + return true + } + + // The direct supertype may be PropertyReference0 or something + return if (superClassName.startsWith("kotlin.jvm.internal.")) + superClass.isCallableReferenceSyntheticClass() + else + false + } + private fun Method.isDelegateToDefaultInterfaceImpl(): Boolean { if (allLineLocations().size != 1) return false if (!virtualMachine().canGetBytecodes()) return false