From 01b79f640f9f4e7a042ee1567269b8a364d5ae99 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Thu, 10 Dec 2015 12:23:31 +0300 Subject: [PATCH] DecompiledNavigationUtils -> findDecompiledDeclaration() --- .../codeInsight/DescriptorToSourceUtilsIde.kt | 14 +- .../navigation/DecompiledNavigationUtils.kt | 175 +++++++++--------- 2 files changed, 90 insertions(+), 99 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/codeInsight/DescriptorToSourceUtilsIde.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/codeInsight/DescriptorToSourceUtilsIde.kt index 0c21ceadd19..96c49efbc79 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/codeInsight/DescriptorToSourceUtilsIde.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/codeInsight/DescriptorToSourceUtilsIde.kt @@ -18,16 +18,10 @@ package org.jetbrains.kotlin.idea.codeInsight import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -import org.jetbrains.kotlin.idea.decompiler.navigation.DecompiledNavigationUtils +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.idea.decompiler.navigation.findDecompiledDeclaration import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver -import com.intellij.psi.JavaPsiFacade -import org.jetbrains.kotlin.idea.search.allScope -import org.jetbrains.kotlin.utils.addIfNotNull -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.* -import java.util.* -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.utils.addToStdlib.sequenceOfLazyValues public object DescriptorToSourceUtilsIde { @@ -52,7 +46,7 @@ public object DescriptorToSourceUtilsIde { // therefore we put both source declaration and decompiled declaration to stream, and afterwards we filter it in getAllDeclarations sequenceOfLazyValues( { DescriptorToSourceUtils.getSourceFromDescriptor(effectiveReferenced) }, - { BuiltInsReferenceResolver.resolveBuiltInSymbol(project, effectiveReferenced) ?: DecompiledNavigationUtils.getDeclarationFromDecompiledClassFile(project, effectiveReferenced) } + { BuiltInsReferenceResolver.resolveBuiltInSymbol(project, effectiveReferenced) ?: findDecompiledDeclaration(project, effectiveReferenced) } ) }.filterNotNull() } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.kt index 2b687bebee5..05e1bad35ca 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/DecompiledNavigationUtils.kt @@ -39,97 +39,94 @@ import org.jetbrains.kotlin.serialization.js.KotlinJavascriptPackageFragment import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils -object DecompiledNavigationUtils { +fun findDecompiledDeclaration( + project: Project, + referencedDescriptor: DeclarationDescriptor): KtDeclaration? { + if (isLocal(referencedDescriptor)) return null - fun getDeclarationFromDecompiledClassFile( - project: Project, - referencedDescriptor: DeclarationDescriptor): KtDeclaration? { - if (isLocal(referencedDescriptor)) return null + val virtualFile = findVirtualFileContainingDescriptor(project, referencedDescriptor) ?: return null - val virtualFile = findVirtualFileContainingDescriptor(project, referencedDescriptor) ?: return null - - val psiFile = PsiManager.getInstance(project).findFile(virtualFile) - if (psiFile !is KtDecompiledFile) { - return null - } - - return psiFile.getDeclarationForDescriptor(referencedDescriptor) - } - - private fun isLocal(descriptor: DeclarationDescriptor): Boolean { - if (descriptor is ParameterDescriptor) { - return isLocal(descriptor.containingDeclaration) - } - else { - return DescriptorUtils.isLocal(descriptor) - } - } - - /* - Find virtual file which contains the declaration of descriptor we're navigating to. - */ - private fun findVirtualFileContainingDescriptor( - project: Project, - referencedDescriptor: DeclarationDescriptor): VirtualFile? { - if (ErrorUtils.isError(referencedDescriptor)) return null - - val containerClassId = getContainerClassId(project, referencedDescriptor) ?: return null - - val scopeToSearchIn = KotlinSourceFilterScope.sourceAndClassFiles(GlobalSearchScope.allScope(project), project) - - val virtualFileFinderFactory: VirtualFileFinderFactory - if (isFromKotlinJavasriptMetadata(referencedDescriptor)) { - virtualFileFinderFactory = JsVirtualFileFinderFactory.SERVICE.getInstance(project) - } - else { - virtualFileFinderFactory = JvmVirtualFileFinderFactory.SERVICE.getInstance(project) - } - - val fileFinder = virtualFileFinderFactory.create(scopeToSearchIn) - return fileFinder.findVirtualFileWithHeader(containerClassId) - } - - private fun isFromKotlinJavasriptMetadata(referencedDescriptor: DeclarationDescriptor): Boolean { - val packageFragmentDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, PackageFragmentDescriptor::class.java, false) - return packageFragmentDescriptor is KotlinJavascriptPackageFragment - } - - //TODO: navigate to inner classes - //TODO: should we construct proper SourceElement's for decompiled parts / facades? - private fun getContainerClassId(project: Project, referencedDescriptor: DeclarationDescriptor): ClassId? { - val deserializedCallableContainer = DescriptorUtils.getParentOfType(referencedDescriptor, DeserializedCallableMemberDescriptor::class.java, true) - if (deserializedCallableContainer != null) { - return getContainerClassId(project, deserializedCallableContainer) - } - - val containerDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, ClassOrPackageFragmentDescriptor::class.java, false) - if (containerDescriptor is PackageFragmentDescriptor) { - val packageFQN = containerDescriptor.fqName - - if (referencedDescriptor is DeserializedCallableMemberDescriptor) { - val partClassName = JvmFileClassUtil.getImplClassName(referencedDescriptor) - if (partClassName != null) { - val partFQN = packageFQN.child(partClassName) - val multifileFacadeJetFiles = StaticFacadeIndexUtil.getMultifileClassForPart(partFQN, GlobalSearchScope.allScope(project), project) - if (multifileFacadeJetFiles.isEmpty()) { - return ClassId(packageFQN, partClassName) - } - else { - val multifileFacade = multifileFacadeJetFiles.iterator().next() - val multifileFacadeName = multifileFacade.virtualFile.nameWithoutExtension - return ClassId(packageFQN, Name.identifier(multifileFacadeName)) - } - } - } - - return getPackageClassId(packageFQN) - } - if (containerDescriptor is ClassDescriptor) { - if (containerDescriptor.containingDeclaration is ClassDescriptor || ExpressionTypingUtils.isLocal(containerDescriptor.containingDeclaration, containerDescriptor)) { - return getContainerClassId(project, containerDescriptor.containingDeclaration) - } - return containerDescriptor.classId - } + val psiFile = PsiManager.getInstance(project).findFile(virtualFile) + if (psiFile !is KtDecompiledFile) { return null } + + return psiFile.getDeclarationForDescriptor(referencedDescriptor) +} + +private fun isLocal(descriptor: DeclarationDescriptor): Boolean { + if (descriptor is ParameterDescriptor) { + return isLocal(descriptor.containingDeclaration) + } + else { + return DescriptorUtils.isLocal(descriptor) + } +} + +/* + Find virtual file which contains the declaration of descriptor we're navigating to. + */ +private fun findVirtualFileContainingDescriptor( + project: Project, + referencedDescriptor: DeclarationDescriptor): VirtualFile? { + if (ErrorUtils.isError(referencedDescriptor)) return null + + val containerClassId = getContainerClassId(project, referencedDescriptor) ?: return null + + val scopeToSearchIn = KotlinSourceFilterScope.sourceAndClassFiles(GlobalSearchScope.allScope(project), project) + + val virtualFileFinderFactory: VirtualFileFinderFactory + if (isFromKotlinJavasriptMetadata(referencedDescriptor)) { + virtualFileFinderFactory = JsVirtualFileFinderFactory.SERVICE.getInstance(project) + } + else { + virtualFileFinderFactory = JvmVirtualFileFinderFactory.SERVICE.getInstance(project) + } + + val fileFinder = virtualFileFinderFactory.create(scopeToSearchIn) + return fileFinder.findVirtualFileWithHeader(containerClassId) +} + +private fun isFromKotlinJavasriptMetadata(referencedDescriptor: DeclarationDescriptor): Boolean { + val packageFragmentDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, PackageFragmentDescriptor::class.java, false) + return packageFragmentDescriptor is KotlinJavascriptPackageFragment +} + +//TODO: navigate to inner classes +//TODO: should we construct proper SourceElement's for decompiled parts / facades? +private fun getContainerClassId(project: Project, referencedDescriptor: DeclarationDescriptor): ClassId? { + val deserializedCallableContainer = DescriptorUtils.getParentOfType(referencedDescriptor, DeserializedCallableMemberDescriptor::class.java, true) + if (deserializedCallableContainer != null) { + return getContainerClassId(project, deserializedCallableContainer) + } + + val containerDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, ClassOrPackageFragmentDescriptor::class.java, false) + if (containerDescriptor is PackageFragmentDescriptor) { + val packageFQN = containerDescriptor.fqName + + if (referencedDescriptor is DeserializedCallableMemberDescriptor) { + val partClassName = JvmFileClassUtil.getImplClassName(referencedDescriptor) + if (partClassName != null) { + val partFQN = packageFQN.child(partClassName) + val multifileFacadeJetFiles = StaticFacadeIndexUtil.getMultifileClassForPart(partFQN, GlobalSearchScope.allScope(project), project) + if (multifileFacadeJetFiles.isEmpty()) { + return ClassId(packageFQN, partClassName) + } + else { + val multifileFacade = multifileFacadeJetFiles.iterator().next() + val multifileFacadeName = multifileFacade.virtualFile.nameWithoutExtension + return ClassId(packageFQN, Name.identifier(multifileFacadeName)) + } + } + } + + return getPackageClassId(packageFQN) + } + if (containerDescriptor is ClassDescriptor) { + if (containerDescriptor.containingDeclaration is ClassDescriptor || ExpressionTypingUtils.isLocal(containerDescriptor.containingDeclaration, containerDescriptor)) { + return getContainerClassId(project, containerDescriptor.containingDeclaration) + } + return containerDescriptor.classId + } + return null }