J2K DecompiledNavigationUtils: autoconvert

This commit is contained in:
Pavel V. Talanov
2015-12-10 12:19:02 +03:00
parent 976fbf32ba
commit 9ad6685310
@@ -14,147 +14,122 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.decompiler.navigation; package org.jetbrains.kotlin.idea.decompiler.navigation
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager
import com.intellij.psi.PsiManager; import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil
import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile; import org.jetbrains.kotlin.idea.vfilefinder.JsVirtualFileFinderFactory
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope; import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinderFactory
import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil; import org.jetbrains.kotlin.load.kotlin.OldPackageFacadeClassUtils.getPackageClassId
import org.jetbrains.kotlin.idea.vfilefinder.JsVirtualFileFinderFactory; import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinderFactory; import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder; import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory; import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.psi.KtDeclaration; import org.jetbrains.kotlin.serialization.js.KotlinJavascriptPackageFragment
import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptPackageFragment;
import org.jetbrains.kotlin.types.ErrorUtils;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
import java.util.Collection; object DecompiledNavigationUtils {
import static org.jetbrains.kotlin.load.kotlin.OldPackageFacadeClassUtils.getPackageClassId; fun getDeclarationFromDecompiledClassFile(
project: Project,
referencedDescriptor: DeclarationDescriptor): KtDeclaration? {
if (isLocal(referencedDescriptor)) return null
public final class DecompiledNavigationUtils { val virtualFile = findVirtualFileContainingDescriptor(project, referencedDescriptor) ?: return null
@Nullable val psiFile = PsiManager.getInstance(project).findFile(virtualFile)
public static KtDeclaration getDeclarationFromDecompiledClassFile( if (psiFile !is KtDecompiledFile) {
@NotNull Project project, return null
@NotNull DeclarationDescriptor referencedDescriptor
) {
if (isLocal(referencedDescriptor)) return null;
VirtualFile virtualFile = findVirtualFileContainingDescriptor(project, referencedDescriptor);
if (virtualFile == null) return null;
PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
if (!(psiFile instanceof KtDecompiledFile)) {
return null;
} }
return ((KtDecompiledFile) psiFile).getDeclarationForDescriptor(referencedDescriptor); return psiFile.getDeclarationForDescriptor(referencedDescriptor)
} }
private static boolean isLocal(DeclarationDescriptor descriptor) { private fun isLocal(descriptor: DeclarationDescriptor): Boolean {
if (descriptor instanceof ParameterDescriptor) { if (descriptor is ParameterDescriptor) {
return isLocal(descriptor.getContainingDeclaration()); return isLocal(descriptor.containingDeclaration)
} }
else { else {
return DescriptorUtils.isLocal(descriptor); return DescriptorUtils.isLocal(descriptor)
} }
} }
/* /*
Find virtual file which contains the declaration of descriptor we're navigating to. Find virtual file which contains the declaration of descriptor we're navigating to.
*/ */
@Nullable private fun findVirtualFileContainingDescriptor(
private static VirtualFile findVirtualFileContainingDescriptor( project: Project,
@NotNull Project project, referencedDescriptor: DeclarationDescriptor): VirtualFile? {
@NotNull DeclarationDescriptor referencedDescriptor if (ErrorUtils.isError(referencedDescriptor)) return null
) {
if (ErrorUtils.isError(referencedDescriptor)) return null;
ClassId containerClassId = getContainerClassId(project, referencedDescriptor); val containerClassId = getContainerClassId(project, referencedDescriptor) ?: return null
if (containerClassId == null) return null;
GlobalSearchScope scopeToSearchIn = KotlinSourceFilterScope.sourceAndClassFiles(GlobalSearchScope.allScope(project), project); val scopeToSearchIn = KotlinSourceFilterScope.sourceAndClassFiles(GlobalSearchScope.allScope(project), project)
VirtualFileFinderFactory virtualFileFinderFactory; val virtualFileFinderFactory: VirtualFileFinderFactory
if (isFromKotlinJavasriptMetadata(referencedDescriptor)) { if (isFromKotlinJavasriptMetadata(referencedDescriptor)) {
virtualFileFinderFactory = JsVirtualFileFinderFactory.SERVICE.getInstance(project); virtualFileFinderFactory = JsVirtualFileFinderFactory.SERVICE.getInstance(project)
} }
else { else {
virtualFileFinderFactory = JvmVirtualFileFinderFactory.SERVICE.getInstance(project); virtualFileFinderFactory = JvmVirtualFileFinderFactory.SERVICE.getInstance(project)
} }
VirtualFileFinder fileFinder = virtualFileFinderFactory.create(scopeToSearchIn); val fileFinder = virtualFileFinderFactory.create(scopeToSearchIn)
return fileFinder.findVirtualFileWithHeader(containerClassId); return fileFinder.findVirtualFileWithHeader(containerClassId)
} }
private static boolean isFromKotlinJavasriptMetadata(@NotNull DeclarationDescriptor referencedDescriptor) { private fun isFromKotlinJavasriptMetadata(referencedDescriptor: DeclarationDescriptor): Boolean {
PackageFragmentDescriptor packageFragmentDescriptor = val packageFragmentDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, PackageFragmentDescriptor::class.java, false)
DescriptorUtils.getParentOfType(referencedDescriptor, PackageFragmentDescriptor.class, false); return packageFragmentDescriptor is KotlinJavascriptPackageFragment
return packageFragmentDescriptor instanceof KotlinJavascriptPackageFragment;
} }
//TODO: navigate to inner classes //TODO: navigate to inner classes
//TODO: should we construct proper SourceElement's for decompiled parts / facades? //TODO: should we construct proper SourceElement's for decompiled parts / facades?
@Nullable private fun getContainerClassId(project: Project, referencedDescriptor: DeclarationDescriptor): ClassId? {
private static ClassId getContainerClassId(@NotNull Project project, @NotNull DeclarationDescriptor referencedDescriptor) { val deserializedCallableContainer = DescriptorUtils.getParentOfType(referencedDescriptor, DeserializedCallableMemberDescriptor::class.java, true)
DeserializedCallableMemberDescriptor deserializedCallableContainer =
DescriptorUtils.getParentOfType(referencedDescriptor, DeserializedCallableMemberDescriptor.class, true);
if (deserializedCallableContainer != null) { if (deserializedCallableContainer != null) {
return getContainerClassId(project, deserializedCallableContainer); return getContainerClassId(project, deserializedCallableContainer)
} }
ClassOrPackageFragmentDescriptor val containerDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, ClassOrPackageFragmentDescriptor::class.java, false)
containerDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, ClassOrPackageFragmentDescriptor.class, false); if (containerDescriptor is PackageFragmentDescriptor) {
if (containerDescriptor instanceof PackageFragmentDescriptor) { val packageFQN = containerDescriptor.fqName
FqName packageFQN = ((PackageFragmentDescriptor) containerDescriptor).getFqName();
if (referencedDescriptor instanceof DeserializedCallableMemberDescriptor) { if (referencedDescriptor is DeserializedCallableMemberDescriptor) {
Name partClassName = JvmFileClassUtil.getImplClassName((DeserializedCallableMemberDescriptor) referencedDescriptor); val partClassName = JvmFileClassUtil.getImplClassName(referencedDescriptor)
if (partClassName != null) { if (partClassName != null) {
FqName partFQN = packageFQN.child(partClassName); val partFQN = packageFQN.child(partClassName)
Collection<KtFile> multifileFacadeJetFiles = val multifileFacadeJetFiles = StaticFacadeIndexUtil.getMultifileClassForPart(partFQN, GlobalSearchScope.allScope(project), project)
StaticFacadeIndexUtil.getMultifileClassForPart(partFQN, GlobalSearchScope.allScope(project), project);
if (multifileFacadeJetFiles.isEmpty()) { if (multifileFacadeJetFiles.isEmpty()) {
return new ClassId(packageFQN, partClassName); return ClassId(packageFQN, partClassName)
} }
else { else {
KtFile multifileFacade = multifileFacadeJetFiles.iterator().next(); val multifileFacade = multifileFacadeJetFiles.iterator().next()
String multifileFacadeName = multifileFacade.getVirtualFile().getNameWithoutExtension(); val multifileFacadeName = multifileFacade.virtualFile.nameWithoutExtension
return new ClassId(packageFQN, Name.identifier(multifileFacadeName)); return ClassId(packageFQN, Name.identifier(multifileFacadeName))
} }
} }
} }
return getPackageClassId(packageFQN); return getPackageClassId(packageFQN)
} }
if (containerDescriptor instanceof ClassDescriptor) { if (containerDescriptor is ClassDescriptor) {
if (containerDescriptor.getContainingDeclaration() instanceof ClassDescriptor if (containerDescriptor.containingDeclaration is ClassDescriptor || ExpressionTypingUtils.isLocal(containerDescriptor.containingDeclaration, containerDescriptor)) {
|| ExpressionTypingUtils.isLocal(containerDescriptor.getContainingDeclaration(), containerDescriptor)) { return getContainerClassId(project, containerDescriptor.containingDeclaration)
return getContainerClassId(project, containerDescriptor.getContainingDeclaration());
} }
return DescriptorUtilsKt.getClassId((ClassDescriptor) containerDescriptor); return containerDescriptor.classId
} }
return null; return null
}
private DecompiledNavigationUtils() {
} }
} }