KtDecompiledFile: hack to be able to navigate to builtIns on jvm

Which sometimes are loaded differently than they are rendered (see BuiltInClassesAreSerializableOnJvm)
This commit is contained in:
Pavel V. Talanov
2015-12-10 12:17:24 +03:00
parent b5568f9ace
commit 3f0d71411e
2 changed files with 35 additions and 18 deletions
@@ -68,18 +68,21 @@ class BuiltInClassesAreSerializableOnJvm(
else return listOf()
}
private fun isSerializableInJava(classFqName: FqName): Boolean {
val fqNameUnsafe = classFqName.toUnsafe()
if (fqNameUnsafe == KotlinBuiltIns.FQ_NAMES.array || KotlinBuiltIns.isPrimitiveArray(fqNameUnsafe)) {
return true
companion object {
fun isSerializableInJava(classFqName: FqName): Boolean {
val fqNameUnsafe = classFqName.toUnsafe()
if (fqNameUnsafe == KotlinBuiltIns.FQ_NAMES.array || KotlinBuiltIns.isPrimitiveArray(fqNameUnsafe)) {
return true
}
val javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqNameUnsafe) ?: return false
val classViaReflection = try {
Class.forName(javaClassId.asSingleFqName().asString())
}
catch (e: ClassNotFoundException) {
return false
}
return Serializable::class.java.isAssignableFrom(classViaReflection)
}
val javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqNameUnsafe) ?: return false
val classViaReflection = try {
Class.forName(javaClassId.asSingleFqName().asString())
}
catch (e: ClassNotFoundException) {
return false
}
return Serializable::class.java.isAssignableFrom(classViaReflection)
}
}
@@ -20,15 +20,21 @@ import com.intellij.openapi.util.TextRange
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
import org.jetbrains.kotlin.idea.decompiler.textBuilder.descriptorToKey
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.kotlin.BuiltInClassesAreSerializableOnJvm
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
open class KtDecompiledFile(
@@ -54,14 +60,21 @@ open class KtDecompiledFile(
return classOrObject?.getPrimaryConstructor() ?: classOrObject
}
val key = descriptorToKey(original)
return original.findElementForDescriptor() ?: run {
if (descriptor !is ClassDescriptor) return null
val range = decompiledText.get().renderedDescriptorsToRange[key]
return if (range != null) {
PsiTreeUtil.findElementOfClassAtRange(this, range.getStartOffset(), range.getEndOffset(), javaClass<KtDeclaration>())
val classFqName = descriptor.fqNameSafe
if (BuiltInClassesAreSerializableOnJvm.isSerializableInJava(classFqName)) {
val builtInDescriptor = TargetPlatform.Default.builtIns.builtInsModule.resolveTopLevelClass(classFqName, NoLookupLocation.FROM_IDE)
return builtInDescriptor?.findElementForDescriptor()
}
return null
}
else {
null
}
private fun DeclarationDescriptor.findElementForDescriptor(): KtDeclaration? {
return decompiledText.get().renderedDescriptorsToRange[descriptorToKey(this)]?.let { range ->
PsiTreeUtil.findElementOfClassAtRange(this@KtDecompiledFile, range.getStartOffset(), range.getEndOffset(), javaClass<KtDeclaration>())
}
}
@@ -81,3 +94,4 @@ open class KtDecompiledFile(
return decompiledText.get().renderedDescriptorsToRange
}
}