From 42d14f68378356603ef82feee3162812889b8ddb Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 27 Aug 2015 13:11:12 +0300 Subject: [PATCH] Navigate to corresponding implementation class (which is file part). TODO: proper SourceElements for file parts / file facades / static facades. --- .../navigation/DecompiledNavigationUtils.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.java index 834750e0df8..4443f4e4a45 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.java @@ -32,9 +32,15 @@ import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinderFactory; import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder; import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory; import org.jetbrains.kotlin.name.ClassId; +import org.jetbrains.kotlin.name.FqName; +import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.JetDeclaration; import org.jetbrains.kotlin.resolve.DescriptorUtils; +import org.jetbrains.kotlin.serialization.ProtoBuf; +import org.jetbrains.kotlin.serialization.deserialization.NameResolver; +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor; import org.jetbrains.kotlin.serialization.js.KotlinJavascriptPackageFragment; +import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf; import org.jetbrains.kotlin.types.ErrorUtils; import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils; @@ -107,12 +113,31 @@ public final class DecompiledNavigationUtils { } //TODO: navigate to inner classes + //TODO: should we construct proper SourceElement's for decompiled parts / facades? @Nullable private static ClassId getContainerClassId(@NotNull DeclarationDescriptor referencedDescriptor) { + DeserializedCallableMemberDescriptor deserializedCallableContainer = + DescriptorUtils.getParentOfType(referencedDescriptor, DeserializedCallableMemberDescriptor.class, true); + if (deserializedCallableContainer != null) { + return getContainerClassId(deserializedCallableContainer); + } + ClassOrPackageFragmentDescriptor containerDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, ClassOrPackageFragmentDescriptor.class, false); if (containerDescriptor instanceof PackageFragmentDescriptor) { - return getPackageClassId(((PackageFragmentDescriptor) containerDescriptor).getFqName()); + FqName packageFQN = ((PackageFragmentDescriptor) containerDescriptor).getFqName(); + + if (referencedDescriptor instanceof DeserializedCallableMemberDescriptor) { + DeserializedCallableMemberDescriptor deserializedDescriptor = (DeserializedCallableMemberDescriptor) referencedDescriptor; + ProtoBuf.Callable proto = deserializedDescriptor.getProto(); + NameResolver nameResolver = deserializedDescriptor.getNameResolver(); + if (proto.hasExtension(JvmProtoBuf.implClassName)) { + Name implClassName = nameResolver.getName(proto.getExtension(JvmProtoBuf.implClassName)); + return new ClassId(packageFQN, implClassName); + } + } + + return getPackageClassId(packageFQN); } if (containerDescriptor instanceof ClassDescriptor) { if (containerDescriptor.getContainingDeclaration() instanceof ClassDescriptor